diff --git a/kdb-bot/src/bot/config/appsettings.development.json b/kdb-bot/src/bot/config/appsettings.development.json index 9000413b..a69ebd74 100644 --- a/kdb-bot/src/bot/config/appsettings.development.json +++ b/kdb-bot/src/bot/config/appsettings.development.json @@ -13,7 +13,7 @@ }, "BotLoggingSettings": { "Api": { - "Path": "logs/", + "Path": "logs/$date_now/", "Filename": "api.log", "ConsoleLogLevel": "TRACE", "FileLogLevel": "TRACE" diff --git a/kdb-bot/src/bot/config/appsettings.edrafts-pc-ubuntu.json b/kdb-bot/src/bot/config/appsettings.edrafts-pc-ubuntu.json index f0b9f1d1..9deca017 100644 --- a/kdb-bot/src/bot/config/appsettings.edrafts-pc-ubuntu.json +++ b/kdb-bot/src/bot/config/appsettings.edrafts-pc-ubuntu.json @@ -8,7 +8,7 @@ "LoggingSettings": { "Path": "logs/", "Filename": "bot.log", - "ConsoleLogLevel": "TRACE", + "ConsoleLogLevel": "DEBUG", "FileLogLevel": "TRACE" }, "BotLoggingSettings": { @@ -27,7 +27,7 @@ "Database": { "Path": "logs/", "Filename": "database.log", - "ConsoleLogLevel": "TRACE", + "ConsoleLogLevel": "DEBUG", "FileLogLevel": "TRACE" }, "Message": { diff --git a/kdb-bot/src/bot/config/appsettings.production.json b/kdb-bot/src/bot/config/appsettings.production.json index 2fd3a039..0b1ba8c6 100644 --- a/kdb-bot/src/bot/config/appsettings.production.json +++ b/kdb-bot/src/bot/config/appsettings.production.json @@ -13,7 +13,7 @@ }, "BotLoggingSettings": { "Api": { - "Path": "logs/", + "Path": "logs/$date_now/", "Filename": "api.log", "ConsoleLogLevel": "ERROR", "FileLogLevel": "INFO" diff --git a/kdb-bot/src/bot/config/appsettings.staging.json b/kdb-bot/src/bot/config/appsettings.staging.json index b36825ee..d467b0da 100644 --- a/kdb-bot/src/bot/config/appsettings.staging.json +++ b/kdb-bot/src/bot/config/appsettings.staging.json @@ -13,7 +13,7 @@ }, "BotLoggingSettings": { "Api": { - "Path": "logs/", + "Path": "logs/$date_now/", "Filename": "api.log", "ConsoleLogLevel": "INFO", "FileLogLevel": "DEBUG" diff --git a/kdb-bot/src/bot_api/api.py b/kdb-bot/src/bot_api/api.py index f1e79077..b31eee19 100644 --- a/kdb-bot/src/bot_api/api.py +++ b/kdb-bot/src/bot_api/api.py @@ -1,13 +1,15 @@ -import json +import re import sys +import textwrap import uuid from functools import partial +from typing import Union import eventlet from cpl_core.dependency_injection import ServiceProviderABC from cpl_core.utils import CredentialManager from eventlet import wsgi -from flask import Flask, request, jsonify, Response, make_response +from flask import Flask, request, jsonify, Response from flask_cors import CORS from flask_socketio import SocketIO from werkzeug.exceptions import NotFound @@ -40,21 +42,36 @@ class Api(Flask): self._logger = logger self._services = services - self._apt_settings = api_settings + self._api_settings = api_settings self._auth_settings = auth_settings self._cors = CORS(self, support_credentials=True) - # register before request - self.before_request_funcs.setdefault(None, []).append(self.before_request) + # register hooks + self.before_request(self.before_request_hook) + self.after_request(self.after_request_hook) + + # register error handler exc_class, code = self._get_exc_class_and_code(Exception) - self.error_handler_spec[None][code][exc_class] = self.handle_exception + self.register_error_handler(exc_class, self.handle_exception) # websockets self._socketio = SocketIO(self, cors_allowed_origins='*', path='/api/socket.io') self._socketio.on_event('connect', self.on_connect) self._socketio.on_event('disconnect', self.on_disconnect) + self._requests = {} + + @staticmethod + def _get_methods_from_registered_route() -> Union[list[str], str]: + methods = ['Unknown'] + if request.path in Route.registered_routes and len(Route.registered_routes[request.path]) >= 1 and 'methods' in Route.registered_routes[request.path][1]: + methods = Route.registered_routes[request.path][1]['methods'] + + if len(methods) == 1: + return methods[0] + return methods + def _register_routes(self): for path, f in Route.registered_routes.items(): route = f[0] @@ -88,20 +105,46 @@ class Api(Flask): error = ErrorDTO(None, user_message) return jsonify(error.to_dict()), 400 - def before_request(self, *args, **kwargs): - self._logger.debug(__name__, f'Received GET @{request.url}') - headers = str(request.headers).replace("\n", "\n\t") - self._logger.trace(__name__, f'Headers: \n\t{headers}') + def before_request_hook(self): + request_id = uuid.uuid4() + self._requests[request] = request_id + method = request.access_control_request_method + + self._logger.info(__name__, f'Received {request_id} @ {self._get_methods_from_registered_route() if method is None else method} {request.url} from {request.remote_addr}') + + headers = str(request.headers).replace('\n', '\n\t\t') + data = request.get_data() + data = '' if len(data) == 0 else str(data.decode(encoding="utf-8")) + + text = textwrap.dedent(f'Request: {request_id}:\n\tHeader:\n\t\t{headers}\n\tUser-Agent: {request.user_agent.string}\n\tBody: {data}') + self._logger.trace(__name__, text) + + def after_request_hook(self, response: Response): + method = request.access_control_request_method + request_id = f'{self._get_methods_from_registered_route() if method is None else method} {request.url} from {request.remote_addr}' + if request in self._requests: + request_id = self._requests[request] + + self._logger.info(__name__, f'Answered {request_id}') + + headers = str(request.headers).replace('\n', '\n\t\t') + data = request.get_data() + data = '' if len(data) == 0 else str(data.decode(encoding="utf-8")) + + text = textwrap.dedent(f'Request: {request_id}:\n\tHeader:\n\t\t{headers}\n\tResponse: {data}') + self._logger.trace(__name__, text) + + return response def start(self): - self._logger.info(__name__, f'Starting API {self._apt_settings.host}:{self._apt_settings.port}') + self._logger.info(__name__, f'Starting API {self._api_settings.host}:{self._api_settings.port}') self._register_routes() self.secret_key = CredentialManager.decrypt(self._auth_settings.secret_key) # from waitress import serve # https://docs.pylonsproject.org/projects/waitress/en/stable/arguments.html # serve(self, host=self._apt_settings.host, port=self._apt_settings.port, threads=10, connection_limit=1000, channel_timeout=10) wsgi.server( - eventlet.listen((self._apt_settings.host, self._apt_settings.port)), + eventlet.listen((self._api_settings.host, self._api_settings.port)), self, log_output=False ) diff --git a/kdb-bot/src/bot_api/config/apisettings.edrafts-pc-ubuntu.json b/kdb-bot/src/bot_api/config/apisettings.edrafts-pc-ubuntu.json index f122db51..100812aa 100644 --- a/kdb-bot/src/bot_api/config/apisettings.edrafts-pc-ubuntu.json +++ b/kdb-bot/src/bot_api/config/apisettings.edrafts-pc-ubuntu.json @@ -1,19 +1,18 @@ { "Api": { - "Port": 5000, + "Port": 8044, "Host": "0.0.0.0", "RedirectToHTTPS": false }, "Authentication": { "SecretKey": "RjNiNUxEeisjSnZ6Zz1XIUBnc2EleHNG", - "Issuer": "http://localhost:5000", + "Issuer": "http://localhost:8084", "Audience": "http://localhost:4200", "TokenExpireTime": 1, "RefreshTokenExpireTime": 7 }, "DiscordAuthentication": { "ClientSecret": "V3FTb3JYVFBiVktEeHZxdWJDWW4xcnBCbXRwdmpwcy0=", - "_RedirectURL": "http://localhost:5000/api/auth/discord/register", "RedirectURL": "http://localhost:4200/auth/register", "Scope": [ "identify", diff --git a/kdb-web/src/app/app.module.ts b/kdb-web/src/app/app.module.ts index bda8098f..2753cf18 100644 --- a/kdb-web/src/app/app.module.ts +++ b/kdb-web/src/app/app.module.ts @@ -37,7 +37,7 @@ import { SettingsService } from './services/settings/settings.service'; JwtModule.forRoot({ config: { tokenGetter, - allowedDomains: ['localhost:5000', 'localhost:5001'], + allowedDomains: ['localhost:8044', 'localhost:8041', 'localhost:5000'], disallowedRoutes: [] } }), diff --git a/kdb-web/src/app/services/socket/socket.service.ts b/kdb-web/src/app/services/socket/socket.service.ts index a5520b3f..9cd05e9a 100644 --- a/kdb-web/src/app/services/socket/socket.service.ts +++ b/kdb-web/src/app/services/socket/socket.service.ts @@ -56,6 +56,7 @@ export class SocketService { this.socket.on("disconnect", () => { if (this.disconnected) { + this.spinnerService.showSpinner(); return; }