集中式日志记录的最佳实践是什么?

25

我的团队负责支持100多个应用程序。这些应用程序没有任何通用的架构,因此那些进行日志记录的应用程序通常会使用自定义代码记录到本地文件或本地数据库,并且这一切都是不可管理的。我们想要改变这种情况。

我们正在逐步将应用程序迁移到使用log4net并标准化记录的内容类型。接下来的问题是:我们应该把日志发送到哪里?

我认为最好使用一个专门用于接收所有日志的中央SQL Server,这将提供简单的维护(备份/归档的一个地方)并提供将来某些数据挖掘和趋势分析的可能性。

这是这类事情的最佳实践吗,还是我们应该考虑使用一些专门的应用程序日志服务器?

更新:我应该更清楚地提到log4net和SQL Server:我们是微软公司,大多数东西都是用.NET编写的。UNIX解决方案对我们无用。


这个问题的被接受答案虽然有智慧,但已经过时了。关系型数据库管理系统不是记录日志的最佳选择,因为您获得的查询能力程度的好处会被性能/灵活性/成本所抵消。尝试向一个拥有十亿行数据的表中添加一个新列或索引。我找到的最好的解决方案是使用反向索引来针对原始数据进行处理。对于任何非微不足道的用途,Solr或Elasticsearch都比SQL更好。请查阅Elasticsearch的Logstash和Kibana插件。 - Richard Marr
同意Richard的观点,提供的答案有些过时了。最好使用微软提供的Application Insights功能。它可以用于任何语言,而不仅仅是微软语言。Application Insights分为两个部分。SDK用于仪表化遥测(日志数据)和在Azure仪表板中可视化这些日志。SDK是开源的,您需要支付Azure可视化工具的费用。如果您不想支付,则可以在代码中使用Application Insights并将这些日志发送到开源的Elastic Stack。 - Manoj Kalluri
9个回答

23

一个警告:在大型商店中有超过100个应用程序,可能有数百甚至数千台主机运行这些应用程序时,请避免使用任何导致紧密耦合的东西。这基本上排除了直接连接到SQL Server或任何数据库解决方案,因为您的应用程序日志记录将取决于日志存储库的可用性。

中央存储库的可用性比“如果无法连接,则不记录”要复杂一些,因为通常最有趣的事件发生在出现问题时,而不是万事大吉时。如果您的日志记录正好在事情变得有趣时删除条目,那么它永远不会被信任来解决事件,并因此未能获得其他利益相关者(即应用程序所有者)的支持和推动。
如果您决定自行实现保留并重试失败的日志信息传递,您将面临艰巨的挑战:这不是一个简单的任务,比听起来要复杂得多,从高效可靠地存储保留的信息开始,到实施良好的重试和智能回退逻辑结束。

您还必须回答身份验证和安全性问题。大型组织具有多个域,具有各种信任关系,员工通过VPN或来自家庭的直接访问进行冒险,一些应用程序无人值守运行,某些服务配置为以本地用户身份运行,某些计算机没有加入域等等。您最好回答每个应用程序的日志记录模块到处部署时将如何验证与中央存储库的身份(以及哪些情况将不受支持)的问题。

理想情况下,您应该使用现成的日志记录模块传递机制。 MSMQ可能是最合适的选择:强大的异步可靠传递(至少在大多数用例的范围内),在每个Windows主机上都可用(可选)。这是最大的痛点,您的应用程序将依赖于非默认的操作系统组件。

中央存储库存储必须能够提供请求的信息,例如:

  • 应用程序开发人员调查事件
  • 客户支持团队调查由客户投诉报告的丢失交易
  • 安全组进行取证
  • 业务经理需要统计数据、趋势和聚合信息(BI)。
  • 对于任何规模较大、寿命较长的组织来说,唯一能够提供这种功能的存储方式是关系型引擎,因此可能会选择 SQL Server。在文本文件上进行分析真的不会有太大作用。

    因此,我建议使用基于消息传递的日志传输/交付(MSMQ)和关系型中央存储库(SQL Server),可能还要在其上面添加分析组件(Analysis Services Data Mining)。正如您所看到的,这显然不是小事,它涵盖的范围略微超出了配置 log4net。

    至于记录什么,您已经考虑过了,但我想再补充一点:通常情况下,特别是在事件调查时,您希望能够请求额外的信息。这意味着您想要知道来自事件机器的某些文件内容、某些注册表键、某些性能计数器值或完整的进程转储。能够从中央存储库界面请求此信息非常有用,但总是收集此信息并不切实际,因此必须在应用程序和中央存储库之间建立某种双向通信,当应用程序报告事件时,可以要求添加额外的信息(例如故障进程的转储)。必须有很多基础设施才能实现这样的事情,从应用程序日志和中央存储库之间的协议,到中央存储库识别重复事件的能力,再到日志记录库收集所需的额外信息的能力,以及操作员标记下一次发生需要额外信息的事件的能力。

    我理解这个答案可能看起来有些过度,但我曾经在这个问题领域工作了相当长时间,当我还在微软公司时,我曾经查看过许多 Dr. Watson 的在线崩溃报告,我可以告诉您,这些要求是存在的,它们是有效的关注点,当实现这个解决方案时,会极大地帮助。最终,您无法修复您无法测量的问题。一个大型组织依赖于对其应用程序库进行良好的管理和监控,包括日志记录和审计。

    有一些第三方供应商提供解决方案,其中一些甚至与Log4net集成,例如bugcollect.com(全面披露:这是我的公司),错误流量控制器Exceptioneer等。


    3
    你的“谨慎的一个世界”是有意的双关语吗?我的意思是,它显然更像是一个世界而不是一个词。;-) (注:原文中加粗的单词为world而非word) - Wim
    1
    @Wim:诚实的笔误,但我会保留它,这样更有趣。 - Remus Rusanu
    Exceptioneer已经停止运营一年左右了。exceptron.com是一个不错的替代选择。免责声明:我在exceptron工作 :D - kay.one

    9
    Logstash + Elasticsearch + Kibana + Redis 或 RabbitMQ + NLog 或 Log4net
    存储 + 搜索 & 分析: Elasticsearch 收集 & 解析: Logstash 可视化: Kibana 队列 & 缓冲: Redis 应用程序中使用: NLog

    就可扩展性而言,我更倾向于放弃SQL,转而使用ES。Redis在Windows上并没有真正的生产就绪客户端,但我相信您可以找到另一个数据结构服务器来充当代理。 - Lino Silva
    1
    几年过去了,您是否已经更改了此架构的日志记录基础设施?由于它结合了5个系统,您是否在某个地方详细说明了安装设置? - Jan Zahradník

    5
    到目前为止提到的1024字节Syslog消息长度限制是误导性的,并且错误地对基于Syslog的问题解决方案进行了偏见。
    过时的“BSD Syslog协议”的限制确实是1024字节。 BSD syslog协议-4.1 syslog消息部分 现代的“Syslog协议”的限制取决于实现,但必须至少为480字节,应该至少为2048字节,甚至可能更高。 BSD syslog协议-6.1.消息长度 例如,Rsyslog的配置设置称为MaxMessageSize,文档建议将其设置为至少64kb。 rsyslog-配置指令

    即使提问者所在的组织是“微软之家”,认为“UNIX解决方案不好用”,也不应该阻止没有歧视性的读者获取准确的信息。


    3

    虽然可以使用SQL,但我使用Splunk来聚合日志。通过Splunk允许设置数据索引的方式以及使用其查询工具制作一些漂亮的图表,我能够找到一些惊人的信息。你也可以免费下载其基础版本。


    2
    正如其他回答所指出的那样,最接近行业标准的是syslog。但是不要因为你生活在Windows世界而绝望。Kiwi有一个在Windows上运行的syslog守护进程,而且是免费的。了解更多信息更新
    正如@MichaelFreidgeim所指出的,Kiwi现在对他们的syslog守护进程收费。然而,还有其他免费的替代品可用。这个其他SO答案链接到其中的一些。

    syslog协议有一个1024字节的限制,这对于一般应用程序日志记录来说是不够的。此外,Kiwi现在不再免费。 - Michael Freidgeim
    @MichaelFreidgeim - 伙计,你一定写了很长的消息。就我个人而言,我很少需要超过256个字符的单条消息。 - APC

    1
    在Unix上,有{{link1:syslog}}。
    此外,您可能还想查看{{link2:此案例研究}}。

    1
    如果您使用log4net将日志记录到本地EventViewer,您可以在Windows 2008上挖掘这些日志,请参阅此集中审计文章
    然后,在该框中,您可以轻松导入这些事件并在其上提供一些管理和挖掘工具。

    唉,我们是政府机构,所以一切都是Windows 2003。:-/ 不管怎样,还是谢谢。 - Stewart Johnson

    1

    正如其他人已经指出的那样,直接将来自许多应用程序和主机的日志定向到数据库并不是一个好主意。我只想再添加一个支持使用专用集中式日志服务器的优点——它可以将您的应用程序与日志基础设施解耦。由于您在使用 .Net,有几个很好的选择——log4netNLog。两者都是非常好的产品,但我特别喜欢 NLog,它在处理更重的负载时被证明是更好的表现者,具有更好的配置选项,并且正在积极维护。据我所知,Log4Net 已经有几年没有更新了,并且存在一些问题,但仍然是非常强大的解决方案。因此,一旦您使用这样的框架,您就可以在应用程序级别上控制它何时、以何种方式以及何时将其日志传输到集中式服务器。如果需要的话。

    请看一下logFaces,它是专为您所描述的情况而建立的 - 用于聚合来自多个应用和主机的日志,提供集中存储和源以进行分析和监视。并且在不对现有代码库进行任何更改的情况下,不会对其造成干扰。它可以处理大量的应用程序和主机负载,并让您指定想要执行的操作。另一方面,您还可以使用非常好的GUI进行实时监视或深入数据。您根本不必直接处理数据库。可以选择许多数据库 - 包括SQL和NoSQL。顺便说一下,RDBS在处理非常大的数据存储时并不是最佳性能表现。logFaces可以与MongoDB一起使用 - 这种设置通常比最佳传统RDBS品牌高出十倍左右。特别是在使用容量限制集合时。
    (声明一下,我是logFaces的作者)

    0

    如果你在*nix机器上运行,传统的解决方案是syslog


    1
    syslog协议有一个1024字节的限制,这对于一般应用程序记录是不够的。 - Michael Freidgeim

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