我想知道记录我的节点应用程序背后的最佳做法。我正在https://12factor.net/logs阅读12因素应用指南,并指出应始终将日志发送到stdout
。很酷,但那么有人会如何管理生产中的日志?是否有一个应用程序可以挖掘发送给stdout
的任何内容?另外,建议我只登录stdout
而不是stderr
?我很欣赏这个问题的观点。
答案 0 :(得分:9)
是否有应用程序可以抓取发送到
node app.js > app.out
的任何内容?
您链接的页面提供了一些日志管理工具的示例,但最简单的版本只是将应用程序的输出重定向到文件。所以在bash stdout
中。您也可以将stderr
和node app.js 2> app.err 1> app.out
分开,如stdout
。
您还可以使用某种服务从该文件中收集日志,然后将它们编入索引以便在其他位置进行搜索。
仅仅记录到stdout
的建议背后的想法是让环境控制如何处理日志,因为应用程序不一定知道它最终将在其中运行的环境。此外,通过将所有日志视为事件流,您可以选择如何处理此流,直至环境。例如,您可能希望将日志流直接发送到日志聚合服务,或者您可能希望先对其进行预处理,然后将结果流式传输到其他位置。如果您要求特定输出(例如记录到文件),则会降低服务的可移植性。
12因素指南的两个主要目标是“适合在现代云平台上部署”并提供“执行环境之间的最大可移植性”。在您的实例上可能有临时存储的云平台上,或者运行相同服务的许多实例,您需要将日志聚合到某个中央存储中。通过提供日志流,您可以将其保留到环境中以协调如何执行此操作。如果将它们直接放入文件中,则必须根据每个应用程序决定放置日志的位置定制环境,然后将它们重定向到中央存储。因此,使用SELECT board.boardID, board.userID, board.postID, items.Url,
items.Image
FROM board
JOIN items on userID = items.user_id
作为日志主要是一种有用的约定。
答案 1 :(得分:2)
我认为明确表示" [web]应用程序应该将日志写入stdout
"这是一个错误。
相反,我建议:
a)专业品质,强大的网络应用应该拥有日志
b)应用程序应该对待" log"作为一个抽象的"流"对象
c)理想情况下,记录器实现 MAY 可配置为写入stdout,stderr,文件,日期戳文件,旋转文件,按严重性级别过滤等等等。
我坚决认为硬编码写入stdout,没有任何干预"记录器"抽象, POOR 实践。
这是一篇好文章:
答案 2 :(得分:1)
很酷,但是有人会如何管理生产中的日志?
您正在寻找的日志接收器。
是否有一个应用程序可以捕获发送到stdout的所有内容?
是,不是。这是原木船。它可能是一个应用程序,但实际上只是您的应用程序并不真正了解的执行或运行时环境中的某个过程。
查看此问题的另一种方法是关注点分离。就像在另一个答案中指出的那样,它是关于让环境拥有日志中发生的事情,而只是期望应用程序完全关注发出日志事件。我认为12FA文档中缺少的是,他们没有为您完成难题,因为对于从stdout出发的方向会有不同的意见,因此我将根据我的个人经验补充这些缺失的内容,以提供帮助以及我在整个云空间中看到的一切。
不用说,您的应用程序应该具有某种“记录器”抽象,但这实际上只是向stdout发出日志事件的入口。该抽象的责任是将您的日志事件以所需的格式发送到日志流(stdout),然后完成您的应用程序的责任。实际上,12FA文档到此结束。
12 Factor App是关于创建对云友好且可移植的应用程序的,因此您必须假设您甚至不知道执行/运行时环境是什么。因此,我们不知道什么是“环境”,这就是重点。因此,从这里开始,执行/运行时环境负责处理流并将其移至接收器。
因此,我们现在解决此问题的方法是为stdout流提供某种侦听器,该侦听器将获取输出并将其发送到下游到日志接收器。
“ ship”可能是环境或运行时中的某个东西,或者说真的是运行您的应用程序后台(流侦听器)的某个东西;这可能是其他自定义过程;甚至可能是卡夫卡。关键是它应该是应用程序中真正不知道的单独的“类”。它只是侦听流并将其发送到接收器。在某些解决方案中,这是您需要构建的东西,在其他解决方案中,则由平台来处理。简单地说“我如何将水流送到水槽?”
“接收器”是目的地。它可以是控制台(实际上是一个流读取器),可以是文件,可以是Splunk,Application Insights,Stack Driver等。有简单的解决方案,也有更大更复杂的企业解决方案,但是这个概念仍然存在。一样。
简而言之,如果我们要写到标准输出“我们如何在生产中管理日志”,这就是您问题的答案。您要查找的是日志接收器。在12FA的本地语言中,“ splunk”之类的东西不是“ log”。日志是流本身(stdout)。就12FA而言-您的应用程序不知道接收器是什么,理想情况下,它不应该是因为该接收器可能会更改,在这种情况下,您的所有应用程序都将崩溃,或者可能有很多不同的接收器,并且可能会使您的接收器陷入困境如果您是直接写到接收器而不是首先使用stdout,则应将应用程序关闭。如果没有别的话,那只是另一种脱钩练习。
您可以一次将多个接收器发送到一个接收器,也可以将其发送到单个接收器并使其他组件将日志从该接收器“运送”到另一个接收器。取决于您的需求。
默认情况下,您实际上可以在云服务提供商中看到越来越多的信息。例如,在GCP上,所有到stdout的日志都会自动被提取并发送到stackdriver。在Azure中,只要将工具添加到.NET应用程序(应用程序诊断程序包),它就会向stdout发出事件,并且它会被天蓝色的监控器拾取。还有越来越多的程序包开始实现此模式,因此在.NET中,您可以使用Serilog来抽象大多数这些概念。
Logger -> Log Event -> Log [stream] (stdout) -> Sink -> Your eyeballs