From 3b3d363ec8c6bf1b264d703f9683cf4483b86fed Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Sun, 18 Jun 2017 12:32:42 +0100 Subject: [PATCH 01/12] Initial version of Observer APIs --- .../contrib/observer/SpanBuilderObserver.java | 51 +++++++++++++ .../contrib/observer/SpanObserver.java | 73 +++++++++++++++++++ .../contrib/observer/TracerObserver.java | 9 +++ 3 files changed, 133 insertions(+) create mode 100644 opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanBuilderObserver.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/SpanBuilderObserver.java b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanBuilderObserver.java new file mode 100644 index 0000000..e86559a --- /dev/null +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanBuilderObserver.java @@ -0,0 +1,51 @@ +/** + * 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 io.opentracing.Span; +import io.opentracing.SpanContext; + +/** + * This interface represents an observer used to receive notifications related to a {@link SpanBuilder}. + * + */ +public interface SpanBuilderObserver { + + /** + * Notifies observer that the named tag has been set/changed. + * + * @param name The tag name + * @param value The tag value + */ + void onWithTag(String name, Object value); + + /** + * Notifies observer that a reference has been added of the specified + * type. + * + * @param referenceType The reference type + * @param referencedContext The referenced span context + */ + void onAddReference(String referenceType, SpanContext referencedContext); + + /** + * Notifies the observer that the {@link Span} has been started. + * + * @param span The started span + * @param startMicros The start time in microseconds + * @return The observer for the span + */ + SpanObserver onStart(Span span, long startMicros); + +} 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..58967df --- /dev/null +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanObserver.java @@ -0,0 +1,73 @@ +/** + * 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 Span}. + * + */ +public interface SpanObserver { + + /** + * Notifies the observer that the operation name has been changed. + * + * @param operationName The new operation name + */ + void onSetOperationName(String operationName); + + /** + * Notifies the observer that the named tag has been set/changed. + * + * @param name The tag name + * @param value The tag value + */ + void onSetTag(String name, Object value); + + /** + * Notifies the observer that the named baggage item has been set/changed. + * + * @param key The baggage key + * @param value The baggage value + */ + void onSetBaggageItem(String key, String value); + + /** + * Notifies the observer that a log event has been recorded. + * + * @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(long timestampMicroseconds, Map fields); + + /** + * Notifies the observer that a log event has been recorded. + * + * @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(long timestampMicroseconds, String event); + + /** + * Notifies the observer that the associated {@link Span} has finished. + * + * @param finishMicros The finish time in microseconds + */ + void onFinish(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..2d6fcc9 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 @@ -19,4 +19,13 @@ */ public interface TracerObserver { + /** + * Notifies the observer that a new span is being built with the supplied operation + * name. + * + * @param operationName The operation name + * @return The observer for the {@link SpanBuilder} + */ + SpanBuilderObserver onBuildSpan(String operationName); + } From 63cfe5b52b4ea5f31acb0cbba72f3452f086900c Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Wed, 21 Jun 2017 08:59:59 +0100 Subject: [PATCH 02/12] Update based on comments --- .../observer/ExampleStatefulObserver.java | 67 +++++++++++++++++++ .../observer/ExampleStatelessObserver.java | 48 +++++++++++++ .../contrib/observer/SpanBuilderObserver.java | 51 -------------- .../contrib/observer/SpanData.java | 46 +++++++++++++ .../contrib/observer/SpanObserver.java | 20 ++++-- .../contrib/observer/TracerObserver.java | 11 +-- 6 files changed, 181 insertions(+), 62 deletions(-) create mode 100644 opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java create mode 100644 opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java delete mode 100644 opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanBuilderObserver.java create mode 100644 opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java diff --git a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java new file mode 100644 index 0000000..ed3b62a --- /dev/null +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java @@ -0,0 +1,67 @@ +package io.opentracing.contrib.observer; + +import java.util.HashMap; +import java.util.Map; + +public class ExampleStatefulObserver implements TracerObserver { + + @Override + public SpanObserver onStart(SpanData spanData, long startMicros, String operationName) { + return new StatefulSpanObserver(spanData, startMicros, operationName); + } + + public static class SpanState { + private final long startMicros; + private String operationName; + + public SpanState(SpanData spanData, long startMicros, String operationName) { + this.startMicros = startMicros; + this.operationName = operationName; + } + } + + public static class StatefulSpanObserver implements SpanObserver { + + private Map spanState = new HashMap(); + + public StatefulSpanObserver(SpanData spanData, long startMicros, String operationName) { + SpanState state = new SpanState(spanData, startMicros, operationName); + spanState.put(spanData.getSpanId(), state); + } + + @Override + public void onSetOperationName(SpanData spanData, String operationName) { + // TODO Auto-generated method stub + + } + + @Override + public void onSetTag(SpanData spanData, String name, Object value) { + // TODO Auto-generated method stub + + } + + @Override + public void onSetBaggageItem(SpanData spanData, String key, String value) { + // TODO Auto-generated method stub + + } + + @Override + public void onLog(SpanData spanData, long timestampMicroseconds, Map fields) { + // TODO Auto-generated method stub + + } + + @Override + public void onLog(SpanData spanData, long timestampMicroseconds, String event) { + // TODO Auto-generated method stub + + } + + @Override + public void onFinish(SpanData spanData, long finishMicros) { + SpanState state = spanState.remove(spanData.getSpanId()); + } + } +} diff --git a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java new file mode 100644 index 0000000..5bd8200 --- /dev/null +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java @@ -0,0 +1,48 @@ +package io.opentracing.contrib.observer; + +import java.util.Map; + +public class ExampleStatelessObserver implements TracerObserver, SpanObserver { + + @Override + public SpanObserver onStart(SpanData spanData, long startMicros, String operationName) { + return this; + } + + @Override + public void onSetOperationName(SpanData spanData, String operationName) { + // TODO Auto-generated method stub + + } + + @Override + public void onSetTag(SpanData spanData, String name, Object value) { + // TODO Auto-generated method stub + + } + + @Override + public void onSetBaggageItem(SpanData spanData, String key, String value) { + // TODO Auto-generated method stub + + } + + @Override + public void onLog(SpanData spanData, long timestampMicroseconds, Map fields) { + // TODO Auto-generated method stub + + } + + @Override + public void onLog(SpanData spanData, long timestampMicroseconds, String event) { + // TODO Auto-generated method stub + + } + + @Override + public void onFinish(SpanData spanData, long finishMicros) { + // TODO Auto-generated method stub + + } + +} diff --git a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanBuilderObserver.java b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanBuilderObserver.java deleted file mode 100644 index e86559a..0000000 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanBuilderObserver.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * 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 io.opentracing.Span; -import io.opentracing.SpanContext; - -/** - * This interface represents an observer used to receive notifications related to a {@link SpanBuilder}. - * - */ -public interface SpanBuilderObserver { - - /** - * Notifies observer that the named tag has been set/changed. - * - * @param name The tag name - * @param value The tag value - */ - void onWithTag(String name, Object value); - - /** - * Notifies observer that a reference has been added of the specified - * type. - * - * @param referenceType The reference type - * @param referencedContext The referenced span context - */ - void onAddReference(String referenceType, SpanContext referencedContext); - - /** - * Notifies the observer that the {@link Span} has been started. - * - * @param span The started span - * @param startMicros The start time in microseconds - * @return The observer for the span - */ - SpanObserver onStart(Span span, long startMicros); - -} 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..62e4b30 --- /dev/null +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java @@ -0,0 +1,46 @@ +/** + * 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; + +/** + * This interface provides information about the current {@link Span} to the observer + * methods. + * + */ +public interface SpanData { + + /** + * This method returns an id that can be used for correlation purposes. It should only + * be used within the application to uniquely distinguish one span from another, + * to enable state to be maintained within observer implementation where appropriate. + * + * @return The unique id for the span + */ + Object getSpanId(); + + String getOperationName(); + + /* Spec does not indicate that a tag key could have multiple values - but some tracers support + * this? Would be good to understand the usecase for multivalued keys - and add some text in the + * spec to clarify this? + * Possibly as well as returning the String,Boolean,Number values, it could return a List in those cases? + * + * Q: Do we need a 'getTags' method - in which case would it return Map> ? + * Other option may be to have a Set getTagKeys() ? + */ + Object getTag(String key); + + 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 index 58967df..6310df0 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanObserver.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanObserver.java @@ -24,50 +24,56 @@ 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(String operationName); + void onSetOperationName(SpanData spanData, String operationName); /** * Notifies the observer that the named tag has been set/changed. * - * @param name The tag name + * @param spanData The data for the span + * @param key The tag key * @param value The tag value */ - void onSetTag(String name, Object 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(String key, String 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(long timestampMicroseconds, Map fields); + 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(long timestampMicroseconds, String event); + void onLog(SpanData spanData, long timestampMicroseconds, String event); /** * Notifies the observer that the associated {@link Span} has finished. * + * @param spanData The data for the span * @param finishMicros The finish time in microseconds */ - void onFinish(long finishMicros); + 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 2d6fcc9..b18670f 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,6 +13,8 @@ */ package io.opentracing.contrib.observer; +import io.opentracing.Span; + /** * This interface represents an observer used to receive notifications related to {@link Span}s. * @@ -20,12 +22,13 @@ public interface TracerObserver { /** - * Notifies the observer that a new span is being built with the supplied operation - * name. + * Notifies the observer that a new span has been started with the supplied details. * + * @param spanData The data for the span being started + * @param startMicros The start time in microseconds * @param operationName The operation name - * @return The observer for the {@link SpanBuilder} + * @return The observer for the {@link Span} */ - SpanBuilderObserver onBuildSpan(String operationName); + SpanObserver onStart(SpanData spanData, long startMicros, String operationName); } From a2338232d19ab0bd6cb50de962af78f259a689f1 Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Wed, 21 Jun 2017 09:12:35 +0100 Subject: [PATCH 03/12] fix header --- .../contrib/observer/ExampleStatefulObserver.java | 13 +++++++++++++ .../contrib/observer/ExampleStatelessObserver.java | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java index ed3b62a..3c56d61 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java @@ -1,3 +1,16 @@ +/** + * 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.HashMap; diff --git a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java index 5bd8200..f1009ec 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java @@ -1,3 +1,16 @@ +/** + * 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; From e94ac6ef92472b4e5e17dc5216bb0eb6d2afa63e Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Wed, 21 Jun 2017 09:44:58 +0100 Subject: [PATCH 04/12] Include startTime in SpanData, to allow stateless onFinish method to calculate the duration, e.g. for reporting metrics --- .../java/io/opentracing/contrib/observer/SpanData.java | 7 +++++++ 1 file changed, 7 insertions(+) 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 index 62e4b30..a7b082d 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java @@ -29,6 +29,13 @@ public interface SpanData { */ Object getSpanId(); + /** + * The start time of the {@link Span}. + * + * @return The start time, in microseconds + */ + long getStartTime(); + String getOperationName(); /* Spec does not indicate that a tag key could have multiple values - but some tracers support From 65d14012be3164a345072a94c8e0b06ec344f383 Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Wed, 21 Jun 2017 09:50:34 +0100 Subject: [PATCH 05/12] Don't pass startTime and op to onStart, as available in the spanData --- .../contrib/observer/ExampleStatefulObserver.java | 14 +++++++------- .../contrib/observer/ExampleStatelessObserver.java | 2 +- .../contrib/observer/TracerObserver.java | 6 ++---- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java index 3c56d61..37e422d 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java @@ -19,17 +19,17 @@ public class ExampleStatefulObserver implements TracerObserver { @Override - public SpanObserver onStart(SpanData spanData, long startMicros, String operationName) { - return new StatefulSpanObserver(spanData, startMicros, operationName); + public SpanObserver onStart(SpanData spanData) { + return new StatefulSpanObserver(spanData); } public static class SpanState { private final long startMicros; private String operationName; - public SpanState(SpanData spanData, long startMicros, String operationName) { - this.startMicros = startMicros; - this.operationName = operationName; + public SpanState(SpanData spanData) { + this.startMicros = spanData.getStartTime(); + this.operationName = spanData.getOperationName(); } } @@ -37,8 +37,8 @@ public static class StatefulSpanObserver implements SpanObserver { private Map spanState = new HashMap(); - public StatefulSpanObserver(SpanData spanData, long startMicros, String operationName) { - SpanState state = new SpanState(spanData, startMicros, operationName); + public StatefulSpanObserver(SpanData spanData) { + SpanState state = new SpanState(spanData); spanState.put(spanData.getSpanId(), state); } diff --git a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java index f1009ec..6b79773 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java @@ -18,7 +18,7 @@ public class ExampleStatelessObserver implements TracerObserver, SpanObserver { @Override - public SpanObserver onStart(SpanData spanData, long startMicros, String operationName) { + public SpanObserver onStart(SpanData spanData) { return this; } 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 b18670f..443a0a7 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 @@ -22,13 +22,11 @@ public interface TracerObserver { /** - * Notifies the observer that a new span has been started with the supplied details. + * Notifies the observer that a new span has been started with the supplied data. * * @param spanData The data for the span being started - * @param startMicros The start time in microseconds - * @param operationName The operation name * @return The observer for the {@link Span} */ - SpanObserver onStart(SpanData spanData, long startMicros, String operationName); + SpanObserver onStart(SpanData spanData); } From 79dea5c4c0604a9600fe92485b460740605d9810 Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Wed, 21 Jun 2017 11:57:55 +0100 Subject: [PATCH 06/12] Remove misleading state in stateful observer example --- .../contrib/observer/ExampleStatefulObserver.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java index 37e422d..439f5c0 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java @@ -23,22 +23,17 @@ public SpanObserver onStart(SpanData spanData) { return new StatefulSpanObserver(spanData); } - public static class SpanState { - private final long startMicros; - private String operationName; - - public SpanState(SpanData spanData) { - this.startMicros = spanData.getStartTime(); - this.operationName = spanData.getOperationName(); + public static class MyObserverState { + public MyObserverState() { } } public static class StatefulSpanObserver implements SpanObserver { - private Map spanState = new HashMap(); + private Map spanState = new HashMap(); public StatefulSpanObserver(SpanData spanData) { - SpanState state = new SpanState(spanData); + MyObserverState state = new MyObserverState(); spanState.put(spanData.getSpanId(), state); } @@ -74,7 +69,7 @@ public void onLog(SpanData spanData, long timestampMicroseconds, String event) { @Override public void onFinish(SpanData spanData, long finishMicros) { - SpanState state = spanState.remove(spanData.getSpanId()); + MyObserverState state = spanState.remove(spanData.getSpanId()); } } } From 9be2556666f1d47010adc9c8b1328569c42aea97 Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Thu, 22 Jun 2017 10:32:12 +0100 Subject: [PATCH 07/12] Added getTags on SpanObserver, updated TracerObserver javadoc to provide example, removed example observer classes --- .../observer/ExampleStatefulObserver.java | 75 ------------------- .../observer/ExampleStatelessObserver.java | 61 --------------- .../contrib/observer/SpanData.java | 42 +++++++---- .../contrib/observer/SpanObserver.java | 7 +- .../contrib/observer/TracerObserver.java | 16 ++++ 5 files changed, 47 insertions(+), 154 deletions(-) delete mode 100644 opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java delete mode 100644 opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java diff --git a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java deleted file mode 100644 index 439f5c0..0000000 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatefulObserver.java +++ /dev/null @@ -1,75 +0,0 @@ -/** - * 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.HashMap; -import java.util.Map; - -public class ExampleStatefulObserver implements TracerObserver { - - @Override - public SpanObserver onStart(SpanData spanData) { - return new StatefulSpanObserver(spanData); - } - - public static class MyObserverState { - public MyObserverState() { - } - } - - public static class StatefulSpanObserver implements SpanObserver { - - private Map spanState = new HashMap(); - - public StatefulSpanObserver(SpanData spanData) { - MyObserverState state = new MyObserverState(); - spanState.put(spanData.getSpanId(), state); - } - - @Override - public void onSetOperationName(SpanData spanData, String operationName) { - // TODO Auto-generated method stub - - } - - @Override - public void onSetTag(SpanData spanData, String name, Object value) { - // TODO Auto-generated method stub - - } - - @Override - public void onSetBaggageItem(SpanData spanData, String key, String value) { - // TODO Auto-generated method stub - - } - - @Override - public void onLog(SpanData spanData, long timestampMicroseconds, Map fields) { - // TODO Auto-generated method stub - - } - - @Override - public void onLog(SpanData spanData, long timestampMicroseconds, String event) { - // TODO Auto-generated method stub - - } - - @Override - public void onFinish(SpanData spanData, long finishMicros) { - MyObserverState state = spanState.remove(spanData.getSpanId()); - } - } -} diff --git a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java deleted file mode 100644 index 6b79773..0000000 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/ExampleStatelessObserver.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * 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; - -public class ExampleStatelessObserver implements TracerObserver, SpanObserver { - - @Override - public SpanObserver onStart(SpanData spanData) { - return this; - } - - @Override - public void onSetOperationName(SpanData spanData, String operationName) { - // TODO Auto-generated method stub - - } - - @Override - public void onSetTag(SpanData spanData, String name, Object value) { - // TODO Auto-generated method stub - - } - - @Override - public void onSetBaggageItem(SpanData spanData, String key, String value) { - // TODO Auto-generated method stub - - } - - @Override - public void onLog(SpanData spanData, long timestampMicroseconds, Map fields) { - // TODO Auto-generated method stub - - } - - @Override - public void onLog(SpanData spanData, long timestampMicroseconds, String event) { - // TODO Auto-generated method stub - - } - - @Override - public void onFinish(SpanData spanData, long finishMicros) { - // TODO Auto-generated method stub - - } - -} 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 index a7b082d..6065560 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java @@ -13,41 +13,53 @@ */ package io.opentracing.contrib.observer; +import java.util.Map; + /** - * This interface provides information about the current {@link Span} to the observer + * 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 correlation purposes. It should only - * be used within the application to uniquely distinguish one span from another, - * to enable state to be maintained within observer implementation where appropriate. + * 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 unique id for the span + * @return The correlation id for the span, MUST implement equals/hashCode to enable + * it to be used as a map key */ - Object getSpanId(); + Object getCorrelationId(); /** - * The start time of the {@link Span}. + * The start time of the {@link io.opentracing.Span}. * * @return The start time, in microseconds */ long getStartTime(); + /** + * The operation name of the {@link io.opentracing.Span}. + * + * @return The operation name + */ String getOperationName(); - /* Spec does not indicate that a tag key could have multiple values - but some tracers support - * this? Would be good to understand the usecase for multivalued keys - and add some text in the - * spec to clarify this? - * Possibly as well as returning the String,Boolean,Number values, it could return a List in those cases? - * - * Q: Do we need a 'getTags' method - in which case would it return Map> ? - * Other option may be to have a Set getTagKeys() ? + /** + * This method provides access to the tags associated with the span. + * + * @return The tags */ - Object getTag(String key); + Map getTags(); + /** + * 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 index 6310df0..d212d6a 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanObserver.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanObserver.java @@ -16,7 +16,7 @@ import java.util.Map; /** - * This interface represents an observer used to receive notifications related to a {@link Span}. + * This interface represents an observer used to receive notifications related to a {@link io.opentracing.Span}. * */ public interface SpanObserver { @@ -30,7 +30,8 @@ public interface SpanObserver { void onSetOperationName(SpanData spanData, String operationName); /** - * Notifies the observer that the named tag has been set/changed. + * 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 @@ -69,7 +70,7 @@ public interface SpanObserver { void onLog(SpanData spanData, long timestampMicroseconds, String event); /** - * Notifies the observer that the associated {@link Span} has finished. + * 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 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 443a0a7..04056db 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 @@ -24,6 +24,22 @@ 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 being started * @return The observer for the {@link Span} */ From 5c1070171937b45642cd3a0736d22939e09b63a7 Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Wed, 28 Jun 2017 14:52:21 +0100 Subject: [PATCH 08/12] Add accessor for finish time and also to calculate duration, as found useful in java-metrics --- .../opentracing/contrib/observer/SpanData.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) 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 index 6065560..82dd278 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java @@ -36,10 +36,24 @@ public interface SpanData { /** * The start time of the {@link io.opentracing.Span}. * - * @return The start time, in microseconds + * @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}. * From 92b222436871d37bc3135c5a8468ad44466a9cef Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Tue, 4 Jul 2017 10:23:55 +0100 Subject: [PATCH 09/12] Change getTags to enable list of values to be supported --- .../main/java/io/opentracing/contrib/observer/SpanData.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 index 82dd278..ab0ce25 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java @@ -13,6 +13,7 @@ */ package io.opentracing.contrib.observer; +import java.util.List; import java.util.Map; /** @@ -66,7 +67,7 @@ public interface SpanData { * * @return The tags */ - Map getTags(); + Map> getTags(); /** * This method retrieves a baggage item associated with the supplied key. From f0faa912f275e4dc074561c11ee2b6c503448ef8 Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Tue, 4 Jul 2017 13:50:52 +0100 Subject: [PATCH 10/12] Fix formatting issue --- .../src/main/java/io/opentracing/contrib/observer/SpanData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index ab0ce25..8c2d8ac 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java @@ -67,7 +67,7 @@ public interface SpanData { * * @return The tags */ - Map> getTags(); + Map> getTags(); /** * This method retrieves a baggage item associated with the supplied key. From 5d38bba8e2d71718e396225f6315b0a968c0c825 Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Fri, 7 Jul 2017 10:51:05 +0100 Subject: [PATCH 11/12] Use a simplified approach for getting tags ignoring potential for multiple values --- .../java/io/opentracing/contrib/observer/SpanData.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 index 8c2d8ac..1ba09fa 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java @@ -13,7 +13,6 @@ */ package io.opentracing.contrib.observer; -import java.util.List; import java.util.Map; /** @@ -63,11 +62,13 @@ public interface SpanData { String getOperationName(); /** - * This method provides access to the tags associated with the span. + * 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(); + Map getTags(); /** * This method retrieves a baggage item associated with the supplied key. From d70fad0f3f28b79f5ea163ac3f5196f5e6c40232 Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Fri, 7 Jul 2017 11:36:40 +0100 Subject: [PATCH 12/12] Added extra type based tag accessors and clarified when callbacks are called --- .../contrib/observer/SpanData.java | 27 +++++++++++++++++++ .../contrib/observer/SpanObserver.java | 4 ++- .../contrib/observer/TracerObserver.java | 2 +- 3 files changed, 31 insertions(+), 2 deletions(-) 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 index 1ba09fa..7645714 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanData.java @@ -70,6 +70,33 @@ public interface SpanData { */ 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. * 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 index d212d6a..633e9f8 100644 --- a/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanObserver.java +++ b/opentracing-observer/src/main/java/io/opentracing/contrib/observer/SpanObserver.java @@ -17,7 +17,9 @@ /** * 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 { 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 04056db..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 @@ -40,7 +40,7 @@ public interface TracerObserver { * 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 being started + * @param spanData The data for the span that has been started * @return The observer for the {@link Span} */ SpanObserver onStart(SpanData spanData);