WIP: Auto-config for Extensions API tracer wrapper, metrics (with promethe… - #15
WIP: Auto-config for Extensions API tracer wrapper, metrics (with promethe…#15objectiser wants to merge 3 commits into
Conversation
…us metrics reporter) and tracer resolver.
| @Configuration | ||
| public class TracerBeanPostProcessor implements BeanPostProcessor { | ||
|
|
||
| private static final Logger log = Logger.getLogger(TracerBeanPostProcessor.class.getName()); |
There was a problem hiding this comment.
All logging frameworks provide a logback for JUL, and JUL is the only logging framework that doesn't require an external dependency. So, it's usually a better choice for a library.
There was a problem hiding this comment.
By the way: my point is moot if slf4j is already a dependency (I'm not sure that's the case)
There was a problem hiding this comment.
I think we should use what is default/preferred in spring boot, and I guess it's not JUL
There was a problem hiding this comment.
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html
commons logging - so could switch.
jpkrohling
left a comment
There was a problem hiding this comment.
LGTM, although I can't judge on the Spring semantics.
| private String metricsName; | ||
|
|
||
| @Autowired(required=false) | ||
| private Set<MetricLabel> metricLabels; |
There was a problem hiding this comment.
Where is this coming from? Spring I guess, but what happens when required = false?
There was a problem hiding this comment.
Yes - the app provides the MetricLabel beans. If none are provided, then metricLabels is null.
| import org.springframework.context.annotation.Configuration; | ||
|
|
||
| @Configuration | ||
| @ConditionalOnClass(value = {io.prometheus.client.exporter.MetricsServlet.class, |
There was a problem hiding this comment.
I think it would be more readable if the classes are imported.
There was a problem hiding this comment.
Need to check - but examples I have seen did not import the class, possibly because it may affect class loading of this class?
There was a problem hiding this comment.
Just found some examples that use the annotation on imported classes, so I guess it isn't a problem - so will change.
|
|
||
| tracerObserver.onStart(spanData).onFinish(spanData, System.currentTimeMillis()); | ||
|
|
||
| Mockito.verify(metricsReporter).reportSpan(spanData); |
There was a problem hiding this comment.
It's been a while since I last used mockito, so, I'm missing something here... You are asserting that reportSpan has been called and that the mocked spanData was used as parameter, but what actually called the reporter?
There was a problem hiding this comment.
Essentially the resolved tracerObserver is a metrics observer configured with the mock metricsReporter - so when the onFinish is called with the mock spanData it gets passed through to the metrics reporter via the metrics observer.
|
|
||
| @Bean | ||
| public io.opentracing.Tracer tracer() { | ||
| return io.opentracing.contrib.tracerresolver.TracerResolver.resolveTracer(); |
There was a problem hiding this comment.
Same reason as above - depends on whether this affects the ConditionalOnClass annotation.
Could we make changes in |
couldn't work to avoid tracer resolver and |
|
There are two issues issue - resolving the Dealing with Now, in terms of resolving the Not saying that the current approach is ideal - it needs more work to understand how best to deal with resolving the |
|
As a suggestion for dealing with registering with |
|
How does the TracerResolver work? IIRC it registers the resolved tracer to GlobalTracer and the app obtains the tracer from it. As I propose we can simply change the current |
|
Let me split out the tracer resolver part into a separate PR, as it needs to be discussed separately. |
|
|
||
| @Override | ||
| public void contextInitialized(javax.servlet.ServletContextEvent sce) { | ||
| sce.getServletContext().setAttribute(TracingFilter.SKIP_PATTERN, Pattern.compile(metricsPath)); |
There was a problem hiding this comment.
This skip pattern param is used only when the filter is registered via web.xml. In spring-web it is registered directly.
There was a problem hiding this comment.
This wasn't intended as a real solution, hence starting discussion here opentracing-contrib/java-spring-web#28.
| import io.prometheus.client.exporter.MetricsServlet; | ||
|
|
||
| @Configuration | ||
| @ConditionalOnClass(value = {MetricsServlet.class, TracingFilter.class}) |
There was a problem hiding this comment.
I think this should not depend on TracingFilter
|
I have been thinking about this for a while and we should define boundaries of this project. The purpose of this repository is to instrument spring cloud related frameworks. This tracer/prometheus metrics integration is not spring/cloud related. Btw there is also spring boot metrics project https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-metrics.html and https://github.com/micrometer-metrics/micrometer (not sure how they overlap). So far tracer instance has been obtained from spring context which is a standard way in spring I am not sure if tracer resolver autoconfig adds a benefit here. If users what to use it they can simple drop traver resolver dependency on classpath and write: and it is not necessary to have auto-config and starter artefact for it. |
|
I would view its scope slightly differently - I believe it is about making OpenTracing based instrumentation as easy as possible to consume within spring boot/cloud. The metrics references you mentioned do not provide the same level of application metric granularity as Regarding TracerResolver autoconfig (which is now in a different PR) - the Tracer needs to get into the spring context somehow, what you are suggesting is that this must be done by the application developer, while I am suggesting that having the option to include it via auto-config may mean the app developer doesn't have to change any code. Isn't it better to give the developer a choice? |
It's true, I would vote for a little explicit code rather than maintaining (in my opinion unnecessary) wrapper around trace resolver. So if you want to integrate tracing you have to include certain dependencies in your class path. In other words change project source code e.g (pom, gradle). This would be all if we supported trace resolver starter. However, what I propose is to add one self-contained class: You don't have to reference this class from anywhere. If you want to remove tracing you just remove it. I think it's better to stick with spring conventions and keep the configuration concise. |
|
Closing, moving autoconfigure code to: |
…us metrics reporter) and tracer resolver.
Prototype to investigate how we can add metrics (with prometheus reporter) support to an OpenTracing instrumented SB app with zero or minimal additional configuration.
This branch shows an updated accountmgr service that now only requires the maven dependencies, and additional metrics labels defined as beans (although these could be defined in a shared module to be completely outside scope of app):
https://github.com/objectiser/opentracing-prometheus-example/tree/autoconfig/simple/accountmgr
Currently contains a number of changes that could be separated out into their own PRs:
TracerObserveris found