简体   繁体   English

如何在Java中将多个线程和类写入同一个日志文件?

[英]How do I make multiple threads and classes write into the same log file in Java?

Within a java application, I have several Classes and Threads here and there. 在java应用程序中,我有几个Classes和Threads。 I would like them all to write their logs to one single file. 我希望他们都将他们的日志写入一个文件。 How can I achieve that? 我怎样才能做到这一点?

Also here's some more questions: 还有一些问题:

  1. Do I receive the same instance of a logger if I define the same name for them even in different classes. 如果我为它们定义相同的名称,即使在不同的类中,我也会收到相同的记录器实例。 To be clear, are the following two loggers the same: 需要说明的是,以下两个记录器是相同的:

     class MyClass1 { Logger logger1 = Logger.getLogger("theSameName"); } class MyClass2{ Logger logger2 = Logger.getLogger("theSameName"); } 
  2. What happens if I define two of the FileHandler in two separate Threads that have the same file name? 如果我在两个具有相同文件名的独立线程中定义两个FileHandler会发生什么? Do both of them write to the same file? 他们两个都写到同一个文件? If yes, what happens if the file is already opened by the first one, when the second one tries to open and write to it? 如果是,如果第一个文件已经打开,第二个文件尝试打开并写入文件时会发生什么?

  3. What happens if I try to add the same FielHandler to a logger more than once as in: 如果我尝试将多个FielHandler添加到记录器中,会发生什么情况,如:

     logger.addHandler(myFileHandler); // in Thread one ... logger.addHandler(myFileHandler); // in Thread two 

Will I receive a RuntimeException because of the two FileHandler may try to open the same file simultaneously? 我是否会收到RuntimeException因为两个FileHandler可能会尝试同时打开同一个文件?

I'm using java-util-logging not log4j . 我正在使用java-util-logging而不是log4j

Make a singleton log class so any other class or thread tries creating a copy of it, will actually be using the same instance. 创建一个单例日志类,以便任何其他类或线程尝试创建它的副本,实际上将使用相同的实例。

Example implementation with java.util.logging : 使用java.util.logging示例实现:

public class LogMe {        
    private static LogMe logMe;
    private static Logger logger;    
    private static FileHandler fh;
    private static Formatter sf;

    public LogMe() {
        //Make this class a singleton
        if (logMe != null) {
            return;
        }

        //Create the log file            
        try {
            fh = new FileHandler("../xyz/LogFile.log");
        } catch (Exception e) {
            e.printStackTrace();
        }

        sf = new SimpleFormatter();
        fh.setFormatter(sf);            
        logger.addHandler(fh);

        //Part of making this class a singleton
        logger = Logger.getLogger("LogMe");
        logMe = this;        
    }

    public Logger getLogger() {
        return LogMe.logger;
    }
}

Then in your classes you will be using it like this: 然后在你的课程中你会像这样使用它:

class MyClass1 {
    LogMe logMe1 = new LogMe();
    Logger logger2 = logMe1.getLogger();
    logger.info("X 01");
}

class MyClass2 {
    LogMe logMe2 = new LogMe();
    Logger logger2 = logMe2.getLogger();
    logger.info("X 02");
}

Notice that whatever you name the LogMe and its Logger in your classes it won't have any effect because they are referencing the same instance of LogMe and its Logger 请注意,无论您在类中命名LogMe及其Logger ,它都不会产生任何影响,因为它们引用了LogMe及其Logger的相同实例

Example output in the log file will look something like this: 日志文件中的示例输出如下所示:

Oct 1, 2015 10:43:47 AM 
INFO: X 01 
Oct 1, 2015 10:43:47 AM 
INFO: X 02

Notice that the order of these log lines will depends on the order of execution of your classes. 请注意,这些日志行的顺序取决于类的执行顺序。 Also you won't need any synchronization, quoting JavaDoc of Logger: 您也不需要任何同步,引用Logger的JavaDoc:

All methods on Logger are multi-thread safe. Logger上的所有方法都是多线程安全的。

Do I receive the same instance of a logger if I define the same name for them even in different classes. 如果我为它们定义相同的名称,即使在不同的类中,我也会收到相同的记录器实例。

I don't believe it is defined anywhere, but most like it is the same object and it shouldn't matter. 我不认为它是在任何地方定义的,但大多数人都喜欢它是同一个对象,它应该无关紧要。 The libraries don't determine which file to write to based on Logger instances. 库不会根据Logger实例确定要写入哪个文件。

What happens if I define two FileHandlers in two separate Threads that have the same file name? 如果我在两个具有相同文件名的独立线程中定义两个FileHandler会发生什么?

Most like you will get two logging handlers. 最像您将获得两个日志处理程序。 This means everything will be logged twice unless you attempt to write to the same file in which case it is likely to get corrupted. 这意味着除非您尝试写入同一文件,否则所有内容都将被记录两次,在这种情况下它可能会被破坏。

There is no good reason to do this. 没有充分的理由这样做。 Just define your configuration on start up, once. 只需在启动时定义一次配置即可。

What happens if I try to add the same FielHandler to a logger more than once as in: 如果我尝试将多个FielHandler添加到记录器中,会发生什么情况,如:

It is unlikely the underlying library will notice and it will corrupt the file. 底层库不太可能会注意到它会破坏文件。 If you really need to know, I suggest you try it but don't do this in production. 如果你真的需要知道,我建议你尝试一下,但不要在生产中这样做。

Will I receive a RuntimeException or something because two FileHandler may try to open the same file simultaneously? 我是否会收到RuntimeException,因为两个FileHandler可能会同时尝试打开同一个文件?

This is not what FileOutputStream does or the OS. 这不是FileOutputStream所做的或操作系统。 You just get a corrupted file. 你只是得到一个损坏的文件。

Create a singleton class that will be used by your application. 创建一个将由您的应用程序使用的单例类。

Here is everything you need to know when writing a singleton in Java: http://learnjava.today/2015/08/the-best-singleton-in-java/ 以下是在Java中编写单例时需要了解的所有内容: http//learnjava.today/2015/08/the-best-singleton-in-java/

Keep coding ;) 继续编码;)

package javaloggers;

import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
//singleton class logger wrapper
public class LogWrap {
    public static final Logger aLogger = Logger.getLogger("myLogger");
    private static LogWrap instance = null;
    public static LogWrap getInstance(){
        if(instance==null){
            getLoggerReady();
            instance = new LogWrap();
        }
        return instance;
    }
    private static void getLoggerReady(){
        try{
            FileHandler fh = new FileHandler("test-log.txt");
            fh.setFormatter(new SimpleFormatter());
            aLogger.addHandler(fh);
            aLogger.setUseParentHandlers(false);
            aLogger.setLevel(Level.ALL);
        } catch(Exception e){
            System.out.print("Error: Logger creation issue: "+e);
        }           
    }
}
class test {
    public static void main(String args[]){
        //usage
        LogWrap logWrap = LogWrap.getInstance();
        logWrap.aLogger.severe( "Hello world!" );
    }
}

I have code that pushes data to multiple OutputStreams . 我有代码将数据推送到多个OutputStreams I use it to duplicate System.out to both System.out and a FileOutputStream . 我用它将System.out复制到System.outFileOutputStream

I would basically "reroll" that code so it use multiple input streams to pipe to one "master" file. 我基本上会“重新”重新编写代码,因此它使用多个输入流来管道传输到一个“主”文件。

Here is my code 这是我的代码

// This is an OutputStream that duplicate behavior across multiple OutStreams
public class MultiOutputStream extends OutputStream {
  OutputStream[] outputStreams;
  public MultiOutputStream(OutputStream... outputStreams) {
    this.outputStreams = outputStreams;
  }
  @Override
  public void write(int b) throws IOException {
    for (OutputStream out : outputStreams)
        out.write(b);
  }
  @Override
  public void write(byte[] b) throws IOException {
    for (OutputStream out : outputStreams)
        out.write(b);
  }
  @Override
  public void write(byte[] b, int off, int len) throws IOException {
    for (OutputStream out : outputStreams)
        out.write(b, off, len);
  }
  @Override
  public void flush() throws IOException {
    for (OutputStream out : outputStreams)
        out.flush();
  }
  @Override
  public void close() throws IOException {
    for (OutputStream out : outputStreams)
        out.close();
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java:如何使用记录器将多个类记录到同一文件中? - Java : How to use a logger to log from multiple classes into a same file? 如何使用Java中的线程读写文件? - How do I read and write to a file using threads in java? 在不锁定的情况下从多个线程写入同一文件,Java - write from multiple threads on same file without locking, Java java - 如何跨多个类传递相同的对象java? - How do I pass the same object across multiple classes java? 如何让多个线程使用相同的socket来读写? - How to make multiple threads use the same socket to read and write? 多线程在java中使用同一个对象会复制它吗? - Do multiple threads Using the same object in java make a copy of it? 多个线程如何通过使用Java中的同一连接来写入数据库? - How can multiple Threads write to the database by using the same connection in java? 如何在 Java 中的多个线程之间共享公共日志文件 - How to share common log file among multiple threads in Java Java中的for循环如何让多个线程同时运行? - How to make multiple Threads run at the same time using a for loop in Java? 如何在Java中将多个行写入文本文件? - How do I write multiple lines to a text file in Java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM