如何在python记录器中记录请求的特定属性

cod*_*ode 2 python logging server

我有一个python文件'server.py'

#!/usr/bin/env python

import sys, BaseHTTPServer
from mylogger import logging
logger = logging.getLogger(__name__)

class RESTRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):
        logger.error('Just random log')
        self.send_response(200)
        self.end_headers()

def rest_server(port):
    'Starts the REST server'
    http_server = BaseHTTPServer.HTTPServer(('', port), RESTRequestHandler)
    print 'Starting HTTP server at port %d' % port
    try:
        http_server.serve_forever()
    except KeyboardInterrupt:
        pass
    print 'Stopping HTTP server'
    http_server.server_close()

def main(argv):
    rest_server(8080)

if __name__ == '__main__':
    main(sys.argv[1:])
Run Code Online (Sandbox Code Playgroud)

我还有另一个文件“ mylogger.py”

__all__ = ['logging']

import logging
FORMAT = '%(asctime)s | %(tid)d | %(message)s'

def req_extractor(*args, **kargs):
    print(args)
    print(kargs)
    print(locals())
    # here i want to get request X-App-Tid
    return {'tid': 1}

class CustomLogger(logging.Logger):
    def _log(self, level, msg, args, exc_info=None, extra=None):
        reqObj = req_extractor()
        if extra is None: extra = {}
        reqObj.update(extra)
        super(CustomLogger, self)._log(level, msg, args, exc_info, reqObj)

logging.setLoggerClass(CustomLogger)

logging.basicConfig(
        filename='python.log',
        format=FORMAT,
        datefmt='%m/%d/%Y %I:%M:%S %p',
        level=logging.DEBUG)
Run Code Online (Sandbox Code Playgroud)

当我打电话时

curl -H 'X-App-Tid:1' -i http://localhost:8080
Run Code Online (Sandbox Code Playgroud)

我得到

07/23/2019 04:50:45 PM | 1 | Just random log
Run Code Online (Sandbox Code Playgroud)

我可以tid在日志中打印,但是我想从请求标头中提取它X-App-Tid

注意:不允许更改server.py文件,但我可以在mylogger.py中进行任何更改

有什么帮助吗?

Tar*_*ani 6

您可以像下面那样更新记录器,以覆盖现有的类

__all__ = ['logging']

import logging

import BaseHTTPServer
org = BaseHTTPServer.BaseHTTPRequestHandler

current_class = None

class MyClass(BaseHTTPServer.BaseHTTPRequestHandler, object):

   def parse_request(self):
       global current_class
       current_class = self
       value =  super(MyClass, self).parse_request()

       return value

BaseHTTPServer.BaseHTTPRequestHandler = MyClass       

FORMAT = '%(asctime)s | %(tid)d | %(message)s'

def req_extractor(*args, **kargs):
    print(args)
    print(kargs)
    print(locals())
    global current_class
    if current_class:
       print current_class.headers['X-App-Tid']
    # here i want to get request 
    return {'tid': 1}

class CustomLogger(logging.Logger):
    def _log(self, level, msg, args, exc_info=None, extra=None):
        reqObj = req_extractor()
        if extra is None: extra = {}
        reqObj.update(extra)
        super(CustomLogger, self)._log(level, msg, args, exc_info, reqObj)

logging.setLoggerClass(CustomLogger)

logging.basicConfig(
        filename='python.log',
        format=FORMAT,
        datefmt='%m/%d/%Y %I:%M:%S %p',
        level=logging.DEBUG)

Run Code Online (Sandbox Code Playgroud)

然后它会工作

标头打印