-
Notifications
You must be signed in to change notification settings - Fork 140
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 ability to disable ActivitySource
s from being listened to
#5795
base: master
Are you sure you want to change the base?
Changes from all commits
e67e038
277351d
8c314e6
8d2f356
436bd00
f4e4f36
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 |
---|---|---|
|
@@ -9,12 +9,17 @@ namespace Datadog.Trace.Activity.Handlers | |
{ | ||
internal static class ActivityHandlersRegister | ||
{ | ||
// Disable Activity Handler does not listen to the activity source at all. | ||
internal static readonly DisableActivityHandler DisableHandler = new(); | ||
Comment on lines
+12
to
+13
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. Is there any value in having a separate i.e. should we allow people to disable handlers, but also change all our existing "ignored" handlers to be disabled? 🤔 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. So for the "Ignored" Activities we do go and update them for context propagation so they are ignored in the sense that we don't create a Datadog span for them, but we still do need to do things as we listen to the source. I think we want to keep that. The "Disabled" toggles that listener off so we don't know anything about them. 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. OK, cool, then I guess my question is: what are the implications if someone disables an activity that's in the "middle" of the trace? What about if it's a "root" activity? Will that mess up our tracing, or will we just have a gap (which is fine) but everything else in terms or parenting etc would work ok? I guess that's somewhat covered by the tests, but it's not entirely clear to me 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. Those are good questions I haven't really looked at this stuff in a long time so I don't know off the top of my head, but I will add test cases to the sample project to test this out. |
||
|
||
// Ignore Activity Handler catches existing integrations that also emits activities. | ||
internal static readonly IgnoreActivityHandler IgnoreHandler = new(); | ||
|
||
// Activity handlers in order, the first handler where ShouldListenTo returns true will always handle that source. | ||
internal static readonly IActivityHandler[] Handlers = | ||
{ | ||
DisableHandler, | ||
|
||
IgnoreHandler, | ||
|
||
// Azure Service Bus handlers | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// <copyright file="DisableActivityHandler.cs" company="Datadog"> | ||
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. | ||
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. | ||
// </copyright> | ||
|
||
#nullable enable | ||
|
||
using System.Collections.Generic; | ||
using System.Text.RegularExpressions; | ||
using Datadog.Trace.Activity.DuckTypes; | ||
using Datadog.Trace.Sampling; | ||
|
||
namespace Datadog.Trace.Activity.Handlers | ||
{ | ||
internal class DisableActivityHandler : IActivityHandler | ||
{ | ||
private List<Regex>? _disabledSourceNameGlobs = null; | ||
private bool _disableAll = false; | ||
|
||
public void ActivityStarted<T>(string sourceName, T activity) | ||
where T : IActivity | ||
{ | ||
// do nothing; this should not be called | ||
} | ||
|
||
public void ActivityStopped<T>(string sourceName, T activity) | ||
where T : IActivity | ||
{ | ||
// do nothing; this should not be called | ||
} | ||
|
||
/// <summary> | ||
/// Determines whether <see cref="DisableActivityHandler"/> will "listen" to <paramref name="sourceName"/>. | ||
/// <para> | ||
/// Note that "listen" in this case means that the created ActivityListener will not subscribe to the ActivitySource. | ||
/// </para> | ||
/// </summary> | ||
/// <returns><see langword="true"/> when the Tracer will disable the ActivitySource; otherwise <see langword="false"/></returns> | ||
public bool ShouldListenTo(string sourceName, string? version) | ||
{ | ||
if (_disableAll) | ||
{ | ||
return true; // "*" was specified as a pattern, short circuit to disable all | ||
} | ||
|
||
_disabledSourceNameGlobs ??= PopulateGlobs(); | ||
if (_disabledSourceNameGlobs.Count == 0) | ||
{ | ||
return false; // no glob patterns specified, sourceName will not be disabled | ||
} | ||
|
||
foreach (var regex in _disabledSourceNameGlobs) | ||
{ | ||
if (regex.IsMatch(sourceName)) | ||
{ | ||
return true; // disable ActivitySource of "sourceName" from being listened to by the tracer | ||
} | ||
} | ||
|
||
// sources were specified to be disabled, but this sourceName didn't match any of them | ||
return false; // sourceName will _not_ be disabled | ||
} | ||
|
||
private List<Regex> PopulateGlobs() | ||
{ | ||
var globs = new List<Regex>(); | ||
var toDisable = Tracer.Instance.Settings.DisabledActivitySources; | ||
if (toDisable is null || toDisable.Length == 0) | ||
{ | ||
return globs; | ||
} | ||
|
||
foreach (var disabledSourceNameGlob in toDisable) | ||
{ | ||
// HACK: using RegexBuilder here even though it isn't _really_ for this | ||
var globRegex = RegexBuilder.Build(disabledSourceNameGlob, SamplingRulesFormat.Glob, RegexBuilder.DefaultTimeout); | ||
// handle special case where a "*" pattern will be null | ||
if (globRegex is null) | ||
{ | ||
_disableAll = true; | ||
return []; | ||
} | ||
|
||
globs.Add(globRegex); | ||
} | ||
|
||
return globs; | ||
} | ||
} | ||
} |
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.
Rather than checking the type of the handler here, I wonder if it makes more sense to change the return from
ShouldListenTo
to be an enum instead e.g. something like this (I hate all of these names though!)