From d3936e9cc281318cf84fc619e8c9dc5b29e48e4a Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Mon, 10 Jul 2017 10:35:37 +0100 Subject: [PATCH] Initial version of Observer APIs (#3) Initial version of Observer APIs --- .../contrib/observer/SpanData.java | 108 ++++++++++++++++++ .../contrib/observer/SpanObserver.java | 82 +++++++++++++ .../contrib/observer/TracerObserver.java | 26 +++++ 3 files changed, 216 insertions(+) create mode 100644 opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java create mode 100644 opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanObserver.java diff --git a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java new file mode 100644 index 0000000..7645714 --- /dev/null +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java @@ -0,0 +1,108 @@ +/** + * Copyright 2017 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.contrib.observer; + +import java.util.Map; + +/** + * This interface provides information about the current {@link io.opentracing.Span} to the observer + * methods. + * + */ +public interface SpanData { + + /** + * This method returns an id that can be used for correlate actions invoked on a + * stateful observer. It should only be used within the scope of an application, + * to uniquely distinguish one span from another, to enable state to be maintained + * within observer implementation where appropriate. + * + * @return The correlation id for the span, MUST implement equals/hashCode to enable + * it to be used as a map key + */ + Object getCorrelationId(); + + /** + * The start time of the {@link io.opentracing.Span}. + * + * @return The start time (in microseconds) + */ + long getStartTime(); + + /** + * The finish time of the {@link io.opentracing.Span}. + * + * @return The finish time (in microseconds), or 0 if not available + */ + long getFinishTime(); + + /** + * The duration of the {@link io.opentracing.Span}. + * + * @return The duration (in microseconds), or 0 if the span is not finished + */ + long getDuration(); + + /** + * The operation name of the {@link io.opentracing.Span}. + * + * @return The operation name + */ + String getOperationName(); + + /** + * This method provides access to the tags associated with the span. If the + * tracer implementation supports multiple values for a key, then only the + * most recent value will be returned. + * + * @return The tags + */ + Map getTags(); + + /** + * This method returns the tag value, associated with the supplied key, + * if it exists and has a {@link String} type. + * + * @param key The tag key + * @return The value, if exists and is a {@link String} type, otherwise null + */ + String getStringTag(String key); + + /** + * This method returns the tag value, associated with the supplied key, + * if it exists and has a {@link Number} type. + * + * @param key The tag key + * @return The value, if exists and is a {@link Number} type, otherwise null + */ + Number getNumberTag(String key); + + /** + * This method returns the tag value, associated with the supplied key, + * if it exists and has a {@link Boolean} type. + * + * @param key The tag key + * @return The value, if exists and is a {@link Boolean} type, otherwise null + */ + Boolean getBooleanTag(String key); + + /** + * This method retrieves a baggage item associated with the supplied key. + * + * @param key The key + * @return The baggage item, or null if undefined + */ + Object getBaggageItem(String key); + +} diff --git a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanObserver.java b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanObserver.java new file mode 100644 index 0000000..633e9f8 --- /dev/null +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanObserver.java @@ -0,0 +1,82 @@ +/** + * Copyright 2017 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.contrib.observer; + +import java.util.Map; + +/** + * This interface represents an observer used to receive notifications related to a {@link io.opentracing.Span}. + *

+ * Note: All of these callback functions are called after the associated operation has been performed on the + * {@link io.opentracing.Span}, i.e. they are post-change notifications. + */ +public interface SpanObserver { + + /** + * Notifies the observer that the operation name has been changed. + * + * @param spanData The data for the span + * @param operationName The new operation name + */ + void onSetOperationName(SpanData spanData, String operationName); + + /** + * Notifies the observer that the tag with the supplied key has been set or updated + * on a {@link io.opentracing.Span}. + * + * @param spanData The data for the span + * @param key The tag key + * @param value The tag value + */ + void onSetTag(SpanData spanData, String key, Object value); + + /** + * Notifies the observer that the named baggage item has been set/changed. + * + * @param spanData The data for the span + * @param key The baggage key + * @param value The baggage value + */ + void onSetBaggageItem(SpanData spanData, String key, String value); + + /** + * Notifies the observer that a log event has been recorded. + * + * @param spanData The data for the span + * @param timestampMicroseconds The explicit timestamp for the log record. Must be greater than or equal to the + * Span's start timestamp. + * @param fields key:value log fields. Tracer implementations should support String, numeric, and boolean values; + * some may also support arbitrary Objects. + */ + void onLog(SpanData spanData, long timestampMicroseconds, Map fields); + + /** + * Notifies the observer that a log event has been recorded. + * + * @param spanData The data for the span + * @param timestampMicroseconds The explicit timestamp for the log record. Must be greater than or equal to the + * Span's start timestamp. + * @param event the event value; often a stable identifier for a moment in the Span lifecycle + */ + void onLog(SpanData spanData, long timestampMicroseconds, String event); + + /** + * Notifies the observer that a span associated with the supplied data has finished. + * + * @param spanData The data for the span + * @param finishMicros The finish time in microseconds + */ + void onFinish(SpanData spanData, long finishMicros); + +} diff --git a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/TracerObserver.java b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/TracerObserver.java index d41b00c..39ef6d2 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/TracerObserver.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/TracerObserver.java @@ -13,10 +13,36 @@ */ package io.opentracing.contrib.observer; +import io.opentracing.Span; + /** * This interface represents an observer used to receive notifications related to {@link Span}s. * */ public interface TracerObserver { + /** + * Notifies the observer that a new span has been started with the supplied data. + * + *

An observer can either be implemented as stateful or stateless: + * + *

* A stateful implementation should return a new instance of a {@link SpanObserver} implementation + * for each span that is started, allowing this implementation to locally maintain + * information about that span as subsequent {@link SpanObserver} methods are called. For example, + * where the observer is interested in a sequence of events associated with the span, such as the + * recording of a new tag initiating a metric which then needs to be completed/recorded when the + * span is finished. + * + *

* A stateless implementation should return a singleton instance + * of the {@link SpanObserver}. Each call to the observer will be handled in isolation. For example, + * this approach would be useful when only interested in a specific event - such as + * a {@link SpanObserver#onLog onLog} event which can result in the log details being recorded + * to a logging framework, or {@link SpanObserver#onFinish onFinish} + * being used to record metrics about the duration of the span. + * + * @param spanData The data for the span that has been started + * @return The observer for the {@link Span} + */ + SpanObserver onStart(SpanData spanData); + }