org.elasticsearch.common.logging.log4j.LogConfigurator Maven / Gradle / Ivy
The newest version!
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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.elasticsearch.common.logging.log4j;
import com.google.common.collect.ImmutableMap;
import org.apache.log4j.PropertyConfigurator;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.env.Environment;
import java.io.IOException;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import static org.elasticsearch.common.Strings.cleanPath;
import static org.elasticsearch.common.settings.Settings.settingsBuilder;
/**
*
*/
public class LogConfigurator {
static final List ALLOWED_SUFFIXES = Arrays.asList(".yml", ".yaml", ".json", ".properties");
private static boolean loaded;
private static ImmutableMap replacements = new MapBuilder()
.put("console", "org.elasticsearch.common.logging.log4j.ConsoleAppender")
.put("async", "org.apache.log4j.AsyncAppender")
.put("dailyRollingFile", "org.apache.log4j.DailyRollingFileAppender")
.put("externallyRolledFile", "org.apache.log4j.ExternallyRolledFileAppender")
.put("file", "org.apache.log4j.FileAppender")
.put("jdbc", "org.apache.log4j.jdbc.JDBCAppender")
.put("jms", "org.apache.log4j.net.JMSAppender")
.put("lf5", "org.apache.log4j.lf5.LF5Appender")
.put("ntevent", "org.apache.log4j.nt.NTEventLogAppender")
.put("null", "org.apache.log4j.NullAppender")
.put("rollingFile", "org.apache.log4j.RollingFileAppender")
.put("extrasRollingFile", "org.apache.log4j.rolling.RollingFileAppender")
.put("smtp", "org.apache.log4j.net.SMTPAppender")
.put("socket", "org.apache.log4j.net.SocketAppender")
.put("socketHub", "org.apache.log4j.net.SocketHubAppender")
.put("syslog", "org.apache.log4j.net.SyslogAppender")
.put("telnet", "org.apache.log4j.net.TelnetAppender")
.put("terminal", "org.elasticsearch.common.logging.log4j.TerminalAppender")
// policies
.put("timeBased", "org.apache.log4j.rolling.TimeBasedRollingPolicy")
.put("sizeBased", "org.apache.log4j.rolling.SizeBasedTriggeringPolicy")
// layouts
.put("simple", "org.apache.log4j.SimpleLayout")
.put("html", "org.apache.log4j.HTMLLayout")
.put("pattern", "org.apache.log4j.PatternLayout")
.put("consolePattern", "org.apache.log4j.PatternLayout")
.put("enhancedPattern", "org.apache.log4j.EnhancedPatternLayout")
.put("ttcc", "org.apache.log4j.TTCCLayout")
.put("xml", "org.apache.log4j.XMLLayout")
.immutableMap();
/**
* Consolidates settings and converts them into actual log4j settings, then initializes loggers and appenders.
*
* @param settings custom settings that should be applied
* @param resolveConfig controls whether the logging conf file should be read too or not.
*/
public static void configure(Settings settings, boolean resolveConfig) {
if (loaded) {
return;
}
loaded = true;
// TODO: this is partly a copy of InternalSettingsPreparer...we should pass in Environment and not do all this...
Environment environment = new Environment(settings);
Settings.Builder settingsBuilder = settingsBuilder();
if (resolveConfig) {
resolveConfig(environment, settingsBuilder);
}
settingsBuilder
.putProperties("elasticsearch.", System.getProperties())
.putProperties("es.", System.getProperties());
// add custom settings after config was added so that they are not overwritten by config
settingsBuilder.put(settings);
settingsBuilder.replacePropertyPlaceholders();
Properties props = new Properties();
for (Map.Entry entry : settingsBuilder.build().getAsMap().entrySet()) {
String key = "log4j." + entry.getKey();
String value = entry.getValue();
if (replacements.containsKey(value)) {
value = replacements.get(value);
}
if (key.endsWith(".value")) {
props.setProperty(key.substring(0, key.length() - ".value".length()), value);
} else if (key.endsWith(".type")) {
props.setProperty(key.substring(0, key.length() - ".type".length()), value);
} else {
props.setProperty(key, value);
}
}
// ensure explicit path to logs dir exists
props.setProperty("log4j.path.logs", cleanPath(environment.logsFile().toAbsolutePath().toString()));
PropertyConfigurator.configure(props);
}
/**
* sets the loaded flag to false so that logging configuration can be
* overridden. Should only be used in tests.
*/
static void reset() {
loaded = false;
}
static void resolveConfig(Environment env, final Settings.Builder settingsBuilder) {
try {
Files.walkFileTree(env.configFile(), EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
String fileName = file.getFileName().toString();
if (fileName.startsWith("logging.")) {
for (String allowedSuffix : ALLOWED_SUFFIXES) {
if (fileName.endsWith(allowedSuffix)) {
loadConfig(file, settingsBuilder);
break;
}
}
}
return FileVisitResult.CONTINUE;
}
});
} catch (IOException ioe) {
throw new ElasticsearchException("Failed to load logging configuration", ioe);
}
}
static void loadConfig(Path file, Settings.Builder settingsBuilder) {
try {
settingsBuilder.loadFromPath(file);
} catch (SettingsException | NoClassDefFoundError e) {
// ignore
}
}
}