English 中文(简体)
• 如何使用具有多个类别的标识4j?
原标题:how to use log4j with multiple classes?
  • 时间:2011-10-02 06:07:42
  •  标签:
  • java
  • log4j

I m currently writing a big project in java, with numerous classes, some classes are quiet small, that simply represent objects with only few methods. I have a logger set in my main class, and it works fine. I want to be able to use only one logger (with one console appender) with all the classes. I tried to pass a reference to the logger to the different classes, but it doesn t look right. besides, sometimes I m running tests on the classes without running main, and thus the logger is not initialized for the other classes.

我指的是,如何从不同类别到一个标识,不同类别之间没有硬性依赖,并且能够独立使用每个类别标识,如何达到这一目的的最佳方法?

最佳回答

如果我能正确理解,你在一分钟就知道:

public class Main {
    public static final Logger LOGGER = Logger.getLogger(Main.class);
}

public class AnotherClass {
    public void doSomething() {
        Main.LOGGER.debug("value=" + value);
    }
}

或者,你将记录转录到该类别的建筑商。

首先,你只能使用转至洛格的同样价值,使用一种全球记录。 如:

public class Main {
    private static final Logger LOGGER = Logger.getLogger("GLOBAL");
}

public class AnotherClass {
    private final Logger LOGGER = Logger.getLogger("GLOBAL");

    public void doSomething() {
        LOGGER.debug("value=" + value);
    }
}

这完全使用相同的记录。 抵达 这两条电话中都有同一个物体。 你不再依赖不同班级,这将发挥作用。

我从你们的评论中收集到的是,你正在通过手法(使用<代码>BasicConfigurator.configure)进行配置。 大部分时间都是必要的,你应该做你的工作,简单地把 log4j.properties或 log4j.xml加到你的班子。 在Eclipse中,添加到弧/(或如果你重新使用ven子/main/资源)。 如果您重新使用黄麻,则添加到测试/源目录中(或 /测试/resource/资源)。 这是一种更长的组合日志4j的方法,因为你不必在课堂之间传递信息。

此外,建议使用记录仪的方式是将这一类别转至Logger.get Carloger()。 这样,你就可以根据类别名称来筛选你们的产出,这通常比仅仅有一个全球记录更有用:

public class Main {
    private static final Logger LOGGER = Logger.getLogger(Main.class);
    public static final main(String[] args) {
        LOGGER.debug("started");
    }
}

public class AnotherClass {
    private final Logger LOGGER = Logger.getLogger(this.getClass());

    public void doSomething() {
        LOGGER.debug("value=" + value);
    }
}

然后,在原木4j.properties中,你可以将单一用户汇到一个档案中。

# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1

# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender

# A1 uses PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

最后,没有必要宣布所有沉积为静止。 如果你在制造标的><>>>>>>[*]时,这只会产生明显的影响。 申报您的伐木业为非统计领域,使您能够使用< 代码> 记录仪表。 这页数为,其中很好地解释了原状和混合物。 因此,除非你有充分理由不使用非统计领域。

Cameron is right when he say that you should try and use slf4j if possible, it has one killer feature, you can use multiple logging frameworks with it.

[*]和我指抽签。

问题回答

Your logger instances should typically be private, static and final. By doing so, each class will have it s own logger instance (that is created once the class is loaded), so that you could identify the class where the log record was created, and also you no longer need to pass logger instances across classes.

The best way to do it is to have each class have it s own logger (named after the class), then set up your configuration so that they all append to the same appender.

For example:

class A {
    private static final Logger log = Logger.getLogger(A.class);
}

class B {
    private static final Logger log = Logger.getLogger(B.class);
}

然后,您的记录4j. 效绩可像记录4j中的例子:

# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1

# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender

# A1 uses PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

<代码>A和B将登录根 log,并因此登录同一个投影器(在这种情况下是独角)。

这将使你想到的是:每一类人都是独立的,但他们都写上同一个记录。 你也获得了奖金,你可以改变原木4j组合中每一类的伐木水平。

除此以外,如果项目仍处于早期发展阶段,你可能希望考虑将项目移至4j。 硫4j比原木4j有某些改进,因此很难与原木合作。

我最近找到了这一解决办法。

Use @Log4j annotation with all the classes in which you wish using logger.

福利:

  1. Easy to maintain, easy to track down.
  2. Only one object of the logger is created which will be used through out.

如何做到这一点?

Pre-req:Install Lombok Plugin,install Lombok Plugin, 编辑,在你的项目中增加了Lombok的依赖。

现在定义部分:

@Log4j2
public class TestClass {
    TestClass() {
        log.info("Default Constructor"); 
        //With the help of lombok plugin, you ll be able to see the suggestions
    }
    <Data members and data methods>
}

最新资料:

如果没有这方面的一些研究,你可以使用其他方法。 采用这种方法的伐木班,一旦你制定守则,并产生Jar,所有使用说明的班次都将共用一个单一吨的Logger。

  1. Make sure you are keeping the same standard throughout the project, if someone else starts using the general definition of classes like the traditional way, you might end up having multiple instances.
  2. Make sure that you are using the same logger classes throughout the project, if you have chosen to use @Slf4j, keep it consistent throughout, you might end up with some errors at some places and yes definitely inconsistencies.

The reason you have multiple logger instances is because you want them to behave different when logging (usually by printing out the class name they are configured with). If you do not care about that, you can just create a single static logger instance in a class and use that all over the place.

为了形成单一记录,你可以简单地建立一个固定的通用记录类别,作为单一点记录,因此,如果我们需要改变记录包,你将只更新这一类别。

final public class Logger {
    private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger("Log");

    enum Level {Error, Warn, Fatal, Info, Debug}

    private Logger() {/* do nothing */};

    public static void logError(Class clazz, String msg) {
        log(Level.Error, clazz, msg, null);
    }

    public static void logWarn(Class clazz, String msg) {
        log(Level.Warn, clazz, msg, null);
    }

    public static void logFatal(Class clazz, String msg) {
        log(Level.Fatal, clazz, msg, null);
    }

    public static void logInfo(Class clazz, String msg) {
        log(Level.Info, clazz, msg, null);
    }

    public static void logDebug(Class clazz, String msg) {
        log(Level.Debug, clazz, msg, null);
    }


    public static void logError(Class clazz, String msg, Throwable throwable) {
        log(Level.Error, clazz, msg, throwable);
    }


    public static void logWarn(Class clazz, String msg, Throwable throwable) {
        log(Level.Warn, clazz, msg, throwable);
    }

    public static void logFatal(Class clazz, String msg, Throwable throwable) {
        log(Level.Fatal, clazz, msg, throwable);
    }

    public static void logInfo(Class clazz, String msg, Throwable throwable) {
        log(Level.Info, clazz, msg, throwable);
    }

    public static void logDebug(Class clazz, String msg, Throwable throwable) {
        log(Level.Debug, clazz, msg, throwable);
    }

    private static void log(Level level, Class clazz, String msg, Throwable throwable) {
        String message = String.format("[%s] : %s", clazz, msg);
        switch (level) {
            case Info:
                logger.info(message, throwable);
                break;
            case Warn:
                logger.warn(message, throwable);
                break;
            case Error:
                logger.error(message, throwable);
                break;
            case Fatal:
                logger.fatal(message, throwable);
                break;
            default:
            case Debug:
                logger.debug(message, throwable);
        }
    }

}




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...