diff --git a/ocaml/sdk-gen/csharp/autogen/src/JsonRpc.cs b/ocaml/sdk-gen/csharp/autogen/src/JsonRpc.cs index 71c9ea81f4c..71eb59797a0 100644 --- a/ocaml/sdk-gen/csharp/autogen/src/JsonRpc.cs +++ b/ocaml/sdk-gen/csharp/autogen/src/JsonRpc.cs @@ -29,6 +29,9 @@ using System; using System.Collections.Generic; +#if (NET462_OR_GREATER || NETSTANDARD2_0_OR_GREATER) +using System.Diagnostics; +#endif using System.IO; using System.Net; using System.Net.Security; @@ -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 + private static ActivitySource source = new ActivitySource("XenAPI.JsonRpcClient", "1.0"); +#endif + public JsonRpcClient(string baseUrl) { Url = baseUrl; @@ -207,6 +215,14 @@ protected virtual T Rpc(string callName, JToken parameters, JsonSerializer se // therefore the latter will be done only in DEBUG mode using (var postStream = new MemoryStream()) { +#if (NET462_OR_GREATER || NETSTANDARD2_0_OR_GREATER) + using (Activity activity = source.CreateActivity("XenAPI" + callName, ActivityKind.Client)) + { + // .NET 5 would use W3C format for the header by default but we build for .Net 4.x still + activity?.SetIdFormat(ActivityIdFormat.W3C); + activity?.Start(); + activity?.SetTag("rpc.jsonrpc.request_id", id); +#endif using (var sw = new StreamWriter(postStream)) { #if DEBUG @@ -225,6 +241,10 @@ protected virtual T Rpc(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/ + activity?.SetTag("rpc.method", callName); +#endif PerformPostRequest(postStream, responseStream); responseStream.Position = 0; @@ -239,12 +259,25 @@ protected virtual T Rpc(string callName, JToken parameters, JsonSerializer se #else var res2 = (JsonResponseV2)serializer.Deserialize(responseReader, typeof(JsonResponseV2)); #endif + +#if (NET462_OR_GREATER || NETSTANDARD2_0_OR_GREATER) + activity?.SetTag("rpc.jsonrpc.version", "2.0"); +#endif if (res2.Error != null) { var descr = new List { res2.Error.Message }; descr.AddRange(res2.Error.Data.ToObject()); +#if (NET462_OR_GREATER || NETSTANDARD2_0_OR_GREATER) + activity?.SetTag("otel.status_code", "ERROR"); + activity?.SetTag("rpc.jsonrpc.error_code", res2.Error.Code); + activity?.SetTag("rpc.jsonrpc.error_message", descr); +#endif throw new Failure(descr); } + +#if (NET462_OR_GREATER || NETSTANDARD2_0_OR_GREATER) + activity?.SetTag("otel.status_code", "OK"); +#endif return res2.Result; default: #if DEBUG @@ -256,14 +289,25 @@ protected virtual T Rpc(string callName, JToken parameters, JsonSerializer se if (res1.Error != null) { var errorArray = res1.Error.ToObject(); - if (errorArray != null) + if (errorArray != null) { +#if (NET462_OR_GREATER || NETSTANDARD2_0_OR_GREATER) + activity?.SetTag("otel.status_code", "ERROR"); + //activity?.SetTag("rpc.jsonrpc.error_message", errorArray); +#endif throw new Failure(errorArray); + } } +#if (NET462_OR_GREATER || NETSTANDARD2_0_OR_GREATER) + activity?.SetTag("otel.status_code", "OK"); +#endif return res1.Result; } } } } +#if (NET462_OR_GREATER || NETSTANDARD2_0_OR_GREATER) + } +#endif } } @@ -293,6 +337,23 @@ protected virtual void PerformPostRequest(Stream postStream, Stream responseStre webRequest.Headers.Add(header.Key, header.Value); } +#if (NET462_OR_GREATER || NETSTANDARD2_0_OR_GREATER) + // 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) + var activity = Activity.Current; + if (activity != null && activity.IdFormat == ActivityIdFormat.W3C) + { + webRequest.Headers.Add("traceparent", activity.Id); + var state = activity.TraceStateString; + if (state?.Length > 0) + { + webRequest.Headers.Add("tracestate", state); + } + } +#endif + using (var str = webRequest.GetRequestStream()) { postStream.CopyTo(str); diff --git a/ocaml/sdk-gen/csharp/autogen/src/XenServer.csproj b/ocaml/sdk-gen/csharp/autogen/src/XenServer.csproj index bf387509141..dca57a17557 100644 --- a/ocaml/sdk-gen/csharp/autogen/src/XenServer.csproj +++ b/ocaml/sdk-gen/csharp/autogen/src/XenServer.csproj @@ -18,6 +18,7 @@ packageIcon.png git README-NuGet.md + true @@ -30,6 +31,9 @@ + + + True diff --git a/ocaml/sdk-gen/csharp/autogen/src/packages.lock.json b/ocaml/sdk-gen/csharp/autogen/src/packages.lock.json new file mode 100644 index 00000000000..bca624389d3 --- /dev/null +++ b/ocaml/sdk-gen/csharp/autogen/src/packages.lock.json @@ -0,0 +1,84 @@ +{ + "version": 1, + "dependencies": { + ".NETFramework,Version=v4.5": { + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.2, )", + "resolved": "1.0.2", + "contentHash": "5/cSEVld+px/CuRrbohO/djfg6++eR6zGpy88MgqloXvkj//WXWpFZyu/OpkXPN0u5m+dN/EVwLNYFUxD4h2+A==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net45": "1.0.2" + } + }, + "Newtonsoft.Json": { + "type": "Direct", + "requested": "[13.0.3, )", + "resolved": "13.0.3", + "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" + }, + "Microsoft.NETFramework.ReferenceAssemblies.net45": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "Nm14pRmqB+4u2JEMdtngnbDcJidTmswMxOJ992TpTwiwcUTERxLlHwwSh0HiUoRjS0TO0sozsiB0h6FHjCUdEA==" + } + }, + ".NETStandard,Version=v2.0": { + "NETStandard.Library": { + "type": "Direct", + "requested": "[2.0.3, )", + "resolved": "2.0.3", + "contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Newtonsoft.Json": { + "type": "Direct", + "requested": "[13.0.3, )", + "resolved": "13.0.3", + "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Direct", + "requested": "[8.0.1, )", + "resolved": "8.0.1", + "contentHash": "vaoWjvkG1aenR2XdjaVivlCV9fADfgyhW5bZtXT23qaEea0lWiUljdQuze4E31vKM7ZWJaSUsbYIKE3rnzfZUg==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.4.0", + "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + } + } + } +} \ No newline at end of file