zalando / opentracing-toolbox Goto Github PK
View Code? Open in Web Editor NEWBest-of-breed OpenTracing utilities, instrumentations and extensions
License: MIT License
Best-of-breed OpenTracing utilities, instrumentations and extensions
License: MIT License
At least for the public interfaces which are meant to be used by programmers, each method should have one or two sentences saying what they are doing.
(For example, I've seen the forEach
and delegate
methods, but I don't understand what they are supposed to be doing.)
This library is compiled, build and released against Spring 4 and Spring Boot 1 by default. Support for Spring 5 and Spring Boot 2 is supported via special build profiles that are primarily used by travis.
The goal is to change the default to Spring 5 and Spring Boot 2.
In the upcoming weeks, we're trying to move to Spring Boot 2 internally. It's therefore the next logical step to have all libraries support it natively.
properties
sectionspring5
profile to spring4
spring4-*
profiles into spring4
Tracer.start could return something AutoClosable to support try-with-resources idiom like:
try (AutoClosable x = tracer.start()) {
// do work
}
I have a spring-boot project with tracer added (more details below). Configuration is just the default one, just the trace name is configured. I'm trying to get my trace value in a @Scheduled
method, but I get IllegalStateException: X-Flow-ID has not been started
.
Question: how is it supposed to work? I think the documentation on this is missing.
spring-boot:1.4.6
.tracer-spring-boot-starter:0.16.0
in dependencies.tracer.traces.X-Flow-ID=flow-id
@Scheduled
method inside of which I'm calling tracer.get("X-Flow-ID").getValue()
on an @Autowired Tracer tracer
field.java.lang.IllegalStateException: X-Flow-ID has not been started
at org.zalando.tracer.DefaultTracer.getAndCheckValue(DefaultTracer.java:102) ~[tracer-core-0.16.0.jar:na]
at org.zalando.tracer.DefaultTracer.access$000(DefaultTracer.java:15) ~[tracer-core-0.16.0.jar:na]
at org.zalando.tracer.DefaultTracer$1.getValue(DefaultTracer.java:68) ~[tracer-core-0.16.0.jar:na]
I didn't really find any docs of what a "support for scheduling" means. I'm sure I'm doing something wrong, but can you point out what's missing? I was expecting that the trace will be already initialized and I can just get it's value (and send in an outgoing request).
I think it would be worth to talk about the length (count of chars) of a generated identifier in the README. I'd like to use the new PhraseGenerator
but I am not sure if the phrases can be longer than 22 chars (that's my restriction).
Implement request-response 'weave' pattern logging which gives human readable way to follow correlated request-response log statements and concurrent request-response interleaving.
Idea is borrowed from here : https://pablosichert.github.io/concurrency-logger/
──‣ ┈┈┈┈┈ GET┈ ┬┈│┈│┈┈┈│┈┈ /
──‣ ┈┈┈┈┈ GET┈ │┈│┈│┈┬┈│┈┈ /
──‣ ┈┈┈┈┈ GET┈ │┈│┈│┈│┈│┈┬ /
200 ┈11ms GET┈ │┈┴┈│┈│┈│┈│ /
200 ┈┈4ms GET┈ │┈┈┈│┈│┈┴┈│ /
200 ┈┈6ms GET┈ │┈┈┈┴┈│┈┈┈│ /
──‣ ┈┈┈┈┈ GET┈ │┈┬┈┈┈│┈┈┈│ /
──‣ ┈┈┈┈┈ GET┈ │┈│┈┬┈│┈┈┈│ /
200 ┈┈5ms GET┈ │┈│┈┴┈│┈┈┈│ /
──‣ ┈┈┈┈┈ GET┈ │┈│┈┬┈│┈┈┈│ /
200 ┈21ms GET┈ │┈│┈│┈│┈┈┈┴ /
200 ┈27ms GET┈ │┈┴┈│┈│┈┈┈┈ /
──‣ ┈┈┈┈┈ GET┈ │┈┬┈│┈│┈┈┈┈ /
──‣ ┈┈┈┈┈ GET┈ │┈│┈│┈│┈┬┈┈ /
200 ┈42ms GET┈ │┈│┈│┈┴┈│┈┈ /
200 ┈23ms GET┈ │┈│┈┴┈┈┈│┈┈ /
200 ┈46ms GET┈ ┴┈│┈┈┈┈┈│┈┈ /
One possible (?) way is to store in logging context current weave pattern and log it as a part of logline along with flow-id
{TRACE} [XNIO-3 task-4] [R595UgNfSHSq0vDzTZsoMw] [│┈│┈┴┈┈┈│┈┈] [org.zalando.logbook.Logbook] {"origin":"remote","type":"response"...
The referenced implementation uses coloring and multiline log statements which could be omitted for initial implementation.
Exist:
http://mvnrepository.com/artifact/org.zalando/tracer-aspectj
http://mvnrepository.com/artifact/org.zalando/tracer-core
http://mvnrepository.com/artifact/org.zalando/tracer-httpclient
http://mvnrepository.com/artifact/org.zalando/tracer-servlet
Does not exist:
http://mvnrepository.com/artifact/org.zalando/tracer-spring-boot-starter
As a developer
I want to update jacoco maven plugin version
So that it does not enforce coverage for empty private constructors
At least an example would be nice
Automatic trace management for background tasks using @Scheduled
would be cool.
Right now traces are not closed in case the servlet encounters an exception. This is a problem when the container decides to reuse the thread.
Currently, when including org.zalando:tracer-spring-boot-starter
into Spring 5 reactive applications Spring cannot start (NoClassDefFoundError: javax/servlet/Filter
) because of TracerAutoConfiguration
's hard dependency on javax.servlet.Filter
.
Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.zalando.tracer.spring.TracerAutoConfiguration] from ClassLoader [sun.misc.Launcher$AppClassLoader@18b4aac2]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:659)
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:556)
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:541)
at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:599)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:726)
....
Caused by: java.lang.NoClassDefFoundError: javax/servlet/Filter
The application should start, but disable servlet filtering. All other configurations should be preserved.
It fails.
Extract TracerFilterAutoConfiguration
into separate class and add @ConditionalOnWebApplication
there.
Hey guys :)
More of a question then an actual issue...
I introduced Tracer in our projects and wanted to introduce transaction Id stacking (flow id stacking in Zalando speech ;) ). Unfortunately Tracer does not support this in the current version.
My Intention is to have multiple Traces of the same name running at the same time. Basically I get a call through HTTP with an existing trace. To document where things are going from now on I add a new one to the same name (now there are two active) to make tracing of this specific part of the overall transaction easier.
Is there an easier way of doing this?
Or is this a possible feature for Tracer?
To manage traces for tests
https://github.com/spring-projects/spring-boot/wiki/Building-On-Spring-Boot
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-custom-starter-naming
tracer-spring-boot-autoconfigure
org.zalando.tracer.autoconfigure
This library will be restructured and have it's scope and purpose shifted and extended at the same time. The library will be extended to into a collection of OpenTracing related libraries.
The move from custom implementation (0-x and 1.x) to a utility library on top of OpenTracing (2.x) could already be seen as the first step in that direction. #209 also discusses some aspects in this regard. Ultimately it can be stated that the Tracer library is being phased out in favor of OpenTracing which we embrace even further.
opentracing-toolbox
opentracing-flowid
tracer-*
to opentracing-flowid-*
org.zalando.tracer
to org.zalando.opentracing.flowid
Tracer*
classes to FlowId*
tracer
to flowid
MDCSpanObserver
and dependency to opentracing-api-extensions-tracer
(see next step)opentracing-proxy
module (internal project right now)
opentracing-jdbc
module (internal project right now)
DataSource
levelopentracing-toolbox-spring-addons
(name tbd)
HandlerInterceptorSpanDecorator
WebFluxSpanDecorator
might be added laterRestTemplateSpanDecorator
or WebClientSpanDecorator
as for now because Riptide: OpenTracing already provides a better alternativeopentracing-toolbox-spring-boot-autoconfigure
(name tbd)
AutoConfiguration
sTracer
using opentracing-proxy
DataSource
s using opentracing-jdbc
HandlerInterceptorSpanDecorator
📣 All instrumentation modules in this library will be customizable but have their default configuration set match Zalando's version of the semantic conventions.
In case client application doesn't have properly configured tracer and uses NoopTracer instance it will fail during incoming http call with 500 error.
Incoming http call should pass FlowFilter and reach application business logic.
Following exception thrown:
java.lang.NoSuchMethodError: io.opentracing.ScopeManager.active()Lio/opentracing/Scope;
at io.opentracing.contrib.api.tracer.APIExtensionsTracer.activeSpan(APIExtensionsTracer.java:65)
at io.opentracing.util.GlobalTracer.activeSpan(GlobalTracer.java:209)
at io.opentracing.contrib.api.tracer.APIExtensionsTracer.activeSpan(APIExtensionsTracer.java:63)
at org.zalando.tracer.DefaultFlow.activeSpan(DefaultFlow.java:75)
at org.zalando.tracer.DefaultFlow.readFrom(DefaultFlow.java:23)
at org.zalando.tracer.servlet.FlowFilter.doFilter(FlowFilter.java:25)
at org.zalando.tracer.servlet.HttpFilter.doFilter(HttpFilter.java:28)
The problem resides in utilising APIExtensionsTracer which is incompatible with OpenTracing-api 0.33.0.
Can be exposed by following test:
package org.zalando.tracer;
import io.opentracing.contrib.api.tracer.APIExtensionsTracer;
import io.opentracing.noop.NoopTracerFactory;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
class DefaultFlowNoopTracerTest {
private final APIExtensionsTracer tracer = new APIExtensionsTracer(NoopTracerFactory.create());
private final Flow unit = Flow.create(tracer);
@Test
void shouldThrowNoActiveSpanFoundException() {
assertThrows(IllegalStateException.class, unit::currentId);
}
}
We should settle on one and only one name that is not overloaded already.
Given we follow the path outlined in #204 then we are in a somewhat fuzzy spot in terms of naming:
tracer
repositoriytracer-*
modules and artifactsorg.zalando.tracer
packageTracer
main APITracerFilter
TracerHttpRequestInterceptor
TracerAutoConfiguration
tracer
configuration namespace (Spring Boot)Tracer
, hence the switch to **Flow*.tracer
repositoriy 💥tracer-*
modules and artifacts 💥org.zalando.tracer
package 💥Flow
main APIFlowFilter
FlowHttpRequestInterceptor
TracerAutoConfiguration
💥tracer
configuration namespace (Spring Boot) 💥Looks like you closed Issue #20 and the link doesn't work anymore :)
I'm using the default spring configuration and if I do this:
GlobalScope.launch{ someOperationThatUsuallyLogsWithTracer() }
I don't see the tracer in the logs.
Maybe I'm missing something in the settings?
Not sure if this is a bug or a feature request. Please feel free to ask for details in order to reproduce it.
Javadocs should be generated without warnings.
mvn javadoc:javadoc -D maven.javadoc.failOnWarnings
produces:
2 warnings
[WARNING] Javadoc Warnings
[WARNING] /home/wschoenborn/Projects/tracer/tracer-core/src/main/java/org/zalando/tracer/Flow.java:29: warning: no description for @return
[WARNING] * @return
[WARNING] ^
[WARNING] /home/wschoenborn/Projects/tracer/tracer-core/src/main/java/org/zalando/tracer/Flow.java:30: warning: no description for @throws
[WARNING] * @throws IllegalStateException
[WARNING] ^
failOnWarnings
in javadoc plugin configurationSee above
Release a new version
Maybe similar to zalando/logbook#199?
Using the following name:
If we use tracer together with zalando tokens library (https://github.com/zalando-stups/spring-boot-zalando-stups-tokens) and have tracer.async.enabled: true and _@EnableAsync_, we get the following WARN log message every time the tokens are refreshed (by default every 5 seconds):
2016-07-28 14:58:03,194 {WARN} [restartedMain] [] [org.zalando.stups.tokens.CompositeMetricsListener] X-Flow-ID has not been started
java.lang.IllegalStateException: X-Flow-ID has not been started
at com.google.common.base.Preconditions.checkState(Preconditions.java:199) ~[guava-19.0.jar:?]
at org.zalando.tracer.DefaultTracer.getAndCheckValue(DefaultTracer.java:105) ~[tracer-core-0.8.0.jar:?]
at org.zalando.tracer.DefaultTracer.lambda$forEach$4(DefaultTracer.java:84) ~[tracer-core-0.8.0.jar:?]
at java.util.Map.forEach(Map.java:630) ~[?:1.8.0_91]
at org.zalando.tracer.DefaultTracer.forEach(DefaultTracer.java:83) ~[tracer-core-0.8.0.jar:?]
at org.zalando.tracer.Tracer.snapshot(Tracer.java:132) ~[tracer-core-0.8.0.jar:?]
at org.zalando.tracer.Tracer.preserve(Tracer.java:166) ~[tracer-core-0.8.0.jar:?]
at org.zalando.tracer.spring.TracerTaskExecutor.execute(TracerTaskExecutor.java:38) ~[tracer-spring-boot-starter-0.8.0.jar:?]
at org.springframework.core.task.support.TaskExecutorAdapter.submit(TaskExecutorAdapter.java:106) ~[spring-core-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.aop.interceptor.AsyncExecutionAspectSupport.doSubmit(AsyncExecutionAspectSupport.java:273) ~[spring-aop-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.invoke(AsyncExecutionInterceptor.java:130) ~[spring-aop-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at com.sun.proxy.$Proxy85.submitToTimer(Unknown Source) ~[?:?]
at org.zalando.stups.tokens.CompositeMetricsListener.submitToTimer(CompositeMetricsListener.java:23) [spring-boot-zalando-stups-tokens-0.9.11.jar:?]
at org.zalando.stups.tokens.AccessTokenRefresher.createToken(AccessTokenRefresher.java:181) [tokens-0.9.9.jar:?]
at org.zalando.stups.tokens.AccessTokenRefresher.run(AccessTokenRefresher.java:137) [tokens-0.9.9.jar:?]
at org.zalando.stups.tokens.AccessTokenRefresher.start(AccessTokenRefresher.java:92) [tokens-0.9.9.jar:?]
at org.zalando.stups.tokens.AccessTokensBuilder.start(AccessTokensBuilder.java:279) [tokens-0.9.9.jar:?]
at org.zalando.stups.tokens.AccessTokensBean.start(AccessTokensBean.java:174) [spring-boot-zalando-stups-tokens-0.9.11.jar:?]
at org.zalando.stups.tokens.config.AccessTokensBeanAutoConfiguration.accessTokensBean(AccessTokensBeanAutoConfiguration.java:66) [spring-boot-zalando-stups-tokens-0.9.11.jar:?]
at org.zalando.stups.tokens.config.AccessTokensBeanAutoConfiguration$$EnhancerBySpringCGLIB$$e2ed77b5.CGLIB$accessTokensBean$0(<generated>) [spring-boot-zalando-stups-tokens-0.9.11.jar:?]
at org.zalando.stups.tokens.config.AccessTokensBeanAutoConfiguration$$EnhancerBySpringCGLIB$$e2ed77b5$$FastClassBySpringCGLIB$$ff80ee9.invoke(<generated>) [spring-boot-zalando-stups-tokens-0.9.11.jar:?]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) [spring-core-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356) [spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.zalando.stups.tokens.config.AccessTokensBeanAutoConfiguration$$EnhancerBySpringCGLIB$$e2ed77b5.accessTokensBean(<generated>) [spring-boot-zalando-stups-tokens-0.9.11.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1192) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1192) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) [spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) [spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) [spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:760) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:360) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:306) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
at de.zalando.atlas.catalog.api.CatalogApiApplication.main(CatalogApiApplication.java:19) [classes/:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.3.6.RELEASE.jar:1.3.6.RELEASE]
This seems to be because the code here assumes Tracer was already started: TracerTaskExecutor.java#L38
A workaround for this at the moment is to disable the MetricsListenerAutoConfiguration:
@EnableAutoConfiguration(exclude = {MetricsListenerAutoConfiguration.class})
trace-core
trace-slf4j
trace-spring
(maybe this can be done in a more generic way?)trace-servlet
trace-cxf
(maybe this can be done in a more generic way?)trace-httpcomponents
(as an alternative to spring + cxf)A common use case for stacked traces is to process a batch (outer trace) and start a specific trace per item being processed (inner trace). For event processing we keep a reference to the original trace id, so we use that as a seed. Currently we need to do this like this:
for (final Event event : batch.getEvents()) {
tracer.start(withFlowIdOf(event));
try {
consumer.consume(event);
} finally {
tracer.stop();
}
}
private Function<String, String> withFlowIdOf(final Event event) {
return $ -> event.getMetadata().getFlowId();
}
I would be nice if Event
could annotate a special method like this:
class Event {
@ProvidesTrace("X-Flow-ID")
public String getFlowId() {
return getMetadata().getFlowId();
}
}
for (final Event event : batch.getEvents()) {
tracer.start(event);
try {
consumer.consume(event);
} finally {
tracer.stop();
}
}
Alternatively there could be a special interface, but that would require that a) a class can only provide one and b) that every class needs to implement two methods, on for the name and one for the value.
There is no examples of how to use it:
When I try to run an application with tracer-spring-boot-starter
version 0.6.0 with the configuration in application.yaml
tracer: aspect.enabled: true async.enabled: true filter.enabled: true logging: enabled: false category: org.zalando.tracer.Tracer mdc.enabled: true scheduling.enabled: true traces: X-Trace-ID: uuid X-Flow-ID: X-FLOW-ID
Then I got the following error. Can you please shed some light on this ?
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'tracerFilter' defined in class path resource [org/zalando/tracer/spring/TracerAutoConfiguration.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [org.zalando.tracer.Tracer]: Error creating bean with name 'tracer' defined in class path resource [org/zalando/tracer/spring/TracerAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.zalando.tracer.Tracer]: Factory method 'tracer' threw exception; nested exception is java.lang.UnsupportedOperationException; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tracer' defined in class path resource [org/zalando/tracer/spring/TracerAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.zalando.tracer.Tracer]: Factory method 'tracer' threw exception; nested exception is java.lang.UnsupportedOperationException at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.boot.context.embedded.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:233) ~[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at org.springframework.boot.context.embedded.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:214) ~[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:90) ~[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at org.springframework.boot.context.embedded.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:78) ~[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getServletContextInitializerBeans(EmbeddedWebApplicationContext.java:237) ~[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.selfInitialize(EmbeddedWebApplicationContext.java:224) ~[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.access$000(EmbeddedWebApplicationContext.java:85) ~[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:209) ~[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at org.springframework.boot.context.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:55) ~[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5240) ~[tomcat-embed-core-8.0.33.jar:8.0.33] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147) ~[tomcat-embed-core-8.0.33.jar:8.0.33] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408) ~[tomcat-embed-core-8.0.33.jar:8.0.33] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398) ~[tomcat-embed-core-8.0.33.jar:8.0.33] at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_45] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_45] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_45] at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_45] Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tracer' defined in class path resource [org/zalando/tracer/spring/TracerAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.zalando.tracer.Tracer]: Factory method 'tracer' threw exception; nested exception is java.lang.UnsupportedOperationException at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1192) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] ... 26 common frames omitted Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.zalando.tracer.Tracer]: Factory method 'tracer' threw exception; nested exception is java.lang.UnsupportedOperationException at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] ... 39 common frames omitted Caused by: java.lang.UnsupportedOperationException: null at org.zalando.tracer.spring.DefaultGeneratorResolver$$Lambda$46/780090089.get(Unknown Source) ~[na:na] at java.util.Optional.orElseThrow(Optional.java:290) ~[na:1.8.0_45] at org.zalando.tracer.spring.DefaultGeneratorResolver.resolve(DefaultGeneratorResolver.java:44) ~[tracer-spring-boot-starter-0.6.0.jar:na] at org.zalando.tracer.spring.TracerAutoConfiguration$$Lambda$44/692711475.apply(Unknown Source) ~[na:na] at com.google.common.collect.Maps$7.transformEntry(Maps.java:1812) ~[guava-18.0.jar:na] at com.google.common.collect.Maps$10.getValue(Maps.java:1857) ~[guava-18.0.jar:na] at java.util.Map.forEach(Map.java:625) ~[na:1.8.0_45] at org.zalando.tracer.spring.TracerAutoConfiguration.tracer(TracerAutoConfiguration.java:115) ~[tracer-spring-boot-starter-0.6.0.jar:na] at org.zalando.tracer.spring.TracerAutoConfiguration$$EnhancerBySpringCGLIB$$551674a.CGLIB$tracer$1(<generated>) ~[tracer-spring-boot-starter-0.6.0.jar:na] at org.zalando.tracer.spring.TracerAutoConfiguration$$EnhancerBySpringCGLIB$$551674a$$FastClassBySpringCGLIB$$99280dc5.invoke(<generated>) ~[tracer-spring-boot-starter-0.6.0.jar:na] at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.zalando.tracer.spring.TracerAutoConfiguration$$EnhancerBySpringCGLIB$$551674a.tracer(<generated>) ~[tracer-spring-boot-starter-0.6.0.jar:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_45] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_45] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_45] at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_45] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] ... 40 common frames omitted
Instead of using random64 + string concat, maybe it would be faster to generate a random byte array of size 16 and transform it into a hex string.
Current performance:
Benchmark Mode Cnt Score Error Units
Random128GeneratorBenchmark.benchmark thrpt 20 6220510.086 ± 706340.069 ops/s
Random64GeneratorBenchmark.benchmark thrpt 20 17923599.807 ± 1393506.401 ops/s
Hey -- it is, right? If so, we can promote more broadly.
About to edit the jackson-datatype-money README now ... :)
You use two interfaces in your tracer and logbook module which do the same
interface HttpFilter extends Filter {
@Override
default void init(final FilterConfig filterConfig) {
// no initialization needed by default
}
@Override
default void doFilter(final ServletRequest request, final ServletResponse response,
final FilterChain chain) throws ServletException, IOException {
if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
throw new IllegalArgumentException(getClass().getSimpleName() + " only supports HTTP");
}
final HttpServletRequest httpRequest = (HttpServletRequest) request;
final HttpServletResponse httpResponse = (HttpServletResponse) response;
doFilter(httpRequest, httpResponse, chain);
}
void doFilter(final HttpServletRequest httpRequest, final HttpServletResponse httpResponse,
final FilterChain chain) throws ServletException, IOException;
@Override
default void destroy() {
// no deconstruction needed by default
}
}
interface HttpFilter extends Filter {
@Override
default void init(final FilterConfig filterConfig) {
// no initialization needed by default
}
@Override
default void doFilter(final ServletRequest request, final ServletResponse response,
final FilterChain chain) throws ServletException, IOException {
if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
final HttpServletRequest httpRequest = (HttpServletRequest) request;
final HttpServletResponse httpResponse = (HttpServletResponse) response;
doFilter(httpRequest, httpResponse, chain);
} else {
throw new IllegalArgumentException(getClass().getSimpleName() + " only supports HTTP");
}
}
void doFilter(final HttpServletRequest request, final HttpServletResponse response,
final FilterChain chain) throws ServletException, IOException;
@Override
default void destroy() {
// no deconstruction needed by default
}
}
Do you intend to somehow solve this or don't you want to have a common library shared across your modules?
Shared library?
We developed something very similiar to your tracer module and think about switching to your module. I came across this issue while I compared it to our module and if it would fit.
flow-local
?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.