LoggerHelper.java

/*
 * Copyright 2022 Global Crop Diversity Trust
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.gringlobal.util;

import java.util.concurrent.Callable;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;

/**
 * Logging utilities.
 *
 * @author Matija Obreza
 */
public class LoggerHelper {

	/**
	 * Temporarily enable logging at selected log level for the specified logger.
	 */
	public static <T> T withLoglevel(Level level, String loggerName, Callable<T> callable) throws Exception {
		LoggerContext context = (LoggerContext) LogManager.getContext(false);
		Configuration config = context.getConfiguration();

		Level prevLevel;
		LoggerConfig loggerConfig = config.getLoggerConfig(loggerName);

		if (loggerConfig.getName().length() == 0) { // Need a new logger
			var newLoggerConfig = new LoggerConfig(loggerName, level, false);
			config.getRootLogger().getAppenders().values().forEach(appender -> {
				newLoggerConfig.addAppender(appender, level, null);
			});
			config.addLogger(loggerName, newLoggerConfig);
			loggerConfig = newLoggerConfig;
			prevLevel = null;

		} else { // We have a logger
			prevLevel = loggerConfig.getLevel();
		}

		loggerConfig.setLevel(level);
		context.updateLoggers();

		System.out.println("\nLogging " + loggerName + "@" + level + " started!");
		try {
			return callable.call();
		} finally {
			if (prevLevel == null) {
				config.removeLogger(loggerName);
			} else {
				loggerConfig.setLevel(prevLevel);
			}
			context.updateLoggers();
			System.out.println("Logging " + loggerName + "@" + level + " done.\n");
		}
	}

	/**
	 * Switch on SQL query logging.
	 */
	public static <T> T withSqlLogging(Callable<T> callable) throws Exception {
		return withLoglevel(Level.DEBUG, "org.hibernate.SQL", callable);
	}

}