Grails日志记录 - 是否有任何现有的解决方案能够记录调用实际发生的File + Line? [英] Grails logging - Is there any existing solution to be able to log the File + Line where the call actually occured?

查看:82
本文介绍了Grails日志记录 - 是否有任何现有的解决方案能够记录调用实际发生的File + Line?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Grails的新手,我正在尝试配置Log4j,以便记录发生日志调用的确切文件和行。没有模式作为 conversionPattern !看来Grails以Log4j没有看到真正的调用来源的方式来包装记录器。



我知道这个线程,但我不确定如何创建一个自定义的appender。我无法相信没有人已经开发出了解决这个问题的方法!



我接受任何建议:




  • 使用除Log4j以外的其他工具可以在Grails中获得实际的文件+行(Logback?)?
  • 任何具有现有自定义appender他愿意分享?



  • 预先感谢!

    解决方案

    我其实是自己做的。我想我应该为它做一个适当的Grails插件,但对于Grails来说,我仍然不够自信,以确保代码始终有效。我通过使用Grails 2.2.4从控制器和服务中进行日志记录来测试它,并且它似乎运行良好。
    $ b 它通过检查堆栈跟踪来查找调用发生的实际文件和行,然后将这些信息添加到 MDC 线程上下文。 (其他)appender可以使用%X {fileAndLine} 标记使用添加到 MDC 的值。



    下面是代码和javadoc(阅读它!):

      package logFileLineInjectorGrailsPlugin 

    import org.apache.log4j.Appender;
    import org.apache.log4j.AppenderSkeleton;
    import org.apache.log4j.spi.LoggingEvent;
    import org.apache.log4j.Logger;
    import java.lang.StackTraceElement;
    import org.apache.log4j.MDC;

    / **
    *允许日志appender访问实际发生日志调用的FILE和LINE。
    *
    *(1)将这个伪appender添加到Config.groovy中的其他appender。然后,您可以在其他appender中使用
    *%X {fileAndLine}来输出实际发生日志调用的文件和行。
    *
    * ------------
    * log4j = {
    * appenders {
    * appender name:'fileAndLineInjector',new logFileLineInjectorGrailsPlugin.FileAndLineInjector()
    * //使用%X {fileAndLine}标记的控制台appender示例:
    * console name:'stdout',layout:pattern(conversionPattern:'[%d {yyyy-MM-dd HH:mm:ss}]%-5p〜%m〜%c〜%X {fileAndLine}%n')
    *}
    *(...)
    * ------------
    *
    *(2)然后添加它在您要使用的记录器的声明中有* first * appender引用%X {fileAndLine}令牌。
    *
    *例如:
    *
    * ------------
    * root {
    * error'fileAndLineInjector ','stdout'
    *}
    * ------------
    *
    *使用此设置,调用log.error (测试!)会导致类似:
    *
    * [2013-08-12 19:16:15]错误〜测试! 〜在Eclipse / STS / GGTS(我没有尝试在其他IDE中),当%X { fileAndLine}在内部控制台输出,文本是可点击的
    *并导致实际的文件/行。
    *
    *
    * /
    class FileAndLineInjector extends AppenderSkeleton {

    @Override
    public void close(){
    }

    @Override
    public boolean requiresLayout(){
    return false;

    $ b @Override
    protected void append(LoggingEvent event){

    StackTraceElement [] strackTraceElements = Thread.currentThread()。getStackTrace();

    StackTraceElement targetStackTraceElement = null;
    for(int i = 0; i< strackTraceElements.length; i ++){
    StackTraceElement strackTraceElement = strackTraceElements [i];
    if(strackTraceElement!= null&&
    strackTraceElement.declaringClass!= null&&
    strackTraceElement.declaringClass.startsWith(org.apache.commons.logging.Log\ $)&&
    i<(strackTraceElements.length - 1)){
    targetStackTraceElement = strackTraceElements [++ i];
    while(targetStackTraceElement.declaringClass!= null&&
    targetStackTraceElement.declaringClass.startsWith(org.codehaus.groovy.runtime.callsite。)&&
    i<( strackTraceElements.length - 1)){
    targetStackTraceElement = strackTraceElements [++ i];
    }
    break; (targetStackTraceElement!= null){
    MDC.put(fileAndLine,(+ targetStackTraceElement.getFileName()+):



    + targetStackTraceElement.getLineNumber()+));
    } else {
    MDC.remove(fileAndLine);



    code
    $ b

    让我知道是否有东西不清楚,或者如果你找到一种方法来改善它!


    I'm new to Grails and I'm trying to configure Log4j so it logs the exact file and line where the log call occured. No pattern works as the conversionPattern! It seems Grails wraps the logger in a way that Log4j doesn't see the real source of the call.

    I'm aware of this thread, but I'm not sure how to create a custom appender. I just can't believe nobody already developed something to fix this issue!

    I'm open to any suggestions :

    • Does using something else than Log4j work in Grails to get the actual file+line (Logback?)?
    • Anyone with an existing "custom appender" he's willing to share?

    Thanks in advance!

    解决方案

    I actually did it by myself. I guess I should do a proper Grails plugin for it, but I'm still not comfortable enough with Grails to be sure the code will always work. I tested it by logging from a Controller and from a Service, using Grails 2.2.4, and it seems to work well.

    It works by checking the stacktrace to find the actual file and line where the call occurred and then it adds this information in the MDC thread context. Values added to MDC can be used by the (other) appenders using the %X{fileAndLine} token.

    Here's the code and the javadoc (read it!) :

    package logFileLineInjectorGrailsPlugin
    
    import org.apache.log4j.Appender;
    import org.apache.log4j.AppenderSkeleton;
    import org.apache.log4j.spi.LoggingEvent;
    import org.apache.log4j.Logger;
    import java.lang.StackTraceElement;
    import org.apache.log4j.MDC;
    
    /**
     * Allows the log appenders to have access to the FILE and LINE where the log call actually occurred.
     * 
     * (1) Add this pseudo appender to your other appenders, in Config.groovy. Then you can use 
     * "%X{fileAndLine}" in the other appenders to output the file and line where the log call actually occurred.
     * 
     * ------------
     * log4j = {
     *     appenders {
     *      appender name:'fileAndLineInjector', new logFileLineInjectorGrailsPlugin.FileAndLineInjector()
     *      // example of a console appender using the "%X{fileAndLine}" token :
     *         console name:'stdout', layout:pattern(conversionPattern: '[%d{yyyy-MM-dd HH:mm:ss}] %-5p ~ %m ~ %c ~ %X{fileAndLine}%n')
     *     }
     *  (...)
     * ------------
     * 
     * (2) Then add it has the *first* appender reference in the declarations of the loggers in which you want to use the "%X{fileAndLine}" token.
     *  
     * For example :
     * 
     * ------------
     * root {
     *     error 'fileAndLineInjector', 'stdout'
     * }
     * ------------
     *  
     * With this setup in place, a call to log.error("test!") will result in something like :
     *  
     * [2013-08-12 19:16:15] ERROR ~ test! ~ grails.app.services.testProject.TestService ~ (TestService.groovy:8)
     * 
     * In Eclipse/STS/GGTS (I didn't try in other IDEs), when "%X{fileAndLine}" is outputed in the internal console, the text is clickable
     * and leads to the actual file/line.
     * 
     *
     */
    class FileAndLineInjector extends AppenderSkeleton {
    
        @Override
        public void close() {
        }
    
        @Override
        public boolean requiresLayout() {
            return false;
        }
    
        @Override
        protected void append(LoggingEvent event) {
    
            StackTraceElement[] strackTraceElements = Thread.currentThread().getStackTrace();
    
            StackTraceElement targetStackTraceElement = null;
            for(int i = 0; i < strackTraceElements.length; i++) {
                StackTraceElement strackTraceElement = strackTraceElements[i];
                if(strackTraceElement != null &&
                   strackTraceElement.declaringClass != null &&
                   strackTraceElement.declaringClass.startsWith("org.apache.commons.logging.Log\$") &&
                   i < (strackTraceElements.length - 1)) {
                       targetStackTraceElement = strackTraceElements[++i];
                       while(targetStackTraceElement.declaringClass != null &&
                             targetStackTraceElement.declaringClass.startsWith("org.codehaus.groovy.runtime.callsite.") &&
                             i < (strackTraceElements.length - 1)) {
                           targetStackTraceElement = strackTraceElements[++i];
                       }
                       break;
                }
            }
    
            if(targetStackTraceElement != null) {
                MDC.put("fileAndLine", "(" + targetStackTraceElement.getFileName() + ":" + targetStackTraceElement.getLineNumber() + ")");
            } else {
                MDC.remove("fileAndLine");
            }
        }
    }
    

    Let me know if something is not clear or if you find a way to improve it!

    这篇关于Grails日志记录 - 是否有任何现有的解决方案能够记录调用实际发生的File + Line?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆