简体   繁体   English

LoggerFactory.getLogger(ClassName.class) vs LoggerFactory.getLogger(this.getClass().getName())

[英]LoggerFactory.getLogger(ClassName.class) vs LoggerFactory.getLogger(this.getClass().getName())

I'm trying to improve my optimization skills in Java.我正在努力提高我的 Java 优化技能。 In order to achieve that, I've got an old program I made and I'm trying my best to make it better.为了实现这一目标,我制作了一个旧程序,并且正在尽最大努力让它变得更好。 In this program I'm using SL4J for logging.在这个程序中,我使用 SL4J 进行日志记录。 To get the logger I did:为了得到记录器,我做了:

private static final Logger logger = LoggerFactory.getLogger(this.getClass().getName());

At the time I wrote the code, I thought this was the best option, because I remove a reference to the class name(which may be refactored).在我写代码的时候,我认为这是最好的选择,因为我删除了对类名的引用(可能会被重构)。 But now I'm not so sure anymore...但现在我不太确定了......

private static final Logger logger = LoggerFactory.getLogger(ClassName.class);

On the other side, keeps the reference to the class name, but it removes one method call.另一方面,保留对类名的引用,但它删除了一个方法调用。 This may not be a big improvement in performance for one class, but when you have lots of class, this may be something.对于一个班级来说,这可能不是一个很大的性能改进,但是当你有很多班级时,这可能是一些事情。

So my question is:所以我的问题是:

Which approach is better?哪种方法更好? Using the class name or getting it through reflection?使用类名还是通过反射获取?

Please, motivate your answer with pro and cons.请用利弊来激励你的答案。 Thank you.谢谢你。

I'll share my opinion here.我会在这里分享我的看法。 I would say that this is the case that you shouldn't be bothered from the performance point of view.我想说的是,从性能的角度来看,您不应该受到打扰。 Probably in the code there are parts that can be optimized much more than this thing :)可能在代码中有比这件事可以优化的部分:)

Now, regarding your question.现在,关于你的问题。 Take a look on LoggerFactory's code看一下LoggerFactory 的代码

Note that getLogger(Class<?> name) just calls the overloaded method:注意getLogger(Class<?> name)只是调用了重载的方法:

Logger logger = getLogger(clazz.getName());

And makes some additional calculations.并进行一些额外的计算。 So the method with String is obviously slightly faster.所以带String的方法显然要快一些。

In general the pattern is to maintain the Logger reference as a static field in the class, something like this:一般来说,模式是将 Logger 引用作为类中的静态字段来维护,如下所示:

public class SomeClass {
   private static final Logger LOG =   LoggerFactory.getLogger(SomeClass.class);
}

In this case you can't really use this.getClass() because this doesn't actually exists (you're running in a static context).在这种情况下,你不能真正使用this.getClass()因为this实际上并不存在(你在一个静态的环境中运行)。

From my experience its better to use the ClassName.getClass() as a parameter unless you really want to use the same logger from different classes.根据我的经验,最好使用ClassName.getClass()作为参数,除非您真的想使用来自不同类的相同记录器。 In such a case you better use some logical constant that denotes the logger.在这种情况下,您最好使用一些表示记录器的逻辑常量。

For example, let's say you're trying to use 3 different classes to access the database.例如,假设您尝试使用 3 个不同的类来访问数据库。 So you create logger 'DB', assign a file appender that will write to database.log and you want to reuse the same logger among these 3 different classes.因此,您创建记录器“DB”,分配一个将写入 database.log 的文件附加程序,并且您希望在这 3 个不同的类中重用相同的记录器。

So you should use the following code:所以你应该使用以下代码:

public class SomeClass {
   private static final Logger LOG =   LoggerFactory.getLogger("DB");
}

Hope this helps希望这可以帮助

Late entry!迟到!

As I am likely to be searching for this in the future.因为我将来可能会寻找这个。

There is a way to create copy/paste friendly Logger instances (granted this is almost never a good reason to do something!) by using Java 7's MethodHandles class.有一种方法可以通过使用 Java 7 的 MethodHandles 类来创建对复制/粘贴友好的 Logger 实例(当然这几乎从来都不是做某事的好理由!)。

private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

What I usually do is我通常做的是

private static final Logger logger = LoggerFactory.getLogger(ClassName.class);

However, the idiom然而,成语

protected final Logger log = LoggerFactory.getLogger(getClass());

is equally common.同样常见。 In this question you can find more info about these conventions. 在这个问题中,您可以找到有关这些约定的更多信息。

I prefer我更喜欢

Logger logger = LoggerFactory.getLogger(ClassName.class);

Because因为

this.getClass() 

Can be override by one of class children and you will see child class name in log.可以由班级孩子之一覆盖,您将在日志中看到子班级名称。 Sometimes it can be confusing because log actually is performed in parent class有时可能会令人困惑,因为日志实际上是在父类中执行的

When in static context you can't use LoggerFactory.getLogger(getClass()) OR LoggerFactory.getLogger(this.getClass().getName())在静态上下文中,您不能使用LoggerFactory.getLogger(getClass())LoggerFactory.getLogger(this.getClass().getName())

And then you have to use LoggerFactory.getLogger(ClassName.class)然后你必须使用LoggerFactory.getLogger(ClassName.class)

Anyways I prefer Lombok's @Log4j2 , less code and does the job : https://projectlombok.org/api/lombok/extern/log4j/Log4j2.html无论如何,我更喜欢 Lombok 的@Log4j2 ,更少的代码并完成工作: https : @Log4j2

If you don't want to write the class name every time you declare a logger, you can use the following utility method:如果不想每次声明记录器都写类名,可以使用下面的实用方法:

    public static org.slf4j.Logger getLogger() {
        final Throwable t = new Throwable();
        t.fillInStackTrace();
        return LoggerFactory.getLogger(t.getStackTrace()[1].getClassName());
    }

The method can be used tis way:该方法可以采用以下方式:

private static final Logger LOG = TheClassContainingTheMethod.getLogger();

With such an approach, the logger declaration is always the same for all the classes.使用这种方法,所有类的记录器声明总是相同的。

我用这个

private static final Logger log = LoggerFactory.getLogger(ClassName.class);

Use this用这个

private final Logger logger = LoggerFactory.getLogger(this.getClass()); 

}
// logic
try
{
// todo
}

catch (NullPointerException e) {
        logger.error("Error:-" + e.getMessage());
          return ResponseUtil.errorResponse(e.getMessage());
        }

        catch (Exception e) {
            logger.error("Error:-" + e.getMessage());
            return ResponseUtil.errorResponse(e.getMessage());
        }

暂无
暂无

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

相关问题 LoggerFactory.getLogger“root”与“class”名称的区别是什么? - What the difference in LoggerFactory.getLogger “root” vs “class” name? 自定义Logger消息格式Java LoggerFactory.getLogger(getClass()) - Custom Logger message format Java LoggerFactory.getLogger(getClass()) Slf4j LoggerFactory.getLogger和声纳 - Slf4j LoggerFactory.getLogger and sonarqube SessionBean 上的实例 LoggerFactory.getLogger 上的 StackOverFlowError - StackOverFlowError on instance LoggerFactory.getLogger on a SessionBean 为什么不建议每次都调用LoggerFactory.getLogger(...)? - Why calling LoggerFactory.getLogger(…) every time is not recommended? SLF4J,避免每次都写 LoggerFactory.getLogger(MyClassName.class) - SLF4J, To avoid writing LoggerFactory.getLogger(MyClassName.class) every time LoggerFactory不能getLogger - LoggerFactory cannot getLogger 错误:从Spring 1.5.9升级到2.0.1后找不到符号Logger logger = Logger.getLogger(this.getClass()。getName()) - error: cannot find symbol Logger logger = Logger.getLogger(this.getClass().getName()) after Spring 1.5.9 upgrade to 2.0.1 java:找不到符号符号:类getLogger位置:类org.slf4j.LoggerFactory - java: cannot find symbol symbol: class getLogger location: class org.slf4j.LoggerFactory Logger.getLogger(“ Classname” .class.getName())。log(Level.SEVERE,null,ex); - Logger.getLogger(“Classname”.class.getName()).log(Level.SEVERE, null, ex);
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM