use a shared logger through a fabric in order to have the same settings everywhere

parent 2c1b4bb7
Pipeline #1532 failed with stage
in 3 minutes and 12 seconds
......@@ -12,7 +12,6 @@ import os
import sys
import uuid
import hashlib
import logging
from flask import Blueprint, Response, request, current_app, session, abort
from flask_restplus import Api as ApiPlus
......@@ -25,6 +24,7 @@ from ..desc import __version__, __release__, __url__, __doc__
from ..engines.server import BUIServer # noqa
from ..exceptions import BUIserverException
from ..config import config
from ..tools.logging import logger
bui = current_app # type: BUIServer
EXEMPT_METHODS = set(['OPTIONS'])
......@@ -95,7 +95,7 @@ def check_acl(func):
class Api(ApiPlus):
"""Wrapper class around :class:`flask_restplus.Api`"""
logger = logging.getLogger('burp-ui')
logger = logger
# TODO: should use global object instead of reference
loaded = False
release = __release__
......
......@@ -7,13 +7,14 @@
.. moduleauthor:: Ziirish <hi+burpui@ziirish.me>
"""
import logging
import inspect
import json
from flask_restplus import Resource as ResourcePlus
from flask_restplus.errors import abort
from ...tools.logging import logger
class Resource(ResourcePlus):
"""Subclass default Resource to manage ACL"""
......@@ -21,7 +22,7 @@ class Resource(ResourcePlus):
# per resource
login_required = True
logger = logging.getLogger('burp-ui')
logger = logger
def abort(self, code=500, message=None, **kwargs):
"""
......
......@@ -13,8 +13,6 @@ import os
import time
import logging
from logging import Formatter
from .desc import __version__, __release__
from .extensions import create_celery, create_db, create_websocket, \
parse_db_setting, get_redis_server
......@@ -52,6 +50,7 @@ def create_app(conf=None, verbose=0, logfile=None, **kwargs):
from flask_bower import Bower
from flask_babel import gettext
from .utils import ReverseProxied, lookup_file, is_uuid
from .tools.logging import logger
from .security import basic_login_from_request
from .engines.server import BUIServer as BurpUI
from .sessions import session_manager
......@@ -60,8 +59,6 @@ def create_app(conf=None, verbose=0, logfile=None, **kwargs):
from .ext.i18n import babel, get_locale
from .misc.auth.handler import BUIanon
logger = logging.getLogger('burp-ui')
gunicorn = kwargs.get('gunicorn', True)
unittest = kwargs.get('unittest', False)
debug = kwargs.get('debug', False)
......@@ -70,59 +67,22 @@ def create_app(conf=None, verbose=0, logfile=None, **kwargs):
celery_worker = kwargs.get('celery_worker', False)
websocket_server = kwargs.get('websocket_server', False)
# The debug argument used to be a boolean so we keep supporting this format
if isinstance(verbose, bool):
if verbose:
verbose = logging.DEBUG
else:
verbose = logging.CRITICAL
else:
levels = [
logging.CRITICAL,
logging.ERROR,
logging.WARNING,
logging.INFO,
logging.DEBUG
]
if verbose >= len(levels):
verbose = len(levels) - 1
if not verbose:
verbose = 0
verbose = levels[verbose]
if logfile:
from logging.handlers import RotatingFileHandler
handler = RotatingFileHandler(
logfile,
maxBytes=1024 * 1024 * 100,
backupCount=5
)
else:
from logging import StreamHandler
handler = StreamHandler()
if not unittest: # pragma: no cover
from ._compat import patch_json
patch_json()
if verbose > logging.DEBUG:
LOG_FORMAT = (
'[%(asctime)s] %(levelname)s in '
'%(module)s.%(funcName)s: %(message)s'
)
else:
LOG_FORMAT = (
'-' * 27 +
'[%(asctime)s]' +
'-' * 28 + '\n' +
'%(levelname)s in %(module)s.%(funcName)s ' +
'[%(pathname)s:%(lineno)d]:\n' +
'%(message)s\n' +
'-' * 80
)
# We initialize the core
app = BurpUI()
handler.setLevel(verbose)
handler.setFormatter(Formatter(LOG_FORMAT))
app.config['CFG'] = None
app.config['LOG_FILE'] = logfile
app.config['LOG_LEVEL'] = verbose
logger.setLevel(verbose)
logger.init_app(app)
if verbose:
app.enable_logger()
logger.addHandler(handler)
app.gunicorn = gunicorn
logger.debug(
'conf: {}\n'.format(conf) +
......@@ -137,18 +97,6 @@ def create_app(conf=None, verbose=0, logfile=None, **kwargs):
'websocket_server: {}'.format(websocket_server)
)
if not unittest: # pragma: no cover
from ._compat import patch_json
patch_json()
# We initialize the core
app = BurpUI()
if verbose:
app.enable_logger()
app.gunicorn = gunicorn
app.config['CFG'] = None
# Some config
app.config['BUI_CLI'] = cli
......
......@@ -10,14 +10,15 @@
import os
import re
import codecs
import logging
import configobj
import validate
from .tools.logging import logger
class BUIConfig(dict):
"""Custom config parser"""
logger = logging.getLogger('burp-ui')
logger = logger
mtime = 0
def __init__(self, config=None, explain=False, defaults=None):
......
......@@ -17,12 +17,12 @@ import datetime
from itertools import count
from async_generator import asynccontextmanager
from logging.handlers import RotatingFileHandler
from ..exceptions import BUIserverException
from ..misc.backend.utils.burp2 import Monitor
from ..config import config
from .._compat import to_bytes, to_unicode
from ..tools.logging import logger
from ..desc import __version__
......@@ -84,46 +84,19 @@ class Pool:
class MonitorPool:
logger = logging.getLogger('burp-ui') # type: logging.Logger
logger = logger
# cache status results
_status_cache = {}
_last_status_cleanup = datetime.datetime.now()
_time_to_cache = datetime.timedelta(seconds=5)
def __init__(self, conf=None, level=0, logfile=None, debug=False):
self.debug = debug
def __init__(self, conf=None, level=0, logfile=None):
level = level or 0
if level > logging.NOTSET:
levels = [
logging.CRITICAL,
logging.ERROR,
logging.WARNING,
logging.INFO,
logging.DEBUG,
]
if level >= len(levels):
level = len(levels) - 1
lvl = levels[level]
self.logger.setLevel(lvl)
if lvl > logging.DEBUG:
LOG_FORMAT = '[%(asctime)s] %(levelname)s in %(module)s.%(funcName)s: %(message)s'
else:
LOG_FORMAT = (
'-' * 80 + '\n' +
'%(levelname)s in %(module)s.%(funcName)s [%(pathname)s:%(lineno)d]:\n' +
'%(message)s\n' +
'-' * 80
)
if logfile:
handler = RotatingFileHandler(logfile, maxBytes=1024 * 1024 * 100, backupCount=20)
else:
handler = logging.StreamHandler()
handler.setLevel(lvl)
handler.setFormatter(logging.Formatter(LOG_FORMAT))
self.logger.addHandler(handler)
self.logger.info(f'conf: {conf}')
self.logger.info('level: {}'.format(logging.getLevelName(lvl)))
self.logger.init_logger(config=dict(level=level, logfile=logfile))
lvl = logging.getLevelName(self.logger.getEffectiveLevel())
self.logger.info(f'conf: {conf}')
self.logger.info(f'level: {lvl}')
if not conf:
raise IOError('No configuration file found')
......
......@@ -12,6 +12,7 @@ import re
import sys
import logging
from ..tools.logging import logger
from ..misc.auth.handler import UserAuthHandler
from ..misc.acl.handler import ACLloader
from ..misc.audit.handler import BUIauditLoader
......@@ -92,7 +93,7 @@ class BUIServer(Flask):
super(BUIServer, self).__init__('burpui')
self.init = False
# We cannot override the Flask's logger so we use our own
self._logger = logging.getLogger('burp-ui')
self._logger = logger
self._logger.disabled = True
self.conf = config
# switch the flask config with our magic config object
......
......@@ -3,6 +3,7 @@ import re
import logging
from .interface import BUIaudit, BUIauditLogger as BUIauditLoggerInterface
from ...tools.logging import logger as parent_logger
class BUIauditLoader(BUIaudit):
......@@ -69,7 +70,7 @@ class BUIauditLoader(BUIaudit):
class BUIauditLogger(BUIauditLoggerInterface):
_logger = logging.getLogger('burp-ui.audit') # type: logging.Logger
_logger = parent_logger.getChild('audit') # type: logging.Logger
def __init__(self, loader):
self.loader = loader
......
......@@ -81,8 +81,8 @@ class BUIauditLogger(BUIauditLoggerInterface):
caller = ''
stack = inspect.stack()
exclude = [
'interface.py',
'handler.py',
'audit/interface.py',
'audit/handler.py',
]
for frame in stack:
if any([frame.filename.endswith(x) for x in exclude]):
......
......@@ -10,11 +10,11 @@
from flask_login import UserMixin, AnonymousUserMixin
from abc import ABCMeta, abstractmethod, abstractproperty
import logging
from ...tools.logging import logger
class BUIloader:
logger = logging.getLogger('burp-ui')
logger = logger
class BUIhandler(object, metaclass=ABCMeta):
......
......@@ -9,7 +9,7 @@
"""
from abc import ABCMeta, abstractmethod
import logging
from ...tools.logging import logger
class BUIparser(object, metaclass=ABCMeta):
......@@ -17,7 +17,7 @@ class BUIparser(object, metaclass=ABCMeta):
interface for ``burp`` configuration files parser.
"""
logger = logging.getLogger('burp-ui')
logger = logger
@abstractmethod
def read_server_conf(self, conf=None):
......
......@@ -8,12 +8,13 @@
import os
import re
import codecs
import logging
import subprocess
from hashlib import md5
from OpenSSL import crypto
from ...tools.logging import logger
class OSSLAuth(object):
"""OpenSSL wrapper"""
......@@ -29,7 +30,7 @@ class OSSLAuth(object):
:param global_conf: Global config
:type global_conf: :class:`burpui.misc.parser.utils.Config`
"""
self.logger = logging.getLogger('burp-ui')
self.logger = logger
self.name = ca_name
self.ossl_conf = ossl_conf
self.global_conf = global_conf
......
# -*- coding: utf8 -*-
"""
Burp-UI is a web-ui for burp backup written in python with Flask and
jQuery/Bootstrap
.. module:: burpui.logging
:platform: Unix
:synopsis: Burp-UI logging module.
.. moduleauthor:: Ziirish <hi+burpui@ziirish.me>
"""
import logging
def convert_level(verbose):
# This is already a valid level
if logging.getLevelName(verbose) != "Level %s" % verbose:
return verbose
# The debug argument used to be a boolean so we keep supporting this format
if isinstance(verbose, bool):
if verbose:
verbose = logging.DEBUG
else:
verbose = logging.CRITICAL
else:
levels = [
logging.CRITICAL,
logging.ERROR,
logging.WARNING,
logging.INFO,
logging.DEBUG
]
if verbose >= len(levels):
verbose = len(levels) - 1
if not verbose:
verbose = 0
verbose = levels[verbose]
return verbose
class Logger(logging.Logger):
"""
Helper class to share our logging object across the application
"""
app = None
_handler = None
def __init__(self, app=None, name=None, level=logging.NOTSET):
"""
:param app: Application context
:type app: flask.Flask
:param name: Logger name
:type name: str
:param level: Default logging level
:type level: int
"""
if app and not name: # pragma: nocover
name = app.name
elif not name:
name = "burp-ui"
logging.Logger.__init__(self, name, level)
if app: # pragma: nocover
self.init_app(app)
def init_app(self, app):
"""
:param app: Application context
:type app: flask.Flask
"""
self.app = app
config = {
'level': app.config.get("LOG_LEVEL"),
'logfile': app.config.get("LOG_FILE")
}
self.init_logger(config)
def init_logger(self, config):
"""
:param config: Logger configuration
:type config: dict
"""
level = config.get("level", None)
level = self.level if level is None else level
level = convert_level(level)
logfile = config.get("logfile")
if self._handler is not None:
self.removeHandler(self._handler)
if logfile:
handler = logging.FileHandler(logfile)
else:
handler = logging.StreamHandler()
if level > logging.DEBUG:
LOG_FORMAT = (
'[%(asctime)s] %(levelname)s in '
'%(module)s.%(funcName)s: %(message)s'
)
else:
LOG_FORMAT = (
'-' * 27 +
'[%(asctime)s]' +
'-' * 28 + '\n' +
'%(levelname)s in %(module)s.%(funcName)s ' +
'[%(pathname)s:%(lineno)d]:\n' +
'%(message)s\n' +
'-' * 80
)
handler.setLevel(level)
handler.setFormatter(logging.Formatter(LOG_FORMAT))
self.setLevel(level)
self.addHandler(handler)
self._handler = handler
logger = Logger()
......@@ -20,8 +20,9 @@ ROOT = os.path.dirname(os.path.realpath(__file__))
# Try to load modules from our current env first
sys.path.insert(0, os.path.join(ROOT, '..'))
logger = logging.getLogger('burp-ui')
logger.setLevel(logging.CRITICAL)
from burpui_agent.tools.logging import logger
logger.init_logger(config=dict(level=logging.CRITICAL))
def parse_args(name=None):
......@@ -30,7 +31,6 @@ def parse_args(name=None):
mname = 'bui-agent'
parser = ArgumentParser(prog=mname)
parser.add_argument('-v', '--verbose', dest='log', help='increase output verbosity (e.g., -vv is more verbose than -v)', action='count')
parser.add_argument('-d', '--debug', dest='debug', help='enable debug mode', action='store_true')
parser.add_argument('-V', '--version', dest='version', help='print version and exit', action='store_true')
parser.add_argument('-c', '--config', dest='config', help='burp-ui configuration file', metavar='<CONFIG>')
parser.add_argument('-l', '--logfile', dest='logfile', help='output logs in defined file', metavar='<FILE>')
......@@ -75,7 +75,7 @@ def agent(options=None):
conf = lookup_file(conf)
check_config(conf)
agent = Agent(conf, options.log, options.logfile, options.debug)
agent = Agent(conf, options.log, options.logfile)
trio.run(agent.run)
......
../../../../burpui/tools/logging.py
\ No newline at end of file
......@@ -113,8 +113,8 @@ setup(
(confdir, [os.path.join(confdir, 'buiagent.sample.cfg')]),
],
install_requires=[
'trio==0.4.0',
'arrow==0.12.0',
'trio==0.10.0',
'arrow==0.12.1',
'tzlocal==1.5.1',
'pyOpenSSL>=17.5.0',
'configobj==5.0.6',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment