Giter VIP home page Giter VIP logo

java-thrift's Introduction

Build Status Coverage Status Released Version Apache-2.0 license

OpenTracing Apache Thrift Instrumentation

OpenTracing instrumentation for Apache Thrift

pom.xml

<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-thrift</artifactId>
    <version>VERSION</version>
</dependency>

Usage

Please don't use FieldID equal 3333. It is a magic number for injected span context.

// Instantiate tracer
Tracer tracer = ...

// Optionally register tracer with GlobalTracer
GlobalTracer.register(tracer);

Synchronous mode

Server

// Decorate TProcessor with SpanProcessor e.g.
TProcessor processor = ...
TProcessor spanProcessor = new SpanProcessor(processor, tracer);
TServerTransport transport = ...
TServer server = new TSimpleServer(new Args(transport).processor(spanProcessor));

Client

// Decorate TProtocol with SpanProtocol e.g.

TTransport transport = ...
TProtocol protocol = new TBinaryProtocol(transport);
TProtocol spanProtocol = new SpanProtocol(protocol, tracer)

Asynchronous mode

Server

// Decorate TProcessor with SpanProcessor
TProcessor processor = ...
TProcessor spanProcessor = new SpanProcessor(processor, tracer);

TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(8890, 30000);
TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(tnbSocketTransport);
tnbArgs.processor(spanProcessor);
TServer server = new TNonblockingServer(tnbArgs);

Client

// Decorate TProtocolFactory with SpanProtocol.Factory
TProtocolFactory factory = new TBinaryProtocol.Factory();
SpanProtocol.Factory protocolFactory = new SpanProtocol.Factory(factory, tracer, false);

TNonblockingTransport transport = new TNonblockingSocket("localhost", 8890);
TAsyncClientManager clientManager = new TAsyncClientManager();
AsyncClient asyncClient = new AsyncClient(protocolFactory, clientManager, transport);

// Decorate AsyncMethodCallback with TracingAsyncMethodCallback:
AsyncMethodCallback<T> callback = ...
TracingAsyncMethodCallback<T> tracingCallback = new TracingAsyncMethodCallback(callback, protocolFactory);

asyncClient.callMethod(..., tracingCallback);

Custom Client Span Tags

To customise the tags added to spans on the client side, create a custom implementation of ClientSpanDecorator.

class MyClientSpanDecorator implements ClientSpanDecorator {
    
    @Override
    public void decorate(Span span, TMessage message) {
        // Add custom tags to the span.
    }
    
    @Override
    public void onError(Throwable throwable, Span span) {
        // Add custom tags for when an error is thrown by the thrift call.
    }
}

Then pass this into your SpanProtocol.

TProtocol spanProtocol = new SpanProtocol(protocol, tracer, new MyClientSpanDecorator() );

If no custom ClientSpanDecorator is provided, the DefaultClientSpanDecorator is used. This delegates its methods to the static methods in the SpanDecorator class. The DefaultClientSpanDecorator can be extended if you want to add to the default behaviour.

License

Apache 2.0 License.

java-thrift's People

Contributors

dependabot[bot] avatar froodulous avatar malafeev avatar mpetazzoni avatar safris avatar yurishkuro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

java-thrift's Issues

Log exception details when Message.type == TMessageType.EXCEPTION

Currently, when a message of type EXCEPTION is returned by a thrift service, the server-side span is tagged as an error. However, no details of the exception are logged to the span. When the SpanProcessor catches an exception, it creates error logs and adds them to the span. Can the library do the same when the exception is returned by thrift? Just the type of the exception being returned would be useful.

needs to be backwards-compatible

@malafeev IIRC (please correct me if I'm wrong), this approach requires that servers upgrade before clients. That is operationally sketchy/dangerous.

Am I missing something about the name-prepending-based approach?

An alternative would be to use a "magic" tag number within the top-level message. I would favor that approach for the forwards- and backwards-compatibility benefits.

Trace context is included multiple times when Thrift messages involves sub-structures

Because the trace context information is written in writeFieldStop(), it will be included at the end of each Thrift structure that gets encoded on the protocol. This is problematic when the request includes collections of other Thrift structures, as the trace context information will be added many many times at the end of each "object", adding a considerable amount of overhead to the network exchanges.

That being said, I'm not sure there is another way to do this given the hooks given to us by the TProtocol interface, unless there is somehow a way to use writeMessageEnd()?

Cut a 0.0.4 release?

Hi @malafeev,

Thanks for the quick turnaround on merging #3 and #4! With those two fixes I got java-thrift to correctly trace my Thrift RPC calls, and pass along trace context from client to server as desired. Would you be willing to make a 0.0.4 release and deploy that to Maven Central? It would make dependency management much easier.

Thanks in advance!

TCompactProtocol protocol id violation

I was seeing a protocol id exception using TCompactProtocol with some complicated unit tests (multiple clients threads, complex thrift structures, variety of interactions). I fixed this issue by replacing "injected" with an integer level that follows structure nesting:
jspofford@e3b54db#diff-7571f63b5051b15d8bf04742cfc4e517

I would have submitted a pull request but had trouble reproducing in your simplified unit tests. I'd need to dig further to isolate how the stream position is being upset. You may want to include this change anyway simply to ensure that the span data is sent in the last field stop instead of the first one, assuming you want to measure until the end of the incoming data serialization instead of just the first structure.

Unit tests pass with this change.

One-way calls lead to thread scope leak/accumulation

The current code of the SpanProtocol assumes that a receive will always follow a write to close the tracing scope once the response has been received from the server. Unfortunately that's not always the case when you consider oneway endpoints.

@pavolloffay Any ideas on how to handle this?

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.