Code Monkey home page Code Monkey logo

java-web-servlet-filter's Introduction

Build Status Released Version

OpenTracing Java Web Servlet Filter Instrumentation

This library provides instrumentation for Java Web Servlet applications.

Initialization

Tracing filter can be programmatically initialized:

   TracingFilter filter = new TracingFilter(tracer);
   servletContext.addFilter("tracingFilter", filter);

or added to web.xml, however it requires to register a tracer instance: GlobalTracer.register(tracer).

Tracer override

If a tracer has been associated with the ServletContext as an attribute with key io.opentracing.Tracer, then it will override any tracer explicitly passed to the filter or registered with the GlobalTracer.

This approach can be used where OpenTracing and Tracer implementation specific dependencies are configured within a servlet container (rather than bundled with the webapp), and we don't wish to share a single GlobalTracer instance across all webapps (e.g. as this may mean all webapps report their spans associated with the same service name).

In these situations, using a ServletContextListener to create a Tracer will enable it to be specific to the webapp and managed with its lifecycle.

Accessing Server Span

Current server span context is accessible in HttpServletRequest attributes.

   SpanContext spanContext = (SpanContext)httpservletRequest.getAttribute(TracingFilter.SERVER_SPAN_CONTEXT);
   

Development

./mvnw clean install

Release

Follow instructions in RELEASE

java-web-servlet-filter's People

Contributors

bensigelman avatar dependabot[bot] avatar jianshaow avatar ledor473 avatar objectiser avatar pavolloffay avatar pmaciolek avatar serceman avatar sjoerdtalsma avatar skabashnyuk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

java-web-servlet-filter's Issues

Use getRequestURL instead of getMethod for naming the spans

Giving name to spans based on the HTTP Method does not look intuitive on the tracers UI(Jaeger, Lightstep, Zipkin etc). For example there can be several PUT
requests and the span will look in the UI with name "PUT" in the tracer. A viewer cannot figure out that PUT request is related with which URL(or which service) until he click on the span and checks the tags.
Here is the view from Lightstep (Note : regdiscovery-tracer is the name of the tracer)
screen shot 2018-10-26 at 10 26 12 pm

I think it will good to use request URL instead of HTTP Method so that viewer at the first view on the tracer UI can figure out the particular span is meant for which http request.

Allows clients to customize operation naming pattern

Similar to #45 and #42, I'd like different operation names than are provided by this library by default.

Instead of changing the default on everybody already using the library or using a potentially high cardinality field like requestURL, provide an API for customizing the operation naming strategy. The java-grpc OpenTracing contrib provides a similar option: https://github.com/opentracing-contrib/java-grpc/blob/master/src/main/java/io/opentracing/contrib/grpc/OperationNameConstructor.java

I'm happy to contribute a PR.

Check for null extracted context before creating a child span

There are some implementations (I've observed) of OpenTracing that do not accept null arguments to SpanBuilder.asChildOf(). If tracer.extract() returns null (ie. no span context was passed to the servlet) and it is used to create a child span, .asChildOf() will cause a NullPointerException.

The equivalent operation would be to avoid calling .asChildOf() if extractedContext is null, which should work for any implementation.

Include license header to each java file

It might look not very important however as far as I can
see most of the other opentracing-X project has a license as a header.
I faced with this during IP certification process when I
want to include opentracing-web-servlet-filter to Eclipse Che project.
I hope that the license in the root folder is enough for IP team. But who knows...
I can submit PR if needed.

Thoughts?

Header without value causes NoSuchElementException

This happened:

java.util.NoSuchElementException
1 at java.util.ArrayList$Itr.next (ArrayList.java:854)
2 at io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter$MultivaluedMapFlatIterator.next (HttpServletRequestExtractAdapter.java:84)
3 at io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter$MultivaluedMapFlatIterator.next (HttpServletRequestExtractAdapter.java:58)

The request came with header without values:

Accept: application/json
Broken-Header: 
Content-Type: application/json

There's a test for this case with comment that "this should not really happen" but it happens :)

I was running 0.0.3, but 0.0.7 seems to have the same logic.

Keep interface clean

I noticed that several interfaces have anonymous implementation in it.

  • STANDARD_TAGS in ServletFilterSpanDecorator
  • STANDARD_LOGS in HandlerInterceptorSpanDecorator
  • HANDLER_METHOD_OPERATION_NAME in HandlerInterceptorSpanDecorator

Is there a reason?

I wanted to add queryString to Tags.HTTP_URL but since I can't extend STANDARD_TAGS, I have to create my own class and copy paste all methods and change what I need. If I could extend the class, I could have just override onRequest.

Current State

Hi! 👋 I have some questions, since the repo has not been updated for a few years.

  1. What is the current status of this project?
  2. Is it still being maintained?
  3. Is there an alternative that could be used?

ServletFilterSpanDecorator wrongly sets http.status_code to 500 in case of ClientAbortException-s

ClientAbortException happen in Tomcat when the client disconnected before the response from the server.
Can obviously happen at any time since it's upto the client when to disconnect or not.
Tomcat and Spring are both ignoring this exception and the Tomcat access log valve shows response as 200 still (what would have been returned, had the client not disconnected).

Tomcat version: 9.0.63
Ignoring of client aborts was added in Tomcat with 9.0.13 - https://bz.apache.org/bugzilla/show_bug.cgi?id=62797

But TracingFilter catches all Throwable-s:
https://github.com/opentracing-contrib/java-web-servlet-filter/blob/master/opentracing-web-servlet-filter/src/main/java/io/opentracing/contrib/web/servlet/filter/TracingFilter.java#L198

And then ServletFilterSpanDecorator goes ahead and reports the span with status 500:
https://github.com/opentracing-contrib/java-web-servlet-filter/blob/master/opentracing-web-servlet-filter/src/main/java/io/opentracing/contrib/web/servlet/filter/ServletFilterSpanDecorator.java#L113

Exception from the request that is still reported as successful by Tomcat:

	at io.opentracing.contrib.web.servlet.filter.TracingFilter.doFilter(TracingFilter.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at ch.qos.logback.access.tomcat.LogbackValve.invoke(LogbackValve.java:256)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
	at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:769)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
	at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:353)
	at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:783)
	at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:688)
	at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:388)
	at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:366)
	at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96)

创建filter,引用web.xml报错

异常信息如下:
java.lang.NullPointerException at brave.opentracing.BraveSpanBuilder.addReference(BraveSpanBuilder.java:72) at brave.opentracing.BraveSpanBuilder.asChildOf(BraveSpanBuilder.java:60) at brave.opentracing.BraveSpanBuilder.asChildOf(BraveSpanBuilder.java:41) at io.opentracing.contrib.web.servlet.filter.TracingFilter.doFilter(TracingFilter.java:154) at com.efounder.opentracing.OpentracingFilter.doFilter(OpentracingFilter.java:28)

filter 代码如下:

`public class OpentracingFilter implements Filter {

private TracingFilter filter = null;

@Override
public void init(FilterConfig filterConfig) throws ServletException {
	Tracer tracer = OpentracingManager.me().getTracer();
	filter = new TracingFilter(tracer);
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
		throws IOException, ServletException {
	filter.doFilter(request, response, chain);
}

@Override
public void destroy() {
	filter.destroy();
}

}`

请指教

Performance issue with Tomcat

As is documented in the comments of MimeHeaders, each call of nextElement() has a complexity of O(n) with a comparison done with all previous elements to ensure the uniqueness.

Jetty has better performance since it uses HashSet to get a set of header keys.

I wonder if we could treat org.apache.catalina.connector.Request as a special case. A simple index-based iteration does improve the performance.

how to set Sampling Configuration for same operation name with different request URI

Reqirement

for example, I have a service. Service have two http interface, and both are POST method:

I want to set different sampling for interfaces above:

{
  "service_strategies": [
    {
      "service": "myservice",
      "type": "probabilistic",
      "param": 0.8,
      "operation_strategies": [
        {
          "operation": "encrypt",
          "type": "probabilistic",
          "param": 0.4
        },
        {
          "operation": "decrypt",
          "type": "probabilistic",
          "param": 0.6
        }
      ]
    }
  ]
}

Main Question

Because all operation name are http method, how can I set different sampling configuration for them?

Thinking

1, I want to change operation name by ServletFilterSpanDecorator, but it performs after sampler action.

2, According to #42 and #45, it is not recommended to change operation name. Two reasons as following:

  • request URI may have multiple pattern. /user/{id}
  • high cardinality

(1) request URI may have multiple pattern.
If resolves multiple pattern problem, jaeger-client maybe need to implement pattern resolver.

(2) high cardinality. It is appreciated that talk more details about high cardinality, such as high cardinality affects what(storage? query? or others?) @pavolloffay

How about adding some control to HttpServletRequestExtractAdapter?

Here's the story: HttpServletRequestExtractAdapter extracts all the header values into a map. Just wondering, what would be the best way for it to skip some specific headers. For instance, I don't want to extract Authorization header (otherwise it's propagated to outgoing requests by some implementations of Tracer).

Does it make sense to add some control to HttpServletRequestExtractAdapter? Like, passing a filter function to the constructor.

More descriptive operation names

Currently the span names are set to the method of the request, e.g. POST.

It would be helpful if this were something like: 'HTTP POST api/v1/foo/'
or just included the endpoint.

Alternatively, we could configure the tracer with a function that returns a span name from a request.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.