首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在运行时添加Sentry Log4j2 appender

在运行时添加Sentry Log4j2 appender
EN

Stack Overflow用户
提问于 2022-02-21 13:59:04
回答 1查看 279关注 0票数 0

我一直在浏览以前关于在运行时添加Log4j2附加器的线程,但它们似乎都不适合我的场景。

我们将一个长时间运行的Flink作业打包到一个胖罐子中,实质上是将它提交给正在运行的Flink集群。我们希望将错误日志转发给Sentry。Sentry提供了一个我希望能够使用的Log4j2附录,但是所有让Log4j2工作的尝试都失败了--有点疯狂(花了几天时间)。

由于Flink (他还使用log4j2)提供了一组默认的日志配置,这些配置优先于我们在jar中绑定的任何配置文件;因此,我基本上只能在运行时配置这个附录,看看它是否会注册该附录并将LogEvents转发给它。

作为附带说明,:我试图覆盖Flink提供的配置文件(实质上是将附录直接添加到Log4j2.properties文件中),但是Flink由于缺少依赖项io.sentry.IHub而无法加载插件--io.sentry.IHub--这是没有意义的,因为所有示例/哨兵文档都没有提到类路径中已经存在的log4j相关依赖项之外的任何其他依赖项。

我遵循了log4j文档中的示例:初始化后以编程方式修改当前配置,但是日志无法进入Sentry。

SentryLog4j.scala

代码语言:javascript
复制
package com.REDACTED.thoros.config

import io.sentry.log4j2.SentryAppender
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.core.LoggerContext
import org.apache.logging.log4j.core.config.AppenderRef
import org.apache.logging.log4j.core.config.Configuration
import org.apache.logging.log4j.core.config.LoggerConfig

object SentryLog4j2 {
 val SENTRY_LOGGER_NAME = "Sentry"
 val SENTRY_BREADCRUMBS_LEVEL: Level = Level.ALL
 val SENTRY_MINIMUM_EVENT_LEVEL: Level = Level.ERROR
 val SENTRY_DSN =
   "REDACTED"

 def init(): Unit = {
   // scalafix:off
   val loggerContext: LoggerContext =
     LogManager.getContext(false).asInstanceOf[LoggerContext]
   val configuration: Configuration = loggerContext.getConfiguration

   val sentryAppender: SentryAppender = SentryAppender.createAppender(
     SENTRY_LOGGER_NAME,
     SENTRY_BREADCRUMBS_LEVEL,
     SENTRY_MINIMUM_EVENT_LEVEL,
     SENTRY_DSN,
     false,
     null
   )
   sentryAppender.start()
   configuration.addAppender(sentryAppender)
   // Creating a new dedicated logger for Sentry
   val ref: AppenderRef =
     AppenderRef.createAppenderRef("Sentry", null, null)
   val refs: Array[AppenderRef] = Array(ref)
   val loggerConfig: LoggerConfig = LoggerConfig.createLogger(
     false,
     Level.ERROR,
     "org.apache.logging.log4j",
     "true",
     refs,
     null,
     configuration,
     null
   )
   loggerConfig.addAppender(sentryAppender, null, null)
   configuration.addLogger("org.apache.logging.log4j", loggerConfig)
   println(configuration.getAppenders)
   loggerContext.updateLoggers()
   // scalafix:on
 }
}

然后在SentryLog4j.init模块中调用Main ()。

代码语言:javascript
复制
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import org.apache.logging.log4j.core.LoggerContext
import org.apache.logging.log4j.core.config.Configuration

object Main {
  val logger: Logger = LogManager.getLogger()
  sys.env.get("ENVIRONMENT") match {
    case Some("dev") | Some("staging") | Some("production") =>
      SentryLog4j2.init()
    case _ => SentryLog4j2.init() // <-- this was only added during debugging
  }

    def main(args: Array[String]): Unit = {
       logger.error("test") // this does not forward the logevent to the appender
    }
}

我想我需要在loggerConfig中注册rootLogger使用的附录,这样所有的logger.error语句都与配置的Sentry appender相匹配吗?

非常感谢与此相关的任何指导!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-23 14:28:47

虽然不是如何让log4j2和SentryAppender工作的答案。对于其他遇到这个问题的人,我只简单地解释一下我是如何让哨兵集成工作的。我最终决定要做的是放弃使用SentryAppender,而使用原始的哨兵客户机。添加一个包装类,公开典型的debuginfowarnerror方法。然后,对于warn+方法,我还将日志事件发送给Sentry。

这基本上是我让它在Flink集群中工作的唯一方法。

见下面的例子:

代码语言:javascript
复制
sealed trait LoggerLike {
  type LoggerFn = (String, Option[Object]) => Unit
  val debug: LoggerFn
  val info: LoggerFn
  val warn: LoggerFn
  val error: LoggerFn
}


trait LazyLogging {
  @transient
  protected lazy val logger: CustomLogger =
    CustomLogger.getLogger(getClass.getName, enableSentry = true)
}


final class CustomLogger(slf4JLogger: Logger) extends LoggerLike {...your implementation...}

然后,对于每个类/对象(至少是scala语言),只需扩展LazyLogging特性以获得一个记录器实例。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71207581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档