def create_logger(app): if app.config.get('ENVIRONMENT') == 'production': server_addr = ('localhost', 25) else: server_addr = ('localhost', 2525) mail_handler = logbook.MailHandler( '*****@*****.**', ['*****@*****.**'], server_addr=server_addr, level='DEBUG', format_string=u'''Subject: ERROR at gitorama.com [{record.time:%Y-%m-%d %H:%M}] {record.extra[request_id]}: {record.level_name}: {record.channel}: {record.message}''', related_format_string= u'[{record.time:%Y-%m-%d %H:%M}] {record.extra[request_id]}: {record.level_name}: {record.channel}: {record.message}', ) file_handler = logbook.FileHandler( app.config['LOG_FILE'], level='DEBUG', format_string= u'[{record.time:%Y-%m-%d %H:%M}] {record.extra[request_id]}: {record.level_name}: {record.channel}: {record.message}' ) def inject_id(record): record.extra['request_id'] = getattr(_request_ctx_stack.top, 'logbook_request_id', None) logger = logbook.NestedSetup([ logbook.NullHandler(), logbook.FingersCrossedHandler(mail_handler, reset=True), logbook.FingersCrossedHandler(file_handler, reset=True, bubble=True), logbook.Processor(inject_id), ]) return logger
def test_mail_handler_batching(activation_strategy, logger): mail_handler = make_fake_mail_handler() handler = logbook.FingersCrossedHandler(mail_handler, reset=True) with activation_strategy(handler): logger.warn('Testing') logger.debug('Even more') logger.error('And this triggers it') logger.info('Aha') logger.error('And this triggers it again!') assert len(mail_handler.mails) == 2 mail = mail_handler.mails[0][2] pieces = mail.split('Log records that led up to this one:') assert len(pieces) == 2 body, rest = pieces rest = rest.replace('\r', '') assert re.search('Message type:\s+ERROR', body) assert re.search('Module:\s+%s' % __name__, body) assert re.search('Function:\s+test_mail_handler_batching', body) related = rest.strip().split('\n\n') assert len(related) == 2 assert re.search('Message type:\s+WARNING', related[0]) assert re.search('Message type:\s+DEBUG', related[1]) assert 'And this triggers it again' in mail_handler.mails[1][2]
def test_fingerscrossed_buffer_size(activation_strategy): logger = logbook.Logger('Test') test_handler = logbook.TestHandler() handler = logbook.FingersCrossedHandler(test_handler, buffer_size=3) with activation_strategy(handler): logger.info('Never gonna give you up') logger.warn('Aha!') logger.warn('Moar!') logger.error('Pure hate!') assert test_handler.formatted_records == ['[WARNING] Test: Aha!', '[WARNING] Test: Moar!', '[ERROR] Test: Pure hate!']
def test_fingerscrossed_buffer_size(self): logger = logbook.Logger('Test') test_handler = logbook.TestHandler() handler = logbook.FingersCrossedHandler(test_handler, buffer_size=3) with handler: logger.info('Never gonna give you up') logger.warn('Aha!') logger.warn('Moar!') logger.error('Pure hate!') self.assertEqual(test_handler.formatted_records, [ '[WARNING] Test: Aha!', '[WARNING] Test: Moar!', '[ERROR] Test: Pure hate!' ])
def setup_logbook(app_name, config, min_level=None): if not config.syslog: try: os.makedirs(config.log_dir) except OSError: pass app_config = config.applications[app_name] or {} handlers = app_config.get("handlers") or config.default.handler_list logbook_handlers = [] finger_cross_config = config.finger_cross.copy() top_handler = True if min_level: min_level = logbook.lookup_level(min_level) for handler_name in handlers: handler_config = config.handlers[handler_name].copy() level = handler_config.get("level") if min_level and level: level = logbook.lookup_level(level) handler_config["level"] = max(min_level, level) handler_class = getattr(logbook, handler_config.pop("type")) finger_cross = handler_config.pop("finger_cross", False) _replace_config(handler_config, "__APP__", app_name) if "format_string" not in handler_config and handler_class is not logbook.NullHandler: handler_config["format_string"] = config.default.format_string if top_handler: handler_config["bubble"] = False if "filter" in handler_config: handler_config["filter"] = globals()[handler_config["filter"]] handler = handler_class(**handler_config) if finger_cross: finger_cross_level = logbook.lookup_level( finger_cross_config.pop("action_level")) handler = logbook.FingersCrossedHandler( handler, action_level=finger_cross_level, **finger_cross_config) logbook_handlers.append(handler) top_handler = False setup = logbook.NestedSetup(logbook_handlers) return setup
def test_fingerscrossed(activation_strategy, logger, default_handler): handler = logbook.FingersCrossedHandler(default_handler, logbook.WARNING) # if no warning occurs, the infos are not logged with activation_strategy(handler): with capturing_stderr_context() as captured: logger.info('some info') assert captured.getvalue() == '' assert (not handler.triggered) # but if it does, all log messages are output with activation_strategy(handler): with capturing_stderr_context() as captured: logger.info('some info') logger.warning('something happened') logger.info('something else happened') logs = captured.getvalue() assert 'some info' in logs assert 'something happened' in logs assert 'something else happened' in logs assert handler.triggered
def test_fingerscrossed(self): handler = logbook.FingersCrossedHandler(logbook.default_handler, logbook.WARNING) # if no warning occurs, the infos are not logged with handler: with capture_stderr() as captured: self.log.info('some info') self.assertEqual(captured.getvalue(), '') self.assert_(not handler.triggered) # but if it does, all log messages are output with handler: with capture_stderr() as captured: self.log.info('some info') self.log.warning('something happened') self.log.info('something else happened') logs = captured.getvalue() self.assert_('some info' in logs) self.assert_('something happened' in logs) self.assert_('something else happened' in logs) self.assert_(handler.triggered)
def make_fch(): return logbook.FingersCrossedHandler(handler_factory, logbook.WARNING)
import sys import time from flask import Flask, jsonify, request import logbook from .core import Autocompleter logger = logbook.Logger(__name__) log_handler = logbook.FingersCrossedHandler(logbook.StreamHandler(sys.stderr)) autocompleter = Autocompleter() app = Flask(__name__) @app.route('/search/') def search(): word = request.args.get('word') if not word: return jsonify({'data': [], 'execution_time_ns': 0}) start_time = time.perf_counter_ns() with log_handler: suggestions = list(autocompleter.suggest_matches(word)) time_taken = time.perf_counter_ns() - start_time slow = time_taken > 100_000_000 if slow: logger.error(f'Execution too slow: {time_taken}') return jsonify({ 'data': suggestions, 'execution_time_ns': time_taken, 'is_slow': slow })