Logging erweitern um IP-Adressen #70-4 (#85) #87
@@ -13,7 +13,7 @@
 | 
			
		||||
  },
 | 
			
		||||
  "BotLoggingSettings": {
 | 
			
		||||
    "Api": {
 | 
			
		||||
      "Path": "logs/",
 | 
			
		||||
      "Path": "logs/$date_now/",
 | 
			
		||||
      "Filename": "api.log",
 | 
			
		||||
      "ConsoleLogLevel": "TRACE",
 | 
			
		||||
      "FileLogLevel": "TRACE"
 | 
			
		||||
 
 | 
			
		||||
@@ -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": {
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
  },
 | 
			
		||||
  "BotLoggingSettings": {
 | 
			
		||||
    "Api": {
 | 
			
		||||
      "Path": "logs/",
 | 
			
		||||
      "Path": "logs/$date_now/",
 | 
			
		||||
      "Filename": "api.log",
 | 
			
		||||
      "ConsoleLogLevel": "ERROR",
 | 
			
		||||
      "FileLogLevel": "INFO"
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
  },
 | 
			
		||||
  "BotLoggingSettings": {
 | 
			
		||||
    "Api": {
 | 
			
		||||
      "Path": "logs/",
 | 
			
		||||
      "Path": "logs/$date_now/",
 | 
			
		||||
      "Filename": "api.log",
 | 
			
		||||
      "ConsoleLogLevel": "INFO",
 | 
			
		||||
      "FileLogLevel": "DEBUG"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,14 @@
 | 
			
		||||
import json
 | 
			
		||||
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 +41,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 +104,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
 | 
			
		||||
        )
 | 
			
		||||
 
 | 
			
		||||
@@ -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",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user