Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.quarkus.runtime.logging.LoggingSetupRecorder Maven / Gradle / Ivy
package io.quarkus.runtime.logging;
import static org.wildfly.common.net.HostName.getQualifiedHostName;
import static org.wildfly.common.os.Process.getProcessName;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.logging.ErrorManager;
import java.util.logging.Filter;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import org.jboss.logmanager.ExtFormatter;
import org.jboss.logmanager.LogContext;
import org.jboss.logmanager.LogContextInitializer;
import org.jboss.logmanager.Logger;
import org.jboss.logmanager.errormanager.OnlyOnceErrorManager;
import org.jboss.logmanager.filters.AllFilter;
import org.jboss.logmanager.formatters.ColorPatternFormatter;
import org.jboss.logmanager.formatters.PatternFormatter;
import org.jboss.logmanager.formatters.TextBannerFormatter;
import org.jboss.logmanager.handlers.AsyncHandler;
import org.jboss.logmanager.handlers.ConsoleHandler;
import org.jboss.logmanager.handlers.FileHandler;
import org.jboss.logmanager.handlers.PeriodicSizeRotatingFileHandler;
import org.jboss.logmanager.handlers.SizeRotatingFileHandler;
import org.jboss.logmanager.handlers.SyslogHandler;
import io.quarkus.bootstrap.logging.InitialConfigurator;
import io.quarkus.dev.console.CurrentAppExceptionHighlighter;
import io.quarkus.dev.testing.ExceptionReporting;
import io.quarkus.runtime.ImageMode;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;
import io.quarkus.runtime.configuration.ConfigInstantiator;
import io.quarkus.runtime.console.ConsoleRuntimeConfig;
import io.quarkus.runtime.shutdown.ShutdownListener;
import io.quarkus.runtime.util.ColorSupport;
@Recorder
public class LoggingSetupRecorder {
private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LoggingSetupRecorder.class);
final RuntimeValue consoleRuntimeConfig;
public LoggingSetupRecorder(RuntimeValue consoleRuntimeConfig) {
this.consoleRuntimeConfig = consoleRuntimeConfig;
}
@SuppressWarnings("unused") //called via reflection, as it is in an isolated CL
public static void handleFailedStart() {
handleFailedStart(new RuntimeValue<>(Optional.empty()));
}
public static void handleFailedStart(RuntimeValue>> banner) {
LogConfig config = new LogConfig();
ConfigInstantiator.handleObject(config);
LogBuildTimeConfig buildConfig = new LogBuildTimeConfig();
ConfigInstantiator.handleObject(buildConfig);
ConsoleRuntimeConfig consoleRuntimeConfig = new ConsoleRuntimeConfig();
ConfigInstantiator.handleObject(consoleRuntimeConfig);
new LoggingSetupRecorder(new RuntimeValue<>(consoleRuntimeConfig)).initializeLogging(config, buildConfig,
DiscoveredLogComponents.ofEmpty(),
Collections.emptyMap(),
false, null,
Collections.emptyList(),
Collections.emptyList(),
Collections.emptyList(),
Collections.emptyList(),
Collections.emptyList(), banner, LaunchMode.DEVELOPMENT, false);
}
public ShutdownListener initializeLogging(LogConfig config, LogBuildTimeConfig buildConfig,
DiscoveredLogComponents discoveredLogComponents,
final Map categoryDefaultMinLevels,
final boolean enableWebStream,
final RuntimeValue> streamingDevUiConsoleHandler,
final List>> additionalHandlers,
final List>> additionalNamedHandlers,
final List>> possibleConsoleFormatters,
final List>> possibleFileFormatters,
final List>> possibleSyslogFormatters,
final RuntimeValue>> possibleBannerSupplier,
LaunchMode launchMode,
boolean includeFilters) {
ShutdownNotifier shutdownNotifier = new ShutdownNotifier();
final Map categories = config.categories;
final LogContext logContext = LogContext.getLogContext();
final Logger rootLogger = logContext.getLogger("");
if (config.level.intValue() < buildConfig.minLevel.intValue()) {
log.warnf(
"Root log level %s set below minimum logging level %s, promoting it to %s. Set the build time configuration property 'quarkus.log.min-level' to '%s' to avoid this warning",
config.level, buildConfig.minLevel, buildConfig.minLevel, config.level);
rootLogger.setLevel(buildConfig.minLevel);
} else {
rootLogger.setLevel(config.level);
}
ErrorManager errorManager = new OnlyOnceErrorManager();
final Map filters = config.filters;
List filterElements;
if (filters.isEmpty()) {
filterElements = Collections.emptyList();
} else {
filterElements = new ArrayList<>(filters.size());
filters.forEach(new BiConsumer<>() {
@Override
public void accept(String loggerName, CleanupFilterConfig config) {
filterElements.add(
new LogCleanupFilterElement(loggerName, config.targetLevel, config.ifStartsWith));
}
});
}
LogCleanupFilter cleanupFiler = new LogCleanupFilter(filterElements, shutdownNotifier);
for (Handler handler : LogManager.getLogManager().getLogger("").getHandlers()) {
handler.setFilter(cleanupFiler);
}
Map namedFilters = createNamedFilters(discoveredLogComponents);
final ArrayList handlers = new ArrayList<>(
3 + additionalHandlers.size() + (config.handlers.isPresent() ? config.handlers.get().size() : 0));
if (config.console.enable) {
final Handler consoleHandler = configureConsoleHandler(config.console, consoleRuntimeConfig.getValue(),
errorManager, cleanupFiler, namedFilters, possibleConsoleFormatters, possibleBannerSupplier,
launchMode, includeFilters);
errorManager = consoleHandler.getErrorManager();
handlers.add(consoleHandler);
}
if (launchMode.isDevOrTest()) {
handlers.add(new Handler() {
@Override
public void publish(LogRecord record) {
if (record.getThrown() != null) {
ExceptionReporting.notifyException(record.getThrown());
}
}
@Override
public void flush() {
}
@Override
public void close() throws SecurityException {
}
});
}
if (config.file.enable) {
handlers.add(
configureFileHandler(config.file, errorManager, cleanupFiler, namedFilters, possibleFileFormatters,
includeFilters));
}
if (config.syslog.enable) {
final Handler syslogHandler = configureSyslogHandler(config.syslog, errorManager, cleanupFiler,
namedFilters, possibleSyslogFormatters, includeFilters);
if (syslogHandler != null) {
handlers.add(syslogHandler);
}
}
if ((launchMode.isDevOrTest() || enableWebStream)
&& streamingDevUiConsoleHandler != null
&& streamingDevUiConsoleHandler.getValue().isPresent()) {
Handler handler = streamingDevUiConsoleHandler.getValue().get();
handler.setErrorManager(errorManager);
handler.setFilter(new LogCleanupFilter(filterElements, shutdownNotifier));
if (possibleBannerSupplier != null && possibleBannerSupplier.getValue().isPresent()) {
Supplier bannerSupplier = possibleBannerSupplier.getValue().get();
String header = "\n" + bannerSupplier.get();
handler.publish(new LogRecord(Level.INFO, header));
}
handlers.add(handler);
}
Map namedHandlers = shouldCreateNamedHandlers(config, additionalNamedHandlers)
? createNamedHandlers(config, consoleRuntimeConfig.getValue(), additionalNamedHandlers,
possibleConsoleFormatters, possibleFileFormatters, possibleSyslogFormatters,
errorManager, cleanupFiler, namedFilters, launchMode,
shutdownNotifier, includeFilters)
: Collections.emptyMap();
if (!categories.isEmpty()) {
Map additionalNamedHandlersMap;
if (additionalNamedHandlers.isEmpty()) {
additionalNamedHandlersMap = Collections.emptyMap();
} else {
additionalNamedHandlersMap = new HashMap<>();
for (RuntimeValue> runtimeValue : additionalNamedHandlers) {
runtimeValue.getValue().forEach(
new AdditionalNamedHandlersConsumer(additionalNamedHandlersMap, errorManager, filterElements,
shutdownNotifier));
}
}
namedHandlers.putAll(additionalNamedHandlersMap);
categories.forEach(new BiConsumer<>() {
@Override
public void accept(String categoryName, CategoryConfig config) {
final Level logLevel = getLogLevel(categoryName, categories, CategoryConfig::getLevel,
Collections.emptyMap(), buildConfig.minLevel);
final Level minLogLevel = getLogLevel(categoryName, buildConfig.categories,
CategoryBuildTimeConfig::getMinLevel, categoryDefaultMinLevels, buildConfig.minLevel);
if (logLevel.intValue() < minLogLevel.intValue()) {
log.warnf(
"Log level %s for category '%s' set below minimum logging level %s, promoting it to %s. Set the build time configuration property 'quarkus.log.category.\"%s\".min-level' to '%s' to avoid this warning",
logLevel,
categoryName, minLogLevel, minLogLevel, categoryName, logLevel);
config.level = InheritableLevel.of(minLogLevel.toString());
}
}
});
categories.forEach(new CategoryLoggerConsumer(logContext, namedHandlers, errorManager));
}
for (RuntimeValue> additionalHandler : additionalHandlers) {
final Optional optional = additionalHandler.getValue();
if (optional.isPresent()) {
final Handler handler = optional.get();
handler.setErrorManager(errorManager);
handler.setFilter(cleanupFiler);
handlers.add(handler);
}
}
addNamedHandlersToRootHandlers(config.handlers, namedHandlers, handlers, errorManager);
InitialConfigurator.DELAYED_HANDLER.setAutoFlush(false);
InitialConfigurator.DELAYED_HANDLER.setHandlers(handlers.toArray(LogContextInitializer.NO_HANDLERS));
return shutdownNotifier;
}
private static Map createNamedFilters(DiscoveredLogComponents discoveredLogComponents) {
if (discoveredLogComponents.getNameToFilterClass().isEmpty()) {
return Collections.emptyMap();
}
Map nameToFilter = new HashMap<>();
LogFilterFactory logFilterFactory = LogFilterFactory.load();
discoveredLogComponents.getNameToFilterClass().forEach(new BiConsumer<>() {
@Override
public void accept(String name, String className) {
try {
nameToFilter.put(name, logFilterFactory.create(className));
} catch (Exception e) {
throw new RuntimeException("Unable to create instance of Logging Filter '" + className + "'");
}
}
});
return nameToFilter;
}
/**
* WARNING: this method is part of the recorder but is actually called statically at build time.
* You may not push RuntimeValue's to it.
*/
public static void initializeBuildTimeLogging(LogConfig config, LogBuildTimeConfig buildConfig,
Map categoryDefaultMinLevels,
ConsoleRuntimeConfig consoleConfig,
LaunchMode launchMode) {
ShutdownNotifier dummy = new ShutdownNotifier();
final Map categories = config.categories;
final LogContext logContext = LogContext.getLogContext();
final Logger rootLogger = logContext.getLogger("");
rootLogger.setLevel(config.level);
ErrorManager errorManager = new OnlyOnceErrorManager();
final Map filters = config.filters;
List filterElements = new ArrayList<>(filters.size());
for (Entry entry : filters.entrySet()) {
filterElements.add(
new LogCleanupFilterElement(entry.getKey(), entry.getValue().targetLevel, entry.getValue().ifStartsWith));
}
LogCleanupFilter logCleanupFilter = new LogCleanupFilter(filterElements, dummy);
final ArrayList handlers = new ArrayList<>(3);
if (config.console.enable) {
final Handler consoleHandler = configureConsoleHandler(config.console, consoleConfig, errorManager,
logCleanupFilter, Collections.emptyMap(), Collections.emptyList(),
new RuntimeValue<>(Optional.empty()), launchMode, false);
errorManager = consoleHandler.getErrorManager();
handlers.add(consoleHandler);
}
Map namedHandlers = createNamedHandlers(config, consoleConfig, Collections.emptyList(),
Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), errorManager, logCleanupFilter,
Collections.emptyMap(), launchMode, dummy, false);
for (Map.Entry entry : categories.entrySet()) {
final String categoryName = entry.getKey();
final Level logLevel = getLogLevel(categoryName, categories, CategoryConfig::getLevel,
Collections.emptyMap(), buildConfig.minLevel);
final Level minLogLevel = getLogLevel(categoryName, buildConfig.categories, CategoryBuildTimeConfig::getMinLevel,
categoryDefaultMinLevels, buildConfig.minLevel);
if (logLevel.intValue() < minLogLevel.intValue()) {
String category = entry.getKey();
log.warnf("Log level %s for category '%s' set below minimum logging level %s, promoting it to %s. "
+
"Set the build time configuration property 'quarkus.log.category.\"%s\".min-level' to '%s' to avoid this warning",
logLevel,
category, minLogLevel, minLogLevel, category, logLevel);
entry.getValue().level = InheritableLevel.of(minLogLevel.toString());
}
}
for (Map.Entry entry : categories.entrySet()) {
final String name = entry.getKey();
final Logger categoryLogger = logContext.getLogger(name);
final CategoryConfig categoryConfig = entry.getValue();
if (!categoryConfig.level.isInherited()) {
categoryLogger.setLevel(categoryConfig.level.getLevel());
}
categoryLogger.setUseParentHandlers(categoryConfig.useParentHandlers);
if (categoryConfig.handlers.isPresent()) {
addNamedHandlersToCategory(categoryConfig, namedHandlers, categoryLogger, errorManager);
}
}
addNamedHandlersToRootHandlers(config.handlers, namedHandlers, handlers, errorManager);
InitialConfigurator.DELAYED_HANDLER.setAutoFlush(false);
InitialConfigurator.DELAYED_HANDLER.setBuildTimeHandlers(handlers.toArray(LogContextInitializer.NO_HANDLERS));
}
private boolean shouldCreateNamedHandlers(LogConfig logConfig,
List>> additionalNamedHandlers) {
if (!logConfig.categories.isEmpty()) {
return true;
}
if (logConfig.handlers.isPresent()) {
return !logConfig.handlers.get().isEmpty();
}
return !additionalNamedHandlers.isEmpty();
}
public static Level getLogLevel(String categoryName, Map categories,
Function levelExtractor, Map categoryDefaults, Level rootMinLevel) {
while (true) {
InheritableLevel inheritableLevel = getLogLevelNoInheritance(categoryName, categories, levelExtractor,
categoryDefaults);
if (!inheritableLevel.isInherited()) {
return inheritableLevel.getLevel();
}
final int lastDotIndex = categoryName.lastIndexOf('.');
if (lastDotIndex == -1) {
return rootMinLevel;
}
categoryName = categoryName.substring(0, lastDotIndex);
}
}
public static InheritableLevel getLogLevelNoInheritance(String categoryName, Map categories,
Function levelExtractor, Map categoryDefaults) {
T categoryConfig = categories.get(categoryName);
InheritableLevel inheritableLevel = null;
if (categoryConfig != null) {
inheritableLevel = levelExtractor.apply(categoryConfig);
}
if (inheritableLevel == null) {
inheritableLevel = categoryDefaults.get(categoryName);
}
if (inheritableLevel == null) {
inheritableLevel = InheritableLevel.Inherited.INSTANCE;
}
return inheritableLevel;
}
private static Map createNamedHandlers(LogConfig config, ConsoleRuntimeConfig consoleRuntimeConfig,
List>> additionalNamedHandlers,
List>> possibleConsoleFormatters,
List>> possibleFileFormatters,
List>> possibleSyslogFormatters,
ErrorManager errorManager, LogCleanupFilter cleanupFilter,
Map namedFilters, LaunchMode launchMode,
ShutdownNotifier shutdownHandler, boolean includeFilters) {
Map namedHandlers = new HashMap<>();
for (Entry consoleConfigEntry : config.consoleHandlers.entrySet()) {
ConsoleConfig namedConsoleConfig = consoleConfigEntry.getValue();
if (!namedConsoleConfig.enable) {
continue;
}
final Handler consoleHandler = configureConsoleHandler(namedConsoleConfig, consoleRuntimeConfig,
errorManager, cleanupFilter, namedFilters, possibleConsoleFormatters, null, launchMode,
includeFilters);
addToNamedHandlers(namedHandlers, consoleHandler, consoleConfigEntry.getKey());
}
for (Entry fileConfigEntry : config.fileHandlers.entrySet()) {
FileConfig namedFileConfig = fileConfigEntry.getValue();
if (!namedFileConfig.enable) {
continue;
}
final Handler fileHandler = configureFileHandler(namedFileConfig, errorManager, cleanupFilter, namedFilters,
possibleFileFormatters, includeFilters);
addToNamedHandlers(namedHandlers, fileHandler, fileConfigEntry.getKey());
}
for (Entry sysLogConfigEntry : config.syslogHandlers.entrySet()) {
SyslogConfig namedSyslogConfig = sysLogConfigEntry.getValue();
if (!namedSyslogConfig.enable) {
continue;
}
final Handler syslogHandler = configureSyslogHandler(namedSyslogConfig, errorManager, cleanupFilter,
namedFilters, possibleSyslogFormatters, includeFilters);
if (syslogHandler != null) {
addToNamedHandlers(namedHandlers, syslogHandler, sysLogConfigEntry.getKey());
}
}
Map additionalNamedHandlersMap;
if (additionalNamedHandlers.isEmpty()) {
additionalNamedHandlersMap = Collections.emptyMap();
} else {
additionalNamedHandlersMap = new HashMap<>();
for (RuntimeValue> runtimeValue : additionalNamedHandlers) {
runtimeValue.getValue().forEach(
new AdditionalNamedHandlersConsumer(additionalNamedHandlersMap, errorManager,
cleanupFilter.filterElements.values(), shutdownHandler));
}
}
namedHandlers.putAll(additionalNamedHandlersMap);
return namedHandlers;
}
private static void addToNamedHandlers(Map namedHandlers, Handler handler, String handlerName) {
if (namedHandlers.containsKey(handlerName)) {
throw new RuntimeException(String.format("Only one handler can be configured with the same name '%s'",
handlerName));
}
namedHandlers.put(handlerName, handler);
InitialConfigurator.DELAYED_HANDLER.addLoggingCloseTask(new Runnable() {
@Override
public void run() {
handler.close();
}
});
}
private static void addNamedHandlersToCategory(CategoryConfig categoryConfig, Map namedHandlers,
Logger categoryLogger,
ErrorManager errorManager) {
for (String categoryNamedHandler : categoryConfig.handlers.get()) {
Handler handler = namedHandlers.get(categoryNamedHandler);
if (handler != null) {
categoryLogger.addHandler(handler);
InitialConfigurator.DELAYED_HANDLER.addLoggingCloseTask(new Runnable() {
@Override
public void run() {
categoryLogger.removeHandler(handler);
}
});
} else {
errorManager.error(String.format("Handler with name '%s' is linked to a category but not configured.",
categoryNamedHandler), null, ErrorManager.GENERIC_FAILURE);
}
}
}
private static void addNamedHandlersToRootHandlers(Optional> handlerNames, Map namedHandlers,
ArrayList effectiveHandlers, ErrorManager errorManager) {
if (handlerNames.isEmpty()) {
return;
}
if (handlerNames.get().isEmpty()) {
return;
}
for (String namedHandler : handlerNames.get()) {
Handler handler = namedHandlers.get(namedHandler);
if (handler != null) {
effectiveHandlers.add(handler);
} else {
errorManager.error(String.format("Handler with name '%s' is linked to a category but not configured.",
namedHandler), null, ErrorManager.GENERIC_FAILURE);
}
}
}
public void initializeLoggingForImageBuild() {
if (ImageMode.current() == ImageMode.NATIVE_BUILD) {
final ConsoleHandler handler = new ConsoleHandler(new PatternFormatter(
"%d{HH:mm:ss,SSS} %-5p [%c{1.}] %s%e%n"));
handler.setLevel(Level.INFO);
InitialConfigurator.DELAYED_HANDLER.setAutoFlush(false);
InitialConfigurator.DELAYED_HANDLER.setHandlers(new Handler[] { handler });
}
}
private static Handler configureConsoleHandler(final ConsoleConfig config,
ConsoleRuntimeConfig consoleRuntimeConfig,
final ErrorManager defaultErrorManager,
final LogCleanupFilter cleanupFilter,
final Map namedFilters,
final List>> possibleFormatters,
final RuntimeValue>> possibleBannerSupplier,
LaunchMode launchMode,
boolean includeFilters) {
Formatter formatter = null;
boolean formatterWarning = false;
for (RuntimeValue> value : possibleFormatters) {
if (formatter != null) {
formatterWarning = true;
}
final Optional val = value.getValue();
if (val.isPresent()) {
formatter = val.get();
}
}
boolean color = false;
if (formatter == null) {
Supplier bannerSupplier = null;
if (possibleBannerSupplier != null && possibleBannerSupplier.getValue().isPresent()) {
bannerSupplier = possibleBannerSupplier.getValue().get();
}
if (ColorSupport.isColorEnabled(consoleRuntimeConfig, config)) {
formatter = new ColorPatternFormatter(config.darken, config.format);
color = true;
} else {
formatter = new PatternFormatter(config.format);
}
if (bannerSupplier != null) {
formatter = new TextBannerFormatter(bannerSupplier, ExtFormatter.wrap(formatter, false));
}
}
final ConsoleHandler consoleHandler = new ConsoleHandler(
config.stderr ? ConsoleHandler.Target.SYSTEM_ERR : ConsoleHandler.Target.SYSTEM_OUT, formatter);
consoleHandler.setLevel(config.level);
consoleHandler.setErrorManager(defaultErrorManager);
applyFilter(includeFilters, defaultErrorManager, cleanupFilter, config.filter, namedFilters, consoleHandler);
Handler handler = config.async.enable ? createAsyncHandler(config.async, config.level, consoleHandler)
: consoleHandler;
if (color && launchMode.isDevOrTest() && !config.async.enable) {
final Handler delegate = handler;
handler = new Handler() {
@Override
public void publish(LogRecord record) {
BiConsumer> formatter = CurrentAppExceptionHighlighter.THROWABLE_FORMATTER;
if (formatter != null) {
formatter.accept(record, delegate::publish);
} else {
delegate.publish(record);
}
}
@Override
public void flush() {
delegate.flush();
}
@Override
public void close() throws SecurityException {
delegate.close();
}
};
}
if (formatterWarning) {
handler.getErrorManager().error("Multiple console formatters were activated", null, ErrorManager.GENERIC_FAILURE);
}
return handler;
}
private static Handler configureFileHandler(final FileConfig config, final ErrorManager errorManager,
final LogCleanupFilter cleanupFilter, Map namedFilters,
final List>> possibleFileFormatters,
final boolean includeFilters) {
FileHandler handler;
FileConfig.RotationConfig rotationConfig = config.rotation;
if (rotationConfig.fileSuffix.isPresent()) {
PeriodicSizeRotatingFileHandler periodicSizeRotatingFileHandler = new PeriodicSizeRotatingFileHandler();
periodicSizeRotatingFileHandler.setSuffix(rotationConfig.fileSuffix.get());
periodicSizeRotatingFileHandler.setRotateSize(rotationConfig.maxFileSize.asLongValue());
periodicSizeRotatingFileHandler.setRotateOnBoot(rotationConfig.rotateOnBoot);
periodicSizeRotatingFileHandler.setMaxBackupIndex(rotationConfig.maxBackupIndex);
handler = periodicSizeRotatingFileHandler;
} else {
SizeRotatingFileHandler sizeRotatingFileHandler = new SizeRotatingFileHandler(
rotationConfig.maxFileSize.asLongValue(), rotationConfig.maxBackupIndex);
sizeRotatingFileHandler.setRotateOnBoot(rotationConfig.rotateOnBoot);
handler = sizeRotatingFileHandler;
}
Formatter formatter = null;
boolean formatterWarning = false;
for (RuntimeValue> value : possibleFileFormatters) {
if (formatter != null) {
formatterWarning = true;
}
final Optional val = value.getValue();
if (val.isPresent()) {
formatter = val.get();
}
}
if (formatter == null) {
formatter = new PatternFormatter(config.format);
}
handler.setFormatter(formatter);
handler.setAppend(true);
try {
handler.setFile(config.path);
} catch (FileNotFoundException e) {
errorManager.error("Failed to set log file", e, ErrorManager.OPEN_FAILURE);
}
handler.setErrorManager(errorManager);
handler.setLevel(config.level);
handler.setFilter(cleanupFilter);
if (config.encoding.isPresent()) {
try {
handler.setEncoding(config.encoding.get().name());
} catch (UnsupportedEncodingException e) {
errorManager.error("Failed to set character encoding", e, ErrorManager.GENERIC_FAILURE);
}
}
applyFilter(includeFilters, errorManager, cleanupFilter, config.filter, namedFilters, handler);
if (formatterWarning) {
handler.getErrorManager().error("Multiple file formatters were activated", null, ErrorManager.GENERIC_FAILURE);
}
if (config.async.enable) {
return createAsyncHandler(config.async, config.level, handler);
}
return handler;
}
private static void applyFilter(boolean includeFilters, ErrorManager errorManager, LogCleanupFilter cleanupFilter,
Optional filterName, Map namedFilters, Handler handler) {
if (filterName.isEmpty() || !includeFilters) {
handler.setFilter(cleanupFilter);
} else {
String name = filterName.get();
Filter filter = namedFilters.get(name);
if (filter == null) {
errorManager.error("Unable to find named filter '" + name + "'", null, ErrorManager.GENERIC_FAILURE);
handler.setFilter(cleanupFilter);
} else {
handler.setFilter(new AllFilter(List.of(cleanupFilter, filter)));
}
}
}
private static Handler configureSyslogHandler(final SyslogConfig config, final ErrorManager errorManager,
final LogCleanupFilter logCleanupFilter,
final Map namedFilters,
final List>> possibleSyslogFormatters,
final boolean includeFilters) {
try {
final SyslogHandler handler = new SyslogHandler(config.endpoint.getHostString(), config.endpoint.getPort());
handler.setAppName(config.appName.orElse(getProcessName()));
handler.setHostname(config.hostname.orElse(getQualifiedHostName()));
handler.setFacility(config.facility);
handler.setSyslogType(config.syslogType);
handler.setProtocol(config.protocol);
handler.setBlockOnReconnect(config.blockOnReconnect);
handler.setTruncate(config.truncate);
handler.setUseCountingFraming(config.useCountingFraming);
handler.setLevel(config.level);
if (config.maxLength.isPresent()) {
BigInteger maxLen = config.maxLength.get().asBigInteger();
if (maxLen.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
errorManager.error(
"Using 2GB as the value of maxLength for SyslogHandler as it is the maximum allowed value", null,
ErrorManager.GENERIC_FAILURE);
maxLen = BigInteger.valueOf(Integer.MAX_VALUE);
} else {
BigInteger minimumAllowedMaxLength = BigInteger.valueOf(128);
if (maxLen.compareTo(minimumAllowedMaxLength) < 0) {
errorManager.error(
"Using 128 as the value of maxLength for SyslogHandler as using a smaller value is not allowed",
null, ErrorManager.GENERIC_FAILURE);
maxLen = minimumAllowedMaxLength;
}
}
handler.setMaxLength(maxLen.intValue());
}
Formatter formatter = null;
boolean formatterWarning = false;
for (RuntimeValue> value : possibleSyslogFormatters) {
if (formatter != null) {
formatterWarning = true;
}
final Optional val = value.getValue();
if (val.isPresent()) {
formatter = val.get();
}
}
if (formatter == null) {
formatter = new PatternFormatter(config.format);
}
handler.setFormatter(formatter);
handler.setErrorManager(errorManager);
handler.setFilter(logCleanupFilter);
applyFilter(includeFilters, errorManager, logCleanupFilter, config.filter, namedFilters, handler);
if (formatterWarning) {
handler.getErrorManager().error("Multiple syslog formatters were activated", null,
ErrorManager.GENERIC_FAILURE);
}
if (config.async.enable) {
return createAsyncHandler(config.async, config.level, handler);
}
return handler;
} catch (IOException e) {
errorManager.error("Failed to create syslog handler", e, ErrorManager.OPEN_FAILURE);
return null;
}
}
private static AsyncHandler createAsyncHandler(AsyncConfig asyncConfig, Level level, Handler handler) {
final AsyncHandler asyncHandler = new AsyncHandler(asyncConfig.queueLength);
asyncHandler.setOverflowAction(asyncConfig.overflow);
asyncHandler.addHandler(handler);
asyncHandler.setLevel(level);
return asyncHandler;
}
private static class CategoryLoggerConsumer implements BiConsumer {
private final LogContext logContext;
private final Map namedHandlers;
private final ErrorManager errorManager;
CategoryLoggerConsumer(LogContext logContext, Map namedHandlers, ErrorManager errorManager) {
this.logContext = logContext;
this.namedHandlers = namedHandlers;
this.errorManager = errorManager;
}
@Override
public void accept(String name, CategoryConfig categoryConfig) {
final Logger categoryLogger = logContext.getLogger(name);
if (!categoryConfig.level.isInherited()) {
categoryLogger.setLevel(categoryConfig.level.getLevel());
}
categoryLogger.setUseParentHandlers(categoryConfig.useParentHandlers);
if (categoryConfig.handlers.isPresent()) {
addNamedHandlersToCategory(categoryConfig, namedHandlers, categoryLogger, errorManager);
}
}
}
private static class AdditionalNamedHandlersConsumer implements BiConsumer {
private final Map additionalNamedHandlersMap;
private final ErrorManager errorManager;
private final Collection filterElements;
private final ShutdownNotifier shutdownNotifier;
public AdditionalNamedHandlersConsumer(Map additionalNamedHandlersMap, ErrorManager errorManager,
Collection filterElements, ShutdownNotifier shutdownNotifier) {
this.additionalNamedHandlersMap = additionalNamedHandlersMap;
this.errorManager = errorManager;
this.filterElements = filterElements;
this.shutdownNotifier = shutdownNotifier;
}
@Override
public void accept(String name, Handler handler) {
Handler previous = additionalNamedHandlersMap.putIfAbsent(name, handler);
if (previous != null) {
throw new IllegalStateException(String.format(
"Duplicate key %s (attempted merging values %s and %s)",
name, previous, handler));
}
handler.setErrorManager(errorManager);
handler.setFilter(new LogCleanupFilter(filterElements, shutdownNotifier));
}
}
public static class ShutdownNotifier implements ShutdownListener {
volatile boolean shutdown;
@Override
public void shutdown(ShutdownNotification notification) {
shutdown = true;
notification.done();
}
}
}