提交 c83792cd 编写于 作者: A ascrutae

1. 修复Logger插件导致Classloader问题

2. 修复logger日志的输出路径问题
3. 修复Bytebuddy的Agent的类过滤的效率问题
上级 f9653bbd
#!/bin/sh
# Get standard environment variables
SAMPLE_DUBBO_BIN_PATH=$(cd `dirname $0`; pwd)
SAMPLE_DUBBO_CFG_DIR="${SAMPLE_DUBBO_BIN_PATH}/../config"
SAMPLE_DUBBO_LIB_DIR="${SAMPLE_DUBBO_BIN_PATH}/../lib"
SAMPLE_DUBBO_LOG_DIR="${SAMPLE_DUBBO_BIN_PATH}/../log"
#echo $SW_SERVER_BIN_DIR
#set java home
if [ "$JAVA_HOME" != "" ]; then
JAVA="$JAVA_HOME/bin/java"
else
JAVA=java
fi
CLASSPATH="$SAMPLE_DUBBO_CFG_DIR:$CLASSPATH"
for i in "${SAMPLE_DUBBO_LIB_DIR}"/*.jar
do
CLASSPATH="$i:$CLASSPATH"
done
echo "CLASSPATH=$CLASSPATH"
$JAVA -javaagent:${SAMPLE_DUBBO_BIN_PATH}/../agent/skywalking-agent-1.0-Final.jar -classpath $CLASSPATH com.ai.cloud.skywalking.sample.util.DubboStart
......@@ -78,6 +78,22 @@
<artifactId>h2</artifactId>
<version>1.4.192</version>
</dependency>
<dependency>
<groupId>com.ai.cloud</groupId>
<artifactId>skywalking-log4j-1.x-plugin</artifactId>
<version>1.0-Final</version>
</dependency>
<dependency>
<groupId>com.ai.cloud</groupId>
<artifactId>skywalking-log4j-2.x-plugin</artifactId>
<version>1.0-Final</version>
</dependency>
<dependency>
<groupId>com.ai.cloud</groupId>
<artifactId>skywalking-api</artifactId>
<version>1.0-Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
......@@ -89,10 +105,5 @@
<version>RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.ai.cloud</groupId>
<artifactId>skywalking-log4j-1.x-plugin</artifactId>
<version>1.0-Final</version>
</dependency>
</dependencies>
</project>
#skyWalking用户ID
skywalking.user_id=123
#skyWalking应用编码
skywalking.application_code=skywalking-sample-dubbo
#skywalking auth的环境变量名字
skywalking.auth_system_env_name=SKYWALKING_RUN
#skywalking数据编码
skywalking.charset=UTF-8
skywalking.auth_override=true
#是否打印数据
buriedpoint.printf=true
#埋点异常的最大长度
buriedpoint.max_exception_stack_length=4000
#业务字段的最大长度
buriedpoint.businesskey_max_length=300
#过滤异常
buriedpoint.exclusive_exceptions=java.lang.RuntimeException
#最大发送者的连接数阀比例
sender.connect_percent=100
#发送服务端配置
sender.servers_addr=127.0.0.1:34000
#最大发送的副本数量
sender.max_copy_num=2
#发送的最大长度
sender.max_send_length=20000
#当没有Sender时,尝试获取sender的等待周期
sender.retry_get_sender_wait_interval=2000
#最大消费线程数
consumer.max_consumer=0
#消费者最大等待时间
consumer.max_wait_time=5
#发送失败等待时间
consumer.consumer_fail_retry_wait_interval=50
#每个Buffer的最大个数
buffer.buffer_max_size=18000
#Buffer池的最大长度
buffer.pool_size=5
#发送检查线程检查周期
senderchecker.check_polling_time=200
......@@ -20,4 +20,72 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>${project.build.directory}/installer/lib</outputDirectory>
<excludeTransitive>false</excludeTransitive>
<stripVersion>true</stripVersion>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<outputDirectory>${project.build.directory}/installer/lib</outputDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-start-script</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/installer/bin</outputDirectory>
<resources>
<resource>
<directory>bin</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>clean</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<mkdir dir="${project.build.directory}/installer/agent"/>
<mkdir dir="${project.build.directory}/installer/log"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
......@@ -11,44 +11,29 @@ import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.NamedElement;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.matcher.BooleanMatcher;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import java.io.File;
import java.lang.instrument.Instrumentation;
import java.net.URL;
import java.util.List;
import static net.bytebuddy.matcher.ElementMatchers.any;
import static net.bytebuddy.matcher.ElementMatchers.named;
public class SkywalkingAgent {
private static Logger logger = LogManager.getLogger(SkywalkingAgent.class);
private static Logger logger = LogManager.getLogger(SkywalkingAgent.class);
private static final PluginDefineCategory pluginDefineCategory = PluginDefineCategory.category(new PluginBootstrap().loadPlugins());
public static void premain(String agentArgs, Instrumentation instrumentation) throws PluginException {
initConfig();
if (AuthDesc.isAuth()) {
List<IPlugin> plugins = new PluginBootstrap().loadPlugins();
logger.info("Loaded " + plugins.size() + " plugin");
final PluginDefineCategory pluginDefineCategory = PluginDefineCategory.category(plugins);
startBootPluginDefines(pluginDefineCategory.getBootPluginsDefines());
new AgentBuilder.Default().type(exclusivePackageClass()).transform(new AgentBuilder.Transformer() {
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader) {
AbstractClassEnhancePluginDefine pluginDefine = pluginDefineCategory.getClassEnhancePluginDefines().get(typeDescription.getTypeName());
if (pluginDefine == null) {
return builder;
}
AbstractClassEnhancePluginDefine pluginDefine = pluginDefineCategory.findPluginDefine(typeDescription.getTypeName());
try {
return pluginDefine.define(builder);
} catch (Throwable e) {
e.printStackTrace();
logger.error("Failed to enhance plugin " + pluginDefine.getClass().getName(), e);
return builder;
}
......@@ -59,11 +44,11 @@ public class SkywalkingAgent {
}
private static ElementMatcher.Junction<NamedElement> exclusivePackageClass() {
return myMatcher();
return enhanceClassMatcher();
}
private static <T extends NamedElement> ElementMatcher.Junction<T> myMatcher() {
return new SkyWalkingEnhanceMatcher<T>();
private static <T extends NamedElement> ElementMatcher.Junction<T> enhanceClassMatcher() {
return new SkyWalkingEnhanceMatcher<T>(pluginDefineCategory);
}
......
package com.ai.cloud.skywalking.agent.junction;
import com.ai.cloud.skywalking.plugin.PluginDefineCategory;
import net.bytebuddy.description.NamedElement;
/**
* Created by wusheng on 16/7/31.
*/
public class SkyWalkingEnhanceMatcher<T extends NamedElement> extends AbstractJunction<T> {
private final PluginDefineCategory pluginDefineCategory;
public SkyWalkingEnhanceMatcher(PluginDefineCategory pluginDefineCategory) {
this.pluginDefineCategory = pluginDefineCategory;
}
@Override
public boolean matches(T target) {
return false;
return pluginDefineCategory.findPluginDefine(target.getSourceCodeName()) != null ? true : false;
}
}
......@@ -50,6 +50,25 @@
<artifactId>gson</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
......
......@@ -20,6 +20,7 @@ public class Config {
public static String AGENT_BASE_PATH = "";
}
public static class BuriedPoint {
// 是否打印埋点信息
public static boolean PRINTF = false;
......@@ -33,9 +34,10 @@ public class Config {
public static String EXCLUSIVE_EXCEPTIONS = "";
}
public static class Consumer {
// 最大消费线程数
public static int MAX_CONSUMER = 2;
public static int MAX_CONSUMER = 2;
// 消费者最大等待时间
public static long MAX_WAIT_TIME = 5L;
......@@ -43,6 +45,7 @@ public class Config {
public static long CONSUMER_FAIL_RETRY_WAIT_INTERVAL = 50L;
}
public static class Buffer {
// 每个Buffer的最大个数
public static int BUFFER_MAX_SIZE = 20000;
......@@ -51,11 +54,12 @@ public class Config {
public static int POOL_SIZE = 5;
}
public static class Sender {
// 最大发送数据个数
public static final int MAX_SEND_DATA_SIZE = 10;
// 最大发送者的连接数阀比例
public static int CONNECT_PERCENT = 50;
public static int CONNECT_PERCENT = 50;
// 发送服务端配置
public static String SERVERS_ADDR = "127.0.0.1:34000";
......@@ -80,18 +84,20 @@ public class Config {
public static long RETRY_FIND_CONNECTION_SENDER = 1000;
}
public static class HealthCollector {
// 默认健康检查上报时间
public static long REPORT_INTERVAL = 5 * 60 * 1000L;
}
public static class Logging {
// log文件名
public static String LOG_FILE_NAME = "skywalking-api.log";
// log文件路径
public static String LOG_FILE_PATH = "/tmp/skywalking";
public static String LOG_FILE_NAME = "skywalking-api.log";
// log文件文件夹名字
public static String LOG_DIR_NAME = "logs";
// 最大文件大小
public static int MAX_LOG_FILE_LENGTH = 3 * 1024 * 1024;
public static int MAX_LOG_FILE_LENGTH = 3 * 1024 * 1024;
// skywalking 系统错误文件日志
public static String SYSTEM_ERROR_LOG_FILE_NAME = "skywalking-api-error.log";
}
......
......@@ -12,7 +12,8 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import static com.ai.cloud.skywalking.conf.Config.Logging.LOG_FILE_NAME;
import static com.ai.cloud.skywalking.conf.Config.Logging.LOG_FILE_PATH;
import static com.ai.cloud.skywalking.conf.Config.Logging.LOG_DIR_NAME;
import static com.ai.cloud.skywalking.conf.Config.SkyWalking.AGENT_BASE_PATH;
public class SyncFileWriter implements IWriter {
......@@ -23,12 +24,12 @@ public class SyncFileWriter implements IWriter {
private SyncFileWriter() {
try {
File logFilePath = new File(LOG_FILE_PATH);
File logFilePath = new File(AGENT_BASE_PATH,LOG_DIR_NAME);
if (!logFilePath.exists()) {
logFilePath.mkdirs();
}
os = new FileOutputStream(new File(LOG_FILE_PATH, LOG_FILE_NAME), true);
bufferSize = Long.valueOf(new File(LOG_FILE_PATH, LOG_FILE_NAME).length()).intValue();
os = new FileOutputStream(new File(logFilePath, LOG_FILE_NAME), true);
bufferSize = Long.valueOf(new File(logFilePath, LOG_FILE_NAME).length()).intValue();
} catch (IOException e) {
writeErrorLog(e);
}
......@@ -81,12 +82,12 @@ public class SyncFileWriter implements IWriter {
}
private void revertInputStream() throws FileNotFoundException {
os = new FileOutputStream(new File(Config.Logging.LOG_FILE_PATH, Config.Logging.LOG_FILE_NAME), true);
os = new FileOutputStream(new File(Config.Logging.LOG_DIR_NAME, Config.Logging.LOG_FILE_NAME), true);
}
private void renameLogFile() {
new File(Config.Logging.LOG_FILE_PATH, Config.Logging.LOG_FILE_NAME)
.renameTo(new File(Config.Logging.LOG_FILE_PATH, Config.Logging.LOG_FILE_NAME + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
new File(Config.Logging.LOG_DIR_NAME, Config.Logging.LOG_FILE_NAME)
.renameTo(new File(Config.Logging.LOG_DIR_NAME, Config.Logging.LOG_FILE_NAME + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
}
private void closeInputStream() throws IOException {
......@@ -98,7 +99,7 @@ public class SyncFileWriter implements IWriter {
private void writeErrorLog(Throwable e) {
FileOutputStream fileOutputStream = null;
try {
File file = new File(Config.Logging.LOG_FILE_PATH, Config.Logging.SYSTEM_ERROR_LOG_FILE_NAME);
File file = new File(Config.Logging.LOG_DIR_NAME, Config.Logging.SYSTEM_ERROR_LOG_FILE_NAME);
fileOutputStream = new FileOutputStream(file, true);
fileOutputStream.write(("Failed to init sync File Writer.\n" + LoggingUtil.fetchThrowableStack(e)).getBytes());
} catch (Exception e1) {
......
......@@ -11,13 +11,26 @@ public class PluginDefineCategory {
private static PluginDefineCategory pluginDefineCategory;
private final Map<String, AbstractClassEnhancePluginDefine> classEnhancePluginDefines = new HashMap<String, AbstractClassEnhancePluginDefine>();
private final List<IBootPluginDefine> IBootPluginDefines = new ArrayList<IBootPluginDefine>();
private final Map<String, AbstractClassEnhancePluginDefine> exactClassEnhancePluginDefineMapping =
new HashMap<String, AbstractClassEnhancePluginDefine>();
private final List<IBootPluginDefine> IBootPluginDefines =
new ArrayList<IBootPluginDefine>();
private final Map<String, AbstractClassEnhancePluginDefine> blurryClassEnhancePluginDefineMapping =
new HashMap<String, AbstractClassEnhancePluginDefine>();
private PluginDefineCategory(List<IPlugin> plugins) {
for (IPlugin plugin : plugins) {
if (plugin instanceof AbstractClassEnhancePluginDefine) {
classEnhancePluginDefines.put(((AbstractClassEnhancePluginDefine) plugin).enhanceClassName(), (AbstractClassEnhancePluginDefine) plugin);
String enhanceClassName = ((AbstractClassEnhancePluginDefine) plugin).enhanceClassName();
if (enhanceClassName.endsWith("*")) {
// 加上. 为了区分 com.ai.test com.ai.test1
blurryClassEnhancePluginDefineMapping
.put(enhanceClassName.substring(0, enhanceClassName.length() - 1),
(AbstractClassEnhancePluginDefine) plugin);
} else {
exactClassEnhancePluginDefineMapping
.put(enhanceClassName, (AbstractClassEnhancePluginDefine) plugin);
}
}
if (plugin instanceof IBootPluginDefine) {
......@@ -37,8 +50,25 @@ public class PluginDefineCategory {
return pluginDefineCategory.IBootPluginDefines;
}
public Map<String, AbstractClassEnhancePluginDefine> getClassEnhancePluginDefines() {
return pluginDefineCategory.classEnhancePluginDefines;
public Map<String, AbstractClassEnhancePluginDefine> getExactClassEnhancePluginDefineMapping() {
return pluginDefineCategory.exactClassEnhancePluginDefineMapping;
}
public Map<String, AbstractClassEnhancePluginDefine> getBlurryClassEnhancePluginDefineMapping() {
return blurryClassEnhancePluginDefineMapping;
}
public AbstractClassEnhancePluginDefine findPluginDefine(String enhanceClassName) {
if (exactClassEnhancePluginDefineMapping.containsKey(enhanceClassName)){
return exactClassEnhancePluginDefineMapping.get(enhanceClassName);
}
for (Map.Entry<String, AbstractClassEnhancePluginDefine> entry : blurryClassEnhancePluginDefineMapping.entrySet()){
if (enhanceClassName.startsWith(entry.getKey())){
return entry.getValue();
}
}
return null;
}
}
......@@ -20,7 +20,7 @@ public class ExclusionMatcherTest extends TestCase {
PluginDefineCategory category = PluginDefineCategory.category(pluginDefines);
for (Map.Entry<String, AbstractClassEnhancePluginDefine> entry : category.getClassEnhancePluginDefines().entrySet()) {
for (Map.Entry<String, AbstractClassEnhancePluginDefine> entry : category.getExactClassEnhancePluginDefineMapping().entrySet()) {
DynamicType.Builder<?> newClassBuilder =
new ByteBuddy().rebase(TypePool.Default.ofClassPath().describe(entry.getKey()).resolve(), ClassFileLocator.ForClassLoader.ofClassPath());
......
package test.ai.cloud.plugin;
import com.ai.cloud.skywalking.plugin.AbstractClassEnhancePluginDefine;
import com.ai.cloud.skywalking.plugin.IPlugin;
import com.ai.cloud.skywalking.plugin.PluginDefineCategory;
import com.ai.cloud.skywalking.plugin.PluginException;
import net.bytebuddy.dynamic.DynamicType;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.*;
import static org.powermock.api.mockito.PowerMockito.spy;
;
@RunWith(PowerMockRunner.class)
@PrepareForTest(AbstractClassEnhancePluginDefine.class)
public class PluginDefineCategoryTest {
private PluginDefineCategory pluginDefineCategory;
@Before
public void init() {
PowerMockito.spy(AbstractClassEnhancePluginDefine.class);
AbstractClassEnhancePluginDefine define1 = spy(new AbstractClassEnhancePluginDefine() {
@Override
protected DynamicType.Builder<?> enhance(String enhanceOriginClassName,
DynamicType.Builder<?> newClassBuilder) throws PluginException {
return null;
}
@Override
protected String enhanceClassName() {
return "com.ai.test.*";
}
});
List<IPlugin> plugins = new ArrayList<IPlugin>();
plugins.add(define1);
pluginDefineCategory = PluginDefineCategory.category(plugins);
}
@Test
public void testCategory() throws Exception {
assertEquals(1, pluginDefineCategory.getBlurryClassEnhancePluginDefineMapping().size());
}
@Test
public void testFindPluginDef() {
assertNotNull(pluginDefineCategory.findPluginDefine("com.ai.test.Test"));
assertNotNull(pluginDefineCategory.findPluginDefine("com.ai.test.test.TestA"));
assertNull(pluginDefineCategory.findPluginDefine("com.ai.test1.test"));
}
}
......@@ -34,6 +34,7 @@
<groupId>com.ai.cloud</groupId>
<artifactId>skywalking-api</artifactId>
<version>1.0-Final</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
......
......@@ -28,6 +28,7 @@
<groupId>com.ai.cloud</groupId>
<artifactId>skywalking-api</artifactId>
<version>1.0-Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
......
......@@ -30,6 +30,7 @@
<groupId>com.ai.cloud</groupId>
<artifactId>skywalking-api</artifactId>
<version>1.0-Final</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
......@@ -52,4 +53,4 @@
<url>https://api.bintray.com/maven/wu-sheng/skywalking/com.ai.cloud.skywalking-log4j-1.x-plugin/;publish=1</url>
</repository>
</distributionManagement>
</project>
\ No newline at end of file
</project>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册