For anyone who uses PMD, the title of this blog appears in their list of PMD errors if they don't declare their loggers static and final. Specifically, the LoggerIsNotStaticFinal rule simply says that a log should be declared static and final. I also like to make sure they are private as well. For example:
// Jakarta Commons Logging
private static final Log log = LogFactory.getLog(MyClass.class);
The above code also shows another good practice, which is to pass the Class object to the getLog() method, instead of a string. Why the java.util.logging.Logger class doesn't even provide a method accepting a Class object is simply beyond me. Why did the people who developed the java.util.logging package base their API on Log4j yet omit some of the most useful parts of it? Oh well.
Now to the point.
Why it is good practice to declare loggers private, static, and final? A logger is an internal implementation detail, so it should be private. You only need one logger for all instances of a class, hence static. And a logger should not be able to be replaced, thus final. So if this is good, what's not so good (at least in my opinion)? Simple - any logger that is not private, static, final, and which doesn't pass in a Class object to getLog()! For example, consider this common bit of code, declared in some base class:
// Not so good logger declaration
protected final Log log = LogFactory.getLog(getClass());
Why is this bad? Well, it isn't static for one thing. For another, it uses getClass() to obtain the log. At first this seems efficient since now all subclasses automatically inherit a ready-made log of the correct runtime type. So what's the issue here? The biggest problem with loggers declared in this manner is that you now get all the logging from the superclass mixed in with the logging from the subclass, and it is impossible in the log output to discern which messages came from which class unless you look at the source. This is really annoying if the superclass has a lot of logging that you don't want to see, since you cannot filter it out.
Another problem is that your ability to set log levels differently goes away, for example if a subclass resides in a different package than the superclass. In that case, if you try to filter out logging from the superclass, you can't because the actual runtime class was used to obtain the logger.
Last, having a protected logger just seems to violate basic object-oriented principles. Why in the world should subclasses know about an internal implementation detail from a superclass that is a cross-cutting concern, no less? Anyway, though this is a silly little rant it really is annoying when you extend a superclass that declares a protected logger like this.
分享到:
相关推荐
private static final Logger log = LoggerFactory.getLogger(BaiduFace.class); log.info("消息等...");
private static final Logger log = Logger.getLogger(MyClass.class); ``` 这里的`MyClass`是当前类的名字。这样,Log4j就能识别当前类并按照配置进行日志记录。例如,你可以像下面这样输出日志信息: ```java ...
private static final Logger log = Logger.getLogger(test.class); private static final Logger infoLogger = Logger.getLogger("info.logger"); private static final Logger debugLogger = Logger.getLogger...
private static final Logger LOG = Logger.getLogger(Example.class); private static String topic = "test"; private static int partitionNum = 1; private static String zkConnectUrl = "127.0.0.1:2181"; ...
private static final Logger log = Logger.getLogger(Example.class); public static void main(String[] args) { log.info("This is an info message."); } } ``` 通过以上步骤,我们可以看到log4j的强大...
private static final Logger log = Logger.getLogger(YourClass.class); public static void main(String[] args) { log.debug("Debug message"); log.info("Info message"); log.warn("Warning message"); ...
private static final Logger log = Logger.getLogger(YourClass.class); ``` 3. **输出日志信息**: ```java log.info("This is an info message."); log.debug("This is a debug message."); log.error(...
private static final Logger log = Logger.getLogger(SomeClass.class); // ... } ``` 3. **记录日志信息** 使用Logger对象记录不同级别的日志信息。常见的日志级别有:DEBUG、INFO、WARN、ERROR、FATAL。...
3. **初始化 Logger 对象**:可以通过 `Logger.getLogger()` 方法来获取或创建一个 Logger 实例,例如 `private static final Logger log = Logger.getLogger(当前类.class);`。 4. **打印日志消息**:通过调用 ...
private static final Logger log = Logger.getLogger(DbAgent.class); // ... } ``` 有了Logger实例后,就可以根据需要调用不同的日志方法来记录日志了。例如: - `log.trace(message)`:用于记录最详细的日志...
private static final Logger LOG = LoggerFactory.getLogger(WSMQTTClientSubscribe.class); private final static String CONNECTION_STRING = "tcp://localhost:1883"; private final static boolean CLEAN_...
private static final Logger log = Logger.getLogger(TestWebSocketServlet.class); private static List<WebSocketMessageInbound> connsList = new ArrayList(); @Override protected StreamInbound ...
private static final Logger log = LoggerFactory.getLogger(TestSlf4j.class); public void testLog() { log.info("this is a test log"); } public static void main(String[] args) { TestSlf4j slf = ...
private static final Logger log = Logger.getLogger("wangjunTest"); ... public void reset() { log.info("reset方法启动"); // 其他业务逻辑 } } ``` 记得在类顶部导入必要的包,即`import org.apache....
private static final Logger log = LogManager.getLogger(LoginService.class); public void login(String username, String password) { // 登录逻辑... if (/*登录成功*/) { log.info(username + " logged ...
至于如何在代码中使用Slf4j,我们可以创建一个静态logger变量,例如`private static final Logger log = LoggerFactory.getLogger(MyClass.class);`,然后在需要记录日志的地方调用`log.info()`、`log.debug()`等...
private static final Logger log = LoggerFactory.getLogger(JsonExceptionHandler.class); @Override public Mono<Void> handle(ServerWebExchange exchange, Throwable throwable) { // 根据异常类型,返回...
使用`Slf4j`注解可以自动在类级别引入一个日志变量,例如`private static final Logger log = LoggerFactory.getLogger(MyClass.class);`,这样就可以直接通过这个变量进行日志输出,而无需手动创建。 在描述中提到...
private static final Logger LOG = Logger.getLogger(ZookeeperClientTest.class); private static final String ZK_ADDRESS = "192.168.109.200:2181"; private static final int SESSION_TIMEOUT = 5000; ...
private static final Logger log = LoggerFactory.getLogger(HelloSpringBootApplication.class); public static void main(String[] args) { log.info("Spring Boot 应用启动..."); SpringApplication.run...