Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial version of Observer APIs #3

Merged
merged 12 commits into from
Jul 10, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe join with SpanObserver? How would implementations know wether a specific tag is set on the SpanBuilder or the Span? If there is only one onSetTag method which is invoked no matter if the tag was actually set on a SpanBuilder or a Span, people don't have to worry about that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean have one interface SpanObserver that is used by the SpanBuilder to notify, so it would potentially call onSetTag and onAddReference before onStart, and then afterwards potentially have onSetTag called other times before finally onFinish?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be fine my me - although would like to get other feedback first before applying change.


/**
* 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);

}
Original file line number Diff line number Diff line change
@@ -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);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: the operation name can be set multiple times for a span and could also be set via the SpanBuilder. As you only know the operation name for certain when Span#finish is invoked, in my impl onFinish has a operationName parameter.


/**
* 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<String, ?> 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);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add Span parameter similar to onStart?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of the other methods (apart from onStart) are supplied the Span - what would be the purpose of adding it here?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In both these cases the Observer instance could save the span supplied with the onStart and reuse it when any of the other methods were invoked - although I understand the benefit if an impl was only interested in doing something onFinish it would not require an Observer instance per span.

Currently the go observer only supplies it onStart, so if we wanted to change the approach then would need to address it there aswell.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would not require an Observer instance per span.

That's the key point. In stagemonitor, I have the notion of a StatelessEventListener which is a single instance reused for all spans. This saves a lot of object instantiation and reduces GC overhead imposed by the agent.

Another feature my impl currently supports is altering and omitting of certain tags via the onSetTag method.


}
Original file line number Diff line number Diff line change
Expand Up @@ -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);

}