Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enables plugins to define default logging configuration for their needs. #6805

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -35,6 +35,10 @@ public Log4jESLogger(String prefix, Logger logger) {
this.logger = logger;
}

public Logger logger() {
return logger;
}

public void setLevel(String level) {
if (level == null) {
logger.setLevel(null);
Expand Down
Expand Up @@ -21,12 +21,18 @@

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.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.env.FailedToResolveConfigException;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.EnumSet;
import java.util.Map;
import java.util.Properties;

Expand Down Expand Up @@ -72,23 +78,7 @@ public static void configure(Settings settings) {
loaded = true;
Environment environment = new Environment(settings);
ImmutableSettings.Builder settingsBuilder = settingsBuilder().put(settings);
try {
settingsBuilder.loadFromUrl(environment.resolveConfig("logging.yml"));
} catch (FailedToResolveConfigException e) {
// ignore
} catch (NoClassDefFoundError e) {
// ignore, no yaml
}
try {
settingsBuilder.loadFromUrl(environment.resolveConfig("logging.json"));
} catch (FailedToResolveConfigException e) {
// ignore
}
try {
settingsBuilder.loadFromUrl(environment.resolveConfig("logging.properties"));
} catch (FailedToResolveConfigException e) {
// ignore
}
resolveConfig(environment, settingsBuilder);
settingsBuilder
.putProperties("elasticsearch.", System.getProperties())
.putProperties("es.", System.getProperties())
Expand All @@ -110,4 +100,29 @@ public static void configure(Settings settings) {
}
PropertyConfigurator.configure(props);
}

public static void resolveConfig(Environment env, final ImmutableSettings.Builder settingsBuilder) {

try {
Files.walkFileTree(env.configFile().toPath(), EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (file.getFileName().toString().startsWith("logging.")) {
loadConfig(file, settingsBuilder);
}
return FileVisitResult.CONTINUE;
}
});
} catch (IOException ioe) {
throw new ElasticsearchException("Failed to load logging configuration", ioe);
}
}

public static void loadConfig(Path file, ImmutableSettings.Builder settingsBuilder) {
try {
settingsBuilder.loadFromUrl(file.toUri().toURL());
} catch (FailedToResolveConfigException | NoClassDefFoundError | MalformedURLException e) {
// ignore
}
}
}
22 changes: 22 additions & 0 deletions src/main/java/org/elasticsearch/plugins/PluginManager.java
Expand Up @@ -215,6 +215,15 @@ public void downloadAndExtract(String name) throws IOException {
debug("Installed " + name + " into " + toLocation.getAbsolutePath());
}

File configFile = new File(extractLocation, "config");
if (configFile.exists() && configFile.isDirectory()) {
File toLocation = pluginHandle.configDir(environment);
debug("Found config, moving to " + toLocation.getAbsolutePath());
FileSystemUtils.deleteRecursively(toLocation);
configFile.renameTo(toLocation);
debug("Installed " + name + " into " + toLocation.getAbsolutePath());
}

// try and identify the plugin type, see if it has no .class or .jar files in it
// so its probably a _site, and it it does not have a _site in it, move everything to _site
if (!new File(extractLocation, "_site").exists()) {
Expand Down Expand Up @@ -272,6 +281,15 @@ public void removePlugin(String name) throws IOException {
}
removed = true;
}
File configLocation = pluginHandle.configDir(environment);
if (configLocation.exists()) {
debug("Removing: " + configLocation.getPath());
if (!FileSystemUtils.deleteRecursively(configLocation)) {
throw new IOException("Unable to remove " + pluginHandle.name + ". Check file permissions on " +
configLocation.toString());
}
removed = true;
}
if (removed) {
log("Removed " + name);
} else {
Expand Down Expand Up @@ -585,6 +603,10 @@ File binDir(Environment env) {
return new File(new File(env.homeFile(), "bin"), name);
}

File configDir(Environment env) {
return new File(new File(env.homeFile(), "config"), name);
}

static PluginHandle parse(String name) {
String[] elements = name.split("/");
// We first consider the simplest form: pluginname
Expand Down
@@ -0,0 +1,70 @@
/*
* 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;

import org.apache.log4j.Appender;
import org.apache.log4j.Logger;
import org.elasticsearch.common.logging.log4j.Log4jESLogger;
import org.elasticsearch.common.logging.log4j.Log4jESLoggerFactory;
import org.elasticsearch.common.logging.log4j.LogConfigurator;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.junit.Test;

import java.io.File;
import java.net.URL;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;

/**
*
*/
public class LoggingConfigurationTests {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one should extend ElasticsearchTestCase, otherwise it will use the junit runner instead of the randomized one.


@Test
public void testMultipleConfigs() throws Exception {
File configDir = resolveConfigDir();
Settings settings = ImmutableSettings.builder()
.put("path.conf", configDir.getAbsolutePath())
.build();
LogConfigurator.configure(settings);

ESLogger esLogger = Log4jESLoggerFactory.getLogger("first");
Logger logger = ((Log4jESLogger) esLogger).logger();
Appender appender = logger.getAppender("console1");
assertThat(appender, notNullValue());

esLogger = Log4jESLoggerFactory.getLogger("second");
logger = ((Log4jESLogger) esLogger).logger();
appender = logger.getAppender("console2");
assertThat(appender, notNullValue());

esLogger = Log4jESLoggerFactory.getLogger("third");
logger = ((Log4jESLogger) esLogger).logger();
appender = logger.getAppender("console3");
assertThat(appender, notNullValue());
}

private static File resolveConfigDir() throws Exception {
URL url = LoggingConfigurationTests.class.getResource("config");
return new File(url.toURI());
}
}
38 changes: 35 additions & 3 deletions src/test/java/org/elasticsearch/plugin/PluginManagerTests.java
Expand Up @@ -45,6 +45,7 @@
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.util.concurrent.TimeUnit;

import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
Expand Down Expand Up @@ -88,6 +89,33 @@ public void testLocalPluginInstallSingleFolder() throws Exception {
assertPluginAvailable(pluginName);
}

@Test
public void testLocalPluginInstallWithBinAndConfig() throws Exception {
String pluginName = "plugin-test";
Tuple<Settings, Environment> initialSettings = InternalSettingsPreparer.prepareSettings(
ImmutableSettings.settingsBuilder().build(), false);
Environment env = initialSettings.v2();
File pluginBinDir = new File(new File(env.homeFile(), "bin"), pluginName);
File pluginConfigDir = new File(env.configFile(), pluginName);
try {

PluginManager pluginManager = pluginManager(getPluginUrlForResource("plugin_with_bin_and_config.zip"), initialSettings);

pluginManager.downloadAndExtract(pluginName);

File[] plugins = pluginManager.getListInstalledPlugins();

assertThat(plugins.length, is(1));
assertTrue(pluginBinDir.exists());
assertTrue(pluginConfigDir.exists());

} finally {
// we need to clean up the copied dirs
FileSystemUtils.deleteRecursively(pluginBinDir);
FileSystemUtils.deleteRecursively(pluginConfigDir);
}
}

@Test
public void testLocalPluginInstallSiteFolder() throws Exception {
//When we have only a folder in top-level (no files either) but it's called _site, we make it work
Expand Down Expand Up @@ -131,13 +159,17 @@ public void testSitePluginWithSourceThrows() throws Exception {
downloadAndExtract(pluginName, getPluginUrlForResource("plugin_with_sourcefiles.zip"));
}

private static PluginManager pluginManager(String pluginUrl) {
Tuple<Settings, Environment> initialSettings = InternalSettingsPreparer.prepareSettings(
ImmutableSettings.settingsBuilder().build(), false);
return pluginManager(pluginUrl, initialSettings);
}

/**
* We build a plugin manager instance which wait only for 30 seconds before
* raising an ElasticsearchTimeoutException
*/
private static PluginManager pluginManager(String pluginUrl) {
Tuple<Settings, Environment> initialSettings = InternalSettingsPreparer.prepareSettings(
ImmutableSettings.settingsBuilder().build(), false);
private static PluginManager pluginManager(String pluginUrl, Tuple<Settings, Environment> initialSettings) {
if (!initialSettings.v2().pluginsFile().exists()) {
FileSystemUtils.mkdirs(initialSettings.v2().pluginsFile());
}
Expand Down
@@ -0,0 +1,12 @@
# you can override this using by setting a system property, for example -Des.logger.level=DEBUG
es.logger.level: INFO
rootLogger: ${es.logger.level}, console1
logger:
first: DEBUG, console1

appender:
console1:
type: console
layout:
type: consolePattern
conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
@@ -0,0 +1,10 @@
logger:
# log action execution errors for easier debugging
second: DEBUG, console2

appender:
console2:
type: console
layout:
type: consolePattern
conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
@@ -0,0 +1,10 @@
logger:
# log action execution errors for easier debugging
third: DEBUG, console3

appender:
console3:
type: console
layout:
type: consolePattern
conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
Binary file not shown.