提交 83f8714f 编写于 作者: wu-sheng's avatar wu-sheng

Finish the prototype codes.

上级 d8e21adc
......@@ -42,16 +42,13 @@ public class SnifferConfigInitializer {
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 #overrideConfigBySystemEnv()}
* 2. class path.
* 3. Path, where agent is. {@link #loadConfigFromAgentFolder()}
* <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:
* <p>
* 1. applicationCode. "-DapplicationCode=" or {@link Config.Agent#APPLICATION_CODE}
* 2. servers. "-Dservers=" or {@link Config.Collector#SERVERS}
* Try to locate `agent.config`, which should be in the /config dictionary of agent package.
*
* 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.
*
* At the end, `agent.application_code` and `collector.servers` must be not blank.
*/
public static void initialize() throws ConfigNotFoundException, AgentPackageNotFoundException {
InputStream configFileStream;
......
......@@ -22,8 +22,7 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
import org.skywalking.apm.agent.core.boot.AgentPackagePath;
import org.skywalking.apm.agent.core.plugin.loader.PluginClassLoader;
import org.skywalking.apm.agent.core.plugin.loader.AgentClassLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
......@@ -43,7 +42,7 @@ public class PluginBootstrap {
* @return plugin definition list.
*/
public List<AbstractClassEnhancePluginDefine> loadPlugins() throws AgentPackageNotFoundException {
PluginClassLoader.initAndGet(AgentPackagePath.getPath());
AgentClassLoader.initDefaultLoader();
PluginResourcesResolver resolver = new PluginResourcesResolver();
List<URL> resources = resolver.getResources();
......@@ -68,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());
......
......@@ -23,6 +23,7 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import org.skywalking.apm.agent.core.plugin.loader.AgentClassLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
......@@ -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.
*/
......
......@@ -22,7 +22,7 @@ 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.agent.core.plugin.loader.InterceptorInstanceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
......
......@@ -26,7 +26,7 @@ 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.agent.core.plugin.loader.InterceptorInstanceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
......
......@@ -25,7 +25,7 @@ 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.agent.core.plugin.loader.InterceptorInstanceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
......
......@@ -24,7 +24,7 @@ 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.agent.core.plugin.loader.InterceptorInstanceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
......
......@@ -23,7 +23,7 @@ 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.agent.core.plugin.loader.InterceptorInstanceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
......
......@@ -18,64 +18,174 @@
package org.skywalking.apm.agent.core.plugin.loader;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
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;
import org.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
import org.skywalking.apm.agent.core.boot.AgentPackagePath;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
/**
* The <code>PluginClassLoader</code> represents a classloader,
* The <code>AgentClassLoader</code> represents a classloader,
* which is in charge of finding plugins and interceptors.
*
* @author wusheng
*/
public class PluginClassLoader extends ClassLoader {
private static final ILog logger = LogManager.getLogger(PluginClassLoader.class);
private static PluginClassLoader LOADER;
public class AgentClassLoader extends ClassLoader {
private static final ILog logger = LogManager.getLogger(AgentClassLoader.class);
private static AgentClassLoader LOADER;
private List<File> classpath;
private List<JarFile> allJars;
private List<Jar> allJars;
private ReentrantLock jarScanLock = new ReentrantLock();
private ReentrantLock loadClassLock = new ReentrantLock();
public static PluginClassLoader get() {
public static AgentClassLoader getDefault() {
return LOADER;
}
public static PluginClassLoader initAndGet(File agentDictionary) {
LOADER = new PluginClassLoader(agentDictionary);
return get();
public static AgentClassLoader initDefaultLoader() throws AgentPackageNotFoundException {
LOADER = new AgentClassLoader(AgentClassLoader.class.getClassLoader());
return getDefault();
}
private PluginClassLoader(File agentDictionary) {
super(PluginClassLoader.class.getClassLoader());
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"));
}
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
loadClassLock.lock();
try {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
super.loadClass(name, resolve);
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
} finally {
loadClassLock.unlock();
}
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
throw new ClassNotFoundException(name);
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() + "!/" + name);
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) {
getAllJars();
throw new RuntimeException("");
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;
}
private List<JarFile> getAllJars() {
@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<JarFile>();
allJars = new LinkedList<Jar>();
for (File path : classpath) {
if (path.exists() && path.isDirectory()) {
String[] jarFileNames = path.list(new FilenameFilter() {
......@@ -85,8 +195,10 @@ public class PluginClassLoader extends ClassLoader {
});
for (String fileName : jarFileNames) {
try {
JarFile jar = new JarFile(fileName);
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);
}
......@@ -101,4 +213,14 @@ public class PluginClassLoader extends ClassLoader {
return allJars;
}
private class Jar {
private JarFile jarFile;
private File sourceFile;
private Jar(JarFile jarFile, File sourceFile) {
this.jarFile = jarFile;
this.sourceFile = sourceFile;
}
}
}
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.agent.core.plugin.interceptor.loader;
package org.skywalking.apm.agent.core.plugin.loader;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
......@@ -24,8 +24,11 @@ import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.ProtectionDomain;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import org.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
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;
......@@ -53,7 +56,52 @@ public class InterceptorInstanceLoader {
private static ReentrantLock INSTANCE_LOAD_LOCK = new ReentrantLock();
private static Map<ClassLoader, ClassLoader> EXTEND_PLUGIN_CLASSLOADERS = new HashMap<ClassLoader, ClassLoader>();
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) {
if (InterceptorInstanceLoader.class.getClassLoader().equals(targetClassLoader)) {
inst = targetClassLoader.loadClass(className).newInstance();
} else {
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;
}
/**
* Old load method, just for backup
*
* @param className
* @param targetClassLoader
* @param <T>
* @return
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws ClassNotFoundException
*/
public static <T> T load0(String className, ClassLoader targetClassLoader)
throws InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException {
if (targetClassLoader == null) {
targetClassLoader = InterceptorInstanceLoader.class.getClassLoader();
......
/*
* 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;
/**
* @author wusheng
*/
public class NotImplementationException extends RuntimeException {
}
......@@ -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 = "";
......
......@@ -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) {
......
......@@ -39,7 +39,7 @@ public enum RedisMethodMatch {
.or(named("zrangeByScore")).or(named("smove")).or(named("lset"))
.or(named("decrBy")).or(named("pttl")).or(named("scan"))
.or(named("zrank")).or(named("blpop")).or(named("rpoplpush"))
.or(named("zremrangeByLex")).or(named("get")).or(named("lpop"))
.or(named("zremrangeByLex")).or(named("getDefault")).or(named("lpop"))
.or(named("persist")).or(named("scriptExists")).or(named("georadius"))
.or(named("set")).or(named("srandmember")).or(named("incr")).or(named("setbit"))
.or(named("hexists")).or(named("expireAt")).or(named("pexpire")).or(named("zcard"))
......
......@@ -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
*/
......
......@@ -32,7 +32,7 @@ public class FutureGetInterceptor implements InstanceMethodsAroundInterceptor {
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
Object[] cacheValues = (Object[])objInst.getSkyWalkingDynamicField();
ContextManager.createLocalSpan("future/get:" + ((URI)cacheValues[0]).getPath());
ContextManager.createLocalSpan("future/getDefault:" + ((URI)cacheValues[0]).getPath());
}
@Override
......
......@@ -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>.
......@@ -48,7 +48,7 @@ public class ResponseExtractorFutureInstrumentation extends ClassInstanceMethods
private static final String ADD_CALLBACK_INTERCEPTOR = "org.skywalking.apm.plugin.spring.resttemplate.async.ResponseCallBackInterceptor";
private static final String ENHANCE_CLASS = "org.springframework.web.client.AsyncRestTemplate$ResponseExtractorFuture";
private static final String GET_METHOD_INTERCEPTOR = "org.skywalking.apm.plugin.spring.resttemplate.async.FutureGetInterceptor";
private static final String GET_METHOD_NAME = "get";
private static final String GET_METHOD_NAME = "getDefault";
@Override
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
......
......@@ -75,7 +75,7 @@ public class MemcachedInstrumentation extends ClassInstanceMethodsEnhancePluginD
return named("touch").or(named("append")).or(named("prepend")).or(named("asyncCAS"))
.or(named("cas")).or(named("add")).or(named("set")).or(named("replace"))
.or(named("asyncGet")).or(named("asyncGets")).or(named("gets")).or(named("getAndTouch"))
.or(named("get")).or(named("asyncGetBulk")).or(named("asyncGetAndTouch"))
.or(named("getDefault")).or(named("asyncGetBulk")).or(named("asyncGetAndTouch"))
.or(named("getBulk")).or(named("getStats")).or(named("incr"))
.or(named("decr")).or(named("asyncIncr")).or(named("asyncDecr"))
.or(named("delete"));
......
......@@ -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);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册