使用 PyInstaller 自定义日志处理程序和格式化程序
Custom logging handler and formatter with PyInstaller
我有一个 Python 包,我使用 PyInstaller 作为单个可执行文件分发。
我将 logging
模块与基于文件的配置结合使用。为了实现集中式、基于云的日志记录,我决定使用模块 loggly-python-handler and python-json-logger to send the log information to loggly。后者将日志消息转换为 JSON,第一个使用 HTTP(S) 调用将 (JSON) 日志消息发送到 Loggly。
我的日志记录配置的摘录(当然,实际的 TOKEN
值已被删除):
[handler_loggly]
class=loggly.handlers.HTTPSHandler
formatter=json
args=('https://logs-01.loggly.com/inputs/TOKEN/tag/test','POST')
level=CRITICAL
[formatter_json]
format= %(name)s %(asctime)s %(filename)s %(created)f %(funcName)s %(levelno)s %(lineno)d %(msecs)d %(levelname)s %(message)s
class=pythonjsonlogger.jsonlogger.JsonFormatter
当 运行 在安装了 Python(和必要的库)的机器上时,它工作正常。但是,PyInstaller 生成的可执行文件似乎缺少所需的日志记录模块(因为它们没有在源代码中的任何地方导入,只是在日志记录配置中引用)。
运行 可执行文件时的错误输出:
Traceback (most recent call last):
File "c:\python35\lib\logging\config.py", line 98, in _resolve
AttributeError: module 'pythonjsonlogger' has no attribute 'jsonlogger'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<string>", line 64, in <module>
File "<string>", line 41, in main
File "<string>", line 28, in init_logger
File "c:\python35\lib\logging\config.py", line 76, in fileConfig
File "c:\python35\lib\logging\config.py", line 123, in _create_formatters
File "c:\python35\lib\logging\config.py", line 100, in _resolve
ImportError: No module named 'pythonjsonlogger.jsonlogger'
main returned -1
尝试 1
我试过使用 PyInstaller 的 hidden import functionality 来引用这两个模块:
pyinstaller \
--log-level=DEBUG \
--onefile \
--hidden-import=loggly \
--hidden-import=pythonjsonlogger main.py
日志文件输出:
3463 DEBUG: Hidden import: loggly
3463 INFO: Analyzing hidden import 'loggly'
3463 DEBUG: Hidden import: pythonjsonlogger
3478 INFO: Analyzing hidden import 'pythonjsonlogger'
尝试 2
试图在 PyInstaller 的规范文件(以下摘录)中指定导入:
a = Analysis(['main.py'],
pathex=['C:\Dev\pyWebiExport'],
binaries=None,
datas=None,
hiddenimports=['loggly.handlers.*', 'pythonjsonlogger.jsonlogger.*'],
hookspath=None,
…
日志文件输出:
3510 DEBUG: Hidden import: loggly.handlers.*
3510 INFO: Analyzing hidden import 'loggly.handlers.*'
5694 ERROR: Hidden import 'loggly.handlers.*' not found
5694 DEBUG: Hidden import: pythonjsonlogger.jsonlogger.*
5694 INFO: Analyzing hidden import 'pythonjsonlogger.jsonlogger.*'
5709 ERROR: Hidden import 'pythonjsonlogger.jsonlogger.*' not found
版本信息:
- Python 3.5.1 (Windows, x86)
- PyInstaller 3.0
- python-json-记录器 (0.1.4)
- loggly-python-处理程序 (1.0.0)
我能够通过为 PyInstaller 编写一个 runtime hook 来解决这个问题,它基本上由一个额外的 Python 脚本组成,其内容如下:
import pythonjsonlogger.jsonlogger
import loggly.handlers
我将这些语句保存在文件 loggly_hook.py
和 运行 PyInstaller 中,参数如下:
pyinstaller \
--log-level=DEBUG \
--onefile \
--clean \
--runtime-hook=loggly_hook.py main.py
PyInstaller 日志输出:
10374 INFO: Analyzing run-time hooks ...
10389 INFO: Including custom run-time hook 'loggly_hook.py'
我有一个 Python 包,我使用 PyInstaller 作为单个可执行文件分发。
我将 logging
模块与基于文件的配置结合使用。为了实现集中式、基于云的日志记录,我决定使用模块 loggly-python-handler and python-json-logger to send the log information to loggly。后者将日志消息转换为 JSON,第一个使用 HTTP(S) 调用将 (JSON) 日志消息发送到 Loggly。
我的日志记录配置的摘录(当然,实际的 TOKEN
值已被删除):
[handler_loggly]
class=loggly.handlers.HTTPSHandler
formatter=json
args=('https://logs-01.loggly.com/inputs/TOKEN/tag/test','POST')
level=CRITICAL
[formatter_json]
format= %(name)s %(asctime)s %(filename)s %(created)f %(funcName)s %(levelno)s %(lineno)d %(msecs)d %(levelname)s %(message)s
class=pythonjsonlogger.jsonlogger.JsonFormatter
当 运行 在安装了 Python(和必要的库)的机器上时,它工作正常。但是,PyInstaller 生成的可执行文件似乎缺少所需的日志记录模块(因为它们没有在源代码中的任何地方导入,只是在日志记录配置中引用)。
运行 可执行文件时的错误输出:
Traceback (most recent call last):
File "c:\python35\lib\logging\config.py", line 98, in _resolve
AttributeError: module 'pythonjsonlogger' has no attribute 'jsonlogger'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<string>", line 64, in <module>
File "<string>", line 41, in main
File "<string>", line 28, in init_logger
File "c:\python35\lib\logging\config.py", line 76, in fileConfig
File "c:\python35\lib\logging\config.py", line 123, in _create_formatters
File "c:\python35\lib\logging\config.py", line 100, in _resolve
ImportError: No module named 'pythonjsonlogger.jsonlogger'
main returned -1
尝试 1
我试过使用 PyInstaller 的 hidden import functionality 来引用这两个模块:
pyinstaller \
--log-level=DEBUG \
--onefile \
--hidden-import=loggly \
--hidden-import=pythonjsonlogger main.py
日志文件输出:
3463 DEBUG: Hidden import: loggly
3463 INFO: Analyzing hidden import 'loggly'
3463 DEBUG: Hidden import: pythonjsonlogger
3478 INFO: Analyzing hidden import 'pythonjsonlogger'
尝试 2
试图在 PyInstaller 的规范文件(以下摘录)中指定导入:
a = Analysis(['main.py'],
pathex=['C:\Dev\pyWebiExport'],
binaries=None,
datas=None,
hiddenimports=['loggly.handlers.*', 'pythonjsonlogger.jsonlogger.*'],
hookspath=None,
…
日志文件输出:
3510 DEBUG: Hidden import: loggly.handlers.*
3510 INFO: Analyzing hidden import 'loggly.handlers.*'
5694 ERROR: Hidden import 'loggly.handlers.*' not found
5694 DEBUG: Hidden import: pythonjsonlogger.jsonlogger.*
5694 INFO: Analyzing hidden import 'pythonjsonlogger.jsonlogger.*'
5709 ERROR: Hidden import 'pythonjsonlogger.jsonlogger.*' not found
版本信息:
- Python 3.5.1 (Windows, x86)
- PyInstaller 3.0
- python-json-记录器 (0.1.4)
- loggly-python-处理程序 (1.0.0)
我能够通过为 PyInstaller 编写一个 runtime hook 来解决这个问题,它基本上由一个额外的 Python 脚本组成,其内容如下:
import pythonjsonlogger.jsonlogger
import loggly.handlers
我将这些语句保存在文件 loggly_hook.py
和 运行 PyInstaller 中,参数如下:
pyinstaller \
--log-level=DEBUG \
--onefile \
--clean \
--runtime-hook=loggly_hook.py main.py
PyInstaller 日志输出:
10374 INFO: Analyzing run-time hooks ...
10389 INFO: Including custom run-time hook 'loggly_hook.py'