APM - 零侵入监控Http服务
生活随笔
收集整理的這篇文章主要介紹了
APM - 零侵入监控Http服务
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
文章目錄
- Pre
- HTTP采集入口
- Code
Pre
APM - 零侵入監(jiān)控Service服務(wù)
HTTP采集入口
很顯然第三種更具有通用性,不管是DispacherServlet 還是@Control 都會是基于HttpServlet#service
Code
package com.artisan.collects;import com.artisan.ApmContext; import com.artisan.intf.ICollect; import com.artisan.model.HttpStatistics; import javassist.*;import java.lang.instrument.Instrumentation; import java.lang.reflect.Method; import java.util.Map;/*** Http采集器*/ public class HttpCollect extends AbstractByteTransformCollect implements ICollect {// 采集目標(biāo)// 1.DispatchServlet// 2.@control 下的方法// 3.采集 javax.servlet.service() ---- 采用這種通用的方式private static final String TARGET_CLASS = "javax.servlet.http.HttpServlet";private static final String TARGET_METHOD = "service";private static ApmContext context;public HttpCollect(ApmContext context, Instrumentation instrumentation) {super(instrumentation);this.context = context;}public byte[] buildClass(ClassLoader loader) throws Exception {ClassPool pool = new ClassPool();pool.insertClassPath(new LoaderClassPath(loader));CtClass ctClass = pool.get(TARGET_CLASS);CtMethod oldMethod = ctClass.getDeclaredMethod(TARGET_METHOD);CtMethod newMethod = CtNewMethod.copy(oldMethod, ctClass, null);oldMethod.setName(oldMethod.getName() + "$agent");//HttpServlet.service()'String beginSrc = "Object stat=com.artisan.collects.HttpCollect.begin($args);";String errorSrc = "com.artisan.collects.HttpCollect.error(e,stat);";String endSrc = "com.artisan.collects.HttpCollect.end(stat);";newMethod.setBody(String.format(voidSource, beginSrc, TARGET_METHOD, errorSrc, endSrc));ctClass.addMethod(newMethod);return ctClass.toBytecode();}// url,client IPpublic static HttpStatistics begin(Object args[]) {HttpStatistics httpStatistics = new HttpStatistics();httpStatistics.setBeginTime(System.currentTimeMillis());// 采用適配器的方式 ,避免在tomcat下 agent【appLauncher裝載】無法獲取到HttpServletRequest【common加載】(classLoader機(jī)制)HttpServletRequestAdapter adapter = new HttpServletRequestAdapter(args[0]);httpStatistics.setUrl(adapter.getRequestURI());httpStatistics.setClientIp(adapter.getClientIp());return httpStatistics;}public static void end(Object obj) {HttpStatistics stat = (HttpStatistics) obj;((HttpStatistics) obj).setUseTime(System.currentTimeMillis() - stat.getBeginTime());context.submitCollectResult(stat);}public static void error(Throwable error, Object obj) {HttpStatistics stat = (HttpStatistics) obj;stat.setError(error.getMessage());System.out.println(stat);}final static String voidSource = "{\n"+ "%s"+ " try {\n"+ " %s$agent($$);\n"+ " } catch (Throwable e) {\n"+ "%s"+ " throw e;\n"+ " }finally{\n"+ "%s"+ " }\n"+ "}\n";@Overridepublic byte[] transform(ClassLoader loader, String className) throws Exception {if (!TARGET_CLASS.equals(className)) {return null;}try {return buildClass(loader);} catch (Exception e) {e.printStackTrace();}return null;}private static class HttpServletRequestAdapter {private final Object target;private final Method _getRequestURI;private final Method _getRequestURL;private final Method _getParameterMap;private final Method _getMethod;private final Method _getHeader;private final Method _getRemoteAddr;private final static String targetClassName = "javax.servlet.http.HttpServletRequest";public HttpServletRequestAdapter(Object target) {this.target = target;try {Class<?> targetClass = target.getClass().getClassLoader().loadClass(targetClassName);_getRequestURI = targetClass.getMethod("getRequestURI");_getParameterMap = targetClass.getMethod("getParameterMap");_getMethod = targetClass.getMethod("getMethod");_getHeader = targetClass.getMethod("getHeader", String.class);_getRemoteAddr = targetClass.getMethod("getRemoteAddr");_getRequestURL = targetClass.getMethod("getRequestURL");} catch (NoSuchMethodException e) {throw new IllegalArgumentException("error :" + e.getMessage() + ". probable cause the target is not belong javax.servlet.http.HttpServletRequest ");} catch (ClassNotFoundException e) {throw new IllegalArgumentException("error :" + e.getMessage() + ". probable cause the target is not belong javax.servlet.http.HttpServletRequest ");}}public String getRequestURI() {try {return (String) _getRequestURI.invoke(target);} catch (Exception e) {throw new RuntimeException(e);}}public String getRequestURL() {try {return _getRequestURL.invoke(target).toString();} catch (Exception e) {throw new RuntimeException(e);}}public Map<String, String[]> getParameterMap() {try {return (Map<String, String[]>) _getParameterMap.invoke(target);} catch (Exception e) {throw new RuntimeException(e);}}public String getMethod() {try {return (String) _getMethod.invoke(target);} catch (Exception e) {throw new RuntimeException(e);}}public String getHeader(String name) {try {return (String) _getHeader.invoke(target, name);} catch (Exception e) {throw new RuntimeException(e);}}public String getRemoteAddr() {try {return (String) _getRemoteAddr.invoke(target);} catch (Exception e) {throw new RuntimeException(e);}}public String getClientIp() {String ip = getHeader("x-forwarded-for");if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = getHeader("Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = getHeader("WL-Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = getRemoteAddr();}return ip;}} }總結(jié)
以上是生活随笔為你收集整理的APM - 零侵入监控Http服务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: APM - 零侵入监控Service服务
- 下一篇: APM - 零侵入监控JDBC服务