【问题标题】:can we have level based log files using log4j我们可以使用 log4j 拥有基于级别的日志文件吗
【发布时间】:2015-03-21 07:19:02
【问题描述】:

我使用 log4j 创建了一个应用程序,用于将所有基于级别的日志存储在单个文件中,但在当前情况下,单个文件将保存所有级别日志,例如 ALL、INFO、ERROR、FATAL、WARN、DEBUG等等...因为在我的应用程序中我有一个选项说一个选择框,当我选择错误时,它应该只显示错误日志,如果我选择信息那么它应该只显示信息日志。

我正在解析日志文件以根据特定级别获取适当的日志,但在这种情况下,如果日志文件非常大,则需要更多时间。

我想到的一个解决方案是为每个级别维护单独的日志文件,这样我们就可以避免解析

想知道大家对此的看法。尽管如此,如果这很好,我们如何将基于级别的日志重定向到单独的日志文件,例如 ERROR 日志到 appError.log,INFO 日志到 appInfo.log,以及一个通用日志文件来保存所有基于级别的日志。

我的 log4j.properties 如下所示

# LOG4J configuration
log4j.rootLogger=DEBUG, Appender1, Appender2

log4j.appender.Appender1=org.apache.log4j.ConsoleAppender
log4j.appender.Appender1.layout=org.apache.log4j.PatternLayout
log4j.appender.Appender1.layout.ConversionPattern=%d [%t] %-7p %10c{1} - %m%n

log4j.appender.Appender2=org.apache.log4j.FileAppender
log4j.appender.Appender2.File=${appRootPath}/WEB-INF/logs/LogDemos.log
log4j.appender.Appender2.layout=org.apache.log4j.PatternLayout
log4j.appender.Appender2.layout.ConversionPattern=%d [%t] %-7p %10c{1} - %m%n

解析方法如下图

Scanner scanner = new Scanner(new File(ctx.getRealPath("/")+"/WEB-INF/logs/LogDemos.log"));
        while(scanner.hasNext())
        {
            String level = request.getParameter("level");
            String logs = scanner.nextLine();

            String regex = "(\\d{4}-\\d{2}-\\d{2}) (\\d{2}:\\d{2}:\\d{2},\\d{3}) \\[(.*)\\] ([^ ]*) +([^ ]*) - (.*)$";

            Pattern p = Pattern.compile(regex);

            Matcher m = p.matcher(logs);

            if (m.matches() && m.groupCount() == 6) {

                String date = m.group(1);
                String time = m.group(2);
                String threadId = m.group(3);
                String priority = m.group(4);
                String category = m.group(5);
                String message = m.group(6);
                if(priority.trim().equalsIgnoreCase(level.trim()))
                {
                    logsList.add(logs);
                    System.out.println("date: " + date);
                    System.out.println("time: " + time);
                    System.out.println("threadId: " + threadId);
                    System.out.println("priority: " + priority);
                    System.out.println("category: " + category);
                    System.out.println("message: " + message);
                }
                else
                {
                    logsList.add(logs);
                }
            }

        }
        session.setAttribute("logs", logsList);
        scanner.close();

【问题讨论】:

标签: java apache logging log4j


【解决方案1】:

如果您使用org.apache.log4j.varia.LevelRangeFilter,您可以执行以下操作(对于INFOERROR):

# LOG4J configuration
log4j.rootLogger=DEBUG, OnlyInfo, OnlyError

# Only INFO
log4j.appender.OnlyInfo=org.apache.log4j.FileAppender
log4j.appender.OnlyInfo.File=${appRootPath}/WEB-INF/logs/info.log
log4j.appender.OnlyInfo.File=logs/info.log
log4j.appender.OnlyInfo.layout=org.apache.log4j.PatternLayout
log4j.appender.OnlyInfo.layout.ConversionPattern=%d [%t] %-7p %10c{1} - %m%n
log4j.appender.OnlyInfo.filter.A=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.OnlyInfo.filter.A.LevelMin=INFO    
log4j.appender.OnlyInfo.filter.A.LevelMax=INFO
log4j.appender.OnlyInfo.filter.A.AcceptOnMatch=true

# Only ERROR
log4j.appender.OnlyError=org.apache.log4j.FileAppender
log4j.appender.OnlyError.File=${appRootPath}/WEB-INF/logs/error.log
log4j.appender.OnlyError.layout=org.apache.log4j.PatternLayout
log4j.appender.OnlyError.layout.ConversionPattern=%d [%t] %-7p %10c{1} - %m%n
log4j.appender.OnlyError.filter.A=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.OnlyError.filter.A.LevelMin=ERROR    
log4j.appender.OnlyError.filter.A.LevelMax=ERROR
log4j.appender.OnlyError.filter.A.AcceptOnMatch=true

【讨论】:

    【解决方案2】:

    连接到 Log4J 的默认假设是,只要您关心某个级别的消息(例如 INFO),那么您也会关心更重要的消息(例如 ERROR)。您可以设置记录器的级别和附加程序的阈值以过滤掉低于特定重要性级别的消息,但是如果您想将(比如说)信息消息发送到特定的附加程序而不是警告、错误和致命,那么实现的唯一方法即通过应用 过滤器

    属性配置机制不支持过滤器,因此您必须切换到log4j.xml 配置样式。以下配置示例摘自Log4J wiki

        <appender name="info-out" class="org.apache.log4j.FileAppender"> 
                <param name="File" value="info.log"/> 
                <layout class="org.apache.log4j.PatternLayout"> 
                        <param name="ConversionPattern" value="%m%n"/> 
                </layout> 
                <filter class="org.apache.log4j.varia.LevelMatchFilter">
                        <param name="LevelToMatch" value="info" />
                        <param name="AcceptOnMatch" value="true"/>
                </filter>
                <filter class="org.apache.log4j.varia.DenyAllFilter" />
        </appender> 
    

    【讨论】:

    • @IanRoberts «属性配置机制不支持过滤器»:这种说法并不完全正确。
    • @PaulVargas 哦,好的,我正在浏览我链接到的文档页面,其中指出 PropertyConfigurator 不做过滤器,我不知道信息已经过时了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    相关资源
    最近更新 更多