【问题标题】:Advanced logging for Java Web ApplicationsJava Web 应用程序的高级日志记录
【发布时间】:2016-02-16 09:37:32
【问题描述】:

我想为我的 java web 应用程序构建一个更高级的日志记录机制,类似于 App 引擎日志。 我的需求是:

  1. 将日志流式传输到数据库(例如 sql、bigquery 或其他)
  2. 自动记录重要数据(如应用上下文、请求 url、请求 ID、浏览器用户代理、用户 ID 等)

对于第 1 点,我可以使用“缓冲”实现,将日志放入不同的列表中,并定期由 cron(线程)收集内存中的所有日志并将它们写入数据库(也可以在另一台服务器上)

对于第 2 点,我发现这样做的唯一方法是将所需的对象注入到我的类(子系统)中,例如 ServletContext、HttpServletReqest、当前用户等,所有这些都建模为自定义类(比如说 AppLogContext),它然后可以由日志记录机制使用。

这里的问题是我不知道这是否是一个好习惯。例如,这意味着许多类必须包含这个可以访问 servlet 上下文和 http 请求对象的对象,我认为这可能会产生架构问题(在构建模块、层等时)甚至安全问题。

App Engine 会自动记录此类信息(以及更多,例如延迟、cpu 使用率等,但这更复杂),并且可以在项目的控制台日志中找到(也可以将日志复制到大型查询表) 我需要一些用于 Jetty 或其他 java web 应用服务器的东西。

那么,有没有其他方法可以做到这一点,其他模式,不同的方法? (找不到任何这些点的 3rd 方库)

谢谢。

【问题讨论】:

  • 好吧,让您来解决您似乎缺少的难题:App Engine 记录请求。您可以通过添加过滤器来实现这一点。您可以让过滤器提供一个仅用于当前请求的记录器实例,然后在请求完成时处理写入。这是不好的做法吗?是的,因为您为每个请求增加了很多开销。我建议您查看常用的记录器框架(log4j 等),并在尝试自己的记录器之前看看有什么可能。
  • 关于使用过滤器,我不确定我是否完全理解,但这是否意味着我仍然必须创建一个 Log 对象并将其传递给所有子系统?所以在自定义 MyClass 中,我仍然无法调用 Log.getLog().print(myMessage) 之类的东西吗?
  • 我会以某种方式需要一个 Logger 对象,该对象具有用于创建的静态方法,但具有每个请求范围......否则,如果不将请求(上下文)数据传递给使用的类,使用什么方式匹配(绑定)日志消息以请求 id 我会有吗?这在跟踪大量步骤、复杂操作、在单个请求中完成时非常有用,而且我找不到使用日志库来实现类似的方法。也许我错过了什么......
  • 由于每个请求都应在单独的线程上处理,因此在同一请求期间写入的所有日志都将具有相同的线程 ID。

标签: java google-app-engine logging jetty google-cloud-logging


【解决方案1】:

你真的不需要发明自行车。

您可以遵循一个常见的做法:

  • 只需使用标准记录器将日志记录到文件中
  • 如果你需要在请求上下文中查看日志)Logback、Log4J 和 SLF4J 支持Mapped Diagnostic Context (MDC),这就是你可以用来将当前请求放入每个日志行(只需在过滤器,例如放置请求 id,或生成随机 uuid)。您可以稍后按此 ID 聚合日志条目
  • 然后使用 ELK:
    • Logstash 已将日志收集到
    • 用于存储日志的 ElasticSearch
    • 使用Kibana进行分析

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 2016-07-19
    • 2023-04-08
    • 2016-05-04
    • 2016-04-26
    • 2010-12-28
    • 1970-01-01
    相关资源
    最近更新 更多