提交 c0c1ac50 编写于 作者: P peng-yongsheng

Merge branch 'master' into feature/423

......@@ -10,8 +10,7 @@ Sky Walking | [中文](README_ZH.md)
[![Join the chat at https://gitter.im/sky-walking/Lobby](https://badges.gitter.im/openskywalking/Lobby.svg)](https://gitter.im/openskywalking/Lobby)
[![OpenTracing-1.x Badge](https://img.shields.io/badge/OpenTracing--1.x-enabled-blue.svg)](http://opentracing.io)
* Auto instrumentation by javaagent, **no need to CHANGE any application source code**.
* Provide Java agent, **no need to CHANGE any application source code**.
* High performance agent. Only increase extra **10%** cpu cost in 5000+ tps application, even **When collect all traces**, [check test reports](#test-reports).
* [Supported middlewares, frameworks and libraries](https://github.com/OpenSkywalking/sky-walking/wiki/3.2-supported-list).
* Manual instrumentation
......@@ -19,7 +18,6 @@ Sky Walking | [中文](README_ZH.md)
* Use **@Trace** annotation for any methods you want to trace.
* Integrate traceId into logs for log4j, log4j2 and logback.
* Pure Java server implementation, provide RESTful and gRPC services. Compatibility with other language agents/SDKs.
* [How to uplink metrics and traces to collector?]()
* The UI released on [skywalking-ui](https://github.com/OpenSkywalking/sky-walking-ui)
# Architecture
......
......@@ -11,7 +11,7 @@ Sky Walking | [English](README.md)
[![OpenTracing-1.x Badge](https://img.shields.io/badge/OpenTracing--1.x-enabled-blue.svg)](http://opentracing.io)
* 自动java探针,**不需要修改应用程序源代码**
* Java自动探针,**不需要修改应用程序源代码**
 * 高性能探针,针对单实例5000tps的应用,在**全量采集的情况下**,只增加**10%**的CPU开销。
* [中间件,框架与类库支持列表](https://github.com/wu-sheng/sky-walking/wiki/3.2-supported-list).
* 手动探针
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2017, OpenSkywalking Organization All rights reserved.
~
~ 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.
~
~ Project repository: https://github.com/OpenSkywalking/skywalking
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>apm-commons</artifactId>
<groupId>org.skywalking</groupId>
<version>3.2.3-2017</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apm-logging-api</artifactId>
</project>
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.logging;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.powermock.api.support.membermodification.MemberModifier;
/**
* @author wusheng
*/
public class LogManagerTest {
@Test
public void testGetNoopLogger() {
ILog logger = LogManager.getLogger(LogManagerTest.class);
Assert.assertEquals(NoopLogger.INSTANCE, logger);
}
@Before
@After
public void clear() throws IllegalAccessException {
MemberModifier.field(LogManager.class, "RESOLVER").set(null, null);
}
public class TestLogger implements ILog {
@Override
public void info(String format) {
}
@Override
public void info(String format, Object... arguments) {
}
@Override
public void warn(String format, Object... arguments) {
}
@Override
public void error(String format, Throwable e) {
}
@Override
public void error(Throwable e, String format, Object... arguments) {
}
@Override
public boolean isDebugEnable() {
return false;
}
@Override
public boolean isInfoEnable() {
return false;
}
@Override
public boolean isWarnEnable() {
return false;
}
@Override
public boolean isErrorEnable() {
return false;
}
@Override
public void debug(String format) {
}
@Override
public void debug(String format, Object... arguments) {
}
@Override
public void error(String format) {
}
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.logging;
import org.junit.Assert;
import org.junit.Test;
/**
* Created by wusheng on 2017/2/27.
*/
public class NoopLoggerTest {
@Test
public void testOnNothing() {
Assert.assertFalse(NoopLogger.INSTANCE.isDebugEnable());
Assert.assertFalse(NoopLogger.INSTANCE.isInfoEnable());
Assert.assertFalse(NoopLogger.INSTANCE.isErrorEnable());
Assert.assertFalse(NoopLogger.INSTANCE.isWarnEnable());
NoopLogger.INSTANCE.debug("Any string");
NoopLogger.INSTANCE.debug("Any string", new Object[0]);
NoopLogger.INSTANCE.info("Any string");
NoopLogger.INSTANCE.info("Any string", new Object[0]);
NoopLogger.INSTANCE.warn("Any string", new Object[0]);
NoopLogger.INSTANCE.warn("Any string", new Object[0], new NullPointerException());
NoopLogger.INSTANCE.error("Any string");
NoopLogger.INSTANCE.error("Any string", new NullPointerException());
}
}
......@@ -30,7 +30,6 @@
<modules>
<module>apm-util</module>
<module>apm-logging-api</module>
<module>apm-datacarrier</module>
</modules>
......
......@@ -55,12 +55,12 @@
<dependencies>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-logging-api</artifactId>
<artifactId>apm-network</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-network</artifactId>
<artifactId>apm-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
......@@ -194,6 +194,23 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<delete dir="${project.basedir}/../../packages"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.boot;
/**
* @author wusheng
*/
public class AgentPackageNotFoundException extends Exception {
public AgentPackageNotFoundException(String message) {
super(message);
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.boot;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
/**
* @author wusheng
*/
public class AgentPackagePath {
private static final ILog logger = LogManager.getLogger(AgentPackagePath.class);
private static File AGENT_PACKAGE_PATH;
public static File getPath() throws AgentPackageNotFoundException {
if (AGENT_PACKAGE_PATH == null) {
AGENT_PACKAGE_PATH = findPath();
}
return AGENT_PACKAGE_PATH;
}
public static boolean isPathFound() {
return AGENT_PACKAGE_PATH != null;
}
private static File findPath() throws AgentPackageNotFoundException {
String classResourcePath = AgentPackagePath.class.getName().replaceAll("\\.", "/") + ".class";
URL resource = AgentPackagePath.class.getClassLoader().getSystemClassLoader().getResource(classResourcePath);
if (resource != null) {
String urlString = resource.toString();
logger.debug("The beacon class location is {}.", urlString);
int insidePathIndex = urlString.indexOf('!');
boolean isInJar = insidePathIndex > -1;
if (isInJar) {
urlString = urlString.substring(urlString.indexOf("file:"), insidePathIndex);
File agentJarFile = null;
try {
agentJarFile = new File(new URL(urlString).getFile());
} catch (MalformedURLException e) {
logger.error(e, "Can not locate agent jar file by url:" + urlString);
}
if (agentJarFile.exists()) {
return agentJarFile.getParentFile();
}
} else {
String classLocation = urlString.substring(urlString.indexOf("file:"), urlString.length() - classResourcePath.length());
return new File(classLocation);
}
}
logger.error("Can not locate agent jar file.");
throw new AgentPackageNotFoundException("Can not locate agent jar file.");
}
}
......@@ -22,8 +22,8 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ServiceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
/**
* The <code>ServiceManager</code> bases on {@link ServiceLoader},
......
......@@ -18,11 +18,9 @@
package org.skywalking.apm.agent.core.conf;
import java.util.LinkedList;
import java.util.List;
import org.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.skywalking.apm.agent.core.logging.LogLevel;
import org.skywalking.apm.agent.core.logging.WriterFactory;
import org.skywalking.apm.agent.core.logging.core.LogLevel;
import org.skywalking.apm.agent.core.logging.core.WriterFactory;
/**
* This is the core config in sniffer agent.
......@@ -129,22 +127,6 @@ public class Config {
}
public static class Plugin {
/**
* Name of disabled plugin, The value spilt by <code>,</code>
* if you have multiple plugins need to disable.
*
* Here are the plugin names :
* tomcat-7.x/8.x, dubbo, jedis-2.x, motan, httpclient-4.x, jdbc, mongodb-3.x.
*/
public static List DISABLED_PLUGINS = new LinkedList();
/**
* Name of force enable plugin, The value spilt by <code>,</code>
* if you have multiple plugins need to enable.
*/
public static List FORCE_ENABLE_PLUGINS = new LinkedList();
public static class MongoDB {
/**
* If true, trace all the parameters, default is false.
......
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.conf;
/**
* @author wusheng
*/
public class ConfigNotFoundException extends Exception {
public ConfigNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public ConfigNotFoundException(String message) {
super(message);
}
}
......@@ -18,17 +18,20 @@
package org.skywalking.apm.agent.core.conf;
import org.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
import org.skywalking.apm.agent.core.boot.AgentPackagePath;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import org.skywalking.apm.util.ConfigInitializer;
import org.skywalking.apm.util.StringUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.util.ConfigInitializer;
import org.skywalking.apm.util.StringUtil;
/**
* The <code>SnifferConfigInitializer</code> initializes all configs in several way.
......@@ -38,92 +41,76 @@ import org.skywalking.apm.util.StringUtil;
*/
public class SnifferConfigInitializer {
private static final ILog logger = LogManager.getLogger(SnifferConfigInitializer.class);
private static String CONFIG_FILE_NAME = "/sky-walking.config";
private static String CONFIG_FILE_NAME = "/config/agent.config";
private static String ENV_KEY_PREFIX = "skywalking.";
/**
* Try to locate config file, named {@link #CONFIG_FILE_NAME}, in following order:
* 1. Path from SystemProperty. {@link #loadConfigBySystemProperty()}
* 2. class path.
* 3. Path, where agent is. {@link #loadConfigFromAgentFolder()}
* Try to locate `agent.config`, which should be in the /config dictionary of agent package.
* <p>
* If no found in any path, agent is still going to run in default config, {@link Config},
* but in initialization steps, these following configs must be set, by config file or system properties:
* Also try to override the config by system.env and system.properties. All the keys in these two places should
* start with {@link #ENV_KEY_PREFIX}. e.g. in env `skywalking.agent.application_code=yourAppName` to override
* `agent.application_code` in config file.
* <p>
* 1. applicationCode. "-DapplicationCode=" or {@link Config.Agent#APPLICATION_CODE}
* 2. servers. "-Dservers=" or {@link Config.Collector#SERVERS}
* At the end, `agent.application_code` and `collector.servers` must be not blank.
*/
public static void initialize() {
public static void initialize() throws ConfigNotFoundException, AgentPackageNotFoundException {
InputStream configFileStream;
configFileStream = loadConfigBySystemProperty();
if (configFileStream == null) {
configFileStream = SnifferConfigInitializer.class.getResourceAsStream(CONFIG_FILE_NAME);
if (configFileStream == null) {
logger.info("No config file found, according system property '-Dconfig'.");
configFileStream = loadConfigFromAgentFolder();
} else {
logger.info("{} file found in class path.", CONFIG_FILE_NAME);
}
}
if (configFileStream == null) {
logger.info("No {} found, sky-walking is going to run in default config.", CONFIG_FILE_NAME);
} else {
try {
Properties properties = new Properties();
properties.load(configFileStream);
ConfigInitializer.initialize(properties, Config.class);
} catch (Exception e) {
logger.error("Failed to read the config file, sky-walking is going to run in default config.", e);
}
try {
configFileStream = loadConfigFromAgentFolder();
Properties properties = new Properties();
properties.load(configFileStream);
ConfigInitializer.initialize(properties, Config.class);
} catch (Exception e) {
logger.error(e, "Failed to read the config file, skywalking is going to run in default config.");
}
String applicationCode = System.getProperty("applicationCode");
if (!StringUtil.isEmpty(applicationCode)) {
Config.Agent.APPLICATION_CODE = applicationCode;
}
String servers = System.getProperty("servers");
if (!StringUtil.isEmpty(servers)) {
Config.Collector.SERVERS = servers;
try {
overrideConfigBySystemEnv();
} catch (Exception e) {
logger.error(e, "Failed to read the system env.");
}
if (StringUtil.isEmpty(Config.Agent.APPLICATION_CODE)) {
throw new ExceptionInInitializerError("'-DapplicationCode=' is missing.");
throw new ExceptionInInitializerError("`agent.application_code` is missing.");
}
if (StringUtil.isEmpty(Config.Collector.SERVERS)) {
throw new ExceptionInInitializerError("'-Dservers=' is missing.");
throw new ExceptionInInitializerError("`collector.servers` is missing.");
}
}
/**
* Load the config file by the path, which is provided by system property, usually with a "-Dconfig=" arg.
* Override the config by system env. The env key must start with `skywalking`, the reuslt should be as same as in
* `agent.config`
* <p>
* such as:
* Env key of `agent.application_code` shoule be `skywalking.agent.application_code`
*
* @return the config file {@link InputStream}, or null if not needEnhance.
*/
private static InputStream loadConfigBySystemProperty() {
String config = System.getProperty("config");
if (StringUtil.isEmpty(config)) {
return null;
}
File configFile = new File(config);
if (configFile.exists() && configFile.isDirectory()) {
logger.info("check {} in path {}, according system property.", CONFIG_FILE_NAME, config);
configFile = new File(config, CONFIG_FILE_NAME);
private static void overrideConfigBySystemEnv() throws IllegalAccessException {
Properties properties = new Properties();
Properties systemProperties = System.getProperties();
Iterator<Map.Entry<Object, Object>> entryIterator = systemProperties.entrySet().iterator();
while (entryIterator.hasNext()) {
Map.Entry<Object, Object> prop = entryIterator.next();
if (prop.getKey().toString().startsWith(ENV_KEY_PREFIX)) {
String realKey = prop.getKey().toString().substring(ENV_KEY_PREFIX.length());
properties.put(realKey, prop.getValue());
}
}
if (configFile.exists() && configFile.isFile()) {
try {
logger.info("found {}, according system property.", configFile.getAbsolutePath());
return new FileInputStream(configFile);
} catch (FileNotFoundException e) {
logger.error(e, "Fail to load {} , according system property.", config);
Map<String, String> envs = System.getenv();
for (String envKey : envs.keySet()) {
if (envKey.startsWith(ENV_KEY_PREFIX)) {
String realKey = envKey.substring(ENV_KEY_PREFIX.length());
properties.setProperty(realKey, envs.get(envKey));
}
}
logger.info("No {} found, according system property.", config);
return null;
if (!properties.isEmpty()) {
ConfigInitializer.initialize(properties, Config.class);
}
}
/**
......@@ -131,50 +118,17 @@ public class SnifferConfigInitializer {
*
* @return the config file {@link InputStream}, or null if not needEnhance.
*/
private static InputStream loadConfigFromAgentFolder() {
String agentBasePath = initAgentBasePath();
if (!StringUtil.isEmpty(agentBasePath)) {
File configFile = new File(agentBasePath, CONFIG_FILE_NAME);
if (configFile.exists() && configFile.isFile()) {
try {
logger.info("{} file found in agent folder.", CONFIG_FILE_NAME);
return new FileInputStream(configFile);
} catch (FileNotFoundException e) {
logger.error(e, "Fail to load {} in path {}, according auto-agent-folder mechanism.", CONFIG_FILE_NAME, agentBasePath);
}
}
}
logger.info("No {} file found in agent folder.", CONFIG_FILE_NAME);
return null;
}
/**
* Try to allocate the skywalking-agent.jar
* Some config files or output resources are from this path.
*
* @return he path, where the skywalking-agent.jar is
*/
private static String initAgentBasePath() {
String classResourcePath = SnifferConfigInitializer.class.getName().replaceAll("\\.", "/") + ".class";
URL resource = SnifferConfigInitializer.class.getClassLoader().getSystemClassLoader().getResource(classResourcePath);
if (resource != null) {
String urlString = resource.toString();
logger.debug(urlString);
urlString = urlString.substring(urlString.indexOf("file:"), urlString.indexOf('!'));
File agentJarFile = null;
private static InputStream loadConfigFromAgentFolder() throws AgentPackageNotFoundException, ConfigNotFoundException {
File configFile = new File(AgentPackagePath.getPath(), CONFIG_FILE_NAME);
if (configFile.exists() && configFile.isFile()) {
try {
agentJarFile = new File(new URL(urlString).getFile());
} catch (MalformedURLException e) {
logger.error(e, "Can not locate agent jar file by url:", urlString);
}
if (agentJarFile.exists()) {
return agentJarFile.getParentFile().getAbsolutePath();
logger.info("Config file found in {}.", configFile);
return new FileInputStream(configFile);
} catch (FileNotFoundException e) {
throw new ConfigNotFoundException("Fail to load agent.config", e);
}
}
logger.info("Can not locate agent jar file.");
return null;
throw new ConfigNotFoundException("Fail to load agent config file.");
}
}
......@@ -26,8 +26,8 @@ import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.skywalking.apm.agent.core.dictionary.DictionaryUtil;
import org.skywalking.apm.agent.core.sampling.SamplingService;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import org.skywalking.apm.util.StringUtil;
/**
......
......@@ -26,8 +26,8 @@ import org.skywalking.apm.agent.core.context.ids.DistributedTraceIds;
import org.skywalking.apm.agent.core.context.ids.GlobalIdGenerator;
import org.skywalking.apm.agent.core.context.ids.ID;
import org.skywalking.apm.agent.core.context.ids.NewDistributedTraceId;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import org.skywalking.apm.network.proto.TraceSegmentObject;
import org.skywalking.apm.network.proto.UpstreamSegment;
......
......@@ -37,8 +37,8 @@ import org.skywalking.apm.agent.core.jvm.memorypool.MemoryPoolProvider;
import org.skywalking.apm.agent.core.remote.GRPCChannelListener;
import org.skywalking.apm.agent.core.remote.GRPCChannelManager;
import org.skywalking.apm.agent.core.remote.GRPCChannelStatus;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import org.skywalking.apm.network.proto.JVMMetric;
import org.skywalking.apm.network.proto.JVMMetrics;
import org.skywalking.apm.network.proto.JVMMetricsServiceGrpc;
......
......@@ -19,8 +19,8 @@
package org.skywalking.apm.agent.core.jvm.cpu;
import org.skywalking.apm.agent.core.os.ProcessorUtil;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import org.skywalking.apm.network.proto.CPU;
/**
......
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.logging;
package org.skywalking.apm.agent.core.logging.api;
/**
* The Log interface.
......
......@@ -16,7 +16,9 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.logging;
package org.skywalking.apm.agent.core.logging.api;
import org.skywalking.apm.agent.core.logging.core.EasyLogResolver;
/**
* LogManager is the {@link LogResolver} implementation manager. By using {@link LogResolver}, {@link
......@@ -27,7 +29,7 @@ package org.skywalking.apm.logging;
* override the first without any warning or exception. <p> Created by xin on 2016/11/10.
*/
public class LogManager {
private static LogResolver RESOLVER;
private static LogResolver RESOLVER = new EasyLogResolver();
public static void setLogResolver(LogResolver resolver) {
LogManager.RESOLVER = resolver;
......
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.logging;
package org.skywalking.apm.agent.core.logging.api;
/**
* {@link LogResolver} just do only one thing: return the {@link ILog} implementation.
......
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.logging;
package org.skywalking.apm.agent.core.logging.api;
/**
* No operation logger implementation.
......
......@@ -16,10 +16,10 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.logging;
package org.skywalking.apm.agent.core.logging.core;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogResolver;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogResolver;
/**
* Created by wusheng on 2016/11/26.
......
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.logging;
package org.skywalking.apm.agent.core.logging.core;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
......@@ -25,7 +25,7 @@ import java.util.Date;
import java.util.regex.Matcher;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.conf.Constants;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.util.StringUtil;
/**
......@@ -41,7 +41,7 @@ public class EasyLogger implements ILog {
this.targetClass = targetClass;
}
private void logger(LogLevel level, String message, Throwable e) {
protected void logger(LogLevel level, String message, Throwable e) {
WriterFactory.getLogWriter().write(format(level, message, e));
}
......
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.logging;
package org.skywalking.apm.agent.core.logging.core;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.EventHandler;
......
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.logging;
package org.skywalking.apm.agent.core.logging.core;
public interface IWriter {
void write(String message);
......
......@@ -16,11 +16,11 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.logging;
package org.skywalking.apm.agent.core.logging.core;
/**
* Created by xin on 2016/12/7.
*/
public enum LogLevel {
DEBUG, INFO, WARN, ERROR;
DEBUG, INFO, WARN, ERROR, OFF
}
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.logging;
package org.skywalking.apm.agent.core.logging.core;
/**
* The <code>LogMessageHolder</code> is a {@link String} holder,
......
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.logging;
package org.skywalking.apm.agent.core.logging.core;
import java.io.PrintStream;
......
......@@ -16,14 +16,23 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.logging;
package org.skywalking.apm.agent.core.logging.core;
import org.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
import org.skywalking.apm.agent.core.boot.AgentPackagePath;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.util.StringUtil;
public class WriterFactory {
public static IWriter getLogWriter() {
if (!StringUtil.isEmpty(Config.Logging.DIR)) {
if (AgentPackagePath.isPathFound()) {
if (StringUtil.isEmpty(Config.Logging.DIR)) {
try {
Config.Logging.DIR = AgentPackagePath.getPath() + "/logs";
} catch (AgentPackageNotFoundException e) {
e.printStackTrace();
}
}
return FileWriter.get();
} else {
return SystemOutWriter.INSTANCE;
......
......@@ -21,8 +21,8 @@ package org.skywalking.apm.agent.core.plugin;
import net.bytebuddy.dynamic.DynamicType;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassEnhancePluginDefine;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import org.skywalking.apm.util.StringUtil;
/**
......
......@@ -21,8 +21,10 @@ package org.skywalking.apm.agent.core.plugin;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
import org.skywalking.apm.agent.core.plugin.loader.AgentClassLoader;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
/**
* Plugins finder.
......@@ -39,7 +41,9 @@ public class PluginBootstrap {
*
* @return plugin definition list.
*/
public List<AbstractClassEnhancePluginDefine> loadPlugins() {
public List<AbstractClassEnhancePluginDefine> loadPlugins() throws AgentPackageNotFoundException {
AgentClassLoader.initDefaultLoader();
PluginResourcesResolver resolver = new PluginResourcesResolver();
List<URL> resources = resolver.getResources();
......@@ -63,7 +67,10 @@ public class PluginBootstrap {
try {
logger.debug("loading plugin class {}.", pluginDefine.getDefineClass());
AbstractClassEnhancePluginDefine plugin =
(AbstractClassEnhancePluginDefine)Class.forName(pluginDefine.getDefineClass()).newInstance();
(AbstractClassEnhancePluginDefine)Class.forName(pluginDefine.getDefineClass(),
true,
AgentClassLoader.getDefault())
.newInstance();
plugins.add(plugin);
} catch (Throwable t) {
logger.error(t, "load plugin [{}] failure.", pluginDefine.getDefineClass());
......
......@@ -18,15 +18,16 @@
package org.skywalking.apm.agent.core.plugin;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import org.skywalking.apm.agent.core.plugin.exception.IllegalPluginDefineException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.skywalking.apm.agent.core.plugin.exception.IllegalPluginDefineException;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
public enum PluginCfg {
INSTANCE;
......@@ -45,9 +46,7 @@ public enum PluginCfg {
continue;
}
PluginDefine plugin = PluginDefine.build(pluginDefine);
if (plugin.enable()) {
pluginClassList.add(plugin);
}
pluginClassList.add(plugin);
} catch (IllegalPluginDefineException e) {
logger.error(e, "Failed to format plugin({}) define.", pluginDefine);
}
......
......@@ -18,12 +18,10 @@
package org.skywalking.apm.agent.core.plugin;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.plugin.exception.IllegalPluginDefineException;
import org.skywalking.apm.util.StringUtil;
public class PluginDefine {
public static final String PLUGIN_OFF_PREFIX = "[OFF]";
/**
* Plugin name.
*/
......@@ -34,15 +32,9 @@ public class PluginDefine {
*/
private String defineClass;
/**
* The sate of plugin.
*/
private State state;
private PluginDefine(String name, String defineClass, State state) {
private PluginDefine(String name, String defineClass) {
this.name = name;
this.defineClass = defineClass;
this.state = state;
}
public static PluginDefine build(String define) throws IllegalPluginDefineException {
......@@ -57,32 +49,12 @@ public class PluginDefine {
String pluginName = pluginDefine[0];
String defineClass = pluginDefine[1];
if (pluginName.toUpperCase().startsWith(PLUGIN_OFF_PREFIX)) {
return new PluginDefine(pluginName.substring(PLUGIN_OFF_PREFIX.length()), defineClass, State.OFF);
} else {
return new PluginDefine(pluginName, defineClass, State.ON);
}
}
public boolean enable() {
return !forceDisable() || forceEnable();
}
private boolean forceDisable() {
return state != State.ON || Config.Plugin.DISABLED_PLUGINS.contains(name);
}
private boolean forceEnable() {
return state == State.OFF && Config.Plugin.FORCE_ENABLE_PLUGINS.contains(name);
return new PluginDefine(pluginName, defineClass);
}
public String getDefineClass() {
return defineClass;
}
private enum State {
OFF, ON;
}
}
......@@ -23,8 +23,9 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.plugin.loader.AgentClassLoader;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
/**
* Use the current classloader to read all plugin define file.
......@@ -39,7 +40,7 @@ public class PluginResourcesResolver {
List<URL> cfgUrlPaths = new ArrayList<URL>();
Enumeration<URL> urls;
try {
urls = getDefaultClassLoader().getResources("skywalking-plugin.def");
urls = AgentClassLoader.getDefault().getResources("skywalking-plugin.def");
while (urls.hasMoreElements()) {
URL pluginUrl = urls.nextElement();
......@@ -56,8 +57,8 @@ public class PluginResourcesResolver {
/**
* Get the classloader.
* First get current thread's classloader,
* if fail, get {@link PluginResourcesResolver}'s classloader.
* First getDefault current thread's classloader,
* if fail, getDefault {@link PluginResourcesResolver}'s classloader.
*
* @return the classloader to find plugin definitions.
*/
......
......@@ -30,8 +30,8 @@ import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoin
import org.skywalking.apm.agent.core.plugin.interceptor.EnhanceException;
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import org.skywalking.apm.util.StringUtil;
import static net.bytebuddy.jar.asm.Opcodes.ACC_PRIVATE;
......
......@@ -22,9 +22,9 @@ import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.This;
import org.skywalking.apm.agent.core.plugin.PluginException;
import org.skywalking.apm.agent.core.plugin.interceptor.loader.InterceptorInstanceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoader;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
/**
* The actual byte-buddy's interceptor to intercept constructor methods.
......
......@@ -26,9 +26,9 @@ import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
import net.bytebuddy.implementation.bind.annotation.This;
import org.skywalking.apm.agent.core.plugin.PluginException;
import org.skywalking.apm.agent.core.plugin.interceptor.loader.InterceptorInstanceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoader;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
/**
* The actual byte-buddy's interceptor to intercept class instance methods.
......
......@@ -25,9 +25,9 @@ import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.This;
import org.skywalking.apm.agent.core.plugin.PluginException;
import org.skywalking.apm.agent.core.plugin.interceptor.loader.InterceptorInstanceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoader;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
/**
* The actual byte-buddy's interceptor to intercept class instance methods.
......
......@@ -24,9 +24,9 @@ import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
import org.skywalking.apm.agent.core.plugin.interceptor.loader.InterceptorInstanceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoader;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
/**
* The actual byte-buddy's interceptor to intercept class instance methods.
......
......@@ -23,9 +23,9 @@ import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Morph;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import org.skywalking.apm.agent.core.plugin.interceptor.loader.InterceptorInstanceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.plugin.loader.InterceptorInstanceLoader;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
/**
* The actual byte-buddy's interceptor to intercept class instance methods.
......
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.plugin.interceptor.loader;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.ProtectionDomain;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
/**
* The <code>InterceptorInstanceLoader</code> is a classes finder and container.
* <p>
* This is a very important class in sky-walking's auto-instrumentation mechanism. If you want to fully understand why
* need this, and how it works, you need have knowledge about Classloader appointment mechanism.
* <p>
* The loader will load a class, and focus the target class loader (be intercepted class's classloader) loads it.
* <p>
* If the target class and target class loader are same, the loaded classes( {@link InstanceConstructorInterceptor},
* {@link InstanceMethodsAroundInterceptor} and {@link StaticMethodsAroundInterceptor} implementations) stay in
* singleton.
* <p>
* Created by wusheng on 16/8/2.
*/
public class InterceptorInstanceLoader {
private static final ILog logger = LogManager.getLogger(InterceptorInstanceLoader.class);
private static ConcurrentHashMap<String, Object> INSTANCE_CACHE = new ConcurrentHashMap<String, Object>();
private static ReentrantLock INSTANCE_LOAD_LOCK = new ReentrantLock();
public static <T> T load(String className, ClassLoader targetClassLoader)
throws InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException {
if (targetClassLoader == null) {
targetClassLoader = InterceptorInstanceLoader.class.getClassLoader();
}
String instanceKey = className + "_OF_" + targetClassLoader.getClass().getName() + "@" + Integer.toHexString(targetClassLoader.hashCode());
Object inst = INSTANCE_CACHE.get(instanceKey);
if (inst == null) {
if (InterceptorInstanceLoader.class.getClassLoader().equals(targetClassLoader)) {
inst = targetClassLoader.loadClass(className).newInstance();
} else {
INSTANCE_LOAD_LOCK.lock();
try {
try {
inst = findLoadedClass(className, targetClassLoader);
if (inst == null) {
inst = loadBinary(className, targetClassLoader);
}
if (inst == null) {
throw new ClassNotFoundException(targetClassLoader.toString() + " load interceptor class:" + className + " failure.");
}
} catch (Exception e) {
throw new ClassNotFoundException(targetClassLoader.toString() + " load interceptor class:" + className + " failure.", e);
}
} finally {
INSTANCE_LOAD_LOCK.unlock();
}
}
if (inst != null) {
INSTANCE_CACHE.put(instanceKey, inst);
}
}
return (T)inst;
}
/**
* load class from class binary files.
* Most likely all the interceptor implementations should be loaded by this.
*
* @param className interceptor class name.
* @param targetClassLoader the classloader, which should load the interceptor.
* @param <T>
* @return interceptor instance.
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
*/
private static <T> T loadBinary(String className,
ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException {
String path = "/" + className.replace('.', '/').concat(".class");
byte[] data = null;
BufferedInputStream is = null;
ByteArrayOutputStream baos = null;
try {
logger.debug("Read binary code of {} using classload {}", className, InterceptorInstanceLoader.class.getClassLoader());
is = new BufferedInputStream(InterceptorInstanceLoader.class.getResourceAsStream(path));
baos = new ByteArrayOutputStream();
int ch = 0;
while ((ch = is.read()) != -1) {
baos.write(ch);
}
data = baos.toByteArray();
} catch (IOException e) {
logger.error(e.getMessage(), e);
} finally {
if (is != null)
try {
is.close();
} catch (IOException ignored) {
}
if (baos != null)
try {
baos.close();
} catch (IOException ignored) {
}
}
Method defineClassMethod = null;
Class<?> targetClassLoaderType = targetClassLoader.getClass();
while (defineClassMethod == null && targetClassLoaderType != null) {
try {
defineClassMethod = targetClassLoaderType.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class, ProtectionDomain.class);
} catch (NoSuchMethodException e) {
targetClassLoaderType = targetClassLoaderType.getSuperclass();
}
}
defineClassMethod.setAccessible(true);
logger.debug("load binary code of {} to classloader {}", className, targetClassLoader);
Class<?> type = (Class<?>)defineClassMethod.invoke(targetClassLoader, className, data, 0, data.length, null);
return (T)type.newInstance();
}
/**
* Find loaded class in the current classloader.
* Just in case some classes have already been loaded for some reason.
*
* @param className interceptor class name.
* @param targetClassLoader the classloader, which should load the interceptor.
* @param <T>
* @return interceptor instance.
*/
private static <T> T findLoadedClass(String className,
ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException {
Method defineClassMethod = null;
Class<?> targetClassLoaderType = targetClassLoader.getClass();
while (defineClassMethod == null && targetClassLoaderType != null) {
try {
defineClassMethod = targetClassLoaderType.getDeclaredMethod("findLoadedClass", String.class);
} catch (NoSuchMethodException e) {
targetClassLoaderType = targetClassLoaderType.getSuperclass();
}
}
defineClassMethod.setAccessible(true);
Class<?> type = (Class<?>)defineClassMethod.invoke(targetClassLoader, className);
if (type == null) {
return null;
}
return (T)type.newInstance();
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.plugin.loader;
import org.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
import org.skywalking.apm.agent.core.boot.AgentPackagePath;
import org.skywalking.apm.agent.core.plugin.PluginBootstrap;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
* The <code>AgentClassLoader</code> represents a classloader,
* which is in charge of finding plugins and interceptors.
*
* @author wusheng
*/
public class AgentClassLoader extends ClassLoader {
private static final ILog logger = LogManager.getLogger(AgentClassLoader.class);
/**
* The default class loader for the agent.
*/
private static AgentClassLoader DEFAULT_LOADER;
private List<File> classpath;
private List<Jar> allJars;
private ReentrantLock jarScanLock = new ReentrantLock();
public static AgentClassLoader getDefault() {
return DEFAULT_LOADER;
}
/**
* Init the default
*
* @return
* @throws AgentPackageNotFoundException
*/
public static AgentClassLoader initDefaultLoader() throws AgentPackageNotFoundException {
DEFAULT_LOADER = new AgentClassLoader(PluginBootstrap.class.getClassLoader());
return getDefault();
}
public AgentClassLoader(ClassLoader parent) throws AgentPackageNotFoundException {
super(parent);
File agentDictionary = AgentPackagePath.getPath();
classpath = new LinkedList<File>();
classpath.add(new File(agentDictionary, "plugins"));
classpath.add(new File(agentDictionary, "activations"));
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
List<Jar> allJars = getAllJars();
String path = name.replace('.', '/').concat(".class");
for (Jar jar : allJars) {
JarEntry entry = jar.jarFile.getJarEntry(path);
if (entry != null) {
try {
URL classFileUrl = new URL("jar:file:" + jar.sourceFile.getAbsolutePath() + "!/" + path);
byte[] data = null;
BufferedInputStream is = null;
ByteArrayOutputStream baos = null;
try {
is = new BufferedInputStream(classFileUrl.openStream());
baos = new ByteArrayOutputStream();
int ch = 0;
while ((ch = is.read()) != -1) {
baos.write(ch);
}
data = baos.toByteArray();
} finally {
if (is != null)
try {
is.close();
} catch (IOException ignored) {
}
if (baos != null)
try {
baos.close();
} catch (IOException ignored) {
}
}
return defineClass(name, data, 0, data.length);
} catch (MalformedURLException e) {
logger.error(e, "find class fail.");
} catch (IOException e) {
logger.error(e, "find class fail.");
}
}
}
throw new ClassNotFoundException("Can't find " + name);
}
@Override
protected URL findResource(String name) {
List<Jar> allJars = getAllJars();
for (Jar jar : allJars) {
JarEntry entry = jar.jarFile.getJarEntry(name);
if (entry != null) {
try {
return new URL("jar:file:" + jar.sourceFile.getAbsolutePath() + "!/" + name);
} catch (MalformedURLException e) {
continue;
}
}
}
return null;
}
@Override
protected Enumeration<URL> findResources(String name) throws IOException {
List<URL> allResources = new LinkedList<URL>();
List<Jar> allJars = getAllJars();
for (Jar jar : allJars) {
JarEntry entry = jar.jarFile.getJarEntry(name);
if (entry != null) {
allResources.add(new URL("jar:file:" + jar.sourceFile.getAbsolutePath() + "!/" + name));
}
}
final Iterator<URL> iterator = allResources.iterator();
return new Enumeration<URL>() {
@Override
public boolean hasMoreElements() {
return iterator.hasNext();
}
@Override
public URL nextElement() {
return iterator.next();
}
};
}
private List<Jar> getAllJars() {
if (allJars == null) {
jarScanLock.lock();
try {
if (allJars == null) {
allJars = new LinkedList<Jar>();
for (File path : classpath) {
if (path.exists() && path.isDirectory()) {
String[] jarFileNames = path.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".jar");
}
});
for (String fileName : jarFileNames) {
try {
File file = new File(path, fileName);
Jar jar = new Jar(new JarFile(file), file);
allJars.add(jar);
logger.info("{} loaded.", file.toString());
} catch (IOException e) {
logger.error(e, "{} jar file can't be resolved", fileName);
}
}
}
}
}
} finally {
jarScanLock.unlock();
}
}
return allJars;
}
private class Jar {
private JarFile jarFile;
private File sourceFile;
private Jar(JarFile jarFile, File sourceFile) {
this.jarFile = jarFile;
this.sourceFile = sourceFile;
}
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.plugin.loader;
import org.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
/**
* The <code>InterceptorInstanceLoader</code> is a classes finder and container.
* <p>
* This is a very important class in sky-walking's auto-instrumentation mechanism. If you want to fully understand why
* need this, and how it works, you need have knowledge about Classloader appointment mechanism.
* <p>
* Created by wusheng on 16/8/2.
*/
public class InterceptorInstanceLoader {
private static final ILog logger = LogManager.getLogger(InterceptorInstanceLoader.class);
private static ConcurrentHashMap<String, Object> INSTANCE_CACHE = new ConcurrentHashMap<String, Object>();
private static ReentrantLock INSTANCE_LOAD_LOCK = new ReentrantLock();
private static Map<ClassLoader, ClassLoader> EXTEND_PLUGIN_CLASSLOADERS = new HashMap<ClassLoader, ClassLoader>();
/**
* Load an instance of interceptor, and keep it singleton.
* Create {@link AgentClassLoader} for each targetClassLoader, as an extend classloader.
* It can load interceptor classes from plugins, activations folders.
*
* @param className the interceptor class, which is expected to be found
* @param targetClassLoader the class loader for current application context
* @param <T> expected type
* @return the type reference.
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws ClassNotFoundException
* @throws AgentPackageNotFoundException
*/
public static <T> T load(String className, ClassLoader targetClassLoader)
throws InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException, AgentPackageNotFoundException {
if (targetClassLoader == null) {
targetClassLoader = InterceptorInstanceLoader.class.getClassLoader();
}
String instanceKey = className + "_OF_" + targetClassLoader.getClass().getName() + "@" + Integer.toHexString(targetClassLoader.hashCode());
Object inst = INSTANCE_CACHE.get(instanceKey);
if (inst == null) {
INSTANCE_LOAD_LOCK.lock();
try {
ClassLoader pluginLoader = EXTEND_PLUGIN_CLASSLOADERS.get(targetClassLoader);
if (pluginLoader == null) {
pluginLoader = new AgentClassLoader(targetClassLoader);
EXTEND_PLUGIN_CLASSLOADERS.put(targetClassLoader, pluginLoader);
}
inst = Class.forName(className, true, pluginLoader).newInstance();
} finally {
INSTANCE_LOAD_LOCK.unlock();
}
if (inst != null) {
INSTANCE_CACHE.put(instanceKey, inst);
}
}
return (T) inst;
}
}
......@@ -35,8 +35,8 @@ import org.skywalking.apm.agent.core.dictionary.ApplicationDictionary;
import org.skywalking.apm.agent.core.dictionary.DictionaryUtil;
import org.skywalking.apm.agent.core.dictionary.OperationNameDictionary;
import org.skywalking.apm.agent.core.os.OSUtil;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import org.skywalking.apm.network.proto.Application;
import org.skywalking.apm.network.proto.ApplicationInstance;
import org.skywalking.apm.network.proto.ApplicationInstanceHeartbeat;
......
......@@ -31,8 +31,8 @@ import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import static org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig.Collector.GRPC_SERVERS;
......
......@@ -35,8 +35,8 @@ import org.skywalking.apm.agent.core.boot.BootService;
import org.skywalking.apm.agent.core.boot.DefaultNamedThreadFactory;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
/**
* @author wusheng
......@@ -70,13 +70,15 @@ public class GRPCChannelManager implements BootService, Runnable {
@Override
public void shutdown() throws Throwable {
connectCheckFuture.cancel(true);
managedChannel.shutdownNow();
if (managedChannel != null) {
managedChannel.shutdownNow();
}
logger.debug("Selected collector grpc service shutdown.");
}
@Override
public void run() {
logger.debug("Selected collector grpc service running, reconnect:{}.",reconnect);
logger.debug("Selected collector grpc service running, reconnect:{}.", reconnect);
if (reconnect) {
if (RemoteDownstreamConfig.Collector.GRPC_SERVERS.size() > 0) {
String server = "";
......
......@@ -29,8 +29,8 @@ import org.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.skywalking.apm.commons.datacarrier.DataCarrier;
import org.skywalking.apm.commons.datacarrier.buffer.BufferStrategy;
import org.skywalking.apm.commons.datacarrier.consumer.IConsumer;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import org.skywalking.apm.network.proto.Downstream;
import org.skywalking.apm.network.proto.TraceSegmentServiceGrpc;
import org.skywalking.apm.network.proto.UpstreamSegment;
......
......@@ -27,8 +27,8 @@ import org.skywalking.apm.agent.core.boot.BootService;
import org.skywalking.apm.agent.core.boot.DefaultNamedThreadFactory;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
/**
* The <code>SamplingService</code> take charge of how to sample the {@link TraceSegment}. Every {@link TraceSegment}s
......@@ -86,7 +86,7 @@ public class SamplingService implements BootService {
}
/**
* @return true, if sampling mechanism is on, and get the sampling factor successfully.
* @return true, if sampling mechanism is on, and getDefault the sampling factor successfully.
*/
public boolean trySampling() {
if (on) {
......
......@@ -21,6 +21,8 @@ package org.skywalking.apm.agent.core.boot;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import org.junit.AfterClass;
import org.junit.Rule;
import org.junit.Test;
import org.skywalking.apm.agent.core.context.ContextManager;
......@@ -45,6 +47,11 @@ public class ServiceManagerTest {
@Rule
public AgentServiceRule agentServiceRule = new AgentServiceRule();
@AfterClass
public static void afterClass() {
ServiceManager.INSTANCE.shutdown();
}
@Test
public void testServiceDependencies() throws Exception {
HashMap<Class, BootService> registryService = getFieldValue(ServiceManager.INSTANCE, "bootedServices");
......
......@@ -20,7 +20,8 @@ package org.skywalking.apm.agent.core.conf;
import org.junit.AfterClass;
import org.junit.Test;
import org.skywalking.apm.agent.core.logging.LogLevel;
import org.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
import org.skywalking.apm.agent.core.logging.core.LogLevel;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
......@@ -28,9 +29,10 @@ import static org.hamcrest.MatcherAssert.assertThat;
public class SnifferConfigInitializerTest {
@Test
public void testLoadConfigFromJavaAgentDir() {
System.setProperty("applicationCode", "testApp");
System.setProperty("servers", "127.0.0.1:8090");
public void testLoadConfigFromJavaAgentDir() throws AgentPackageNotFoundException, ConfigNotFoundException {
System.setProperty("skywalking.agent.application_code", "testApp");
System.setProperty("skywalking.collector.servers", "127.0.0.1:8090");
System.setProperty("skywalking.logging.level", "info");
SnifferConfigInitializer.initialize();
assertThat(Config.Agent.APPLICATION_CODE, is("testApp"));
assertThat(Config.Collector.SERVERS, is("127.0.0.1:8090"));
......
......@@ -20,11 +20,10 @@ package org.skywalking.apm.agent.core.context;
import com.google.protobuf.InvalidProtocolBufferException;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.*;
import org.junit.runner.RunWith;
import org.skywalking.apm.agent.core.boot.ServiceManager;
import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig;
import org.skywalking.apm.agent.core.context.tag.Tags;
import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
......@@ -71,6 +70,12 @@ public class ContextManagerTest {
RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID = 1;
}
@AfterClass
public static void afterClass() {
ServiceManager.INSTANCE.shutdown();
}
@Test
public void createSpanWithInvalidateContextCarrier() {
ContextCarrier contextCarrier = new ContextCarrier().deserialize("#AQA=#AQA=4WcWe0tQNQA=|1|#127.0.0.1:8080|#/testEntrySpan|#/testEntrySpan|#AQA=#AQA=Et0We0tQNQA=");
......
......@@ -19,10 +19,8 @@
package org.skywalking.apm.agent.core.context;
import java.util.LinkedList;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.*;
import org.junit.runner.RunWith;
import org.skywalking.apm.agent.core.boot.ServiceManager;
import org.skywalking.apm.agent.core.conf.Config;
......@@ -53,6 +51,11 @@ public class IgnoredTracerContextTest {
RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID = 1;
}
@AfterClass
public static void afterClass() {
ServiceManager.INSTANCE.shutdown();
}
@After
public void tearDown() throws Exception {
}
......
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.logging;
import java.io.PrintStream;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
import org.skywalking.apm.agent.core.conf.Config;
/**
* Created by wusheng on 2017/2/28.
*/
public class WriterFactoryTest {
private static PrintStream ERR_REF;
@BeforeClass
public static void initAndHoldOut() {
ERR_REF = System.err;
}
/**
* During this test case,
* reset {@link System#out} to a Mock object, for avoid a console system.error.
*/
@Test
public void testGetLogWriter() {
PrintStream mockStream = Mockito.mock(PrintStream.class);
System.setErr(mockStream);
Assert.assertEquals(SystemOutWriter.INSTANCE, WriterFactory.getLogWriter());
Config.Logging.DIR = "/only/test/folder";
Assert.assertTrue(WriterFactory.getLogWriter() instanceof FileWriter);
}
@AfterClass
public static void reset() {
Config.Logging.DIR = "";
System.setErr(ERR_REF);
}
}
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.logging;
package org.skywalking.apm.agent.core.logging.core;
import org.junit.Assert;
import org.junit.Test;
......
......@@ -16,9 +16,8 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.logging;
package org.skywalking.apm.agent.core.logging.core;
import java.io.PrintStream;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
......@@ -26,6 +25,8 @@ import org.junit.Test;
import org.mockito.Mockito;
import org.skywalking.apm.agent.core.conf.Constants;
import java.io.PrintStream;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.times;
......@@ -48,7 +49,12 @@ public class EasyLoggerTest {
System.setOut(output);
PrintStream err = Mockito.mock(PrintStream.class);
System.setErr(err);
EasyLogger logger = new EasyLogger(EasyLoggerTest.class);
EasyLogger logger = new EasyLogger(EasyLoggerTest.class) {
@Override
protected void logger(LogLevel level, String message, Throwable e) {
SystemOutWriter.INSTANCE.write(format(level, message, e));
}
};
Assert.assertTrue(logger.isDebugEnable());
Assert.assertTrue(logger.isInfoEnable());
......@@ -67,7 +73,7 @@ public class EasyLoggerTest {
logger.error(new NullPointerException(), "hello {}", "world");
Mockito.verify(output, times(9))
.println(anyString());
.println(anyString());
}
@Test
......@@ -76,7 +82,12 @@ public class EasyLoggerTest {
System.setOut(output);
PrintStream err = Mockito.mock(PrintStream.class);
System.setErr(err);
EasyLogger logger = new EasyLogger(EasyLoggerTest.class);
EasyLogger logger = new EasyLogger(EasyLoggerTest.class) {
@Override
protected void logger(LogLevel level, String message, Throwable e) {
SystemOutWriter.INSTANCE.write(format(level, message, e));
}
};
Assert.assertTrue(logger.isDebugEnable());
Assert.assertTrue(logger.isInfoEnable());
......@@ -95,7 +106,7 @@ public class EasyLoggerTest {
logger.error(new NullPointerException(), "hello {}", "&&&**%%");
Mockito.verify(output, times(9))
.println(anyString());
.println(anyString());
}
@Test
......@@ -105,7 +116,7 @@ public class EasyLoggerTest {
String formatLines = logger.format(exception);
String[] lines = formatLines.split(Constants.LINE_SEPARATOR);
Assert.assertEquals("java.lang.NullPointerException", lines[1]);
Assert.assertEquals("\tat org.skywalking.apm.agent.core.logging.EasyLoggerTest.testFormat(EasyLoggerTest.java:103)", lines[2]);
Assert.assertEquals("\tat org.skywalking.apm.agent.core.logging.core.EasyLoggerTest.testFormat(EasyLoggerTest.java:114)", lines[2]);
}
@AfterClass
......
......@@ -16,16 +16,17 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.logging;
package org.skywalking.apm.agent.core.logging.core;
import java.io.File;
import java.io.IOException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.conf.Constants;
import java.io.File;
import java.io.IOException;
/**
* @author wusheng
*/
......
......@@ -16,14 +16,15 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.logging;
package org.skywalking.apm.agent.core.logging.core;
import java.io.PrintStream;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
import java.io.PrintStream;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.times;
......
......@@ -19,11 +19,11 @@
package org.skywalking.apm.agent.core.remote;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import java.io.IOException;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.*;
import org.skywalking.apm.agent.core.boot.ServiceManager;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig;
import org.skywalking.apm.agent.core.test.tools.AgentServiceRule;
......@@ -44,32 +44,37 @@ public class DiscoveryRestServiceClientTest {
@Rule
public WireMockRule wireMockRule = new WireMockRule(8089);
@AfterClass
public static void afterClass() {
ServiceManager.INSTANCE.shutdown();
}
@Before
public void setUpBeforeClass() {
Config.Collector.DISCOVERY_CHECK_INTERVAL = 1;
stubFor(get(urlEqualTo("/withoutResult"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("[]")));
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("[]")));
stubFor(get(urlEqualTo("/withResult"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("['127.0.0.1:8080','127.0.0.1:8090']")));
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("['127.0.0.1:8080','127.0.0.1:8090']")));
stubFor(get(urlEqualTo("/withSameResult"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("['127.0.0.1:8090','127.0.0.1:8080']")));
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("['127.0.0.1:8090','127.0.0.1:8080']")));
stubFor(get(urlEqualTo("/withDifferenceResult"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("['127.0.0.1:9090','127.0.0.1:18090']")));
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("['127.0.0.1:9090','127.0.0.1:18090']")));
stubFor(get(urlEqualTo("/with404"))
.willReturn(aResponse()
.withStatus(400)));
.willReturn(aResponse()
.withStatus(400)));
}
@Test
......
......@@ -21,12 +21,11 @@ package org.skywalking.apm.agent.core.remote;
import com.google.protobuf.InvalidProtocolBufferException;
import io.grpc.stub.StreamObserver;
import io.grpc.testing.GrpcServerRule;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.*;
import org.junit.runner.RunWith;
import org.powermock.reflect.Whitebox;
import org.skywalking.apm.agent.core.boot.ServiceManager;
......@@ -94,13 +93,18 @@ public class TraceSegmentServiceClientTest {
RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID = 1;
}
@AfterClass
public static void afterClass() {
ServiceManager.INSTANCE.shutdown();
}
@Before
public void setUp() throws Throwable {
Whitebox.setInternalState(ServiceManager.INSTANCE.findService(GRPCChannelManager.class), "reconnect", false);
spy(serviceClient);
Whitebox.setInternalState(serviceClient, "serviceStub",
TraceSegmentServiceGrpc.newStub(grpcServerRule.getChannel()));
TraceSegmentServiceGrpc.newStub(grpcServerRule.getChannel()));
Whitebox.setInternalState(serviceClient, "status", GRPCChannelStatus.CONNECTED);
upstreamSegments = new ArrayList<UpstreamSegment>();
......
agent.application_code = crmApp
collector.servers = 127.0.0.1: 8080
collector.servers = 127.0.0.1:8080
logging.level=info
......@@ -35,8 +35,6 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<premain.class>org.skywalking.apm.agent.SkyWalkingAgent</premain.class>
<shade.package>org.skywalking.apm.dependencies</shade.package>
<shade.net.bytebuddy.source>net.bytebuddy</shade.net.bytebuddy.source>
<shade.net.bytebuddy.target>${shade.package}.${shade.net.bytebuddy.source}</shade.net.bytebuddy.target>
</properties>
......@@ -45,152 +43,7 @@
<!-- plugin -->
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-jedis-2.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-jdbc-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-httpClient-4.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-dubbo-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>tomcat-7.x-8.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>motan-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-mongodb-3.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-resin-3.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-resin-4.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-okhttp-3.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-feign-default-http-9.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-resttemplate-4.3.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-spring-concurrent-util-4.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-springmvc-annotation-4.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-spring-cloud-feign-1.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-struts2-2.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-nutz-mvc-annotation-1.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-nutz-http-1.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-jetty-client-9.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-jetty-server-9.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-spymemcached-2.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-sharding-jdbc-1.5.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-xmemcached-2.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-grpc-1.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<!-- activation -->
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-toolkit-log4j-1.x-activation</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-toolkit-log4j-2.x-activation</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x-activation</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-toolkit-opentracing-activation</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-toolkit-trace-activation</artifactId>
<artifactId>apm-agent-core</artifactId>
<version>${project.version}</version>
</dependency>
......@@ -214,10 +67,6 @@
<createSourcesJar>true</createSourcesJar>
<shadeSourcesContent>true</shadeSourcesContent>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>skywalking-plugin.def</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
......@@ -259,9 +108,13 @@
</goals>
<configuration>
<tasks>
<mkdir dir="${project.basedir}/../../packages"/>
<mkdir dir="${project.basedir}/../../packages/skywalking-agent"/>
<copy file="${project.build.directory}/skywalking-agent.jar"
tofile="${project.basedir}/../../packages/skywalking-agent.jar" overwrite="true"/>
tofile="${project.basedir}/../../packages/skywalking-agent/skywalking-agent.jar" overwrite="true"/>
<mkdir dir="${project.basedir}/../../packages/skywalking-agent/config"/>
<mkdir dir="${project.basedir}/../../packages/skywalking-agent/logs"/>
<copydir src="${project.basedir}/../config"
dest="${project.basedir}/../../packages/skywalking-agent/config" forceoverwrite="true"/>
</tasks>
</configuration>
</execution>
......
......@@ -18,22 +18,18 @@
package org.skywalking.apm.agent;
import java.lang.instrument.Instrumentation;
import java.util.List;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.utility.JavaModule;
import org.skywalking.apm.agent.core.boot.ServiceManager;
import org.skywalking.apm.agent.core.conf.SnifferConfigInitializer;
import org.skywalking.apm.agent.core.logging.EasyLogResolver;
import org.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine;
import org.skywalking.apm.agent.core.plugin.EnhanceContext;
import org.skywalking.apm.agent.core.plugin.PluginBootstrap;
import org.skywalking.apm.agent.core.plugin.PluginException;
import org.skywalking.apm.agent.core.plugin.PluginFinder;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
import org.skywalking.apm.agent.core.plugin.*;
import java.lang.instrument.Instrumentation;
import java.util.List;
/**
* The main entrance of sky-waking agent,
......@@ -42,12 +38,7 @@ import org.skywalking.apm.logging.LogManager;
* @author wusheng
*/
public class SkyWalkingAgent {
private static final ILog logger;
static {
LogManager.setLogResolver(new EasyLogResolver());
logger = LogManager.getLogger(SkyWalkingAgent.class);
}
private static final ILog logger = LogManager.getLogger(SkyWalkingAgent.class);
/**
* Main entrance.
......@@ -58,11 +49,17 @@ public class SkyWalkingAgent {
* @throws PluginException
*/
public static void premain(String agentArgs, Instrumentation instrumentation) throws PluginException {
SnifferConfigInitializer.initialize();
final PluginFinder pluginFinder;
try {
SnifferConfigInitializer.initialize();
final PluginFinder pluginFinder = new PluginFinder(new PluginBootstrap().loadPlugins());
pluginFinder = new PluginFinder(new PluginBootstrap().loadPlugins());
ServiceManager.INSTANCE.boot();
ServiceManager.INSTANCE.boot();
} catch (Exception e) {
logger.error(e, "Skywalking agent initialized failure. Shutting down.");
return;
}
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override public void run() {
......
......@@ -36,4 +36,9 @@
<name>jetty-plugin</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<sdk.plugin.related.dir>/..</sdk.plugin.related.dir>
</properties>
</project>
......@@ -40,6 +40,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<sdk.plugin.related.dir>/..</sdk.plugin.related.dir>
</properties>
</project>
......@@ -56,6 +56,9 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<sdk.plugin.related.dir></sdk.plugin.related.dir>
<shade.net.bytebuddy.source>net.bytebuddy</shade.net.bytebuddy.source>
<shade.net.bytebuddy.target>${shade.package}.${shade.net.bytebuddy.source}</shade.net.bytebuddy.target>
</properties>
<dependencies>
......@@ -63,6 +66,13 @@
<groupId>org.skywalking</groupId>
<artifactId>apm-agent-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-util</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
......@@ -74,6 +84,44 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<createDependencyReducedPom>true</createDependencyReducedPom>
<createSourcesJar>true</createSourcesJar>
<shadeSourcesContent>true</shadeSourcesContent>
<artifactSet>
<excludes>
<exclude>com.lmax:*</exclude>
<exclude>org.apache.httpcomponents:*</exclude>
<exclude>commons-logging:*</exclude>
<exclude>commons-codec:*</exclude>
<exclude>*:gson</exclude>
<exclude>io.grpc:*</exclude>
<exclude>io.netty:*</exclude>
<exclude>com.google.*:*</exclude>
<exclude>com.google.guava:guava</exclude>
</excludes>
</artifactSet>
<relocations>
<relocation>
<pattern>${shade.net.bytebuddy.source}</pattern>
<shadedPattern>${shade.net.bytebuddy.target}</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
......@@ -96,6 +144,51 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<taskdef resource="net/sf/antcontrib/antcontrib.properties"
classpathref="maven.runtime.classpath"/>
<if>
<equals arg1="${project.packaging}" arg2="jar"/>
<then>
<mkdir dir="${project.build.directory}${sdk.plugin.related.dir}/../../../../packages/skywalking-agent/plugins"/>
<copy file="${project.build.directory}/${project.artifactId}-${project.version}.jar"
tofile="${project.build.directory}${sdk.plugin.related.dir}/../../../../packages/skywalking-agent/plugins/${project.artifactId}-${project.version}.jar" overwrite="true"/>
</then>
</if>
</tasks>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b3</version>
<exclusions>
<exclusion>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.8.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
......@@ -35,8 +35,8 @@ import org.skywalking.apm.network.trace.component.ComponentsDefine;
import org.skywalking.apm.plugin.sjdbc.define.AsyncExecuteInterceptor;
/**
* Sharding-jdbc provides {@link EventBusInstance} to help external systems get events of sql execution.
* {@link ExecuteEventListener} can get sql statement start and end events, resulting in db span.
* Sharding-jdbc provides {@link EventBusInstance} to help external systems getDefault events of sql execution.
* {@link ExecuteEventListener} can getDefault sql statement start and end events, resulting in db span.
*
* @author gaohongtao
*/
......
......@@ -36,13 +36,13 @@
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.10.RELEASE</version>
<scope>provided</scope>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.8.RELEASE</version>
<scope>provided</scope>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
......
......@@ -41,6 +41,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<sdk.plugin.related.dir>/..</sdk.plugin.related.dir>
</properties>
</project>
......@@ -32,7 +32,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
/**
* {@link ResponseExtractorFutureInstrumentation} enhance the <code>addCallback</code> method and <code>get</code>
* {@link ResponseExtractorFutureInstrumentation} enhance the <code>addCallback</code> method and <code>getDefault</code>
* method of <code>org.springframework.web.client.AsyncRestTemplate$ResponseExtractorFuture</code> by
* <code>org.skywalking.apm.plugin.spring.resttemplate.async.ResponseCallBackInterceptor</code> and
* <code>org.skywalking.apm.plugin.spring.resttemplate.async.FutureGetInterceptor</code>.
......
......@@ -38,6 +38,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<sdk.plugin.related.dir>/../../..</sdk.plugin.related.dir>
</properties>
</project>
......@@ -38,6 +38,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<sdk.plugin.related.dir>/../..</sdk.plugin.related.dir>
</properties>
</project>
......@@ -33,7 +33,7 @@ import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
/**
* {@link MemcachedInstrumentation} presents that skywalking intercept all constructors and methods of
* {@link net.spy.memcached.MemcachedClient}.
* {@link XMemcachedConstructorWithInetSocketAddressListArgInterceptor} intercepts the constructor with
* <code>org.skywalking.apm.plugin.spymemcached.v2.MemcachedConstructorWithInetSocketAddressListArgInterceptor</code> intercepts the constructor with
* argument {@link java.net.InetSocketAddress}.
*
* @author IluckySi
......
......@@ -23,10 +23,12 @@ import java.util.LinkedList;
import org.junit.rules.ExternalResource;
import org.skywalking.apm.agent.core.boot.BootService;
import org.skywalking.apm.agent.core.boot.ServiceManager;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig;
import org.skywalking.apm.agent.core.context.IgnoredTracerContext;
import org.skywalking.apm.agent.core.context.TracingContext;
import org.skywalking.apm.agent.core.context.TracingContextListener;
import org.skywalking.apm.agent.core.logging.core.LogLevel;
import org.skywalking.apm.agent.test.helper.FieldSetter;
public class AgentServiceRule extends ExternalResource {
......@@ -38,6 +40,7 @@ public class AgentServiceRule extends ExternalResource {
FieldSetter.setValue(ServiceManager.INSTANCE.getClass(), "bootedServices", new HashMap<Class, BootService>());
FieldSetter.setValue(IgnoredTracerContext.ListenerManager.class, "LISTENERS", new LinkedList<TracingContextListener>());
FieldSetter.setValue(TracingContext.ListenerManager.class, "LISTENERS", new LinkedList<TracingContextListener>());
ServiceManager.INSTANCE.shutdown();
} catch (Exception e) {
}
}
......@@ -45,6 +48,7 @@ public class AgentServiceRule extends ExternalResource {
@Override
protected void before() throws Throwable {
super.before();
Config.Logging.LEVEL = LogLevel.OFF;
ServiceManager.INSTANCE.boot();
RemoteDownstreamConfig.Agent.APPLICATION_ID = 1;
RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID = 1;
......
......@@ -22,8 +22,8 @@ import java.lang.reflect.Method;
import org.skywalking.apm.agent.core.context.ContextManager;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;
public class TraceContextInterceptor implements StaticMethodsAroundInterceptor {
......@@ -43,6 +43,6 @@ public class TraceContextInterceptor implements StaticMethodsAroundInterceptor {
@Override
public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
Throwable t) {
logger.error("Failed to get trace Id.", t);
logger.error("Failed to getDefault trace Id.", t);
}
}
......@@ -37,16 +37,118 @@
<artifactId>apm-toolkit-activation</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<shade.net.bytebuddy.source>net.bytebuddy</shade.net.bytebuddy.source>
<shade.net.bytebuddy.target>${shade.package}.${shade.net.bytebuddy.source}</shade.net.bytebuddy.target>
</properties>
<dependencies>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-agent-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-util</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-test-tools</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<createDependencyReducedPom>true</createDependencyReducedPom>
<createSourcesJar>true</createSourcesJar>
<shadeSourcesContent>true</shadeSourcesContent>
<artifactSet>
<excludes>
<exclude>com.lmax:*</exclude>
<exclude>org.apache.httpcomponents:*</exclude>
<exclude>commons-logging:*</exclude>
<exclude>commons-codec:*</exclude>
<exclude>*:gson</exclude>
<exclude>io.grpc:*</exclude>
<exclude>io.netty:*</exclude>
<exclude>com.google.*:*</exclude>
<exclude>com.google.guava:guava</exclude>
</excludes>
</artifactSet>
<relocations>
<relocation>
<pattern>${shade.net.bytebuddy.source}</pattern>
<shadedPattern>${shade.net.bytebuddy.target}</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<taskdef resource="net/sf/antcontrib/antcontrib.properties"
classpathref="maven.runtime.classpath"/>
<if>
<equals arg1="${project.packaging}" arg2="jar"/>
<then>
<mkdir dir="${project.build.directory}/../../../../packages/skywalking-agent/plugins"/>
<copy file="${project.build.directory}/${project.artifactId}-${project.version}.jar"
tofile="${project.build.directory}/../../../../packages/skywalking-agent/activations/${project.artifactId}-${project.version}.jar" overwrite="true"/>
</then>
</if>
</tasks>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b3</version>
<exclusions>
<exclusion>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.8.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
# The application name in UI
agent.application_code=Your_ApplicationName
# The number of sampled traces per 3 seconds
# Negative number means sample traces as many as possible, most likely 100%
# agent.sample_n_per_3_secs=-1
# Ignore the segments if their operation names start with these suffix.
# agent.ignore_suffix=.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg
# Server addresses.
# Mapping to `agent_server/jetty/port` in `config/application.yml` of Collector.
# Examples:
# Single collector:SERVERS="127.0.0.1:8080"
# Collector cluster:SERVERS="10.2.45.126:8080,10.2.45.127:7600"
collector.servers=127.0.0.1:10800
# Logging level
logging.level=DEBUG
......@@ -40,13 +40,6 @@
<properties>
<compiler.version>1.6</compiler.version>
<shade.package>org.skywalking.apm.dependencies</shade.package>
</properties>
<dependencies>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-util</artifactId>
<version>3.2.3-2017</version>
</dependency>
</dependencies>
</project>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册