/**
* Copyright 2015-2016 Red Hat, Inc, and individual contributors.
*
* 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.wildfly.swarm.logging;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.wildfly.swarm.config.Logging;
import org.wildfly.swarm.config.logging.AsyncHandler;
import org.wildfly.swarm.config.logging.ConsoleHandler;
import org.wildfly.swarm.config.logging.CustomFormatter;
import org.wildfly.swarm.config.logging.CustomHandler;
import org.wildfly.swarm.config.logging.FileHandler;
import org.wildfly.swarm.config.logging.Level;
import org.wildfly.swarm.config.logging.PatternFormatter;
import org.wildfly.swarm.config.logging.RootLogger;
import org.wildfly.swarm.config.logging.SyslogHandler;
import org.wildfly.swarm.spi.api.Fraction;
import org.wildfly.swarm.spi.api.annotations.MarshalDMR;
import org.wildfly.swarm.spi.api.annotations.WildFlyExtension;
/**
* @author Bob McWhirter
* @author Ken Finnigan
* @author Lance Ball
*/
@SuppressWarnings("unused")
@WildFlyExtension(module = "org.jboss.as.logging")
@MarshalDMR
public class LoggingFraction extends Logging<LoggingFraction> implements Fraction<LoggingFraction> {
public static final String CONSOLE = "CONSOLE";
public static final String PATTERN = "PATTERN";
public static final String COLOR_PATTERN = "COLOR_PATTERN";
public LoggingFraction applyDefaults() {
Level level = Level.INFO;
String prop = System.getProperty(LoggingProperties.LOGGING);
if (prop != null) {
prop = prop.trim().toUpperCase();
try {
level = Level.valueOf(prop);
} catch (IllegalArgumentException e) {
// Go with default of Level.INFO
}
}
return applyDefaults(level);
}
public LoggingFraction applyDefaults(Level level) {
defaultColorFormatter()
.consoleHandler(Level.ALL, COLOR_PATTERN)
.rootLogger(level, CONSOLE);
Properties allProps = System.getProperties();
for (String name : allProps.stringPropertyNames()) {
if (isSimpleLoggerName(name)) {
String logger = name.substring((LoggingProperties.LOGGING + ".").length());
try {
Level loggerLevel = Level.valueOf(allProps.getProperty(name).trim().toUpperCase());
logger(logger, (l) -> {
l.level(loggerLevel);
l.category(logger);
});
} catch (IllegalArgumentException e) {
// apparently wasn't a logging category+level, ignore.
}
}
}
return this;
}
protected boolean isSimpleLoggerName(String name) {
if (!name.startsWith(LoggingProperties.LOGGING + ".")) {
return false;
}
if (name.endsWith("level")) {
return false;
}
if (name.matches("^.*\\.handlers.[0-9]+$")) {
return false;
}
return true;
}
/**
* Create a default TRACE logging fraction.
*
* @return The fully-configured fraction.
*/
public static LoggingFraction createTraceLoggingFraction() {
return createDefaultLoggingFraction(Level.TRACE);
}
/**
* Create a default DEBUG logging fraction.
*
* @return The fully-configured fraction.
*/
public static LoggingFraction createDebugLoggingFraction() {
return createDefaultLoggingFraction(Level.DEBUG);
}
/**
* Create a default ERROR logging fraction.
*
* @return The fully-configured fraction.
*/
public static LoggingFraction createErrorLoggingFraction() {
return createDefaultLoggingFraction(Level.ERROR);
}
/**
* Create a default INFO logging fraction.
*
* @return The fully-configured fraction.
*/
public static LoggingFraction createDefaultLoggingFraction() {
return createDefaultLoggingFraction(Level.INFO);
}
/**
* Create a default logging fraction for the specified level.
*
* @return The fully-configured fraction.
*/
public static LoggingFraction createDefaultLoggingFraction(Level level) {
return new LoggingFraction().applyDefaults(level);
}
// ------- FORMATTERS ---------
/**
* Configure a default non-color formatter named {@code PATTERN}.
*
* @return This fraction.
*/
public LoggingFraction defaultFormatter() {
return formatter(PATTERN, "%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n");
}
/**
* Configure a default color formatter named {@code COLOR_PATTERN}.
*
* @return This fraction.
*/
public LoggingFraction defaultColorFormatter() {
return formatter(COLOR_PATTERN, "%K{level}%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n");
}
/**
* Add a new PatternFormatter to this Logger
*
* @param name the name of the formatter
* @param pattern the pattern string
* @return This fraction.
*/
public LoggingFraction formatter(String name, String pattern) {
patternFormatter(new PatternFormatter(name).pattern(pattern));
return this;
}
/**
* Add a CustomFormatter to this logger
*
* @param name the name of the formatter
* @param module the module that the logging handler depends on
* @param className the logging handler class to be used
* @return This fraction.
*/
public LoggingFraction customFormatter(String name, String module, String className) {
return customFormatter(name, module, className, null);
}
/**
* Add a CustomFormatter to this logger
*
* @param name the name of the formatter
* @param module the module that the logging handler depends on
* @param className the logging handler class to be used
* @param properties the properties
* @return this fraction
*/
public LoggingFraction customFormatter(String name, String module, String className, Properties properties) {
Map<Object, Object> formatterProperties = new HashMap<>();
final Enumeration<?> names = properties.propertyNames();
while (names.hasMoreElements()) {
final String nextElement = (String) names.nextElement();
formatterProperties.put(nextElement, properties.getProperty(nextElement));
}
customFormatter(new CustomFormatter(name)
.module(module)
.attributeClass(className)
.properties(formatterProperties));
return this;
}
/**
* Get the list of PatternFormatter configurations
*
* @return The list of formatters
*/
public List<PatternFormatter> patternFormatters() {
return subresources().patternFormatters();
}
/**
* Get the list of CustomFormatter configurations
*
* @return The list of custom formatters
*/
public List<CustomFormatter> customFormatters() {
return subresources().customFormatters();
}
// ---------- HANDLERS ----------
/**
* Add a ConsoleHandler to the list of handlers for this logger.
*
* @param level The logging level
* @param formatter A pattern string for the console's formatter
* @return This fraction
*/
public LoggingFraction consoleHandler(Level level, String formatter) {
consoleHandler(new ConsoleHandler(CONSOLE)
.level(level)
.namedFormatter(formatter));
return this;
}
/**
* Get the list of ConsoleHandlers for this logger
*
* @return the list of handlers
*/
public List<ConsoleHandler> consoleHandlers() {
return subresources().consoleHandlers();
}
/**
* Add a FileHandler to the list of handlers for this logger
*
* @param name The name of the handler
* @param path The log file path
* @param level The logging level
* @param formatter The pattern string for the formatter
* @return This fraction
*/
public LoggingFraction fileHandler(String name, String path, Level level, String formatter) {
Map<Object, Object> fileProperties = new HashMap<>();
fileProperties.put("path", path);
fileProperties.put("relative-to", "jboss.server.log.dir");
fileHandler(new FileHandler(name)
.level(level)
.formatter(formatter)
.file(fileProperties));
return this;
}
/**
* Get the list of FileHandlers configured on this logger
*
* @return the list of FileHandlers
*/
public List<FileHandler> fileHandlers() {
return subresources().fileHandlers();
}
/**
* Add a CustomHandler to this logger
*
* @param name the name of the handler
* @param module the module that the handler uses
* @param className the handler class name
* @param properties properties for the handler
* @param formatter a pattern string for the formatter
* @return this fraction
*/
public LoggingFraction customHandler(String name, String module, String className, Properties properties, String formatter) {
Map<Object, Object> handlerProperties = new HashMap<>();
final Enumeration<?> names = properties.propertyNames();
while (names.hasMoreElements()) {
final String nextElement = (String) names.nextElement();
handlerProperties.put(nextElement, properties.getProperty(nextElement));
}
customHandler(new CustomHandler(name)
.module(module)
.attributeClass(className)
.formatter(formatter)
.properties(handlerProperties));
return this;
}
/**
* Get the list of CustomHandlers for this logger
*
* @return the list of handlers
*/
public List<CustomHandler> customHandlers() {
return subresources().customHandlers();
}
/**
* Get the list of AsyncHandlers for this logger
*
* @return the list of handlers
*/
public List<AsyncHandler> asyncHandlers() {
return subresources().asyncHandlers();
}
/**
* Get the list of SyslogHandlers for this logger
*
* @return the list of handlers
*/
public List<SyslogHandler> syslogHandlers() {
return subresources().syslogHandlers();
}
// TODO: Add methods for PeriodicRotatingFileHandler, PeriodicSizeRotatingFileHandler, SizeRotatingFileHandler
// -------- ROOT logger ---------
/**
* Add a root logger to this fraction
*
* @param level the log level
* @param handlers a list of handlers
* @return this fraction
*/
public LoggingFraction rootLogger(Level level, String... handlers) {
rootLogger(new RootLogger().level(level)
.handlers(handlers));
return this;
}
}