log4j-DailRollingFileAppender,文件不按小时滚动

log4j-DailRollingFileAppender,文件不按小时滚动,log4j,Log4j,我为DailyRollingFileAppender提供了以下简单的测试类,以每小时滚动一次日志文件。我面临的问题是,即使我将其设置为“.”yyyy-MM-dd-HH,它似乎也不会每小时滚动到新的日志文件。知道我在代码中哪里做错了吗 public class Test { static Logger logger = Logger.getLogger(Test.class); public static void main(String args[]) throws Exception

我为DailyRollingFileAppender提供了以下简单的测试类,以每小时滚动一次日志文件。我面临的问题是,即使我将其设置为“.”yyyy-MM-dd-HH,它似乎也不会每小时滚动到新的日志文件。知道我在代码中哪里做错了吗

public class Test {
  static Logger logger = Logger.getLogger(Test.class);

  public static void main(String args[]) throws Exception {
      String pattern = "%-20d{dd MMM yyyy HH:mm:ss} [%-5p] - %m%n";

    PatternLayout patternLayout = new PatternLayout(pattern);  

    //CREATE APPENDER.       
    DailyRollingFileAppender myAppender = new DailyRollingFileAppender(patternLayout, "TestOrig.log", "'.'yyyy-MM-dd-HH");

    //ADD APPENDER & LEVEL.
    logger.addAppender(myAppender);
    logger.setLevel   ((Level) Level.DEBUG);


//WRITE MESSAGES.
logger.debug("Successful");
logger.info ("Failed" );
logger.warn ("Failed" );
logger.error("Successful");
logger.fatal("Failed"); 

    while(true)
    {           
        Thread.sleep(1000);
    } 
  }
}

我看这里没有任何错误。当我尝试了几分钟后,我可以看到这是在创建文件

DailyRollingFileAppender myAppender = new DailyRollingFileAppender(patternLayout, "TestOrig.log", "'.'yyyy-MM-dd-HH-mm");
您是否在控制台上看到任何错误


您出错的可能原因可能是,您试图多次运行同一程序,而没有结束以前启动的程序,这会导致文件访问权限问题。

Mike,您上面的评论是正确的。除非在此期间有日志记录活动,否则不会获得新文件。如果需要强制执行该问题,则需要使用runnable启动一个线程,该线程在每个新小时开始后向日志中发布一行

目标是从第1分钟开始,每59.5分钟在日志中发布一篇文章

他的解决方案需要关于如何使用Runnable和Thread的基本标准知识。我假设您运行的是标准应用程序,而不是托管服务器环境

  • 创建一个实现
    Runnable
  • 使用
    覆盖
    run()
    方法,而
    循环到
    true
    布尔变量(isAlive),当应用程序关闭时,应用程序可以设置为
    false
  • 在循环过程中,调用
    静态记录器Logger=Logger.getLogger(YourClassName.class)的
    .info(“Logger Text”)
    方法循环等待时间为60分钟
  • 在应用程序启动时,将
    Runnable
    放入
    new Thread()
    对象中
  • 在启动时将一个
    info()
    post发布到日志中
  • 启动应用程序时启动线程对象
  • Runnable的run()方法可以是

    public void run() { 
        while (isAlive) { // isAlive is a global-level (static, even) boolean 
                          // you declared earlier as true, your app should set it to false
                          // if your app decides to exit
    
            try { 
                logger.info("Rollover Log Text");
                Thread.currentThread().sleep(1000 * 60 * 60); // 60 minutes 
            } catch (InterruptedException ignore) { 
            }
        }
    }
    

    记得在启动
    线程之前将
    isAlive
    设置为
    true
    ,在关机或错误/异常关闭时将其设置为
    false
    ,并在设置为
    false
    后调用线程的
    interrupt()
    方法。这应该每小时记录一次。

    使用@Singleton和@Schedule为计时器服务创建一个类似ejb cron的时间表

    import javax.ejb.Schedule;
    import javax.ejb.Singleton;
    
    
    @Singleton
    public class Cron {
            static Logger logger = Logger.getLogger(Test.class);
        @Schedule(second="0", minute="0", hour="0", dayOfWeek="*", persistent=false)
        public void rollLogs() {
            logger.info("midnight");
        }
    }
    

    嗯,我在这里看到了log4j的行为,如果一个小时后没有日志活动,它将不会将日志文件重命名为TestOrig.log.2011-10-14-14。只有当我关闭应用程序并再次启动时,它才会创建该文件。如果没有日志事件发生,我有没有办法强迫它创建TestOrig.log.2011-10-14-14?没有,它会在下一个日志事件发生时滚动,并在记录时检查是否是滚动的时候。有关详细信息,请参阅DailyLogAppender中的子附件(LoggingEvent事件)的Javadoc。嗨,Fred,谢谢你澄清事实。您能否提供一个示例,说明如何执行这个可运行线程,以每小时检查一次并触发日志事件,因为我对log4j非常陌生。提前感谢。@mike-需要关于如何使用Runnable和Thread的基本标准知识。假设您在标准应用程序中运行,而不是在托管服务器环境中运行,(1)创建一个实现Runnable的类,(2)使用while循环将run()方法覆盖为true boolean,您可以在应用程序关闭时将其标记为false,并在循环期间调用info(“记录器文本”)静态记录器的方法=Logger.getLogger(YourClassName.class),循环等待时间为59分钟。将runnable放入一个新线程,并在启动应用程序时启动该线程。答案要求了解线程的使用情况,而不是log4j;目标是每59.5分钟在日志中发表一篇文章。Runnable的run()方法可以是'public void run(){while(staticBooleanAppIsAlive){try{staticLogger.info(“滚动日志文本”);Thread.currentThread().sleep(1000*60*59.5);//59.5分钟}catch(InterruptedException e){}}},记住设置staticBooleanAppIsAlive并调用interrupt()应用程序关闭时线程的方法。每小时记录一次日志;自己做实验,找出什么时候睡觉。@mike-编辑了我的答案,加入了评论。