-
Notifications
You must be signed in to change notification settings - Fork 48
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
Add tracing instrumentation #80
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,7 +54,8 @@ public abstract class AsyncCommand : Command, IAsyncCommand, ITimeout | |
private bool compressed; | ||
private bool inAuthenticate; | ||
private bool inHeader = true; | ||
|
||
private Activity activity; | ||
|
||
/// <summary> | ||
/// Default Constructor. | ||
/// </summary> | ||
|
@@ -203,14 +204,25 @@ private void ExecuteCore() | |
} | ||
ExecuteCommand(); | ||
} | ||
|
||
private void ExecuteCommand() | ||
{ | ||
iteration++; | ||
|
||
Exception exception = null; | ||
|
||
StartActivity(); | ||
|
||
try | ||
{ | ||
node = (AsyncNode)GetNode(cluster); | ||
|
||
if (activity != null) | ||
{ | ||
activity.SetTag("node.name", node.Name); | ||
activity.SetTag("node.address", node.NodeAddress.ToString()); | ||
} | ||
|
||
node.ValidateErrorCount(); | ||
conn = node.GetAsyncConnection(); | ||
|
||
|
@@ -229,29 +241,60 @@ private void ExecuteCommand() | |
} | ||
catch (AerospikeException.Connection aec) | ||
{ | ||
exception = aec; | ||
ErrorCount++; | ||
ConnectionFailed(aec); | ||
} | ||
catch (AerospikeException.Backoff aeb) | ||
{ | ||
exception = aeb; | ||
ErrorCount++; | ||
Backoff(aeb); | ||
} | ||
catch (AerospikeException ae) | ||
{ | ||
exception = ae; | ||
ErrorCount++; | ||
FailOnApplicationError(ae); | ||
} | ||
catch (SocketException se) | ||
{ | ||
exception = se; | ||
ErrorCount++; | ||
OnSocketError(se.SocketErrorCode); | ||
} | ||
catch (Exception e) | ||
{ | ||
exception = e; | ||
ErrorCount++; | ||
FailOnApplicationError(new AerospikeException(e)); | ||
} | ||
finally | ||
{ | ||
if (activity != null && exception != null) | ||
{ | ||
activity.SetStatus(ActivityStatusCode.Error, exception.ToString()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think the status description should contain the full exception. There are exception tags made for this https://opentelemetry.io/docs/specs/semconv/attributes-registry/exception. See how they do it in That would allow a UI to format the exception if the rights tags are present. |
||
} | ||
} | ||
} | ||
|
||
private void StartActivity() | ||
{ | ||
// Because of the retry mecanism, one operation can result in several I/Os, on several nodes. | ||
// For this reason, we create a new Activity on every retry, so that we can set the actual node | ||
// adress and the I/O status as tags of this current Activity. | ||
|
||
// If we're retrying, stop the previous Activity before restarting a new one. | ||
activity?.Dispose(); | ||
activity = Tracing.Source.StartActivity(GetType().Name, ActivityKind.Client); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://opentelemetry.io/docs/specs/semconv/database/database-spans/ According to the spec, we should try to make the span name look like |
||
if (activity != null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be great to have the following tags:
|
||
// https://github.com/open-telemetry/opentelemetry-specification/blob/6ce62202e5407518e19c56c445c13682ef51a51d/specification/trace/semantic_conventions/span-general.md#general-remote-service-attributes | ||
activity.SetTag("peer.service", Tracing.SERVICE_NAME); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The service name is one of the most important information. When the trace is displayed on a UI (Jaeger, Tempo), it will be the most visible info. I would avoid hardcoding it but either use the cluster name or a new user-provided string. |
||
// https://github.com/open-telemetry/opentelemetry-specification/blob/6ce62202e5407518e19c56c445c13682ef51a51d/specification/trace/semantic_conventions/database.md#connection-level-attributes | ||
activity.SetTag("db.system", Tracing.SERVICE_NAME); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to the spec, |
||
activity.SetTag("iteration", iteration); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There doesn't seem to be a standard for retries tags. Though there is |
||
} | ||
} | ||
|
||
public void OnConnected() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using System.Diagnostics; | ||
|
||
namespace Aerospike.Client | ||
{ | ||
public class Tracing | ||
{ | ||
private const string SOURCE_NAME = "Aerospike.Client"; | ||
|
||
internal const string SERVICE_NAME = "Aerospike"; | ||
|
||
internal static readonly ActivitySource Source = new ActivitySource(SOURCE_NAME); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can add the version of the assembly in the ActivitySource ctor |
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those don't seem to be standard tags, I would use
network.peer*
as mentioned below.