日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

APM - 零侵入监控Http服务

發(fā)布時(shí)間:2025/3/21 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 APM - 零侵入监控Http服务 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • Pre
  • HTTP采集入口
  • Code


Pre

APM - 零侵入監(jiān)控Service服務(wù)


HTTP采集入口

  • DispacherServlet .doServer() ?
  • @Control ?
  • javax.servlet.http.HttpServlet ?
  • 很顯然第三種更具有通用性,不管是DispacherServlet 還是@Control 都會(huì)是基于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裝載】無(wú)法獲取到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服务的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。