Giter Club home page Giter Club logo

java-cassandra-driver's Introduction

Build Status Coverage Status Released Version Apache-2.0 license

OpenTracing Cassandra Driver Instrumentation

OpenTracing instrumentation for Cassandra Driver.

Installation

Cassandra 3

<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-cassandra-driver-3</artifactId>
    <version>VERSION</version>
</dependency>

Cassandra 4

<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-cassandra-driver-4</artifactId>
    <version>VERSION</version>
</dependency>

Usage

// Instantiate tracer
Tracer tracer = ...

Cassandra 3

// Instantiate Cluster Builder:
 Cluster.Builder builder = Cluster.builder().addContactPoints("127.0.0.1").withPort(9142);

// Instantiate Tracing Cluster:
Cluster cluster = new TracingCluster(builder, tracer);

Cassandra 4

// Instantiate CqlSession:
CqlSession session = CqlSession.builder().build()

// Decorate CqlSession with TracingCqlSession:
CqlSession tracingSession = new TracingCqlSession(session, tracer);

// execute query with TracingCqlSession:
tracingSession.execute("...");

Span Names for Cassandra 3

By default, spans for executed queries will be created with the name execute. To use a different name for the query spans, you can create a custom name provider by implementing the QuerySpanNameProvider interface.

QuerySpanNameProvider interface

public interface QuerySpanNameProvider {
  public interface Builder {
    QuerySpanNameProvider build();
  }

  /**
   * Given a Cassandra query, return a name for the span
   * @param query Cassandra query
   * @return Name for query's span
   */
  String querySpanName(String query);

}

CustomStringSpanName

Returns a predefined string for every span. Defaults to execute on null or "" argument to build()

import io.opentracing.contrib.cassandra.QuerySpanNameProvider.CustomStringSpanName;
import io.opentracing.contrib.cassandra.QuerySpanNameProvider.QuerySpanNameProvider;
...

// Initialize with custom string
QuerySpanNameProvider querySpanNameProvider = CustomStringSpanName.newBuilder().build("CUSTOM_NAME");


// Instantiate Tracing Cluster with QuerySpanNameProvider as an argument
Tracer tracer = ...
Cluster.Builder builder = ...
Cluster cluster = new TracingCluster(builder, tracer, querySpanNameProvider);

Session session = cluster.newSession();

// Execute query
session.execute("SELECT * FROM example.table WHERE field = ?", "test");
// Span is created with span name 
// "CUSTOM_NAME"

FullQuerySpanName

Returns the full query as the span name.

import io.opentracing.contrib.cassandra.QuerySpanNameProvider.FullQuerySpanName;
import io.opentracing.contrib.cassandra.QuerySpanNameProvider.QuerySpanNameProvider;
...

// Initialize
QuerySpanNameProvider querySpanNameProvider = FullQuerySpanName.newBuilder().build();


// Instantiate Tracing Cluster with QuerySpanNameProvider as an argument
Tracer tracer = ...
Cluster.Builder builder = ...
Cluster cluster = new TracingCluster(builder, tracer, querySpanNameProvider);

Session session = cluster.newSession();

// Execute query
session.execute("SELECT * FROM example.table WHERE field = ?", "test");

// Span is created with the full query as the span name,
// "SELECT * FROM example.table WHERE field = ?;"

// Span name will be parameterized if the original given query is parameterized.

PrefixedFullQuerySpanName

Returns the full query as the span name, with a custom string prefix. Defaults to Cassandra on null or "" argument to build().

import io.opentracing.contrib.cassandra.QuerySpanNameProvider.PrefixedFullQuerySpanName;
import io.opentracing.contrib.cassandra.QuerySpanNameProvider.QuerySpanNameProvider;
...

// Initialize with custom prefix string
QuerySpanNameProvider querySpanNameProvider = PrefixedFullQuerySpanName.newBuilder().build("CUSTOM_PREFIX");


// Instantiate Tracing Cluster with QuerySpanNameProvider as an argument
Tracer tracer = ...
Cluster.Builder builder = ...
Cluster cluster = new TracingCluster(builder, tracer, querySpanNameProvider);


Session session = cluster.newSession();

// Execute query
session.execute("SELECT * FROM example.table WHERE field = ?", "test");

// Span is created with the full query as the span name, prefixed with the custom prefix, 
// "CUSTOM_PREFIX: SELECT * FROM example.table WHERE field = ?;"

// Span name will be parameterized if the original given query is parameterized.

QueryMethodTableSpanName

Returns formatted string Cassandra.[METHOD] - [TARGET_ENTITY] where [METHOD] is the Cassandra Method and [TARGET_ENTITY] is the entity that the method is acting on (view, keyspace, table, index).

For methods that require no target entity, returns Cassandra.[METHOD].

If a method does require a target entity, but none is found, returns Cassandra.[METHOD] - N/A.

The supported Cassandra methods are:

  • SELECT
  • INSERT
  • UPDATE
  • DELETE
  • BATCH
  • USE
  • CREATE MATERIALIZED VIEW
  • ALTER MATERIALIZED VIEW
  • DROP MATERIALIZED VIEW
  • CREATE KEYSPACE
  • ALTER KEYSPACE
  • DROP KEYSPACE
  • CREATE TABLE
  • ALTER TABLE
  • DROP TABLE
  • TRUNCATE
  • CREATE INDEX
  • DROP INDEX
import io.opentracing.contrib.cassandra.QuerySpanNameProvider.QueryMethodTableSpanName;
import io.opentracing.contrib.cassandra.QuerySpanNameProvider.QuerySpanNameProvider;
...

// Initialize
QuerySpanNameProvider querySpanNameProvider = QueryMethodTableSpanName.newBuilder().build();


// Instantiate Tracing Cluster with QuerySpanNameProvider as an argument
Tracer tracer = ...
Cluster.Builder builder = ...
Cluster cluster = new TracingCluster(builder, tracer, querySpanNameProvider);

Session session = cluster.newSession();

// Execute query
session.execute("SELECT * FROM example.table WHERE field = ?", "test");

// Span is created with the method and target entity in the name,
// "Cassandra.SELECT - example.table"

// Provider has support for additional qualifiers IF EXISTS and IF NOT EXISTS
session.execute("CREATE TABLE example.table;");
session.execute("CREATE TABLE IF NOT EXISTS example.table;")

// Two spans are created with the same name,
// "Cassandra.CREATE_TABLE - example.table"

License

Apache 2.0 License.

java-cassandra-driver's People

Contributors

bhs avatar cykl avatar jordanjlopez avatar malafeev avatar mkjensen avatar rileyjia avatar safris avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

java-cassandra-driver's Issues

Bug with "QueryMethodTableSpanName" for generate query string

Hi,

In my case, I have some query like this:

select ..., ..., batch_id, ..., ... from ...

And the result is Cassandra.BATCH and not Cassandra.SELECT as expected.
This bug comes from QueryMethodTableSpanName.getManipulationMethod() which search the manipulation method in the whole query.

To fix that, may be cut the query at the first space to only scan the first word ?

Support tracing in Cassandra itself

It would be nice if this module not only wrapped Cassandra calls in the client-side spans, but would also inject the opentracing span context into Cassandra requests so that tracing of the Cassandra backend was also possible, e.g. as was done in this blog post.

Missing parent span in case of using Mapper

When using cassandra-driver-mapping OpenTracing instrumentation doesn't work well. E.g. some spans are missing.

I think I have a fix for that, will prepare the PR soon after internal testing yields positive results.

peer.ipv4 tag is number instead of string

The specification calls for peer.ipv4 to be a string:

peer.ipv4 string Remote IPv4 address as a .-separated tuple. E.g., "127.0.0.1"

https://github.com/opentracing/specification/blob/master/semantic_conventions.md

TracingSession is writing the int representation of the ipv4 address.
https://github.com/opentracing-contrib/java-cassandra-driver/blob/master/src/main/java/io/opentracing/contrib/cassandra/TracingSession.java#L306

This makes the tag representation hard to understand:
{db.instance=test, component=java-cassandra, db.type=cassandra, span.kind=client, db.statement=INSERT INTO testtable (key,value) VALUES (?,?), peer.hostname=localhost, peer.port=9044, peer.ipv4=2130706433}

Instead of
{db.instance=test, component=java-cassandra, db.type=cassandra, span.kind=client, db.statement=INSERT INTO testtable (key,value) VALUES (?,?), peer.hostname=localhost, peer.port=9044, peer.ipv4=127.0.0.1}

Support for reactive cassandra

TracingCqlSession.java is overriding (adding the tracing feature):

  • ResultSet execute(...)
  • CompletionStage<AsyncResultSet> executeAsync(...)

However executeReactive(...) is not present in this class, so this means that tracing is not enabled when using cassandra reactive API. It would be nice to have this feature in this project.

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.