Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Log4j:事件出现在错误的日志文件中_Java_File_Events_Log4j_Logging - Fatal编程技术网

Java Log4j:事件出现在错误的日志文件中

Java Log4j:事件出现在错误的日志文件中,java,file,events,log4j,logging,Java,File,Events,Log4j,Logging,为了能够记录和跟踪一些事件,我在java项目中添加了一个LoggingHandler类。在这个类中,我使用两个不同的log4j记录器实例——一个用于记录事件,另一个用于将事件跟踪到不同的文件中。类的初始化块如下所示: public void initialize() { System.out.print("starting logging server ..."); // create logger instances logLogger = Logger.getLog

为了能够记录和跟踪一些事件,我在java项目中添加了一个LoggingHandler类。在这个类中,我使用两个不同的log4j记录器实例——一个用于记录事件,另一个用于将事件跟踪到不同的文件中。类的初始化块如下所示:

public void initialize()
{
    System.out.print("starting logging server ...");

    // create logger instances
    logLogger = Logger.getLogger("log");
    traceLogger = Logger.getLogger("trace");

    // create pattern layout
    String conversionPattern = "%c{2} %d{ABSOLUTE} %r %p %m%n";
    try
    {
        patternLayout = new PatternLayout();
        patternLayout.setConversionPattern(conversionPattern);
    }
    catch (Exception e)
    {
        System.out.println("error: could not create logger layout pattern");
        System.out.println(e);
        System.exit(1);
    }

    // add pattern to file appender
    try
    {
        logFileAppender = new FileAppender(patternLayout, logFilename, false);
        traceFileAppender = new FileAppender(patternLayout, traceFilename, false);
    }
    catch (IOException e)
    {
        System.out.println("error: could not add logger layout pattern to corresponding appender");
        System.out.println(e);
        System.exit(1);
    }

    // add appenders to loggers
    logLogger.addAppender(logFileAppender);
    traceLogger.addAppender(traceFileAppender);

    // set logger level
    logLogger.setLevel(Level.INFO);
    traceLogger.setLevel(Level.INFO);

    // start logging server
    loggingServer = new LoggingServer(logLogger, traceLogger, serverPort, this);
    loggingServer.start();

    System.out.println(" done");
}
    public void logMessage(String message)
{
    synchronized (logLogger)
    {
        if (logLogger.isInfoEnabled() && logFileAppender != null)
        {
            logLogger.info(instanceName + ": " + message);
        }
    }
} 
确保只有线程同时使用记录器实例的功能,每个日志记录/跟踪方法在同步块内调用logging方法.info。一个例子如下所示:

public void initialize()
{
    System.out.print("starting logging server ...");

    // create logger instances
    logLogger = Logger.getLogger("log");
    traceLogger = Logger.getLogger("trace");

    // create pattern layout
    String conversionPattern = "%c{2} %d{ABSOLUTE} %r %p %m%n";
    try
    {
        patternLayout = new PatternLayout();
        patternLayout.setConversionPattern(conversionPattern);
    }
    catch (Exception e)
    {
        System.out.println("error: could not create logger layout pattern");
        System.out.println(e);
        System.exit(1);
    }

    // add pattern to file appender
    try
    {
        logFileAppender = new FileAppender(patternLayout, logFilename, false);
        traceFileAppender = new FileAppender(patternLayout, traceFilename, false);
    }
    catch (IOException e)
    {
        System.out.println("error: could not add logger layout pattern to corresponding appender");
        System.out.println(e);
        System.exit(1);
    }

    // add appenders to loggers
    logLogger.addAppender(logFileAppender);
    traceLogger.addAppender(traceFileAppender);

    // set logger level
    logLogger.setLevel(Level.INFO);
    traceLogger.setLevel(Level.INFO);

    // start logging server
    loggingServer = new LoggingServer(logLogger, traceLogger, serverPort, this);
    loggingServer.start();

    System.out.println(" done");
}
    public void logMessage(String message)
{
    synchronized (logLogger)
    {
        if (logLogger.isInfoEnabled() && logFileAppender != null)
        {
            logLogger.info(instanceName + ": " + message);
        }
    }
} 
如果查看日志文件,我会发现有时错误的文件中会出现事件。一个例子:

trace 10:41:30,773 11080 INFO masterControl(192.168.2.21): string broadcast message was  pushed from 1267093 to vehicle 1055293 (slaveControl 1)
trace 10:41:30,784 11091 INFO masterControl(192.168.2.21): string broadcast message was pushed from 1156513 to vehicle 1105792 (slaveControl 1)
trace 10:41:30,796 11103 INFO masterControl(192.168.2.21): string broadcast message was pushed from 1104306 to vehicle 1055293 (slaveControl 1)
trace 10:41:30,808 11115 INFO masterControl(192.168.2.21): vehicle 1327879 was pushed to slave control 1
10:41:30,808 11115 INFO masterControl(192.168.2.21): string broadcast message was pushed from 1101572 to vehicle 106741 (slaveControl 1)
trace 10:41:30,820 11127 INFO masterControl(192.168.2.21): string broadcast message was pushed from 1055293 to vehicle 1104306 (slaveControl 1)
我认为每当两个事件同时发生时,问题就会出现在这里:10:41:30808。有人知道如何解决我的问题吗?我已经尝试在方法调用后添加睡眠,但没有帮助

比尔

马库斯

编辑:

12104信息主控192.168.2.21:车辆1169775被推到从控1

编辑2:

似乎只有在使用RMI连接从RMI线程内部调用日志记录方法我的客户机/服务器交换信息时才会出现问题

编辑3:

我自己解决了这个问题:看起来log4j并没有完全保存线程。使用单独的对象同步所有日志/跟踪方法后,一切正常。在将消息写入文件之前,可能lib正在将消息写入线程不安全的缓冲区

您不需要在记录器上同步,而需要在输出流上同步

如果使用log4j,输出应该正确同步。获得所见内容的唯一方法是两个线程同时写入同一文件

您是否可能使用相同的输出文件配置了两个附加器?不要那样做;每个appender必须有自己的、不同的文件名


如果您100%确定每个appender都会写入不同的文件,那么剩下的唯一选项就是您有时使用了错误的记录器。

是否会因为某种原因多次调用initialize方法?每次调用都会添加两个新的Appender,它们写入与现有Appender相同的文件。

这个问题已经存在4年了,但我在2013年遇到了同样的问题,我想我已经通过为每个Appender创建一个新的PatternLayout解决了这个问题。希望将来它能帮助其他人解决同样的问题。

如果输出流指的是appender,appender是线程安全的:doAppend方法是同步的。在FileAppender上进行同步后,问题仍然存在,请参见上面的示例。也许我必须将记录器实例放入不同的线程中?不,正如您在初始化方法中看到的,两个appender都绑定到不同的文件logFilename和traceFilename,但它们使用相同的patternLayout。几分钟后,我尝试将日志/跟踪移动到不同的线程,但这也没有帮助。顺便问一下:我使用的是log4j 1.2和Java 1.6.014 log4j 1.2的哪个版本?1.2.15? 这并不重要,但也许你遇到了一个不知名的错误。将其移动到不同的线程只会使情况变得更糟。