Hello,
I’m looking to add context key to my logger for some modules…
This is done using MDC.
I use the AbstractTagDriver.
I would like to add some information in order to filter logs by device.
There is a MDC key device-name reported by the gateway logger.
is it enough if I add :
MDC.put("device-name", "MyDevice");
in the constructor of the AbstractTagDriver.
Or I need to add this at the beginning of each method ?
the doc mention that the MDC
manages contextual information on a per thread basis .
You have to add and remove this key every time you log something. It’s important to remove it before leaving the context of whatever method(s) you’re in or else the next loggers that happen to run on the current thread will have the key set still.
You can use LoggerEx
to build a logger that always sets/unsets the key on every logging statement:
logger = LoggerEx.newBuilder()
.mdcContext("device-name", driverContext.getDeviceName())
.build(String.format("drivers.%s", getClass().getSimpleName()));
There’s a bit of a performance penalty for the convenience, but we tend to use it anyway…
I will try to replace
import org.slf4j.Logger;
logger = LoggerFactory.getLogger(getClass());
import org.slf4j.Logger;
import com.inductiveautomation.ignition.common.util.LoggerEx;
logger = LoggerEx.newBuilder()
.mdcContext("device-name", driverContext.getDeviceName())
.build(getClass()).getLoggerSLF4J();
You need to define your logger field as a LoggerEx
rather than assigning the value of getLoggerSLF4J()
or the MDC keys won’t be set. That method just returns the underlying SLF4J Logger instance.
All my log use
logger.debug("blahblah={}",myVariable);
I have to replace it as follow ? debug => debugf
logger.debugf("blahblah={}",myVariable);
errorf() don’t work with markers like {}
@Kevin.Herron, do you see any risk to replace :
import org.slf4j.Logger;
logger = LoggerFactory.getLogger(getClass());
logger.debug("blahblah={}",myVariable);
with :
import com.inductiveautomation.ignition.common.util.LoggerEx;
import org.slf4j.helpers.MessageFormatter
logger = LoggerEx.newBuilder()
.mdcContext("device-name", driverContext.getDeviceName())
.build(getClass()).getLoggerSLF4J();
logger.debug(MessageFormatter.format("blahblah={}",myVariable));
Using the SLF4J Logger will not get you automatic MDC support. That only happens with LoggerEx. (your example still uses getLoggerSLF4J()
)
You’ll have to manually set/unset the context key if you want to continue using the SLF4J Logger.
oops,
I was thinking at :
import com.inductiveautomation.ignition.common.util.LoggerEx;
import org.slf4j.helpers.MessageFormatter
logger = LoggerEx.newBuilder()
.mdcContext("device-name", driverContext.getDeviceName())
.build(getClass());
logger.debug(MessageFormatter.format("blahblah={}",myVariable));
I think that will work… haven’t tried it though.
If we have common class used in Gateway and Client scope, when we use com.inductiveautomation.ignition.common.util.LoggerEx the MDC data are ignored in the client scope ?
the vision console in 7.9 or 8.0 doesn’t suport MDC filtering.
It’s %s
and %d
like String.format
.
MDC data is only used in the gateway.