Skip to content

Commit 6064e6d

Browse files
committed
refactor: Enhance activity tracking in LDAP operations with detailed tags
1 parent 00ffec8 commit 6064e6d

1 file changed

Lines changed: 77 additions & 9 deletions

File tree

src/TraceableLdapClient/TraceableLdapConnection.cs

Lines changed: 77 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public TraceableLdapConnection(LdapDirectoryIdentifier identifier, NetworkCreden
7878

7979
public void Bind()
8080
{
81-
Activity? activity = StartActivity(nameof(Bind));
81+
Activity? activity = StartActivity(OtelOperations.Bind);
8282
long start = Stopwatch.GetTimestamp();
8383
s_requestCounter.Add(1);
8484
try
@@ -100,7 +100,7 @@ public void Bind()
100100

101101
public void Bind(NetworkCredential newCredential)
102102
{
103-
using Activity? activity = StartActivity(nameof(Bind));
103+
using Activity? activity = StartActivity(OtelOperations.Bind);
104104
long start = Stopwatch.GetTimestamp();
105105
s_requestCounter.Add(1);
106106
activity?.SetTag(OtelTags.Username, newCredential?.UserName);
@@ -123,7 +123,7 @@ public void Bind(NetworkCredential newCredential)
123123

124124
public DirectoryResponse SendRequest(DirectoryRequest request)
125125
{
126-
using Activity? activity = StartActivity(nameof(SendRequest));
126+
using Activity? activity = StartActivity(request);
127127
long start = Stopwatch.GetTimestamp();
128128
s_requestCounter.Add(1);
129129
ArgumentNullException.ThrowIfNull(request);
@@ -133,11 +133,14 @@ public DirectoryResponse SendRequest(DirectoryRequest request)
133133
{
134134
DirectoryResponse response = _inner.SendRequest(request);
135135
activity?.SetTag(OtelTags.ResponseType, response.GetType().Name);
136+
activity?.SetTag(OtelTags.ResultCode, response.ResultCode.ToString());
137+
activity?.SetTag(OtelTags.ErrorMessage, response.ErrorMessage);
136138
activity?.SetStatus(ActivityStatusCode.Ok);
137139
if (response is SearchResponse searchResponse)
138140
{
139141
s_searchEntryCounter.Add(searchResponse.Entries.Count);
140142
}
143+
141144
return response;
142145
}
143146
catch (Exception ex)
@@ -154,7 +157,7 @@ public DirectoryResponse SendRequest(DirectoryRequest request)
154157

155158
public DirectoryResponse SendRequest(DirectoryRequest request, TimeSpan requestTimeout)
156159
{
157-
using Activity? activity = StartActivity(nameof(SendRequest));
160+
using Activity? activity = StartActivity(request);
158161
long start = Stopwatch.GetTimestamp();
159162
s_requestCounter.Add(1);
160163
ArgumentNullException.ThrowIfNull(request);
@@ -164,6 +167,8 @@ public DirectoryResponse SendRequest(DirectoryRequest request, TimeSpan requestT
164167
{
165168
DirectoryResponse response = _inner.SendRequest(request, requestTimeout);
166169
activity?.SetTag(OtelTags.ResponseType, response.GetType().Name);
170+
activity?.SetTag(OtelTags.ResultCode, response.ResultCode.ToString());
171+
activity?.SetTag(OtelTags.ErrorMessage, response.ErrorMessage);
167172
activity?.SetStatus(ActivityStatusCode.Ok);
168173
if (response is SearchResponse searchResponse)
169174
{
@@ -186,7 +191,7 @@ public DirectoryResponse SendRequest(DirectoryRequest request, TimeSpan requestT
186191
public IAsyncResult BeginSendRequest(DirectoryRequest request, PartialResultProcessing partialMode, AsyncCallback callback, object state)
187192
{
188193
ArgumentNullException.ThrowIfNull(request);
189-
Activity? activity = StartActivity(nameof(SendRequest));
194+
Activity? activity = StartActivity(request);
190195
long start = Stopwatch.GetTimestamp();
191196
s_requestCounter.Add(1);
192197
activity?.SetTag(OtelTags.RequestType, request.GetType().Name);
@@ -207,7 +212,7 @@ public IAsyncResult BeginSendRequest(DirectoryRequest request, PartialResultProc
207212
public IAsyncResult BeginSendRequest(DirectoryRequest request, TimeSpan requestTimeout, PartialResultProcessing partialMode, AsyncCallback callback, object state)
208213
{
209214
ArgumentNullException.ThrowIfNull(request);
210-
Activity? activity = StartActivity(nameof(SendRequest));
215+
Activity? activity = StartActivity(request);
211216
long start = Stopwatch.GetTimestamp();
212217
s_requestCounter.Add(1);
213218
activity?.SetTag(OtelTags.RequestType, request.GetType().Name);
@@ -240,6 +245,8 @@ public DirectoryResponse EndSendRequest(IAsyncResult asyncResult)
240245
{
241246
DirectoryResponse response = _inner.EndSendRequest(asyncResult);
242247
activity?.SetTag(OtelTags.ResponseType, response.GetType().Name);
248+
activity?.SetTag(OtelTags.ResultCode, response.ResultCode.ToString());
249+
activity?.SetTag(OtelTags.ErrorMessage, response.ErrorMessage);
243250
activity?.SetStatus(ActivityStatusCode.Ok);
244251
if (response is SearchResponse searchResponse)
245252
{
@@ -339,12 +346,30 @@ protected virtual void Dispose(bool disposing)
339346
}
340347
}
341348

342-
private Activity? StartActivity(string name, ActivityKind kind = ActivityKind.Client)
349+
private Activity? StartActivity(DirectoryRequest request, ActivityKind kind = ActivityKind.Client)
350+
{
351+
string activityName = GetActivityName(request);
352+
Activity? activity = _activitySource.StartActivity(activityName, kind);
353+
if (activity is not null && request is SearchRequest sr)
354+
{
355+
activity.SetTag("ldap.search.base", sr.DistinguishedName);
356+
activity.SetTag("ldap.search.scope", sr.Scope.ToString());
357+
activity.SetTag("ldap.search.filter", sr.Filter);
358+
activity.SetTag("ldap.search.attributes", string.Join(',', sr.Attributes));
359+
activity.SetTag("ldap.search.size_limit", sr.SizeLimit);
360+
activity.SetTag("ldap.search.time_limit", sr.TimeLimit);
361+
}
362+
363+
return activity;
364+
}
365+
366+
private Activity? StartActivity(string operation, ActivityKind kind = ActivityKind.Client)
343367
{
344-
Activity? activity = _activitySource.StartActivity(name, kind);
368+
Activity? activity = _activitySource.StartActivity($"ldap {operation}", kind);
345369
if (activity is not null)
346370
{
347371
SetNetworkTags(activity);
372+
activity.SetTag(OtelTags.Operation, operation);
348373
}
349374

350375
return activity;
@@ -365,19 +390,62 @@ private void SetNetworkTags(Activity activity)
365390
}
366391
}
367392

393+
private static string GetActivityName(DirectoryRequest request)
394+
{
395+
#pragma warning disable CA1308 // Normalize strings to uppercase - OTEL semantic conventions
396+
string operation = request.GetType().Name.Replace("Request", string.Empty, StringComparison.Ordinal).ToLowerInvariant();
397+
#pragma warning restore CA1308 // Normalize strings to uppercase - OTEL semantic conventions
398+
string target = string.Empty;
399+
400+
if (request is SearchRequest sr)
401+
{
402+
target = $"{sr.DistinguishedName} ({sr.Filter})";
403+
}
404+
else if (request is AddRequest ar)
405+
{
406+
target = ar.DistinguishedName;
407+
}
408+
else if (request is DeleteRequest dr)
409+
{
410+
target = dr.DistinguishedName;
411+
}
412+
else if (request is ModifyRequest mr)
413+
{
414+
target = mr.DistinguishedName;
415+
}
416+
else if (request is CompareRequest cr)
417+
{
418+
target = cr.DistinguishedName;
419+
}
420+
else if (request is ExtendedRequest er)
421+
{
422+
target = er.RequestName;
423+
}
424+
425+
return $"{operation} {target}".TrimEnd();
426+
}
427+
368428
private static double GetElapsedMilliseconds(long startTimestamp)
369429
{
370430
if (startTimestamp == 0) return 0;
371431
return Stopwatch.GetElapsedTime(startTimestamp).TotalMilliseconds;
372432
}
373433

434+
private static class OtelOperations
435+
{
436+
public const string Bind = "bind";
437+
}
438+
374439
private static class OtelTags
375440
{
376441
public const string ExceptionType = "exception.type";
377442
public const string ExceptionMessage = "exception.message";
378443
public const string ExceptionStacktrace = "exception.stacktrace";
379444
public const string RequestType = "requestType";
380-
public const string ResponseType = "responseType";
445+
public const string Operation = "ldap.operation";
446+
public const string ResponseType = "ldap.response.type";
447+
public const string ResultCode = "ldap.response.result_code";
448+
public const string ErrorMessage = "ldap.response.error_message";
381449
public const string Username = "username";
382450
public const string Timeout = "timeout";
383451
public const string Aborted = "aborted";

0 commit comments

Comments
 (0)