29
29
30
30
using System ;
31
31
using System . Collections . Generic ;
32
+ #if NETSTANDARD2_0_OR_GREATER
33
+ using System . Diagnostics ;
34
+ #endif
32
35
using System . IO ;
33
36
using System . Net ;
34
37
using System . Net . Security ;
@@ -155,6 +158,11 @@ public partial class JsonRpcClient
155
158
{
156
159
private int _globalId ;
157
160
161
+ #if NETSTANDARD2_0_OR_GREATER
162
+ // TODO: get proper version string from build
163
+ private static ActivitySource source = new ActivitySource ( "XenAPI.JsonRpcClient" , "1.0" ) ;
164
+ #endif
165
+
158
166
public JsonRpcClient ( string baseUrl )
159
167
{
160
168
Url = baseUrl ;
@@ -207,6 +215,14 @@ protected virtual T Rpc<T>(string callName, JToken parameters, JsonSerializer se
207
215
// therefore the latter will be done only in DEBUG mode
208
216
using ( var postStream = new MemoryStream ( ) )
209
217
{
218
+ #if NETSTANDARD2_0_OR_GREATER
219
+ using ( Activity activity = source . CreateActivity ( "XenAPI" + callName , ActivityKind . Client ) )
220
+ {
221
+ // .NET 5 would use W3C format for the header by default but we build for .Net 4.x still
222
+ activity ? . SetIdFormat ( ActivityIdFormat . W3C ) ;
223
+ activity ? . Start ( ) ;
224
+ activity ? . SetTag ( "rpc.jsonrpc.request_id" , id ) ;
225
+ #endif
210
226
using ( var sw = new StreamWriter ( postStream ) )
211
227
{
212
228
#if DEBUG
@@ -225,6 +241,10 @@ protected virtual T Rpc<T>(string callName, JToken parameters, JsonSerializer se
225
241
226
242
using ( var responseStream = new MemoryStream ( ) )
227
243
{
244
+ #if NETSTANDARD2_0_OR_GREATER
245
+ // https://opentelemetry.io/docs/specs/semconv/rpc/json-rpc/
246
+ activity ? . SetTag ( "rpc.method" , callName ) ;
247
+ #endif
228
248
PerformPostRequest ( postStream , responseStream ) ;
229
249
responseStream . Position = 0 ;
230
250
@@ -239,12 +259,25 @@ protected virtual T Rpc<T>(string callName, JToken parameters, JsonSerializer se
239
259
#else
240
260
var res2 = ( JsonResponseV2 < T > ) serializer . Deserialize ( responseReader , typeof ( JsonResponseV2 < T > ) ) ;
241
261
#endif
262
+
263
+ #if NETSTANDARD2_0_OR_GREATER
264
+ activity ? . SetTag ( "rpc.jsonrpc.version" , "2.0" ) ;
265
+ #endif
242
266
if ( res2 . Error != null )
243
267
{
244
268
var descr = new List < string > { res2 . Error . Message } ;
245
269
descr . AddRange ( res2 . Error . Data . ToObject < string [ ] > ( ) ) ;
270
+ #if NETSTANDARD2_0_OR_GREATER
271
+ activity ? . SetTag ( "otel.status_code" , "ERROR" ) ;
272
+ activity ? . SetTag ( "rpc.jsonrpc.error_code" , res2 . Error . Code ) ;
273
+ activity ? . SetTag ( "rpc.jsonrpc.error_message" , descr ) ;
274
+ #endif
246
275
throw new Failure ( descr ) ;
247
276
}
277
+
278
+ #if NETSTANDARD2_0_OR_GREATER
279
+ activity ? . SetTag ( "otel.status_code" , "OK" ) ;
280
+ #endif
248
281
return res2 . Result ;
249
282
default :
250
283
#if DEBUG
@@ -256,14 +289,25 @@ protected virtual T Rpc<T>(string callName, JToken parameters, JsonSerializer se
256
289
if ( res1 . Error != null )
257
290
{
258
291
var errorArray = res1 . Error . ToObject < string [ ] > ( ) ;
259
- if ( errorArray != null )
292
+ if ( errorArray != null ) {
293
+ #if NETSTANDARD2_0_OR_GREATER
294
+ activity ? . SetTag ( "otel.status_code" , "ERROR" ) ;
295
+ //activity?.SetTag("rpc.jsonrpc.error_message", errorArray);
296
+ #endif
260
297
throw new Failure ( errorArray ) ;
298
+ }
261
299
}
300
+ #if NETSTANDARD2_0_OR_GREATER
301
+ activity ? . SetTag ( "otel.status_code" , "OK" ) ;
302
+ #endif
262
303
return res1 . Result ;
263
304
}
264
305
}
265
306
}
266
307
}
308
+ #if NETSTANDARD2_0_OR_GREATER
309
+ }
310
+ #endif
267
311
}
268
312
}
269
313
0 commit comments