Philipp
Philipp

Reputation: 4799

How to set log level per instance and per package hierarchy

My application manages devices in a network. Those are represented in my application by objects and compositions of objects. Each of these devices has an ID and each object related to a device knows about its ID.

When configuring logging, in addition to set the log level per the package hierarchy, I would like to be able to set it per device - that is, all instances related to one device should be eg. put in DEBUG level.

How can I set the log level by the package hierarchy and also by an instance ID?

My thoughts so far:

Currently my loggers are created the "standard" way, by the class type

public class Thermometer extends AnalogDevice {
  private static final Logger logger = LoggerFactory.getLogger(Thermometer.class);
  ...
}

But I want to be able to choose the log level for specific devices. My current idea would be to use the ID in the logger name, like this:

public class Thermometer extends AnalogDevice {
  private final Logger logger;
  public Thermometer(String deviceId){
    logger = LoggerFactory.getLogger(deviceId+"."+Thermometer.class);
    ...
  }
  ...
}

(and the same for other classes in the hierarchy and other classes bound to this device) This would allow to configure log4j to have all messages for device "mydevice123" on DEBUG level.

log4j.logger.mydevice123=DEBUG

But this will potentially create many loggers (per device / per class):

Also I now lost the possibility to set the level on a package hierarchy. This won't work anymore.

log4j.logger.com.example.dev=DEBUG

What's a better way?

Upvotes: 1

Views: 564

Answers (1)

Gab
Gab

Reputation: 8323

Use logback as your logging implementation.

Set your device id in the MDC (Mapped Diagnostic Context) (*)

Set up a DynamicThresholdFilter

(*) IMHO a good approach to set the device id in the MDC is using an aspect applied on every business method which will get the device id from the targeted object (exemple with spring aspects), set the id in context before the method invocation and remove it after

Upvotes: 1

Related Questions