Another approach is to use a Logback TurboFilter. This can give us more control.
Changing the level of the logger itself only let's us turn a particular logger on or off. What if we want to get DEBUG
for user:123
or team:456
for everything in the com.example.billing
module for the next 90 minutes
but stay are WARN
for everything else?
If we use a TurboFilter, we have access to the MDC where we can get the user context. And we can access a dynamic config system to get the rules for which users to match.
This is what https://github.com/prefab-cloud/prefab-cloud-java does using prefab.cloud as the dynamic config and UI.
Simplified:
public class PrefabMDCTurboFilter extends TurboFilter {
private final ConfigClient configClient;
PrefabMDCTurboFilter(ConfigClient configClient) {
this.configClient = configClient;
}
public static void install(ConfigClient configClient) {
PrefabMDCTurboFilter filter = new PrefabMDCTurboFilter(configClient);
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
loggerContext.addTurboFilter(filter);
}
@Override
public FilterReply decide(
Marker marker,
Logger logger,
Level level,
String s,
Object[] objects,
Throwable throwable
) {
Optional<Prefab.LogLevel> loglevelMaybe = configClient.getLogLevelFromStringMap(
logger.getName(),
MDC.getCopyOfContextMap()
);
if (loglevelMaybe.isPresent()) {
Level calculatedMinLogLevelToAccept = LogbackLevelMapper.LEVEL_MAP.get(
loglevelMaybe.get()
);
if (level.isGreaterOrEqual(calculatedMinLogLevelToAccept)) {
return FilterReply.ACCEPT;
}
return FilterReply.DENY;
}
return FilterReply.NEUTRAL;
}
}