[英]How to monitor method execution at third party library?
我有任务以某种方式监视 logback 库中的方法调用。 我开始用 spring aop 做这件事。 因此,例如,我应该在 ch.qos.logback.classic.Logger 类中捕获所有方法的执行。 这是我的方面:
@Aspect
@Configuration
public class LogbackAspect {
@Before(value = "execution(* ch.qos.logback.classic.Logger.*(..))")
public void getInfo(JoinPoint joinPoint) {
System.out.println("+++++AOP " + joinPoint.getSignature().getName());
}
}
但是暂时不行,那么,有没有可能用spring aop拦截方法执行呢? 或者有一些更好的方法来做到这一点?
不幸的是,您只能编织自己的代码。
Brendon 的回答不正确,因为它专注于 Android。 在 Windows、MacOS、Linux 等具有普通 Java 的平台上,您可以拦截第三方代码,条件如下:
-javaagent:/path/to/aspectjweaver.jar
,并正确配置aop.xml 。如果您对使用 Java 命令行参数没有限制,我建议使用 LTW 而不是二进制编织。 Spring 手册中甚至有一章描述了如何直接在 Spring 中使用它。
更新:这是一个MCVE,向您展示如何在纯 Java + AspectJ LTW 中执行此操作。
让我们在安装了 AJDT(AspectJ 开发工具)的 Eclipse 中创建一个 AspectJ 项目。 当然,您也可以使用 AspectJ Maven 插件创建 Maven 项目,甚至不使用,因为如果您通过-javaagent:/path/to/aspectjweaver.jar
使用 LTW,实际上您不需要 AspectJ 编译器。 我的示例项目具有以下结构(Eclipse 布局,而不是 Maven,我只是快速完成):
文件内容如下。
src/de/scrum_master/app/Application.java
package de.scrum_master.app;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Logger;
public class Application {
private static final Logger logger = (Logger) LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
logger.info("Example log from {}", Application.class.getSimpleName());
}
}
源代码/logback.xml
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
src/de/scrum_master/aspect/LogbackAspect.aj(或简单的 LogbackAspect.java)
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class LogbackAspect {
@Before(value = "execution(* ch.qos.logback.classic.Logger.*(..))")
public void getInfo(JoinPoint joinPoint) {
System.out.println(joinPoint);
}
}
src/META-INF/aop.xml
<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
<aspects>
<aspect name="de.scrum_master.aspect.LogbackAspect" />
</aspects>
<weaver options="-verbose -showWeaveInfo" />
</aspectj>
现在为Application
创建一个简单的 Java 运行配置并将 Java 代理添加到命令行:
现在运行程序,控制台日志将是这样的:
[AppClassLoader@18b4aac2] info AspectJ Weaver Version 1.9.5 built on Thursday Nov 28, 2019 at 11:28:53 PST
[AppClassLoader@18b4aac2] info register classloader sun.misc.Launcher$AppClassLoader@18b4aac2
[AppClassLoader@18b4aac2] info using configuration /C:/Users/alexa/Documents/java-src/SO_AJ_LTW_Logback_60295366/bin/META-INF/aop.xml
[AppClassLoader@18b4aac2] info register aspect de.scrum_master.aspect.LogbackAspect
[AppClassLoader@18b4aac2] weaveinfo Join point 'method-execution(ch.qos.logback.classic.Level ch.qos.logback.classic.Logger.getEffectiveLevel())' in Type 'ch.qos.logback.classic.Logger' (Logger.java:109) advised by before advice from 'de.scrum_master.aspect.LogbackAspect' (LogbackAspect.aj)
[AppClassLoader@18b4aac2] weaveinfo Join point 'method-execution(int ch.qos.logback.classic.Logger.getEffectiveLevelInt())' in Type 'ch.qos.logback.classic.Logger' (Logger.java:113) advised by before advice from 'de.scrum_master.aspect.LogbackAspect' (LogbackAspect.aj)
[AppClassLoader@18b4aac2] weaveinfo Join point 'method-execution(ch.qos.logback.classic.Level ch.qos.logback.classic.Logger.getLevel())' in Type 'ch.qos.logback.classic.Logger' (Logger.java:117) advised by before advice from 'de.scrum_master.aspect.LogbackAspect' (LogbackAspect.aj)
(...)
[AppClassLoader@18b4aac2] weaveinfo Join point 'method-execution(java.lang.Object ch.qos.logback.classic.Logger.readResolve())' in Type 'ch.qos.logback.classic.Logger' (Logger.java:787) advised by before advice from 'de.scrum_master.aspect.LogbackAspect' (LogbackAspect.aj)
[AppClassLoader@18b4aac2] info processing reweavable type de.scrum_master.aspect.LogbackAspect: de\scrum_master\aspect\LogbackAspect.aj
[AppClassLoader@18b4aac2] info successfully verified type de.scrum_master.aspect.LogbackAspect exists. Originates from de\scrum_master\aspect\LogbackAspect.aj
execution(void ch.qos.logback.classic.Logger.setLevel(Level))
execution(void ch.qos.logback.classic.Logger.setLevel(Level))
execution(String ch.qos.logback.classic.Logger.toString())
execution(void ch.qos.logback.classic.Logger.addAppender(Appender))
execution(Logger ch.qos.logback.classic.Logger.getChildByName(String))
execution(Logger ch.qos.logback.classic.Logger.createChildByName(String))
execution(Logger ch.qos.logback.classic.Logger.getChildByName(String))
execution(Logger ch.qos.logback.classic.Logger.createChildByName(String))
execution(Logger ch.qos.logback.classic.Logger.getChildByName(String))
execution(Logger ch.qos.logback.classic.Logger.createChildByName(String))
execution(Logger ch.qos.logback.classic.Logger.getChildByName(String))
execution(Logger ch.qos.logback.classic.Logger.createChildByName(String))
execution(void ch.qos.logback.classic.Logger.info(String, Object))
execution(void ch.qos.logback.classic.Logger.filterAndLog_1(String, Marker, Level, String, Object, Throwable))
execution(void ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(String, Marker, Level, String, Object[], Throwable))
execution(String ch.qos.logback.classic.Logger.getName())
execution(LoggerContext ch.qos.logback.classic.Logger.getLoggerContext())
execution(void ch.qos.logback.classic.Logger.callAppenders(ILoggingEvent))
execution(int ch.qos.logback.classic.Logger.appendLoopOnAppenders(ILoggingEvent))
execution(int ch.qos.logback.classic.Logger.appendLoopOnAppenders(ILoggingEvent))
execution(int ch.qos.logback.classic.Logger.appendLoopOnAppenders(ILoggingEvent))
execution(int ch.qos.logback.classic.Logger.appendLoopOnAppenders(ILoggingEvent))
execution(int ch.qos.logback.classic.Logger.appendLoopOnAppenders(ILoggingEvent))
16:04:52.791 [main] INFO de.scrum_master.app.Application - Example log from Application
我认为这正是你想要的。 请参阅Spring 手册以了解如何在那里配置 AspectJ LTW。
检查这个其他答案使用 AspectJ 在 android 中拦截第三方函数
不幸的是,您只能编织自己的代码。
但是,根据您实际需要使用 Logback 做什么,您可以创建一个自定义 Appender 并在其中执行您需要的操作?
更新
如果您想记录这些异常的某种形式的指标,您可以根据 logstash-logback 文档配置 StatusListener
https://github.com/logstash/logstash-logback-encoder#status-listeners
有了这个,您可以接收事件,并记录您需要的任何指标
我尝试使用上面说的配置。 但我想从 tomcat lib 文件夹中编织一个 3rd 方 jar。 在这种情况下,这是行不通的。 谁能建议我们如何实现这一目标?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.