Skip to content

Commit

Permalink
Support the priority of multiple log-conf.xml with the same namespace. (
Browse files Browse the repository at this point in the history
#12)

* Support the priority of multiple log-conf.xml with the same namespace.And the lowest priority is `zero`
  • Loading branch information
ujjboy authored and guanchao-yang committed Jun 5, 2018
1 parent 2e312c7 commit 4f6abfa
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 17 deletions.
4 changes: 4 additions & 0 deletions src/main/java/com/alipay/sofa/common/log/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public interface Constants {
String LOG_DIRECTORY = "log";
String LOG_XML_CONFIG_FILE_NAME = "log-conf.xml";
String LOG_XML_CONFIG_FILE_ENV_PATTERN = "log-conf-%s.xml";
String LOG_CONFIG_PROPERTIES = "config.properties";

String LOG_PATH = "logging.path";
String LOG_PATH_PREFIX = "logging.path.";
Expand All @@ -59,4 +60,7 @@ public interface Constants {
//默认的中间件日志打印路径
String LOGGING_PATH_DEFAULT = System.getProperty("user.home")
+ File.separator + "logs";
// 默认优先级为0,越大越高
int DEFAULT_PRIORITY = 0;

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,23 @@
*/
package com.alipay.sofa.common.log.factory;

import com.alipay.sofa.common.utils.AssertUtil;
import com.alipay.sofa.common.log.Constants;
import com.alipay.sofa.common.log.SpaceInfo;
import com.alipay.sofa.common.log.env.LogEnvUtils;
import com.alipay.sofa.common.utils.AssertUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

Expand Down Expand Up @@ -65,26 +73,104 @@ private URL getSpaceLogConfigFileURL(ClassLoader spaceClassloader, String spaceN
//TODO avoid this pattern "log-conf.xml.console"
String logConfigLocation = spaceName.replace('.', '/') + "/" + LOG_DIRECTORY + "/"
+ getLoggingToolName() + "/" + LOG_XML_CONFIG_FILE_NAME + suffix;
URL configFileUrl = spaceClassloader.getResource(logConfigLocation);

//recommend this pattern "log-conf-console.xml"
if (configFileUrl == null && suffix != null && !suffix.isEmpty()) {
//try again with another env profile file pattern;
logConfigLocation = spaceName.replace('.', '/')
+ "/"
+ LOG_DIRECTORY
+ "/"
+ getLoggingToolName()
+ "/"
+ String.format(LOG_XML_CONFIG_FILE_ENV_PATTERN,
suffix.substring(1));
configFileUrl = spaceClassloader.getResource(logConfigLocation);

URL configFileUrl = null;

try {
List<URL> configFileUrls = new ArrayList<URL>();
Enumeration<URL> urls = spaceClassloader.getResources(logConfigLocation);
// 可能存在多个文件。
if (urls != null) {
while (urls.hasMoreElements()) {
// 读取一个文件
URL url = urls.nextElement();
configFileUrls.add(url);
}
}

configFileUrl = getResource(spaceClassloader, configFileUrls);

//recommend this pattern "log-conf-console.xml"
if (configFileUrl == null && suffix != null && !suffix.isEmpty()) {
//try again with another env profile file pattern;
logConfigLocation = spaceName.replace('.', '/')
+ "/"
+ LOG_DIRECTORY
+ "/"
+ getLoggingToolName()
+ "/"
+ String.format(LOG_XML_CONFIG_FILE_ENV_PATTERN,
suffix.substring(1));
configFileUrl = spaceClassloader.getResource(logConfigLocation);
}
} catch (Exception e) {
if (logger.isWarnEnabled()) {
logger.warn("Error when get resources of " + spaceName + " from classpath", e);
}
}

AssertUtil.state(configFileUrl != null, this + " build error: No " + getLoggingToolName()
+ " config file (" + configFileUrl + ") found!");
return configFileUrl;
}

protected URL getResource(ClassLoader spaceClassloader, List<URL> urls) throws IOException {
if (urls == null || urls.isEmpty()) {
return null;
} else if (urls.size() == 1) {
return urls.get(0);
} else {
List<ConfigFile> configFiles = new ArrayList<ConfigFile>();
for (URL url : urls) {
int priority = DEFAULT_PRIORITY;

File propertiesFile = new File(new File(url.getFile()).getParentFile(),
LOG_CONFIG_PROPERTIES);
if (propertiesFile.exists()) {
// 如果同目录下存在 config.properties
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(propertiesFile);
Properties properties = new Properties();
properties.load(inputStream);
String priorityStr = properties.getProperty("priority");
if (priorityStr != null) {
priority = Integer.parseInt(priorityStr);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}

ConfigFile configFile = new ConfigFile(priority, url);
if (logger.isDebugEnabled()) {
logger.debug("Find url {}, priority is {}", url, priority);
}
configFiles.add(configFile);
}
Collections.sort(configFiles, new Comparator<ConfigFile>() {
@Override
public int compare(ConfigFile o1, ConfigFile o2) {
// 越大越前面
return o2.priority - o1.priority;
}
});
return configFiles.get(0).url;
}
}

private class ConfigFile {
final int priority;
final URL url;

ConfigFile(int priority, URL url) {
this.priority = priority;
this.url = url;
}
}

private void specifySpaceLogConfigProperites(String spaceName) {
//如果system.properties 与 properites 都含有某分配置,那么以 system.properties 为准,同时WARN警告,properties中重复定义会被抛弃;
Iterator<Map.Entry<Object, Object>> iterator = spaceInfo.properties().entrySet().iterator();
Expand All @@ -98,7 +184,7 @@ private void specifySpaceLogConfigProperites(String spaceName) {
}
}

/**
/*
* == 1.space's logger path
*/
String loggingPathKey = LOG_PATH_PREFIX + spaceName;
Expand All @@ -107,7 +193,7 @@ private void specifySpaceLogConfigProperites(String spaceName) {
spaceInfo.properties().setProperty(loggingPathKey, System.getProperty(LOG_PATH));
}

/**
/*
* == 2.space's logger level
*/
String loggingLevelKey = LOG_LEVEL_PREFIX + spaceName;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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 com.alipay.sofa.common.log.factory;

import com.alipay.sofa.common.log.SpaceInfo;
import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
* @author <a href="mailto:[email protected]">GengZhang</a>
*/
public class LoggerSpaceOverrideUsageTest {

@Test
public void testGetResource() throws IOException {
LoggerSpaceFactory4LogbackBuilder builder = new LoggerSpaceFactory4LogbackBuilder(
new SpaceInfo());
ClassLoader classLoader = LoggerSpaceOverrideUsageTest.class.getClassLoader();

Assert.assertNull(builder.getResource(classLoader, null));

List<URL> configFileUrls = new ArrayList<URL>();
Assert.assertNull(builder.getResource(classLoader, configFileUrls));

URL url1 = classLoader.getResource("com/alipay/sofa/testover1/log/log4j/log-conf.xml");
configFileUrls.add(url1);
Assert.assertEquals(url1, builder.getResource(classLoader, configFileUrls));

URL url2 = classLoader.getResource("com/alipay/sofa/testover2/log/log4j/log-conf.xml");
configFileUrls.add(url2);
Assert.assertEquals(url2, builder.getResource(classLoader, configFileUrls));

URL url3 = classLoader.getResource("com/alipay/sofa/testover3/log/log4j/log-conf.xml");
configFileUrls.add(url3);
Assert.assertEquals(url2, builder.getResource(classLoader, configFileUrls));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE log4j:configuration SYSTEM "http://toolkit.alibaba-inc.com/dtd/log4j/log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

<appender name="ROOT-APPENDER" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="${logging.test.path}/${appname}/common-default.log"/>
<param name="append" value="true"/>
<param name="threshold" value="${info}"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p %-32t - %m%n"/>
</layout>
</appender>

<root>
<level value="info"/>
<appender-ref ref="ROOT-APPENDER"/>
</root>

</log4j:configuration>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
priority=200
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE log4j:configuration SYSTEM "http://toolkit.alibaba-inc.com/dtd/log4j/log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

<appender name="ROOT-APPENDER" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="${logging.test.path}/${appname}/common-default.log"/>
<param name="append" value="true"/>
<param name="threshold" value="${info}"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p %-32t - %m%n"/>
</layout>
</appender>

<root>
<level value="debug"/>
<appender-ref ref="ROOT-APPENDER"/>
</root>

</log4j:configuration>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
priority=100
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE log4j:configuration SYSTEM "http://toolkit.alibaba-inc.com/dtd/log4j/log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

<appender name="ROOT-APPENDER" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="${logging.test.path}/${appname}/common-default.log"/>
<param name="append" value="true"/>
<param name="threshold" value="${info}"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p %-32t - %m%n"/>
</layout>
</appender>

<root>
<level value="debug"/>
<appender-ref ref="ROOT-APPENDER"/>
</root>

</log4j:configuration>

0 comments on commit 4f6abfa

Please sign in to comment.