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 java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
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.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
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.eclipse.microprofile.config.ConfigProvider;
import org.eclipse.microprofile.config.spi.ConfigSource;
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.SocketHandler;
import org.jboss.logmanager.handlers.SyslogHandler;
import io.quarkus.bootstrap.logging.InitialConfigurator;
import io.quarkus.dev.console.CurrentAppExceptionHighlighter;
import io.quarkus.dev.console.QuarkusConsole;
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.QuarkusConfigBuilderCustomizer;
import io.quarkus.runtime.console.ConsoleRuntimeConfig;
import io.quarkus.runtime.logging.LogBuildTimeConfig.CategoryBuildTimeConfig;
import io.quarkus.runtime.logging.LogRuntimeConfig.CategoryConfig;
import io.quarkus.runtime.logging.LogRuntimeConfig.CleanupFilterConfig;
import io.quarkus.runtime.logging.LogRuntimeConfig.ConsoleConfig;
import io.quarkus.runtime.logging.LogRuntimeConfig.FileConfig;
import io.quarkus.runtime.logging.LogRuntimeConfig.SocketConfig;
import io.quarkus.runtime.shutdown.ShutdownListener;
import io.smallrye.config.SmallRyeConfig;
import io.smallrye.config.SmallRyeConfigBuilder;
@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) {
SmallRyeConfig config = ConfigProvider.getConfig().unwrap(SmallRyeConfig.class);
// There may be cases where a Config with the mappings is already available, but we can't be sure, so we wrap
// the original Config and map the logging classes.
SmallRyeConfig loggingConfig = new SmallRyeConfigBuilder()
.withCustomizers(new QuarkusConfigBuilderCustomizer())
.withMapping(LogBuildTimeConfig.class)
.withMapping(LogRuntimeConfig.class)
.withMapping(ConsoleRuntimeConfig.class)
.withSources(new ConfigSource() {
@Override
public Set getPropertyNames() {
Set properties = new HashSet<>();
config.getPropertyNames().forEach(properties::add);
return properties;
}
@Override
public String getValue(final String propertyName) {
return config.getRawValue(propertyName);
}
@Override
public String getName() {
return "Logging Config";
}
}).build();
LogRuntimeConfig logRuntimeConfig = loggingConfig.getConfigMapping(LogRuntimeConfig.class);
LogBuildTimeConfig logBuildTimeConfig = loggingConfig.getConfigMapping(LogBuildTimeConfig.class);
ConsoleRuntimeConfig consoleRuntimeConfig = loggingConfig.getConfigMapping(ConsoleRuntimeConfig.class);
new LoggingSetupRecorder(new RuntimeValue<>(consoleRuntimeConfig)).initializeLogging(logRuntimeConfig,
logBuildTimeConfig,
DiscoveredLogComponents.ofEmpty(), emptyMap(), false, null, emptyList(), emptyList(), emptyList(), emptyList(),
emptyList(), emptyList(), banner, LaunchMode.DEVELOPMENT, false);
}
public ShutdownListener initializeLogging(
final LogRuntimeConfig config,
final LogBuildTimeConfig buildConfig,
final 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 List>> possibleSocketFormatters,
final RuntimeValue>> possibleBannerSupplier,
final LaunchMode launchMode,
final boolean includeFilters) {
ShutdownNotifier shutdownNotifier = new ShutdownNotifier();
Map categories = config.categories();
LogContext logContext = LogContext.getLogContext();
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();
Map filters = config.filters();
List filterElements;
if (filters.isEmpty()) {
filterElements = 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);
ArrayList handlers = new ArrayList<>(
3 + additionalHandlers.size() + (config.handlers().isPresent() ? config.handlers().get().size() : 0));
if (config.console().enable()) {
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()) {
Handler syslogHandler = configureSyslogHandler(config.syslog(), errorManager, cleanupFiler, namedFilters,
possibleSyslogFormatters, includeFilters);
if (syslogHandler != null) {
handlers.add(syslogHandler);
}
}
if (config.socket().enable()) {
final Handler socketHandler = configureSocketHandler(config.socket(), errorManager, cleanupFiler,
namedFilters, possibleSocketFormatters, includeFilters);
if (socketHandler != null) {
handlers.add(socketHandler);
}
}
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, possibleSocketFormatters,
errorManager, cleanupFiler, namedFilters, launchMode,
shutdownNotifier, includeFilters)
: emptyMap();
if (!categories.isEmpty()) {
Map additionalNamedHandlersMap;
if (additionalNamedHandlers.isEmpty()) {
additionalNamedHandlersMap = emptyMap();
} else {
additionalNamedHandlersMap = new HashMap<>();
for (RuntimeValue> runtimeValue : additionalNamedHandlers) {
runtimeValue.getValue().forEach(
new AdditionalNamedHandlersConsumer(additionalNamedHandlersMap, errorManager, filterElements,
shutdownNotifier));
}
}
namedHandlers.putAll(additionalNamedHandlersMap);
setUpCategoryLoggers(buildConfig, categoryDefaultMinLevels, categories, logContext, errorManager, namedHandlers);
}
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 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 + "'", e);
}
}
});
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(
final LogRuntimeConfig config,
final LogBuildTimeConfig buildConfig,
final ConsoleRuntimeConfig consoleConfig,
final Map categoryDefaultMinLevels,
final List additionalLogCleanupFilters,
final LaunchMode launchMode) {
ShutdownNotifier dummy = new ShutdownNotifier();
Map categories = config.categories();
LogContext logContext = LogContext.getLogContext();
Logger rootLogger = logContext.getLogger("");
rootLogger.setLevel(config.level());
ErrorManager errorManager = new OnlyOnceErrorManager();
Map filters = config.filters();
List filterElements = new ArrayList<>(filters.size() + additionalLogCleanupFilters.size());
for (Entry entry : filters.entrySet()) {
filterElements.add(new LogCleanupFilterElement(entry.getKey(), entry.getValue().targetLevel(),
entry.getValue().ifStartsWith()));
}
for (LogCleanupFilterElement logCleanupFilter : additionalLogCleanupFilters) {
filterElements.add(new LogCleanupFilterElement(logCleanupFilter.getLoggerName(), logCleanupFilter.getTargetLevel(),
logCleanupFilter.getMessageStarts()));
}
LogCleanupFilter logCleanupFilter = new LogCleanupFilter(filterElements, dummy);
ArrayList handlers = new ArrayList<>(3);
if (config.console().enable()) {
Handler consoleHandler = configureConsoleHandler(config.console(), consoleConfig, errorManager, logCleanupFilter,
emptyMap(), emptyList(), new RuntimeValue<>(Optional.empty()), launchMode, false);
errorManager = consoleHandler.getErrorManager();
handlers.add(consoleHandler);
}
Map namedHandlers = createNamedHandlers(config, consoleConfig, emptyList(),
emptyList(), emptyList(), emptyList(), emptyList(), errorManager, logCleanupFilter,
emptyMap(), launchMode, dummy, false);
setUpCategoryLoggers(buildConfig, categoryDefaultMinLevels, categories, logContext, errorManager, namedHandlers);
addNamedHandlersToRootHandlers(config.handlers(), namedHandlers, handlers, errorManager);
InitialConfigurator.DELAYED_HANDLER.setAutoFlush(false);
InitialConfigurator.DELAYED_HANDLER.setBuildTimeHandlers(handlers.toArray(LogContextInitializer.NO_HANDLERS));
}
private boolean shouldCreateNamedHandlers(
LogRuntimeConfig logRuntimeConfig,
List>> additionalNamedHandlers) {
if (!logRuntimeConfig.categories().isEmpty()) {
return true;
}
if (logRuntimeConfig.handlers().isPresent()) {
return !logRuntimeConfig.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(
LogRuntimeConfig config, ConsoleRuntimeConfig consoleRuntimeConfig,
List>> additionalNamedHandlers,
List>> possibleConsoleFormatters,
List>> possibleFileFormatters,
List>> possibleSyslogFormatters,
List>> possibleSocketFormatters,
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()) {
LogRuntimeConfig.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());
}
}
for (Entry socketConfigEntry : config.socketHandlers().entrySet()) {
SocketConfig namedSocketConfig = socketConfigEntry.getValue();
if (!namedSocketConfig.enable()) {
continue;
}
final Handler socketHandler = configureSocketHandler(namedSocketConfig, errorManager, cleanupFilter,
namedFilters, possibleSocketFormatters, includeFilters);
if (socketHandler != null) {
addToNamedHandlers(namedHandlers, socketHandler, socketConfigEntry.getKey());
}
}
Map additionalNamedHandlersMap;
if (additionalNamedHandlers.isEmpty()) {
additionalNamedHandlersMap = 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 setUpCategoryLoggers(
final LogBuildTimeConfig buildConfig,
final Map categoryDefaultMinLevels,
final Map categories,
final LogContext logContext,
final ErrorManager errorManager,
final Map namedHandlers) {
for (Entry entry : categories.entrySet()) {
String categoryName = entry.getKey();
CategoryConfig categoryConfig = entry.getValue();
InheritableLevel categoryLevel = categoryConfig.level();
Level logLevel = getLogLevel(categoryName, categories, CategoryConfig::level, emptyMap(), buildConfig.minLevel());
Level minLogLevel = getLogLevel(categoryName, buildConfig.categories(), CategoryBuildTimeConfig::minLevel,
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);
categoryLevel = InheritableLevel.of(minLogLevel.toString());
}
Logger categoryLogger = logContext.getLogger(categoryName);
if (!categoryLevel.isInherited()) {
categoryLogger.setLevel(categoryLevel.getLevel());
}
categoryLogger.setUseParentHandlers(categoryConfig.useParentHandlers());
if (categoryConfig.handlers().isPresent()) {
addNamedHandlersToCategory(categoryConfig, namedHandlers, categoryLogger, errorManager);
}
}
}
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,
final 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 (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 LogRuntimeConfig.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 Handler configureSocketHandler(final LogRuntimeConfig.SocketConfig config,
final ErrorManager errorManager,
final LogCleanupFilter logCleanupFilter,
final Map namedFilters,
final List>> possibleSocketFormatters,
final boolean includeFilters) {
try {
final SocketHandler handler = new SocketHandler(config.endpoint().getHostString(), config.endpoint().getPort());
handler.setProtocol(config.protocol());
handler.setBlockOnReconnect(config.blockOnReconnect());
handler.setLevel(config.level());
Formatter formatter = null;
boolean formatterWarning = false;
for (RuntimeValue> value : possibleSocketFormatters) {
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 socket 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 socket handler", e, ErrorManager.OPEN_FAILURE);
return null;
}
}
private static AsyncHandler createAsyncHandler(LogRuntimeConfig.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 boolean isColorEnabled(ConsoleRuntimeConfig consoleConfig, ConsoleConfig logConfig) {
if (consoleConfig.color().isPresent()) {
return consoleConfig.color().get();
}
if (logConfig.color().isPresent()) {
return logConfig.color().get();
}
return QuarkusConsole.hasColorSupport();
}
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();
}
}
}