org.pmw.tinylog.ConfigurationObserver Maven / Gradle / Ivy
/*
* Copyright 2012 Martin Winandy
*
* 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.pmw.tinylog;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import org.pmw.tinylog.writers.Writer;
/**
* Thread to observe a configuration file and reload changes.
*/
abstract class ConfigurationObserver extends Thread {
private static final String THREAD_NAME = "tinylog-ConfigurationObserver";
private static final Configuration DEFAULT_CONFIGURATION = Configurator.defaultConfig().create();
private static final Object mutex = new Object();
private static ConfigurationObserver activeObserver;
private final Configurator basisConfigurator;
private final Properties basisProperties;
private final String file;
private volatile boolean shutdown;
private ConfigurationObserver(final Configurator basisConfigurator, final Properties basisProperties, final String file) {
this.basisConfigurator = basisConfigurator;
this.basisProperties = basisProperties;
this.file = file;
this.shutdown = false;
setName(THREAD_NAME);
setPriority((NORM_PRIORITY + MIN_PRIORITY) / 2);
setDaemon(true);
}
/**
* Create a thread to observe a file from file system.
*
* @param configurator
* Basis configuration
* @param properties
* Basis properties
* @param file
* Configuration file to observe
* @return A new instance of {@link org.pmw.tinylog.ConfigurationObserver ConfigurationObserver}
*/
static ConfigurationObserver createFileConfigurationObserver(final Configurator configurator, final Properties properties, final String file) {
return new ConfigurationObserver(configurator, properties, file) {
@Override
protected InputStream openInputStream() {
try {
return new FileInputStream(file);
} catch (FileNotFoundException ex) {
return null;
}
}
};
}
/**
* Create a thread to observe a file from classpath.
*
* @param configurator
* Basis configuration
* @param properties
* Basis properties
* @param file
* Configuration file to observe
* @return A new instance of {@link org.pmw.tinylog.ConfigurationObserver ConfigurationObserver}
*/
static ConfigurationObserver createResourceConfigurationObserver(final Configurator configurator, final Properties properties, final String file) {
return new ConfigurationObserver(configurator, properties, file) {
@Override
protected InputStream openInputStream() {
return ConfigurationObserver.class.getClassLoader().getResourceAsStream(file);
}
};
}
/**
* Get the active configuration observer.
*
* @return Active configuration observer or null
if there is no active configuration observer
*/
public static ConfigurationObserver getActiveObserver() {
synchronized (mutex) {
return activeObserver;
}
}
@Override
public void start() {
synchronized (mutex) {
Configurator.shutdownConfigurationObserver(true);
super.start();
activeObserver = this;
}
}
@Override
public final void run() {
Properties oldProperties = basisProperties;
Configurator oldConfigurator = basisConfigurator;
while (!shutdown) {
Properties properties = readProperties();
if (properties != null) {
Properties systemProperties = (Properties) System.getProperties().clone();
for (Object key : systemProperties.keySet()) {
String name = (String) key;
if (name.startsWith("tinylog.")) {
properties.put(key, systemProperties.getProperty(name));
}
}
}
if (changed(properties, oldProperties)) {
Configurator configurator = oldConfigurator.copy();
if (properties != null) {
if (levelHasChanged(properties, oldProperties)) {
configurator.level(DEFAULT_CONFIGURATION.getLevel()).resetCustomLevels();
PropertiesLoader.readLevel(configurator, properties);
}
if (formatPaternHasChanged(properties, oldProperties)) {
configurator.formatPattern(DEFAULT_CONFIGURATION.getFormatPattern());
PropertiesLoader.readFormatPattern(configurator, properties);
}
if (localeHasChanged(properties, oldProperties)) {
configurator.locale(DEFAULT_CONFIGURATION.getLocale());
PropertiesLoader.readLocale(configurator, properties);
}
if (maxStackTraceElementsHasChanged(properties, oldProperties)) {
configurator.maxStackTraceElements(DEFAULT_CONFIGURATION.getMaxStackTraceElements());
PropertiesLoader.readMaxStackTraceElements(configurator, properties);
}
if (writerHasChanged(properties, oldProperties)) {
Iterator iterator = DEFAULT_CONFIGURATION.getWriters().iterator();
configurator.writer(iterator.hasNext() ? iterator.next() : null);
while (iterator.hasNext()) {
configurator.addWriter(iterator.next());
}
PropertiesLoader.readWriters(configurator, properties);
}
if (writingThreadHasChanged(properties, oldProperties)) {
WritingThread writingThread = DEFAULT_CONFIGURATION.getWritingThread();
if (writingThread == null) {
configurator.writingThread(false);
} else {
configurator.writingThread(writingThread.getNameOfThreadToObserve(), writingThread.getPriority());
}
PropertiesLoader.readWritingThread(configurator, properties);
}
}
configurator.activate();
oldConfigurator = configurator;
}
oldProperties = properties;
try {
sleep(1000L);
} catch (InterruptedException ex) {
// Ignore and continue
}
}
}
/**
* Shutdown thread.
*/
public void shutdown() {
shutdown = true;
interrupt();
synchronized (mutex) {
if (activeObserver == this) {
activeObserver = null;
}
}
}
/**
* Open the configuration file.
*
* @return Stream of configuration file or null
if not exists.
*/
protected abstract InputStream openInputStream();
private boolean changed(final Properties properties, final Properties oldProperties) {
if (oldProperties == null) {
return properties != null;
} else if (properties == null) {
return true;
} else {
Set
© 2015 - 2025 Weber Informatics LLC | Privacy Policy