我想知道记录我的节点应用程序的最佳实践。我读了https://12factor.net/logs的12要素应用程序指南,它说日志应该总是发送到stdout。很酷,但是在生产过程中,有人会如何管理日志呢?是否有一个应用程序可以获取发送给stdout的任何内容?此外,是否建议我只登录到stdout而不是stderr?我希望对这一问题有一个看法。
发布于 2017-05-14 20:45:30
是否有一个应用程序可以获取发送给
stdout的任何内容?
链接到的页面提供了一些日志管理工具示例,但最简单的版本是将应用程序的输出重定向到文件。所以在bash node app.js > app.out。您还可以将stdout和stderr拆分为node app.js 2> app.err 1> app.out。
此外,您还可以使用某种服务来收集该文件中的日志,然后将它们放在索引中以便在其他地方进行搜索。
建议只登录到stdout的想法是让环境控制如何处理日志,因为应用程序不一定知道它最终将在其中运行的环境。此外,通过将所有日志视为事件流,您可以将如何处理该流的选择留给环境。例如,您可能希望将日志流直接发送到日志聚合服务,或者您可能希望先对其进行预处理,然后将结果流到其他地方。如果您强制执行特定的输出(例如记录到文件),则会降低服务的可移植性。
12要素指南的两个主要目标是“适合在现代云平台上部署”和“在执行环境之间提供最大的可移植性”。在云平台上,您可能在实例上拥有短暂的存储,或者在许多运行相同服务的实例上,您可能希望将日志聚合到某个中央存储中。通过提供日志流,您可以让环境来协调如何做到这一点。如果您将它们直接放入文件中,那么您必须将您的环境调整到每个应用程序决定放置日志的位置,以便将它们重定向到中央存储区。因此,对日志使用stdout主要是一种有用的约定。
发布于 2017-05-14 20:59:20
我认为明确地说"web应用程序应该向stdout写入日志“是错误的。
相反,我建议:
a)专业的、健壮的网络应用程序应该有日志。
( b)应用程序应将“日志”视为抽象的“流”对象。
( c)理想情况下,记录器实现可以配置为写入stdout、stderr、文件、日期标记文件、旋转文件、按严重性级别筛选等。
我强烈地认为,硬编码写到stdout,没有任何干预的“记录器”抽象,是糟糕的实践。
这里有一篇好文章:
发布于 2020-09-26 19:54:30
很酷,但是在生产过程中,有人会如何管理日志呢?
你要找的就是那个水槽。
是否有一个应用程序可以将发送到stdout的所有内容收集起来?
是也不是。这是日志服务器(或日志路由器)。它可以是一个应用程序,但它实际上只是执行或运行时环境中的某个进程,而您的应用程序并不真正了解这些进程。
另一种看待这一问题的方法是分离关注。正如在另一个答案中所述,它是关于让环境拥有日志所发生的事情,并且只期望应用程序完全关注发出日志事件。我认为在12 for文档中缺少的是,他们没有试图为您完成这个谜题,因为对于从标准输出到哪里会有不同的意见,所以我会根据我的个人经验和我在云空间看到的东西来添加那些缺失的部分。
记录器将日志事件发送到日志流(又称“日志”)
不用说,应用程序应该有某种“记录器”抽象,但这实际上只是将日志事件发送到stdout的入口点。抽象的职责是以所需的格式将日志事件放到日志流(stdout)上,然后完成应用程序的责任。事实上,12 In文档就在这里结束。
12 Factor App是关于创建对云友好和可移植的应用程序,因此您必须假设您甚至不知道执行/运行时环境是什么。所以我们不知道什么是“环境”,这就是关键所在。因此,从这里开始,执行/运行时环境负责处理流并将其移动到接收器。
日志船/路由器实现日志流到日志接收器
因此,我们现在解决这个问题的方法是为stdout流提供某种监听器,它将接收输出并将其发送到日志接收器。
"ship“(也称为日志路由器或铲运机)可能是环境中或运行时中的东西,也可能是运行应用程序后台(流侦听器)的东西;它可能是其他一些自定义进程;甚至可能是Kafka --我认为GCP使用from从各种来源收集日志并将它们放到堆栈驱动程序中。关键是它应该是应用程序中的一个单独的“类”,而您的应用程序并不真正了解这个类。它只听溪流,然后把它送到水槽里。在一些解决方案中,这是您需要构建的东西,在其他解决方案中,它是由您的平台处理的。简单地说,“我怎样才能把小溪送到水池?”
“水槽”是目的地。这可以是控制台(你好--它实际上是一个流读取器),也可以是一个文件,也可以是Splunk、Application、Stack驱动程序等。有简单的解决方案,还有更复杂的企业解决方案,但概念不变。
简而言之,这就是你的问题的答案,如果我们写信给stdout“我们如何管理生产中的日志”。您要寻找的是日志接收器或日志聚合器。在12‘t的白话中,像"splunk“这样的东西并不是”日志“。日志本身就是流(stdout)。就12 to而言--您的应用程序不知道接收器是什么,理想情况下,不应该这样做,因为接收器可能会改变,在这种情况下,所有的应用程序都会崩溃,或者可能有许多不同的接收器,这可能会使应用程序陷入困境,特别是如果您首先直接写到接收器而不是stdout的话。这只是另一次脱钩行动,如果没有其他的话。
您可以一次发送到单个接收器、多个接收器,也可以发送到单个接收器,并让其他组件“将”您的日志从该接收器发送到另一个接收器(例如,写入滚动文件并让路由器将其刮入splunk)。取决于你的需要。
在默认情况下,您可以在云提供商中看到越来越多的这种情况出现。例如,在GCP上,所有到stdout的日志都会自动被拾取并发送到堆栈驱动程序。在Azure中,只要将检测工具添加到您的.NET应用程序(应用程序诊断包)中,它就会向stdout发出事件,并由azure监视器获取。也有越来越多的包开始实现这种模式,所以在.NET中您可以使用Serilog来抽象大部分这些概念。
Logger -> Log Event -> Log [stream] (stdout) -> Sink -> Your eyeballs
有一些包和平台提供了其中的一个或多个部分,但是所有这些部分总是存在的。当你意识到12 of日志时,它就更有意义了。
https://stackoverflow.com/questions/43968560
复制相似问题