- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在尝试摆脱 print() 的束缚,并开始使用 ELK 堆栈和 structlog 模块进行集中式日志收集来生成结构化 json 日志行。对于我自己使用loggingHelper模块编写的模块来说,这工作得非常好,我可以导入并使用该模块
logger = Logger()
在其他模块和脚本中。这是loggingHelper模块类:
class Logger:
"""
Wrapper Class to import within other modules and scripts
All the config and log binding (script
"""
def __init__(self):
self.__log = None
logging.basicConfig(level=logging.DEBUG, format='%(message)s')
structlog.configure(logger_factory=LoggerFactory(),
processors=[structlog.stdlib.add_log_level,
structlog.processors.TimeStamper(fmt="iso"),
structlog.processors.JSONRenderer()])
logger = structlog.get_logger()
main_script = os.path.basename(sys.argv[0]) if sys.argv[0] else None
frame = inspect.stack()[1]
log_invocation = os.path.basename(frame[0].f_code.co_filename)
user = getpass.getuser()
"""
Who executed the __main__, what was the executed __main__ file,
where did the log event happen?
"""
self.__log = logger.bind(executedScript = main_script,
logBirth = log_invocation,
executingUser = user)
def info(self, msg, **kwargs):
self.__log.info(msg, **kwargs)
def debug(self, msg, **kwargs):
self.__log.debug(msg, **kwargs)
def error(self, msg, **kwargs):
self.__log.error(msg, **kwargs)
def warn(self, msg, **kwargs):
self.__log.warning(msg, **kwargs)
这会产生格式良好的输出(每行一个 JSON),filebeat 能够读取该输出并将其转发到 Elasticsearch。然而,第三方库完全破坏了格式良好的日志。
{"executingUser": "xyz", "logBirth": "efood.py", "executedScript": "logAlot.py", "context": "SELECT displayname FROM point_of_sale WHERE name = '123'", "level": "debug", "timestamp": "2019-03-15T12:52:42.792398Z", "message": "querying local"}
{"executingUser": "xyz", "logBirth": "efood.py", "executedScript": "logAlot.py", "level": "debug", "timestamp": "2019-03-15T12:52:42.807922Z", "message": "query successful: got 0 rows"}
building service object
auth version used is: v4
Traceback (most recent call last):
File "logAlot.py", line 26, in <module>
ef.EfoodDataControllerMerchantCenter().get_displayname(123)
File "/home/xyz/src/toolkit/commons/connectors/efood.py", line 1126, in get_displayname
return efc.select_from_local(q)['displayname'].values[0]
IndexError: index 0 is out of bounds for axis 0 with size 0
正如您所看到的,来自第三方库(googleapiclient)的信息级别和错误级别消息都被打印出来,而无需通过日志处理器。
使用我编写的loggingHelper模块捕获和格式化一个脚本执行过程中发生的所有事情的最佳方法(也是最Pythonic的)是什么?这是最佳实践吗?
编辑:目前记录器确实写入 stdout 本身,然后使用 >> 和 2>&1 将其重定向到 crontab 中的文件。如果我想重定向第三方库日志记录写入 stdout/stderr 的所有内容,这对我来说似乎是不好的做法,因为这会导致循环,对吗?因此,我的目标不是重定向,而是捕获日志处理器中的所有内容。相应更改了标题。
最佳答案
首先:您不应该在类初始值设定项中执行任何记录器配置(logging.basicConfig
、logging.dictConfig
等) - 日志记录配置应该完成一次并且仅在进程启动时一次。 logging
模块的重点是完全解耦日志记录调用
第二点:我不是 structlog 专家(这是轻描淡写的 - 这实际上是我第一次听说这个包),但你得到的结果是你所期望的代码片段:只有您自己的代码使用 structlog
,所有其他库(stdlib 或第三部分)仍将使用 stdlib
记录器并发出纯文本日志。
从我在 structlog
文档中看到的内容来看,它似乎提供了一些方法 wrap the stdlib's loggers using the structlog.stdlib.LoggerFactory
和 add specific formatters to have a more consistant output 。我还没有测试过这个(还),官方文档有点稀疏,缺乏可用的实际示例(至少我找不到任何示例),但是 this article似乎有一个更明确的示例(当然要适应您自己的上下文和用例)。
警告:正如我所说,我从未使用过structlog
(我第一次听说这个库),所以我可能误解了一些事情,你当然必须进行实验以找出如何正确配置整个事物以使其按预期工作。
作为旁注:在类 UNIX 系统中 stdout
应该用于程序的输出(我的意思是“预期输出”=> 程序的实际结果),而所有错误/报告/调试消息都属于stderr
。除非你有令人信服的理由否则你应该尝试并坚持这个约定(至少对于命令行工具来说,这样你就可以以unix方式链接/管道它们)。
关于python - 捕获 structlog 中的所有 stdout/stderr 以生成 JSON 日志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55219613/
多个 ChildException catch block 和一个 Exception catch block 之间哪个更好? 更好,我的意思是以良好的实践方式。 举例说明: public stati
我正在尝试将脱机计算机记录在文本文件中,以便以后可以再次运行它们。似乎没有被记录或捕获。 function Get-ComputerNameChange { [CmdletBinding()]
我正在将 Scala 'try/catch' 测试代码转换为使用 'intercept' 有没有我不应该使用“拦截”的场景?使用 'intercept' 而不是 'try/catch' 的唯一好处是简
我对erlang很陌生,我正在尝试使用基本的try/catch语句来工作。我正在使用Webmachine处理一些请求,我真正想做的就是解析一些JSON数据并将其返回。如果JSON数据无效,我只想返回一
我不知道如何捕获删除按键。我发现在 ASCII 代码表中,它位于 127 位,但是 if (Key = #127) then 却无济于事。 然后我检查了 VK_DELETE 的值,它是 47。尝试使用
我很少在失败时对数据库查询使用唯一的错误消息 我经常使用简短的标准消息,例如“数据库错误/失败。请与网站管理员联系”或类似的消息。或自动发送给我 我正在寻找一种在PDO中全局设置一次try {}和ca
我有一个变量CompletableFuture completableFuture 。我希望能够使用任何类型的对象来完成它。例如:completableFuture.complete(new Stri
我认为这是基本的东西,但我不知道该怎么做。为什么我得到 IOException never throw in body of相应的 try 语句 public static void main(Str
我在此代码中遇到 JSON 异常: JSONObject jObject = new JSONObject(JSONString); pontosUsuario.setIdUsuari
我正在尝试打印出用单引号括起来的文本。 /bin/bash -lc '/home/CASPER_REPORTS/scripts/CASPER_gen_report.sh CASPER_1' /bin/
我这里遇到了一点问题。我想弄清楚如何捕获 IllegalArgumentException。对于我的程序,如果用户输入负整数,程序应该捕获 IllegalArgumentException 并询问用户
我无法理解 EJBTransactionRolledbackException。 我有实体: @Entity public class MyEntity { @Id @Generate
对于我给自己提出的以下挑战,如果社区的经验给我任何建议,我将不胜感激 - 即,这里有任何关于最佳方法/方向的指示吗? 要求 允许收集/实时监控从用户 Windows PC 到一组特定 IP 地址(或
我想在我的 ABAP 代码中捕获并处理 SAPSQL_DATA_LOSS。 我试过这个: try. SELECT * FROM (rtab_name) AS rtab
我知道捕获错误不是一个好的做法,但在这种情况下,这样做很重要。我正在尝试运行一个包含游戏一部分的 jar,但它给了我一个 unsatisfiedlink 错误,但这是有趣的部分:我正在使用这段代码:
我有一个表单页面,当我保存它时,它会覆盖数据库。表单页面中有一个文本框,允许用户输入 4000 个字符,但如果用户输入的字符超过此值,则会出现以下错误: ERROR 15:54:05 Abstrac
我想知道在python中绑定(bind)键的最简单方法 例如,默认的 python 控制台窗口出现并等待,然后在 psuedo -> if key "Y" is pressed: print (
下面是别人写的类。 我面临的问题是,当它进入parse method时与 null as the rawString ,它正在扔NumberFormatException 。 所以我想做的是,我应该捕
我有一个简单的脚本,可以捕获所有鼠标单击,除非您单击实际有效的内容。链接、Flash 视频等。我如何调整它,以便无论用户点击什么,在视频加载、新页面加载等之前,它都会发送我构建的简单 GET 请求?
我有一个带有一些选择列表的表单,当选择某些值时,这些列表将显示/隐藏更多输入字段。 问题是大多数用户都是数据输入人员,因此他们在输入数据时大量使用键盘,并且选择列表的 change 事件仅在焦点离开输
我是一名优秀的程序员,十分优秀!