在 log4j appenders 内的 config.groovy 中访问会话用户

Posted

技术标签:

【中文标题】在 log4j appenders 内的 config.groovy 中访问会话用户【英文标题】:Accessing session user in config.groovy inside log4j appenders 【发布时间】:2014-10-20 14:45:57 【问题描述】:

我已经在我的应用程序中配置了 log4j 附加程序,以便在出现任何异常时发送邮件。

Config.groovy 中的代码如下所示:

log4j = 
    appenders 
    String currentUrl = grails.serverURL
    String currentEnv = 'Production'
    if (Environment.isDevelopmentMode()) 
        currentEnv = 'Development'
     else if (currentUrl.indexOf('test') > -1) 
        currentEnv = 'Testing'
    
    console name: 'stdout', layout: pattern(conversionPattern: '[%r] %c2 %m%n')
    // if real password is needed, please contact IT department
    def patternLayout = new PatternLayout()
    patternLayout.setConversionPattern("[%r] %c2 %m%n")
    def mailAppender = new SMTPAppender()
    mailAppender.setSMTPUsername('a@abc.com')
    mailAppender.setSMTPPassword('password')
    mailAppender.setFrom("x@xyz.com")
    mailAppender.setTo("user@domain.com")
    mailAppender.setSubject("A log4j error has been generated in the [$currentEnv] environment.")
    mailAppender.setSMTPHost("smtp.elasticemail.com")
    mailAppender.setSMTPPort(2525)
    mailAppender.setBufferSize(4096)
    mailAppender.setLayout(patternLayout)
    appender name: 'mail', mailAppender

    root 
        error 'stdout', 'mail'
        additivity = true
     
   
 

我想在主题中包含屏幕错误源自的当前登录用户。 我使用的是spring security插件,grails版本是1.3.7

我有以下代码:

def user
grails.plugins.springsecurity.onInteractiveAuthenticationSuccessEvent =  e, appCtx ->
   user = org.abc.com.Person.get(appCtx.springSecurityService.currentUser.id)

在 log4j 之外并在主题中使用了用户实例,但它返回 null。

他们是否还有其他方法可以让当前用户进入主题。

有什么办法吗?请推荐

他们还有什么方法可以异步发送邮件吗?

【问题讨论】:

配置在启动时读取一次。 user 在运行时发生变化。所以,如果你想通过电子邮件发送用户名,那么你应该在运行时(一些控制器,或服务等)进行。 这个 log4j appender 只写在 config.groovy 文件中。所以没有办法进入控制器或服务。 是的,我知道并写过。转到您的 Controller 并编写类似 log.debug "session id: $sessionId, user: $currentUser" 的内容。该日志将按照您在Config.groovy中的配置通过电子邮件发送 好的,可以做到。但是由于此附加程序适用于已处理的(由 try/catch 标记)和未处理的异常。对于已处理的异常,我需要编写 log.error 以允许邮寄。 & 在这种情况下,您的解决方案将完美无缺。但是对于未处理的异常情况呢?您的解决方案将要求我在代码中处处处理异常并在处处说 log.error “用户名”,这是我不想要的 【参考方案1】:

这里的关键是使用 log4j 嵌套诊断上下文。 log4j 的documentation 概述了您的用例。

为了说明这一点,让我们以 servlet 为例 向众多客户提供内容。 servlet 可以构建 NDC 在执行其他代码之前在请求的最开始。这 上下文信息可以是客户端的主机名和其他 请求固有的信息...

将其转换为 Grails 并不太难。创建一个将应用于所有请求的过滤器,使用适当的信息填充 NDC before 对任何控制器和操作的调用,然后将其清除 after 调用。

一旦您在 NDC 中公开了这些信息,那么您当然可以将其添加到您的日志记录模式中。

这是解决这个问题的正确方法。

【讨论】:

感谢 Joshua 的指点,我已经根据您的提示在 grails 中实现了解决方案。【参考方案2】:

根据来自 Joshua 的指针,我发现了 Burt 关于同一问题的一篇很棒的博客文章。

http://burtbeckwith.com/blog/?p=521

这是我一直在寻找的问题的确切答案。

【讨论】:

以上是关于在 log4j appenders 内的 config.groovy 中访问会话用户的主要内容,如果未能解决你的问题,请参考以下文章

企业Zookeeper(Zabbx)重点监控指标和日志自动切割和轮转

配置日志框架——Log4j

log4j输出文件位置

mybatis怎么配置log4j打印出sql语句

在log4j.properties中每日appender文件路径,空间不起作用

Log4j输出终端(Appender)详解