use of ch.qos.logback.classic.spi.ILoggingEvent in project UniversalMediaServer by UniversalMediaServer.
the class LoggingTest method testLoggingConfig.
@Test
public void testLoggingConfig() throws ConfigurationException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
// Set up a test (default) configuration
PMS.get();
PmsConfiguration configuration = new PmsConfiguration(false);
PMS.setConfiguration(configuration);
// Load logback configuration
LoggingConfig.loadFile();
// Silence logger
LoggingConfig.setRootLevel(Level.OFF);
// Get access to logger
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
Logger rootLogger = context.getLogger(Logger.ROOT_LOGGER_NAME);
/* During UMS build a valid configuration should be accessible at least under "external resources"
* and thus testing for a valid configuration is considered OK to be able to do the other tests.
* "internal defaults" is returned if a valid configuration can't be found.
*/
// Test for a valid configuration
File file = new File(LoggingConfig.getConfigFilePath());
assertTrue("LoggingConfigIsFile", file.isFile());
assertFalse("LoggingConfigIsFile", file.isDirectory());
// Test getLogFilePaths() and LoggingConfigFileLoader.getLogFilePaths()
HashMap<String, String> logFilePaths = LoggingConfig.getLogFilePaths();
@SuppressWarnings("deprecation") HashMap<String, String> compLogFilePaths = LoggingConfigFileLoader.getLogFilePaths();
Iterator<Appender<ILoggingEvent>> iterator = rootLogger.iteratorForAppenders();
while (iterator.hasNext()) {
Appender<ILoggingEvent> appender = iterator.next();
if (appender instanceof FileAppender) {
FileAppender<ILoggingEvent> fa = (FileAppender<ILoggingEvent>) appender;
assertTrue("LogFilePathsContainsKey", logFilePaths.containsKey(fa.getName()));
assertEquals("LogFilePathsHasPath", logFilePaths.get(fa.getName()), fa.getFile());
if (fa.getName().equals("default.log")) {
assertTrue("CompatibleLogFilePathsContainsKey", compLogFilePaths.containsKey("debug.log"));
assertEquals("CompatibleLogFilePathsHasPath", compLogFilePaths.get("debug.log"), fa.getFile());
} else {
assertTrue("CompatibleLogFilePathsContainsKey", compLogFilePaths.containsKey(fa.getName()));
assertEquals("CompatibleLogFilePathsHasPath", compLogFilePaths.get(fa.getName()), fa.getFile());
}
}
}
// Reset LogBack configuration and create a fake one to not rely on the existing configuration file
context.reset();
TestFileAppender<ILoggingEvent> testDefaultAppender = new TestFileAppender<>();
testDefaultAppender.setName("default.log");
testDefaultAppender.setContext(context);
PatternLayoutEncoder layoutEncoder = new PatternLayoutEncoder();
layoutEncoder.setPattern("%-5level %d{HH:mm:ss.SSS} [%thread] %msg%n");
layoutEncoder.setContext(context);
testDefaultAppender.setEncoder(layoutEncoder);
rootLogger.addAppender(testDefaultAppender);
TestFileAppender<ILoggingEvent> testGenericAppender = new TestFileAppender<>();
testGenericAppender.setName("SomeOtherFileAppender");
testGenericAppender.setContext(context);
layoutEncoder = new PatternLayoutEncoder();
layoutEncoder.setPattern("%-5level %d %msg%n");
layoutEncoder.setContext(context);
testGenericAppender.setEncoder(layoutEncoder);
rootLogger.addAppender(testGenericAppender);
TestAppender<ILoggingEvent> testNonFileAppender = new TestAppender<>();
testNonFileAppender.setName("SomeNonFileAppender");
testNonFileAppender.setContext(context);
rootLogger.addAppender(testNonFileAppender);
// Test setBuffered()
LoggingConfig.setBuffered(true);
iterator = rootLogger.iteratorForAppenders();
while (iterator.hasNext()) {
Appender<ILoggingEvent> appender = iterator.next();
if (appender instanceof OutputStreamAppender && !(appender instanceof ConsoleAppender<?>)) {
// Appender has ImmediateFlush property
assertFalse("LogFileIsBuffered", ((OutputStreamAppender<ILoggingEvent>) appender).isImmediateFlush());
}
}
LoggingConfig.setBuffered(false);
iterator = rootLogger.iteratorForAppenders();
while (iterator.hasNext()) {
Appender<ILoggingEvent> appender = iterator.next();
if (appender instanceof OutputStreamAppender && !(appender instanceof ConsoleAppender<?>)) {
assertTrue("LogFileIsNotBuffered", ((OutputStreamAppender<ILoggingEvent>) appender).isImmediateFlush());
// Appender has ImmediateFlush property
}
}
// Test getRootLevel()
assertEquals("GetRootLevel", LoggingConfig.getRootLevel(), rootLogger.getLevel());
// Test setRootLevel()
LoggingConfig.setRootLevel(Level.ALL);
assertEquals("SetRootLevel", LoggingConfig.getRootLevel(), Level.ALL);
LoggingConfig.setRootLevel(Level.INFO);
assertEquals("SetRootLevel", LoggingConfig.getRootLevel(), Level.INFO);
LoggingConfig.setRootLevel(Level.OFF);
// Test setConsoleFilter()
configuration.setLoggingFilterConsole(Level.WARN);
ConsoleAppender<ILoggingEvent> consoleAppender = new ConsoleAppender<>();
consoleAppender.setContext(context);
PatternLayoutEncoder patternEncoder = new PatternLayoutEncoder();
patternEncoder.setPattern("%msg%n");
patternEncoder.setContext(context);
patternEncoder.start();
consoleAppender.setEncoder(patternEncoder);
consoleAppender.start();
rootLogger.addAppender(consoleAppender);
LoggingConfig.setConsoleFilter();
List<Filter<ILoggingEvent>> filterList = consoleAppender.getCopyOfAttachedFiltersList();
assertEquals("NumberOfConsoleFilters", filterList.size(), 1);
assertTrue("ConsoleFilterIsThresholdFilter", filterList.get(0) instanceof ThresholdFilter);
ThresholdFilter thresholdFilter = (ThresholdFilter) filterList.get(0);
Field field = thresholdFilter.getClass().getDeclaredField("level");
field.setAccessible(true);
assertEquals("ConsoleFilterLevel", field.get(thresholdFilter), Level.WARN);
configuration.setLoggingFilterConsole(Level.TRACE);
LoggingConfig.setConsoleFilter();
filterList = consoleAppender.getCopyOfAttachedFiltersList();
assertEquals("NumberOfConsoleFilters", filterList.size(), 1);
assertTrue("ConsoleFilterIsThresholdFilter", filterList.get(0) instanceof ThresholdFilter);
thresholdFilter = (ThresholdFilter) filterList.get(0);
field = thresholdFilter.getClass().getDeclaredField("level");
field.setAccessible(true);
assertEquals("ConsoleFilterLevel", field.get(thresholdFilter), Level.TRACE);
rootLogger.detachAppender(consoleAppender);
// Test setTracesFilter()
configuration.setLoggingFilterLogsTab(Level.WARN);
FrameAppender<ILoggingEvent> frameAppender = new FrameAppender<>();
frameAppender.setContext(context);
patternEncoder = new PatternLayoutEncoder();
patternEncoder.setPattern("%msg%n");
patternEncoder.setContext(context);
patternEncoder.start();
frameAppender.setEncoder(patternEncoder);
frameAppender.start();
rootLogger.addAppender(frameAppender);
LoggingConfig.setTracesFilter();
filterList = frameAppender.getCopyOfAttachedFiltersList();
assertEquals("NumberOfTracesFilters", filterList.size(), 1);
assertTrue("TracesFilterIsThresholdFilter", filterList.get(0) instanceof ThresholdFilter);
thresholdFilter = (ThresholdFilter) filterList.get(0);
field = thresholdFilter.getClass().getDeclaredField("level");
field.setAccessible(true);
assertEquals("TracesFilterLevel", field.get(thresholdFilter), Level.WARN);
configuration.setLoggingFilterLogsTab(Level.TRACE);
LoggingConfig.setTracesFilter();
filterList = frameAppender.getCopyOfAttachedFiltersList();
assertEquals("NumberOfTracesFilters", filterList.size(), 1);
assertTrue("TracesFilterIsThresholdFilter", filterList.get(0) instanceof ThresholdFilter);
thresholdFilter = (ThresholdFilter) filterList.get(0);
field = thresholdFilter.getClass().getDeclaredField("level");
field.setAccessible(true);
assertEquals("TracesFilterLevel", field.get(thresholdFilter), Level.TRACE);
rootLogger.detachAppender(frameAppender);
// Test isSyslogDisabled()
if (syslogAppenderFound(rootLogger.iteratorForAppenders())) {
assertTrue("SyslogDisabledByConfiguration", LoggingConfig.isSyslogDisabled());
} else {
assertFalse("SyslogNotDisabledByConfiguration", LoggingConfig.isSyslogDisabled());
}
// Test setSyslog() if possible
if (!syslogAppenderFound(rootLogger.iteratorForAppenders())) {
configuration.setLoggingSyslogHost("localhost");
configuration.setLoggingUseSyslog(true);
LoggingConfig.setSyslog();
assertTrue("SyslogEnabled", syslogAppenderFound(rootLogger.iteratorForAppenders()));
configuration.setLoggingUseSyslog(false);
LoggingConfig.setSyslog();
assertFalse("SyslogDisabled", syslogAppenderFound(rootLogger.iteratorForAppenders()));
}
// Test forceVerboseFileEncoder() given that LogBack configuration
// contains at least one file appender with PatternLayoutEncoder
LoggingConfig.forceVerboseFileEncoder();
iterator = rootLogger.iteratorForAppenders();
while (iterator.hasNext()) {
Appender<ILoggingEvent> appender = iterator.next();
if (appender instanceof OutputStreamAppender && !(appender instanceof ConsoleAppender<?>)) {
// Appender has Encoder property
Encoder<ILoggingEvent> encoder = ((OutputStreamAppender<ILoggingEvent>) appender).getEncoder();
if (encoder instanceof PatternLayoutEncoder) {
// Encoder has pattern
patternEncoder = (PatternLayoutEncoder) encoder;
assertTrue("AppenderPatternHasCorrectTimestamp", patternEncoder.getPattern().matches(".*%(d|date)\\{yyyy-MM-dd HH:mm:ss.SSS\\}.*"));
assertTrue("AppenderPatternHasLogger", patternEncoder.getPattern().matches(".*%logger.*"));
}
}
}
context.reset();
}
use of ch.qos.logback.classic.spi.ILoggingEvent in project UniversalMediaServer by UniversalMediaServer.
the class LoggingConfig method setConfigurableFilters.
private static synchronized void setConfigurableFilters(boolean setConsole, boolean setTraces) {
PmsConfiguration configuration = PMS.getConfiguration();
if (loggerContext == null) {
LOGGER.error("Unknown loggerContext, aborting buffered logging. Make sure that loadFile() has been called first.");
return;
}
if (setConsole) {
Level level = configuration.getLoggingFilterConsole();
if (consoleLevel == null || consoleLevel != level) {
consoleLevel = level;
} else {
setConsole = false;
}
}
if (setTraces) {
Level level = configuration.getLoggingFilterLogsTab();
if (tracesLevel == null || tracesLevel != level) {
tracesLevel = level;
} else {
setTraces = false;
}
}
if (setConsole || setTraces) {
// Since Console- and FrameAppender will exist at root level and won't be detached by syslog,
// there's no reason to build an iterator as this should suffice.
Iterator<Appender<ILoggingEvent>> it = CacheLogger.isActive() ? CacheLogger.iteratorForAppenders() : rootLogger.iteratorForAppenders();
while (it.hasNext()) {
Appender<ILoggingEvent> appender = it.next();
if (setConsole && appender instanceof ConsoleAppender) {
ConsoleAppender<ILoggingEvent> ca = (ConsoleAppender<ILoggingEvent>) appender;
boolean createNew = true;
if (!ca.getCopyOfAttachedFiltersList().isEmpty()) {
for (Filter<ILoggingEvent> filter : ca.getCopyOfAttachedFiltersList()) {
if (filter instanceof ThresholdFilter) {
createNew = false;
((ThresholdFilter) filter).setLevel(consoleLevel.levelStr);
((ThresholdFilter) filter).start();
}
}
}
if (createNew) {
ThresholdFilter consoleFilter = new ThresholdFilter();
ca.addFilter(consoleFilter);
consoleFilter.setLevel(consoleLevel.levelStr);
consoleFilter.setContext(loggerContext);
consoleFilter.start();
}
}
if (setTraces && appender instanceof FrameAppender) {
FrameAppender<ILoggingEvent> fa = (FrameAppender<ILoggingEvent>) appender;
boolean createNew = true;
if (!fa.getCopyOfAttachedFiltersList().isEmpty()) {
for (Filter<ILoggingEvent> filter : fa.getCopyOfAttachedFiltersList()) {
if (filter instanceof ThresholdFilter) {
createNew = false;
((ThresholdFilter) filter).setLevel(tracesLevel.levelStr);
((ThresholdFilter) filter).start();
}
}
}
if (createNew) {
ThresholdFilter tracesFilter = new ThresholdFilter();
fa.addFilter(tracesFilter);
tracesFilter.setLevel(tracesLevel.levelStr);
tracesFilter.setContext(loggerContext);
tracesFilter.start();
}
}
}
}
}
use of ch.qos.logback.classic.spi.ILoggingEvent in project UniversalMediaServer by UniversalMediaServer.
the class LoggingConfig method setSyslog.
/**
* Adds/modifies/removes a syslog appender based on PmsConfiguration and
* disables/enables file appenders for easier access to syslog logging for
* users without in-depth knowledge of LogBack. Stops file appenders if
* syslog is started and vice versa.<P>
*
* Must be called after {@link #loadFile()} and after UMS configuration is
* loaded.
*/
public static synchronized void setSyslog() {
ActionType action = ActionType.NONE;
PmsConfiguration configuration = PMS.getConfiguration();
if (loggerContext == null) {
LOGGER.error("Unknown loggerContext, aborting syslog configuration. Make sure that loadFile() has been called first.");
return;
} else if (syslogDisabled) {
// Only create a new syslog appender if there's no syslog appender configured already
LOGGER.warn("A syslog appender is already configured, aborting syslog configuration");
return;
}
if (configuration.getLoggingUseSyslog()) {
// Check for valid parameters
if (configuration.getLoggingSyslogHost().isEmpty()) {
LOGGER.error("Empty syslog hostname, syslog configuration aborted");
return;
}
try {
InetAddress.getByName(configuration.getLoggingSyslogHost());
} catch (UnknownHostException e) {
LOGGER.error("Unknown syslog hostname {}, syslog configuration aborted", configuration.getLoggingSyslogHost());
return;
}
if (configuration.getLoggingSyslogPort() < 1 && configuration.getLoggingSyslogPort() > 65535) {
LOGGER.error("Invalid syslog port {}, using default", configuration.getLoggingSyslogPort());
configuration.setLoggingSyslogPortDefault();
}
if (!configuration.getLoggingSyslogFacility().toLowerCase().matches("auth|authpriv|daemon|cron|ftp|lpr|kern|mail|news|syslog|user|" + "uucp|local0|local1|local2|local3|local4|local5|local6|local7")) {
LOGGER.error("Invalid syslog facility \"{}\", using default", configuration.getLoggingSyslogFacility());
configuration.setLoggingSyslogFacilityDefault();
}
}
if (configuration.getLoggingUseSyslog() && syslog == null) {
syslog = new SyslogAppender();
syslog.setContext(loggerContext);
syslog.setSuffixPattern("UMS [%thread] %msg");
syslog.setName("UMS syslog");
syslog.setCharset(StandardCharsets.UTF_8);
action = ActionType.START;
} else if (!configuration.getLoggingUseSyslog() && syslog != null) {
action = ActionType.STOP;
}
if (syslog != null && (action == ActionType.START || action == ActionType.NONE)) {
syslog.setSyslogHost(configuration.getLoggingSyslogHost());
syslog.setPort(configuration.getLoggingSyslogPort());
syslog.setFacility(configuration.getLoggingSyslogFacility().toUpperCase());
syslog.start();
}
if (action == ActionType.START || action == ActionType.STOP) {
Iterator<Appender<ILoggingEvent>> it = CacheLogger.isActive() ? CacheLogger.iteratorForAppenders() : rootLogger.iteratorForAppenders();
while (it.hasNext()) {
Appender<ILoggingEvent> appender = it.next();
if (action == ActionType.START && appender instanceof FileAppender) {
if (CacheLogger.isActive()) {
CacheLogger.removeAppender(appender);
} else {
rootLogger.detachAppender(appender);
}
syslogDetachedAppenders.add(appender);
// If syslog is disabled later and this appender reactivated, append to the file instead of truncate
((FileAppender<ILoggingEvent>) appender).setAppend(true);
} else if (action == ActionType.STOP && appender == syslog) {
if (CacheLogger.isActive()) {
CacheLogger.removeAppender(syslog);
} else {
rootLogger.detachAppender(syslog);
}
syslog.stop();
syslog = null;
}
}
if (action == ActionType.START) {
if (CacheLogger.isActive()) {
CacheLogger.addAppender(syslog);
} else {
rootLogger.addAppender(syslog);
}
LOGGER.info("Syslog logging started, file logging disabled");
} else {
it = syslogDetachedAppenders.iterator();
while (it.hasNext()) {
Appender<ILoggingEvent> appender = it.next();
if (CacheLogger.isActive()) {
CacheLogger.addAppender(appender);
} else {
rootLogger.addAppender(appender);
}
}
syslogDetachedAppenders.clear();
LOGGER.info("Syslog logging stopped, file logging enabled");
}
}
}
use of ch.qos.logback.classic.spi.ILoggingEvent in project UniversalMediaServer by UniversalMediaServer.
the class LoggingConfig method loadFile.
/**
* Loads the (optional) Logback configuration file.
*
* It loads the file defined in the <code>project.logback</code> property from the current
* directory and (re-)initializes Logback with this file. If running
* headless (<code>System.Property("console")</code> set), then the
* alternative config file defined in <code>project.logback.headless</code> is tried first.
*
* If no config file can be found in the CWD, then nothing is loaded and
* Logback will use the logback.xml file on the classpath as a default. If
* this doesn't exist then a basic console appender is used as fallback.
*
* <strong>Note:</strong> Any error messages generated while parsing the
* config file are dumped only to <code>stdout</code>.
*/
public static synchronized void loadFile() {
File file = null;
if (!setContextAndRoot()) {
return;
}
if (PMS.isHeadless()) {
file = getFile(PropertiesUtil.getProjectProperties().get("project.logback.headless").split(","));
}
if (file == null) {
file = getFile(PropertiesUtil.getProjectProperties().get("project.logback").split(","));
}
if (file == null) {
// Unpredictable: Any logback.xml found in the Classpath is loaded, if that fails defaulting to BasicConfigurator
// See http://logback.qos.ch/xref/ch/qos/logback/classic/BasicConfigurator.html
LOGGER.warn("Could not load LogBack configuration file from " + (PMS.isHeadless() ? PropertiesUtil.getProjectProperties().get("project.logback.headless") + ", " : "") + PropertiesUtil.getProjectProperties().get("project.logback"));
LOGGER.warn("Falling back to somewhat unpredictable defaults, probably only logging to console.");
return;
}
// Now get logback to actually use the config file
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(loggerContext);
try {
// the context was probably already configured by
// default configuration rules
loggerContext.reset();
loggerContext.getStatusManager().clear();
// Do not log between loggerContext.reset() and CacheLogger.initContext()
configurator.doConfigure(file);
if (CacheLogger.isActive()) {
CacheLogger.initContext();
}
// Save the file path after loading the file
synchronized (filepathLock) {
filepath = file.getAbsolutePath();
LOGGER.debug("LogBack started with configuration file: {}", filepath);
}
} catch (JoranException je) {
try {
System.err.println("LogBack configuration failed: " + je.getLocalizedMessage());
System.err.println("Trying to create \"emergency\" configuration");
// Try to create "emergency" appenders for some logging if configuration fails
if (PMS.isHeadless()) {
ConsoleAppender<ILoggingEvent> ca = new ConsoleAppender<>();
PatternLayoutEncoder pe = new PatternLayoutEncoder();
pe.setPattern("%-5level %d{HH:mm:ss.SSS} [%thread] %logger %msg%n");
pe.setContext(loggerContext);
pe.start();
ca.setEncoder(pe);
ca.setContext(loggerContext);
ca.setName("Emergency Console");
ca.start();
loggerContext.getLogger(Logger.ROOT_LOGGER_NAME).addAppender(ca);
} else {
FrameAppender<ILoggingEvent> fa = new FrameAppender<>();
PatternLayoutEncoder pe = new PatternLayoutEncoder();
pe.setPattern("%-5level %d{HH:mm:ss.SSS} [%thread] %logger %msg%n");
pe.setContext(loggerContext);
pe.start();
fa.setEncoder(pe);
fa.setContext(loggerContext);
fa.setName("Emergency Frame");
fa.start();
loggerContext.getLogger(Logger.ROOT_LOGGER_NAME).addAppender(fa);
}
System.err.println("LogBack \"emergency\" configuration applied.");
} catch (Exception e) {
System.err.println("LogBack \"emergency\" configuration failed with: " + e);
}
if (CacheLogger.isActive()) {
CacheLogger.initContext();
}
LOGGER.error("Logback configuration failed with: {}", je.getLocalizedMessage());
StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
return;
}
// Build the iterator
Iterators<Appender<ILoggingEvent>> iterators = new Iterators<>();
// Add CacheLogger appenders if CacheLogger is active
if (CacheLogger.isActive()) {
iterators.addIterator(CacheLogger.iteratorForAppenders());
}
// non-root appenders there.
for (Logger logger : loggerContext.getLoggerList()) {
iterators.addIterator(logger.iteratorForAppenders());
}
// Iterate
Iterator<Appender<ILoggingEvent>> it = iterators.combinedIterator();
synchronized (logFilePathsLock) {
while (it.hasNext()) {
Appender<ILoggingEvent> appender = it.next();
if (appender instanceof FileAppender) {
FileAppender<ILoggingEvent> fa = (FileAppender<ILoggingEvent>) appender;
logFilePaths.put(fa.getName(), fa.getFile());
} else if (appender instanceof SyslogAppender) {
syslogDisabled = true;
}
}
}
// Set filters for console and traces
setConfigurableFilters(true, true);
StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
return;
}
use of ch.qos.logback.classic.spi.ILoggingEvent in project jackrabbit-oak by apache.
the class BroadcastTest method listen.
private static void listen() throws InterruptedException {
String config = "key 123";
ConsoleAppender<ILoggingEvent> ca = new ConsoleAppender<ILoggingEvent>();
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
ca.setContext(lc);
PatternLayout pl = new PatternLayout();
pl.setPattern("%msg%n");
pl.setContext(lc);
pl.start();
ca.setLayout(pl);
ca.start();
ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(TCPBroadcaster.class);
logger.addAppender(ca);
logger.setLevel(Level.DEBUG);
TCPBroadcaster receiver = new TCPBroadcaster(config);
receiver.addListener(new Broadcaster.Listener() {
@Override
public void receive(ByteBuffer buff) {
int end = buff.position();
StringBuilder sb = new StringBuilder();
while (buff.remaining() > 0) {
char c = (char) buff.get();
if (c >= ' ' && c < 128) {
sb.append(c);
} else if (c <= 9) {
sb.append((char) ('0' + c));
} else {
sb.append('.');
}
}
String dateTime = new Timestamp(System.currentTimeMillis()).toString().substring(0, 19);
System.out.println(dateTime + " Received " + sb);
buff.position(end);
}
});
Random r = new Random();
int x = r.nextInt();
System.out.println("Sending " + x);
for (int i = 0; i < 10; i++) {
Thread.sleep(10);
ByteBuffer buff = ByteBuffer.allocate(1024);
buff.putInt(0);
buff.putInt(x);
buff.put(new byte[100]);
buff.flip();
receiver.send(buff);
if (!receiver.isRunning()) {
System.out.println("Did not start or already stopped");
break;
}
}
Thread.sleep(Integer.MAX_VALUE);
}
Aggregations