Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Commit

Permalink
Merge pull request #32 from opentracing/bhs/span_context_etc
Browse files Browse the repository at this point in the history
An RFC for SpanContext, References, as well as changes to carriers
  • Loading branch information
bensigelman authored Jul 15, 2016
2 parents 88c8fef + 623db61 commit b0d7b07
Show file tree
Hide file tree
Showing 25 changed files with 498 additions and 388 deletions.
35 changes: 35 additions & 0 deletions opentracing-api/src/main/java/io/opentracing/References.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Copyright 2016 The OpenTracing Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package io.opentracing;

/**
* References is essentially a namespace for the official OpenTracing reference types.
*
* References are used by Tracer.buildSpan() to describe the relationships between Spans.
*
* @see io.opentracing.Tracer.SpanBuilder#addReference(Object, SpanContext)
*/
public final class References {
private References(){}

/**
* See http://opentracing.io/spec/#causal-span-references for more information about CHILD_OF references
*/
public static final String CHILD_OF = "child_of";

/**
* See http://opentracing.io/spec/#causal-span-references for more information about FOLLOWS_FROM references
*/
public static final String FOLLOWS_FROM = "follows_from";
}
91 changes: 42 additions & 49 deletions opentracing-api/src/main/java/io/opentracing/Span.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,60 +19,53 @@
* <p>Spans are created by the {@link Tracer#buildSpan} interface.
*/
public interface Span extends AutoCloseable {
/**
* Retrieve the associated SpanContext.
*
* @return the SpanContext that encapsulates Span state that should propagate across process boundaries.
*/
SpanContext context();

/**
* Sets the end timestamp and records the span.
*
* <p>This should be the last call made to any span instance, and to do otherwise leads to
* undefined behavior.
*/
void finish();
/**
* Sets the end timestamp and records the span.
*
* <p>This should be the last call made to any span instance, and to do otherwise leads to
* undefined behavior.
*/
void finish();

void close();
void close();

/**
* Set a key:value tag on the Span.
*/
// overloaded 3x to support the BasicType concern
Span setTag(String key, String value);
/**
* Set a key:value tag on the Span.
*/
// overloaded 3x to support the BasicType concern
Span setTag(String key, String value);

/** Same as {@link #setTag(String, String)}, but for boolean values. */
Span setTag(String key, boolean value);
/** Same as {@link #setTag(String, String)}, but for boolean values. */
Span setTag(String key, boolean value);

/** Same as {@link #setTag(String, String)}, but for numeric values. */
Span setTag(String key, Number value);
/** Same as {@link #setTag(String, String)}, but for numeric values. */
Span setTag(String key, Number value);

/**
* Set a Baggage item, represented as a simple string:string pair.
*
* Note that newly-set Baggage items are only guaranteed to propagate to future children of the given Span.
*/
Span setBaggageItem(String key, String value);
/**
* Add a new log event to the Span, accepting an event name string and an optional structured payload argument.
* If specified, the payload argument may be of any type and arbitrary size,
* though implementations are not required to retain all payload arguments
* (or even all parts of all payload arguments).
*
* The timestamp of this log event is the current time.
**/
Span log(String eventName, /* @Nullable */ Object payload);

/** Get a Baggage item by key.
*
* Returns null if no entry found, or baggage is not supported in the current implementation.
*/
String getBaggageItem(String key);

/**
* Add a new log event to the Span, accepting an event name string and an optional structured payload argument.
* If specified, the payload argument may be of any type and arbitrary size,
* though implementations are not required to retain all payload arguments
* (or even all parts of all payload arguments).
*
* The timestamp of this log event is the current time.
**/
Span log(String eventName, /* @Nullable */ Object payload);

/**
* Add a new log event to the Span, accepting an event name string and an optional structured payload argument.
* If specified, the payload argument may be of any type and arbitrary size,
* though implementations are not required to retain all payload arguments
* (or even all parts of all payload arguments).
*
* The timestamp is specified manually here to represent a past log event.
* The timestamp in microseconds in UTC time.
**/
Span log(long timestampMicroseconds, String eventName, /* @Nullable */ Object payload);
/**
* Add a new log event to the Span, accepting an event name string and an optional structured payload argument.
* If specified, the payload argument may be of any type and arbitrary size,
* though implementations are not required to retain all payload arguments
* (or even all parts of all payload arguments).
*
* The timestamp is specified manually here to represent a past log event.
* The timestamp in microseconds in UTC time.
**/
Span log(long timestampMicroseconds, String eventName, /* @Nullable */ Object payload);
}
39 changes: 39 additions & 0 deletions opentracing-api/src/main/java/io/opentracing/SpanContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright 2016 The OpenTracing Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package io.opentracing;

/**
* SpanContext represents Span state that must propagate to descendant Spans and across process boundaries.
*
* SpanContext is logically divided into two pieces: (1) the user-level "Baggage" (see set_baggage_item and get_baggage_item) that propagates across Span boundaries and (2) any Tracer-implementation-specific fields that are needed to identify or otherwise contextualize the associated Span instance (e.g., a <trace_id, span_id, sampled> tuple).
*/
public interface SpanContext {
/**
* Sets a baggage item in the SpanContext as a key/value pair.
*
* Baggage enables powerful distributed context propagation functionality where arbitrary application data can be carried along the full path of request execution throughout the system.
*
* Note 1: Baggage is only propagated to the future (recursive) children of this SpanContext.
*
* Note 2: Baggage is sent in-band with every subsequent local and remote calls, so this feature must be used with care.
*
* @return this SpanContext instance, for chaining
*/
SpanContext setBaggageItem(String key, String value);

/**
* @return the value of the baggage item identified by the given key, or null if no such item could be found
*/
String getBaggageItem(String key);
}
80 changes: 43 additions & 37 deletions opentracing-api/src/main/java/io/opentracing/Tracer.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,78 +15,84 @@


/**
* Tracer is a simple, thin interface for Span creation, and Span propagation into different transport formats.
* Tracer is a simple, thin interface for Span creation and propagation across arbitrary transports.
*/
public interface Tracer {

/**
* Create, start, and return a new Span with the given `operationName`.
* An optional parent Span can be specified used to incorporate the newly-returned Span into an existing trace.
* Return a new SpanBuilder for a Span with the given `operationName`.
*
* <p>Example:
* <p>A contrived example:
* <pre>{@code
Tracer tracer = ...
Span feed = tracer.buildSpan("GetFeed")
.start();
Span parentSpan = tracer.buildSpan("DoWork")
.start();
Span http = tracer.buildSpan("HandleHTTPRequest")
.withParent(feed)
.asChildOf(parentSpan.context())
.withTag("user_agent", req.UserAgent)
.withTag("lucky_number", 42)
.start();
}</pre>
*/
SpanBuilder buildSpan(String operationName);

/** Takes two arguments:
* a Span instance, and
* a “carrier” object in which to inject that Span for cross-process propagation.
/**
* Inject a SpanContext into a `carrier` of a given type, presumably for propagation across process boundaries.
*
* A “carrier” object is some sort of http or rpc envelope, for example HeaderGroup (from Apache HttpComponents).
* <p>Example:
* <pre>{@code
* Tracer tracer = ...
* Span clientSpan = ...
* HttpHeaderWriter httpHeaderWriter = new AnHttpHeaderCarrier(httpRequest);
* tracer.inject(span.context(), httpHeaderWriter);
* }</pre>
*
* Attempting to inject to a carrier that has been registered/configured to this Tracer will result in a
* IllegalStateException.
* @param spanContext the SpanContext instance to inject into the carrier
* @param carrier the carrier for the SpanContext state; when inject() returns, the Tracer implementation will have represented the SpanContext within `carrier`. All Tracer.inject() implementations must support io.opentracing.propagation.TextMapWriter, io.opentracing.propagation.HttpHeaderWriter, and java.nio.ByteBuffer.
*
* All implementations support at minimum the required carriers BinaryWriter and TextMapWriter.
* @see io.opentracing.propagation
*/
<T> void inject(Span span, T carrier);
void inject(SpanContext spanContext, Object carrier);

/** Returns a SpanBuilder provided
* a “carrier” object from which to extract identifying information needed by the new Span instance.
*
* If the carrier object has no such span stored within it, a new Span is created.
*
* Unless there’s an error, it returns a SpanBuilder.
* The Span generated from the builder can be used in the host process like any other.
/**
* Extract a SpanContext from a `carrier` of a given type, presumably after propagation across a process boundary.
*
* (Note that some OpenTracing implementations consider the Spans on either side of an RPC to have the same identity,
* and others consider the caller to be the parent and the receiver to be the child)
* <p>Example:
* <pre>{@code
* Tracer tracer = ...
* HttpHeaderReader httpHeaderReader = new AnHttpHeaderCarrier(httpRequest);
* SpanContext spanCtx = tracer.extract(httpHeaderReader);
* tracer.buildSpan('...').withChildOf(spanCtx).start();
* }</pre>
*
* Attempting to join from a carrier that has been registered/configured to this Tracer will result in a
* IllegalStateException.
* If the span serialized state is invalid (corrupt, wrong version, etc) inside the carrier this will result in an IllegalArgumentException.
*
* If the span serialized state is invalid (corrupt, wrong version, etc) inside the carrier this will result in a
* IllegalArgumentException.
* @param carrier the carrier for the SpanContext state. All Tracer.extract() implementations must support io.opentracing.propagation.TextMapReader, io.opentracing.propagation.HttpHeaderReader, and java.nio.ByteBuffer.
* @returns the SpanContext instance extracted from the carrier
*
* All implementations support at minimum the required carriers BinaryReader and TextMapReader.
* @see io.opentracing.propagation
*/
<T> SpanBuilder join(T carrier);
SpanContext extract(Object carrier);


interface SpanBuilder {

/** Specify the operationName.
*
* If the operationName has already been set (implicitly or explicitly) an IllegalStateException will be thrown.
/**
* A shorthand for withReference(Reference.childOf(parent)).
*/
SpanBuilder withOperationName(String operationName);
SpanBuilder asChildOf(SpanContext parent);

/** Specify the parent span
/**
* Add a reference from the Span being built to a distinct (usually parent) Span. May be called multiple times to represent multiple such References.
*
* @param referenceType the reference type, typically one of the constants defined in References
* @param referencedContext the SpanContext being referenced; e.g., for a References.CHILD_OF referenceType, the referencedContext is the parent
*
* If the parent has already been set an IllegalStateException will be thrown.
* @see io.opentracing.References
*/
SpanBuilder withParent(Span parent);
SpanBuilder addReference(String referenceType, SpanContext referencedContext);

/** Same as {@link Span#setTag(String, String)}, but for the span being built. */
SpanBuilder withTag(String key, String value);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright 2016 The OpenTracing Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package io.opentracing.propagation;

import java.util.Iterator;
import java.util.Map;

/**
* HttpHeaderReader is a built-in carrier for Tracer.inject().
*
* HttpHeaderReader implementations allows Tracers to write key:value String pairs into arbitrary HTTP header representations. In this way, HttpHeaderReader prevents a tight coupling between OpenTracing and any particular Java HTTP Header representation.
*
* @see io.opentracing.Tracer#extract(Object)
*/
public interface HttpHeaderReader {
/**
* Gets HTTP headers from the implementations backing store.
*
* Note that these headers will often be a superset of whatever was injected via an HttpHeaderWriter in the peer. As such, Tracers should use a unique prefix or substring to identify their header map entries.
*
* @return all entries in the HTTP header map; note that keys may appear multiple times (just as they may with HTTP headers)
*
* @see io.opentracing.Tracer#extract(Object)
*/
Iterator<Map.Entry<String,String>> getEntries();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Copyright 2016 The OpenTracing Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package io.opentracing.propagation;

/**
* HttpHeaderWriter is a built-in carrier for Tracer.inject().
*
* HttpHeaderWriter implementations allows Tracers to write key:value String pairs into arbitrary HTTP header representations. In this way, HttpHeaderWriter prevents a tight coupling between OpenTracing and any particular Java HTTP Header representation.
*
* @see io.opentracing.Tracer#inject(io.opentracing.SpanContext, Object)
*/
public interface HttpHeaderWriter {
/**
* Puts a key:value pair into the HTTP header map.
*
* Note that headers added via put() will often share the HTTP header map with other application data. As such, Tracers should use a unique prefix or substring to identify their header map entries.
*
* @param key a key suitable for use in an HTTP header (i.e., case-insensitive, no special characters, etc)
* @param value a value suitable for use in an HTTP header (i.e., URL-escaped)
*
* @see io.opentracing.Tracer#inject(io.opentracing.SpanContext, Object)
*/
void put(String key, String value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,22 @@
*/
package io.opentracing.propagation;

import java.util.Iterator;
import java.util.Map;

/**
* TextMapReader is a built-in carrier for Tracer.extract(). TextMapReader implementations allows Tracers to read key:value String pairs from arbitrary underlying sources of data.
*
* @see io.opentracing.Tracer#extract(Object)
*/
public interface TextMapReader {
Iterable<Map.Entry<String,String>> getEntries();
/**
* Gets an iterator over arbitrary key:value pairs from the TextMapReader.
*
* @return entries in the TextMapReader backing store
*
* @see io.opentracing.Tracer#extract(Object)
* @see io.opentracing.propagation.HttpHeaderReader
*/
Iterator<Map.Entry<String,String>> getEntries();
}
Loading

0 comments on commit b0d7b07

Please sign in to comment.