mirror of
https://github.com/wahyd4/pinpoint.git
synced 2026-08-21 18:56:11 +10:00
[강운덕] [LUCYSUS-1744] agent의 classLoader에서 slf4j logger를 로드하는 코드 개발.
git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-tomcat-profiler/trunk@1369 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
package com.profiler;
|
||||
|
||||
import com.profiler.logging.LoggerBinder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -13,6 +17,7 @@ public class AgentClassLoader {
|
||||
private URLClassLoader classLoader;
|
||||
private String bootClass = "com.profiler.AgentBootStrap";
|
||||
private String bootMethod = "boot";
|
||||
private Object agentBootStrap;
|
||||
|
||||
public AgentClassLoader(URL[] urls) {
|
||||
ClassLoader classLoader = AgentClassLoader.class.getClassLoader();
|
||||
@@ -26,34 +31,69 @@ public class AgentClassLoader {
|
||||
public void setBootMethod(String bootMethod) {
|
||||
this.bootMethod = bootMethod;
|
||||
}
|
||||
public void test() {
|
||||
URL resource = this.classLoader.getResource("/log4j.xml");
|
||||
System.out.println("log4j.xml=" + resource);
|
||||
URL resource1 = this.classLoader.getResource("/nhn_source/hippo_project/deploy/agent/agentlib/lib/log4j.xml");
|
||||
System.out.println("log4j.xml=" + resource1);
|
||||
|
||||
URL[] aaa = this.classLoader.getURLs();
|
||||
for (URL url : aaa) {
|
||||
System.out.println("" + url);
|
||||
}
|
||||
|
||||
URL resource2 = classLoader.getResource(".");
|
||||
System.out.println("resource2:" + resource2);
|
||||
try {
|
||||
Enumeration<URL> resources = this.classLoader.getResources(".");
|
||||
while (resources.hasMoreElements()) {
|
||||
URL url = resources.nextElement();
|
||||
System.out.println("" + url);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void boot() {
|
||||
try{
|
||||
Class<?> bootStrap = this.classLoader.loadClass(bootClass);
|
||||
Object agentBootStrap = bootStrap.newInstance();
|
||||
|
||||
Method bootMethod = bootStrap.getDeclaredMethod(this.bootMethod);
|
||||
|
||||
Thread currentThread = Thread.currentThread();
|
||||
ClassLoader before = currentThread.getContextClassLoader();
|
||||
currentThread.setContextClassLoader(this.classLoader);
|
||||
try {
|
||||
bootMethod.invoke(agentBootStrap);
|
||||
} finally {
|
||||
currentThread.setContextClassLoader(before);
|
||||
}
|
||||
agentBootStrap = bootStrap.newInstance();
|
||||
invoke(bootStrap, this.bootMethod);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException("boot class not found. Caused:" + e.getMessage(), e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException("boot method not found. Caused:" + e.getMessage(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(this.bootMethod + "() fail. Caused:" + e.getMessage(), e);
|
||||
} catch (InstantiationException e) {
|
||||
throw new RuntimeException("boot create fail. Caused:" + e.getMessage(), e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("boot method invoke fail. Caused:" + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private Object invoke(Class<?> clazz, String method) {
|
||||
Method bootMethod = null;
|
||||
try {
|
||||
bootMethod = clazz.getDeclaredMethod(method);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException("boot method not found. Caused:" + e.getMessage(), e);
|
||||
}
|
||||
|
||||
final Thread currentThread = Thread.currentThread();
|
||||
ClassLoader before = currentThread.getContextClassLoader();
|
||||
currentThread.setContextClassLoader(this.classLoader);
|
||||
try {
|
||||
return bootMethod.invoke(agentBootStrap);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(this.bootMethod + "() fail. Caused:" + e.getMessage(), e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("boot method invoke fail. Caused:" + e.getMessage(), e);
|
||||
}
|
||||
finally {
|
||||
currentThread.setContextClassLoader(before);
|
||||
}
|
||||
}
|
||||
|
||||
public LoggerBinder initializeLoggerBinder() {
|
||||
return (LoggerBinder) invoke(agentBootStrap.getClass(), "initializeLoggerBinder");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,15 +29,25 @@ public class ClassPathResolver {
|
||||
private String agentJarFullPath;
|
||||
private String agentDirPath;
|
||||
private Pattern agentPattern;
|
||||
private List<String> fileExtensionList;
|
||||
|
||||
public ClassPathResolver() {
|
||||
this.classPath = getClassPathFromSystemProperty();
|
||||
this.agentPattern = DEFAULT_AGENT_PATTERN;
|
||||
this(getClassPathFromSystemProperty());
|
||||
}
|
||||
|
||||
|
||||
public ClassPathResolver(String classPath) {
|
||||
this.classPath = classPath;
|
||||
this.agentPattern = DEFAULT_AGENT_PATTERN;
|
||||
this.fileExtensionList = getDefaultFileExtensionList();
|
||||
}
|
||||
|
||||
public List<String> getDefaultFileExtensionList() {
|
||||
List<String> extensionList = new ArrayList<String>();
|
||||
extensionList.add("jar");
|
||||
extensionList.add("xml");
|
||||
extensionList.add("properties");
|
||||
return extensionList;
|
||||
}
|
||||
|
||||
public ClassPathResolver(String classPath, String agentPattern) {
|
||||
@@ -53,7 +63,7 @@ public class ClassPathResolver {
|
||||
this.classPath = getClassPathFromSystemProperty();
|
||||
}
|
||||
|
||||
public String getClassPathFromSystemProperty() {
|
||||
public static String getClassPathFromSystemProperty() {
|
||||
return System.getProperty("java.class.path");
|
||||
}
|
||||
|
||||
@@ -119,6 +129,9 @@ public class ClassPathResolver {
|
||||
jarURLList.add(url);
|
||||
}
|
||||
}
|
||||
// agentDir 패스도 넣어야 xml을 찾을 때 해당 패스에서 찾음.
|
||||
URL agentDirUri = toURI(new File(agentLibPath));
|
||||
jarURLList.add(agentDirUri);
|
||||
|
||||
return jarURLList;
|
||||
}
|
||||
@@ -136,7 +149,13 @@ public class ClassPathResolver {
|
||||
return libDir.listFiles(new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
return pathname.getName().lastIndexOf(".jar") != -1;
|
||||
String path = pathname.getName();
|
||||
for (String extension : fileExtensionList) {
|
||||
if (path.lastIndexOf("." + extension) != -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import java.util.logging.Logger;
|
||||
|
||||
import com.profiler.common.ServiceType;
|
||||
import com.profiler.config.ProfilerConfig;
|
||||
import com.profiler.logging.LoggerBinder;
|
||||
import com.profiler.logging.LoggerFactory;
|
||||
import com.profiler.interceptor.bci.ByteCodeInstrumentor;
|
||||
import com.profiler.interceptor.bci.JavaAssistByteCodeInstrumentor;
|
||||
import com.profiler.modifier.DefaultModifierRegistry;
|
||||
@@ -53,11 +55,16 @@ public class TomcatProfiler implements ClassFileTransformer {
|
||||
List<URL> libUrlList = resolveLib(classPathResolver);
|
||||
AgentClassLoader agentClassLoader = new AgentClassLoader(libUrlList.toArray(new URL[libUrlList.size()]));
|
||||
agentClassLoader.setBootClass("com.profiler.boot.BootClassTest");
|
||||
// agentClassLoader.test();
|
||||
try {
|
||||
agentClassLoader.boot();
|
||||
LoggerBinder loggerBinder = agentClassLoader.initializeLoggerBinder();
|
||||
loggerBinder.getLogger("LoggerFactory initialize start");
|
||||
LoggerFactory.initialize(loggerBinder);
|
||||
com.profiler.logging.Logger tomcatLogger = LoggerFactory.getLogger(TomcatProfiler.class);
|
||||
tomcatLogger.info("LoggerFactory initialize end");
|
||||
} catch (Exception e) {
|
||||
logger.info("test error");
|
||||
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
|
||||
logger.log(Level.INFO, "boot class not found", e);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -86,7 +93,7 @@ public class TomcatProfiler implements ClassFileTransformer {
|
||||
return profilerConfig;
|
||||
}
|
||||
|
||||
private static List<URL> resolveLib(ClassPathResolver classPathResolver) {
|
||||
private static List<URL> resolveLib(ClassPathResolver classPathResolver) {
|
||||
String agentJarFullPath = classPathResolver.getAgentJarFullPath();
|
||||
logger.info("agentJarPath:" + agentJarFullPath);
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.profiler.logging;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface Logger {
|
||||
|
||||
public void info(String msg);
|
||||
|
||||
|
||||
public void info(String format, Object arg);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.profiler.logging;
|
||||
|
||||
import com.profiler.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface LoggerBinder {
|
||||
Logger getLogger(String name);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.profiler.logging;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public final class LoggerFactory {
|
||||
|
||||
private static LoggerBinder loggerBinder;
|
||||
|
||||
public static void initialize(LoggerBinder loggerBinder) {
|
||||
if (LoggerFactory.loggerBinder == null) {
|
||||
System.out.println("set logger binder-------------");
|
||||
LoggerFactory.loggerBinder = loggerBinder;
|
||||
}
|
||||
}
|
||||
|
||||
public static Logger getLogger(String name) {
|
||||
return loggerBinder.getLogger(name);
|
||||
}
|
||||
|
||||
public static Logger getLogger(Class name) {
|
||||
return getLogger(name.getName());
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import java.net.InetSocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -45,7 +44,6 @@ public class UdpDataSender implements DataSender, Runnable {
|
||||
private HeaderTBaseSerializer serializer = new HeaderTBaseSerializer();
|
||||
|
||||
private AtomicBoolean allowInput = new AtomicBoolean();
|
||||
private CountDownLatch shutdownLatch = new CountDownLatch(1);
|
||||
|
||||
public UdpDataSender(String host, int port) {
|
||||
Assert.notNull(host, "host must not be null");
|
||||
@@ -115,8 +113,9 @@ public class UdpDataSender implements DataSender, Runnable {
|
||||
}
|
||||
|
||||
try {
|
||||
shutdownLatch.await(5, TimeUnit.SECONDS);
|
||||
ioThread.join(5000);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
logger.info("UdpDataSender stopped incompletely.");
|
||||
}
|
||||
|
||||
@@ -132,7 +131,6 @@ public class UdpDataSender implements DataSender, Runnable {
|
||||
drain: while (true) {
|
||||
try {
|
||||
if (!allowInput.get() && isEmpty()) {
|
||||
shutdownLatch.countDown();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -144,7 +142,6 @@ public class UdpDataSender implements DataSender, Runnable {
|
||||
|
||||
while (true) {
|
||||
if (!allowInput.get() && isEmpty()) {
|
||||
shutdownLatch.countDown();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -155,7 +152,7 @@ public class UdpDataSender implements DataSender, Runnable {
|
||||
}
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
logger.log(Level.WARNING, "Unexpected Error Cause:" + th.getMessage(), th);
|
||||
logger.log(Level.WARNING, "Unexpected Error. Cause:" + th.getMessage(), th);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,7 +162,7 @@ public class UdpDataSender implements DataSender, Runnable {
|
||||
try {
|
||||
sendPacket(dto);
|
||||
} catch (Throwable th) {
|
||||
logger.log(Level.WARNING, "Unexpected Error Cause:" + th.getMessage(), th);
|
||||
logger.log(Level.WARNING, "Unexpected Error. Cause:" + th.getMessage(), th);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user