quarkus-logging-manager
quarkus-logging-manager copied to clipboard
should be able to add logger level at runtime
from the UI and REST API, we should be able to add logger at runtime.
ex : I could have : org.abc.database.level=ERROR but I want to add org.abc.label=debug
I didn't saw a ADD logger from the UI
Yes this will have to be implemented. But that would be a good addition
I created a custom implementation for this. We had at my job a implementation using SpringBoot and I had to do the same thing for quarkus.
I did a HACK. I didn't modify any of quarkus-logging-manager instead a use a RestClient to call logging-manager endpoint from within my application.
I also create a new controller that will handle to logic.
@Slf4j
@Path("/api/v1/loggers")
@Produces(MediaType.APPLICATION_JSON)
public class LoggingController {
@Inject
@RestClient
LoggingServiceRestConnector loggingServiceRestConnector;
@Inject
ObjectMapper mapper;
JsonPersistence persistenceOriginal;
@PostConstruct
void init() throws Exception {
// save original logger levels on disk
persistence.save(getAvailableLoggers(), "original.json");
// load overriden loggers
applyPersistedLogLevels();
}
private void applyPersistedLogLevels() throws Exception {
log.debug("Loading persisted log levels....");
persistence.findAll()
.forEach(loggerSetting -> loggingServiceRestConnector.updateLogger(loggerSetting.getLoggerName(), loggerSetting.getConfiguredLevel())
);
log.debug("....persisted log levels loaded");
}
@Path("/")
@GET
public LoggerSetting getLogger(@QueryParam("loggerName") String loggerName) throws JsonProcessingException {
var logger = loggingServiceRestConnector.getLogger(loggerName);
var jsonNode = mapper.readTree(logger);
return createLoggerSetting(jsonNode);
}
@Path("/available")
@GET
public List<LoggerSetting> getAvailableLoggers() throws JsonProcessingException {
var logger = loggingServiceRestConnector.getLoggers();
var list = new ArrayList<LoggerSetting>();
var jsonNode = mapper.readTree(logger);
for (var node : jsonNode) {
list.add(createLoggerSetting(node));
}
return list;
}
private static LoggerSetting createLoggerSetting(JsonNode jsonNode) {
var loggerSetting = new LoggerSetting();
var name = jsonNode.get("name");
var effectiveLevel = jsonNode.get("effectiveLevel");
var configuredLevel = jsonNode.get("configuredLevel");
if (name != null) {
loggerSetting.setLoggerName(name.asText());
}
if (effectiveLevel != null) {
loggerSetting.setEffectiveLevel(effectiveLevel.asText());
}
if (configuredLevel != null) {
loggerSetting.setConfiguredLevel(configuredLevel.asText());
}
return loggerSetting;
}
@Path("/overridden")
@GET
public Collection<LoggerSetting> getOverriddenLoggers() throws BeanPersistenceException {
return loggingSettingsService.getOverriddenLoggers();
}
@Path("/overridden")
@PUT
public LoggerSetting updateLogger(LoggerSetting logger) throws BeanPersistenceException {
loggingServiceRestConnector.updateLogger(logger.getUniqueKey(), logger.getConfiguredLevel());
// must save override
persistence.update(logger);
return logger;
}
@Path("/overridden")
@DELETE
public LoggerSetting resetLogger(String loggerName) throws BeanPersistenceException, JsonProcessingException {
if (loggerName == null) return null;
var original = persistence.findOriginalById(loggerName);
if (original != null) {
if (original.getConfiguredLevel() != null) {
loggingServiceRestConnector.updateLogger(loggerName, original.getConfiguredLevel());
} else {
loggingServiceRestConnector.updateLogger(loggerName, original.getEffectiveLevel());
}
}
var loggerSetting = getLogger(loggerName);
// must remove override
persistence.remove(loggerSetting);
return loggerSetting;
}
}
I tweak a little bit my code to show what was done without been to explicit
at startup
- call logger-manager to get all the loggers
- save those loggers into original.json
- load the overriden.json that contains all the loggers config
- apply those configs to logger-manager.update(loggername, level)
at runtime
- when a level change, it need to save the new level into oerriden.json
- send the new level to logging-manager
to reset a logger level
- read the original value of the logger from original.json
- sent that lavel to logging-manager
with that.. each time that I kill my application, it will reload my previous loggers settings.
PS. the reason that I created a new controler, it's because I had to respect the same URL that we had for SpringBoot