-
Notifications
You must be signed in to change notification settings - Fork 284
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
CP-44752: propagate System.Diagnostics tracing information using W3C traceparent header #5929
base: master
Are you sure you want to change the base?
Conversation
…ency This only exists on .Net 4.6+, so add it conditionally only when target >Netstandard 2.0 (which includes .Net 4.6). This allows creating activity spans, independently of the tracing framework used. Signed-off-by: Edwin Török <[email protected]>
Internal build succeeded with locked package dependencies too. |
I think I'll also need |
Doesn't exist on .Net45. Signed-off-by: Edwin Török <[email protected]>
This is not available on .Net 4.5 Signed-off-by: Edwin Török <[email protected]>
To avoid someone injecting a malicious binary with the same version in the future, lock all dependencies. Signed-off-by: Edwin Török <[email protected]>
c2723ca
to
3037f81
Compare
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.
haven't tested it yet but I spotted a couple of things on the first run
for SDK PRs also please request reviews manually, because we don't monitor the repo as often as toolstack does, so it helps to see PR reviews under https://github.com/pulls
@@ -155,6 +158,11 @@ public partial class JsonRpcClient | |||
{ | |||
private int _globalId; | |||
|
|||
#if (NET462_OR_GREATER || NETSTANDARD2_0_OR_GREATER) | |||
// TODO: get proper version string from build |
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.
We never merge source with TODOs on master
.
Use the name of the package XenServer.NET
and its version. I think we can get it from https://learn.microsoft.com/en-us/dotnet/api/system.reflection.assemblyname.version?view=netstandard-2.0, but needs testing
If not, this needs a placeholder, and changes to pipelines. We can advise on that if needed
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.
If the client code uses the C# SDK as a project in their code, typeof(JsonRpcClient).Assembly.GetName().Version
should return the SDK version, but in the corner case of someone dropping the sources in a client project (like XenCenter does), it should return the client project version (in XC it would return XenModel's version, which is XC's version).
If we can't have the ocaml build use a placeholder and replace it with the tag (we ran into some trouble with @psafont when we tried it for the API reference), I suggest using new ActivitySource("XenAPI.JsonRpcClient", "@SDK_VERSION@")
(the truth is I dislike placeholders like this, but we have one more insance of it in the PS code).
By the way, is it indeed the SDK version we need here? (As opposed to a string that will be representing the implementing client, somehting like the UserAgent, for example).
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.
but in the corner case of someone dropping the sources in a client project (like XenCenter does)
we could do without the placeholder and just add a line in the README 🤷
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.
By the way, is it indeed the SDK version we need here? (As opposed to a string that will be representing the implementing client, somehting like the UserAgent, for example).
for this, I'd say so
if a client wants to use open telemetry, it should add it itself and then use its own user agent
I may be wrong - I'm not that familiar with what the expected behaviour is
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.
it should add it itself and then use its own user agent
Yes, the thing is we offer the option to use own UserAgent (albeit it sub-optimally designed in my opinion), but we don't offer this option for the activity source with this design.
@@ -225,6 +241,10 @@ protected virtual T Rpc<T>(string callName, JToken parameters, JsonSerializer se | |||
|
|||
using (var responseStream = new MemoryStream()) | |||
{ | |||
#if (NET462_OR_GREATER || NETSTANDARD2_0_OR_GREATER) | |||
// https://opentelemetry.io/docs/specs/semconv/rpc/json-rpc/ |
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.
please add a comment explaining the tag within the source. links can change and not work anymore. If you still think it'd be useful to have a link, I'd use https://archive.org/
if (errorArray != null) { | ||
#if (NET462_OR_GREATER || NETSTANDARD2_0_OR_GREATER) | ||
activity?.SetTag("otel.status_code", "ERROR"); | ||
//activity?.SetTag("rpc.jsonrpc.error_message", errorArray); |
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.
//activity?.SetTag("rpc.jsonrpc.error_message", errorArray); |
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.
Should we be imlementing this properly rather than commenting it out - currently there is disparity between v1 and v2 implementation.
if (errorArray != null) | ||
if (errorArray != null) { | ||
#if (NET462_OR_GREATER || NETSTANDARD2_0_OR_GREATER) | ||
activity?.SetTag("otel.status_code", "ERROR"); |
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.
I'd use const
for all these strings here (such as otel.status_code
, ERROR
, etc.)
@@ -239,12 +259,25 @@ protected virtual T Rpc<T>(string callName, JToken parameters, JsonSerializer se | |||
#else | |||
var res2 = (JsonResponseV2<T>)serializer.Deserialize(responseReader, typeof(JsonResponseV2<T>)); | |||
#endif | |||
|
|||
#if (NET462_OR_GREATER || NETSTANDARD2_0_OR_GREATER) | |||
activity?.SetTag("rpc.jsonrpc.version", "2.0"); |
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.
Shouldn't we be setting this tag further down for v1 too?
// propagate W3C traceparent and tracestate | ||
// HttpClient would do this automatically on .NET 5, | ||
// and .NET 6 would provide even more control over this: https://blog.ladeak.net/posts/opentelemetry-net6-httpclient | ||
// the caller must ensure that the activity is in W3C format (by inheritance or direc setting) |
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.
typo: direc->direct
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.
As above.
The newer System.Net.Http would propagate this automatically, but the older WebRequest doesn't.
Retrieve the span identifier and add the header ourselves. The WebRequest object is fresh for each request, so setting the headers shouldn't cause race conditions.
This adds a dependency on a library that is part of .Net source repository, but distributed outside of it on NuGet: System.Diagnostics. Lock the dependency to a given hash to avoid accidental/malicious changes.
This dependency is not available on .Net45, so all the code and build dependencies are wrapped with appropriate conditional compilation directives (which may look kind of ugly, they can be dropped once XenServer.dll drops support for .Net45 and switches to .Net462 minimum).
No new instrumentation is created, so if the application using XenServer.dll is not configured/set up to use OpenTelemetry or System.Diagnostics.DiagnosticSource, then this is a no-op.
I've tested this using the Powershell 7 module.
Draft PR because: