在结构化日志(JSON)中发出上下文信息的简单库

context-log的Python项目详细描述


Python上下文日志库

关于

context log是一个简单的库,用于在结构化日志(JSON)中发出上下文信息。在

它在Docker或Serverless(例如AWS Lambda)环境中工作得特别好,其中一个线程执行一个请求并生成一个响应。在

库使用python线程来存储上下文信息,这些信息会自动添加到contextMap字段中的所有后续日志中。在

因为库使用Python线程本地上下文,所以它可以跨给定项目中的包和模块工作。在

该方法松散地基于Log4j 2 API Thread Context。在

使用

结构化日志可以用python-json-logger library实现。在

只需将项目依赖项添加到要求.txt公司名称:

python_json_loggerPyYAMLcontext-log

将下面的代码添加到主代码模块。在

resources/logging.yaml文件中添加以下YAML配置,该文件将JSON结构化日志输出到stdout。在

^{pr2}$

使用上下文日志库发出日志。示例如下。在

importlogging.configimportyamlwithopen('resources/logging.yaml','r')aslog_config_file:logging.config.dictConfig(yaml.safe_load(log_config_file))fromcontext_logimportContextLogdefhandler(event,context):# Clear context (e.g. re-use) and get loggerlog=ContextLog.get_logger('handler',True)log.info('start')ContextLog.put('ip','1.2.3.4')# Helper to add start time in ISO and epoch timeContextLog.put_request_start_time()# Process requestsleep(0.1)# Helper to add end time in ISO and epoch time# as well as duration in millisecondsContextLog.put_request_end_time()log.info('end')

第一个日志信息事件:

{"asctime":"2019-09-19 11:53:20,479","name":"handler","levelname":"INFO","message":"start","filename":"test_example.py","contextMap":{}}

第二个日志信息事件:

{"asctime":"2019-09-19 11:53:20,580","name":"handler","levelname":"INFO","message":"end","filename":"test_example.py","contextMap":{"ip":"1.2.3.4","start-time":"2019-09-19T11:53:20.480085","epoch-start-time":1568890400.480085,"end-time":"2019-09-19T11:53:20.580513","epoch-end-time":1568890400.580513,"duration":100.428}}

细节

标准记录器由LoggerAdapter包装。因此,必须执行ContextLog.get_logger(name='<name>', clear=True|False)调用以使记录器发出上下文日志。在

启动新请求时使用clear=True,以便在重新使用线程时清除以前的上下文。这在线程池和AWS Lambda中是典型的情况

要操作或检索contextMap,请使用以下方法:

  • clear()
  • put(key, value)
  • get(key)
  • get_map()

也有许多助手试图标准化日志输出contextMap字段:

  • put_request_id(request_id)
  • put_request_method(request_method)
  • put_request_path(request_path)
  • put_response_status(response_status)
  • put_start_time()
  • put_end_time()
  • put_request_user_id(request_user_id)
  • put_request_client_id(request_client_id)
  • put_request_primary_ip(primary_ip)
  • put_request_client_ip(client_ip)
  • put_request_viewer_country(viewer_country)
  • put_trigger_source(trigger_source)

贡献

拉取请求非常受欢迎。在

运行pytest

创建virtualenv、下载依赖项并运行测试:

python3 -m venv .venv
source .venv/bin/activate
pip3 install -r tests/requirements.txt
pip3 install -e .
pytest

运行毒物分析

pip3 install --user --upgrade tox
tox

将库发布到PyPI

来自Packaging Python Projects站点的简短版本。在

安装释放工具:

python3 -m pip install --user --upgrade setuptools wheel twine

删除旧分发:

rm -rf dist/

生成上下文日志包:

python3 setup.py sdist bdist_wheel

首先上载上下文日志以测试PyPI:

python3 -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java基于条件如何创建StringBuffers并向其添加数据   java如何用UNC路径解决“不表示可正确访问的目录”异常?   在执行提取方法重构后,java代码的速度降低了6倍   java如何修改LDAPCertStore中用于X509证书链验证的LDAP连接属性   awt如何在Java中捕获鼠标光标?   字符串如何设置Java输出流   java NumberFormatException:用于输入字符串:“8:00”   unix/linux“tail f”的Java IO文件实现   java打印输出。带有JOptionPane的txt文件   java解组总是显示0和null   使用MySQL的windows java JavaFX自包含应用程序打包   JavaSpring:方法getBean(String…)是如何实现的根据输入字符串查找bean?   java高效地更新RecyclerView网格或以其他方式显示复杂网格   java向ArrayList添加对象(String、String、int、int)   java在一组文档上使用ForkJoinPool