使用PyInstaller创建自定义日志处理程序和格式化程序

3
我有一个Python包,使用PyInstaller将其打包为单个可执行文件。
我使用logging模块与基于文件的配置相结合。为了实现集中化、基于云的日志记录,我决定使用模块loggly-python-handlerpython-json-logger将日志信息发送到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 的隐藏导入功能来引用这两个模块:

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的spec文件中指定导入项(代码片段如下):

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-logger(0.1.4)
  • loggly-python-handler(1.0.0)
1个回答

2
我通过编写一个 PyInstaller 的 运行时钩子,成功解决了这个问题。该钩子其实就是一个额外的 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'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接