spring - Spring Boot Webflux + Elastic APM 监控
问题描述
我目前是 Elastic APM 的新手。我目前正在使用 spring-webflux 开发一个应用程序,并希望使用 Elastic APM 监控我的应用程序,但不幸的是,它不适合我。
依赖项
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
APM Java 代理版本 - 1.8.0 弹性搜索 - 7.2.0 APM 服务器 - 7.2.0
观察到异常 -
2020-05-07 00:03:31.529 [main] INFO co.elastic.apm.agent.bci.bytebuddy.ErrorLoggingListener - org.springframework.web.context.support.GenericWebApplicationContext refers to a missing class
java.lang.IllegalStateException: Cannot resolve type description for javax.servlet.ServletContext
at co.elastic.apm.agent.shaded.bytebuddy.pool.TypePool$Resolution$Illegal.resolve(TypePool.java:159)
at co.elastic.apm.agent.shaded.bytebuddy.pool.TypePool$Default$LazyTypeDescription$TokenizedGenericType.toErasure(TypePool.java:6241)
at co.elastic.apm.agent.shaded.bytebuddy.pool.TypePool$Default$LazyTypeDescription$GenericTypeToken$Resolution$Raw$RawAnnotatedType.of(TypePool.java:3412)
at co.elastic.apm.agent.shaded.bytebuddy.pool.TypePool$Default$LazyTypeDescription$GenericTypeToken$Resolution$Raw.resolveReturnType(TypePool.java:3302)
at co.elastic.apm.agent.shaded.bytebuddy.pool.TypePool$Default$LazyTypeDescription$LazyMethodDescription.getReturnType(TypePool.java:6796)
at co.elastic.apm.agent.shaded.bytebuddy.description.method.MethodDescription$AbstractBase.asSignatureToken(MethodDescription.java:838)
at co.elastic.apm.agent.bci.bytebuddy.FailSafeDeclaredMethodsCompiler.compile(FailSafeDeclaredMethodsCompiler.java:85)
at co.elastic.apm.agent.bci.bytebuddy.FailSafeDeclaredMethodsCompiler.compile(FailSafeDeclaredMethodsCompiler.java:66)
at co.elastic.apm.agent.shaded.bytebuddy.dynamic.scaffold.MethodRegistry$Default.prepare(MethodRegistry.java:471)
at co.elastic.apm.agent.shaded.bytebuddy.dynamic.scaffold.inline.RedefinitionDynamicTypeBuilder.make(RedefinitionDynamicTypeBuilder.java:198)
at co.elastic.apm.agent.shaded.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.doTransform(AgentBuilder.java:10327)
at co.elastic.apm.agent.shaded.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:10263)
at co.elastic.apm.agent.shaded.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.access$1600(AgentBuilder.java:10029)
at co.elastic.apm.agent.shaded.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$LegacyVmDispatcher.run(AgentBuilder.java:10648)
at co.elastic.apm.agent.shaded.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$LegacyVmDispatcher.run(AgentBuilder.java:10595)
at java.security.AccessController.doPrivileged(Native Method)
at co.elastic.apm.agent.shaded.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:10186)
at sun.instrument.TransformerManager.transform(Unknown Source)
at sun.instrument.InstrumentationImpl.transform(Unknown Source)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.springframework.boot.autoconfigure.condition.FilteringSpringBootCondition.resolve(FilteringSpringBootCondition.java:108)
at org.springframework.boot.autoconfigure.condition.FilteringSpringBootCondition$ClassNameFilter.isPresent(FilteringSpringBootCondition.java:140)
at org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition.getOutcome(OnWebApplicationCondition.java:71)
at org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition.getOutcomes(OnWebApplicationCondition.java:58)
at org.springframework.boot.autoconfigure.condition.FilteringSpringBootCondition.match(FilteringSpringBootCondition.java:49)
at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.filter(AutoConfigurationImportSelector.java:246)
at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getAutoConfigurationEntry(AutoConfigurationImportSelector.java:121)
at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector$AutoConfigurationGroup.process(AutoConfigurationImportSelector.java:396)
at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGrouping.getImports(ConfigurationClassParser.java:882)
at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:808)
at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:779)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:192)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:319)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:236)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:706)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532)
at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:66)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
at com.dhisco.hotel.search.HotelSearchApp.main(HotelSearchApp.java:14)
有人可以建议我缺少什么吗?
解决方案
Elastic APM 现在支持 Webflux(Tomcat 或 Netty): https ://github.com/elastic/apm-agent-java/pull/1305
从 Elastic APM 1.25.0 开始,这可以通过设置enable_experimental_instrumentations
为true
、 inelasticapm.properties
或作为 JVM 参数来启用:
enable_experimental_instrumentations=true
在此之前,它是通过设置disable_instrumentations
为空字符串来启用的:
disable_instrumentations=
https://github.com/elastic/apm-agent-java/issues/60#issuecomment-822419013
Features
Test application:
available as an executable jar and also used for unit-testing instrumentation
provides both functional and annotated controllers endpoints
executable with netty or tomcat as server, which allows to cover Webflux with or without Servlets
provides a client to call itself (based on Webflux client), thus using any third-party HTTP client is not necessary
Instrumentation:
Webflux server: covers both functional and annotated endpoints variants
Webflux client: not covered yet, see add support for Webflux client instrumentation #1306
using new plugin API and indy dispatcher.
adds reactor instrumentation for context-propagation
推荐阅读
- c - 带有条件操作函数的无限while循环问题
- python - 我正在尝试标记数据并遇到语法错误,但我不明白它在哪里
- git - Git 子模块突然不再被识别为有效的 repo,.git/modules/[submodule] 中的一些文件丢失
- pandas - 检查是否在另一列中找到了一次列中的字符串之一
- reactjs - 如何处理对 NextJS 应用程序的表单 POST 操作?
- angular - Angular:自定义表单组件不会对值变化做出反应——比如 2 路数据绑定
- gis - 将代理从一个点移动到数据库中定义的另一个点
- javascript - 在After Effects中自动缩放文本框
- java - hibernate jpa 元模型生成器:“文件管理器问题:尝试为类型重新创建文件”
- logging - Loki Distributed with S3 backend - 时间戳和 Grafana 连接问题