Skip to content
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

Support question mark in wildcard #2875

Merged
merged 10 commits into from
Feb 10, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/OpenTelemetry.Api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

* Improved wildcard support to cover `?` (which matches exactly one character).
reyang marked this conversation as resolved.
Show resolved Hide resolved
([#2875](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2875))

## 1.2.0-rc2

Released 2022-Feb-02
Expand Down
9 changes: 1 addition & 8 deletions src/OpenTelemetry/Metrics/MeterProviderSdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
using System.Diagnostics;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Text.RegularExpressions;
using OpenTelemetry.Internal;
using OpenTelemetry.Resources;

Expand Down Expand Up @@ -84,7 +83,7 @@ internal MeterProviderSdk(
Func<Instrument, bool> shouldListenTo = instrument => false;
if (meterSources.Any(s => s.Contains('*')))
{
var regex = GetWildcardRegex(meterSources);
var regex = this.GetWildcardRegex(meterSources);
shouldListenTo = instrument => regex.IsMatch(instrument.Meter.Name);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a to a contains check for * and ? now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YES 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've fixed this and added test cases.
Not sure if it'll be better to extract the s.Contains('*') || s.Contains('?') logic into a common helper, looks like it is currently used in 3 places.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it'll be better to extract the s.Contains('*') || s.Contains('?') logic into a common helper, looks like it is currently used in 3 places.

I think it'd be a decent minor improvement, so something like:

internal static bool ContainsWildcard(string s)
{
    return s.Contains('*') || s.Contains('?');
}

...

if (meterSources.Any(ContainsWildcard))

but, I'm ok 👍 without if you think it reads better without the helper

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe an extension method on String class? 😆

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That'd work too!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the PR by extracting the wildcard logics to WildcardHelper.

I didn't use String extension method because it could be too noisy (e.g. if someone is using Intellisense).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't use String extension method because it could be too noisy (e.g. if someone is using Intellisense).

Yea I think that's a good call. I was thinking that too, but thought maybe since it'd be internal it'd just affect us and not the whole 🌏

else if (meterSources.Any())
Expand Down Expand Up @@ -235,12 +234,6 @@ internal MeterProviderSdk(
}

this.listener.Start();

static Regex GetWildcardRegex(IEnumerable<string> collection)
{
var pattern = '^' + string.Join("|", from name in collection select "(?:" + Regex.Escape(name).Replace("\\*", ".*") + ')') + '$';
return new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
}
}

internal Resource Resource { get; }
Expand Down
16 changes: 16 additions & 0 deletions src/OpenTelemetry/ProviderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
// </copyright>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
Expand Down Expand Up @@ -69,5 +72,18 @@ internal static Action GetObservableInstrumentCollectCallback(this BaseProvider

return null;
}

internal static Regex GetWildcardRegex(this BaseProvider baseProvider, IEnumerable<string> wildcards = default)
reyang marked this conversation as resolved.
Show resolved Hide resolved
{
if (wildcards == null)
{
return null;
}

var pattern = string.Join(
"|",
from w in wildcards select "(?:" + Regex.Escape(w).Replace("\\*", ".*").Replace("\\?", ".") + ')');
return new Regex('^' + pattern + '$', RegexOptions.Compiled | RegexOptions.IgnoreCase);
}
}
}
13 changes: 3 additions & 10 deletions src/OpenTelemetry/Trace/TracerProviderSdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
using OpenTelemetry.Internal;
using OpenTelemetry.Resources;

Expand Down Expand Up @@ -50,13 +49,13 @@ internal TracerProviderSdk(
this.supportLegacyActivity = legacyActivityOperationNames.Count > 0;

bool legacyActivityWildcardMode = false;
Regex legacyActivityWildcardModeRegex = null;
var legacyActivityWildcardModeRegex = this.GetWildcardRegex();
foreach (var legacyName in legacyActivityOperationNames)
{
if (legacyName.Contains('*'))
{
legacyActivityWildcardMode = true;
legacyActivityWildcardModeRegex = GetWildcardRegex(legacyActivityOperationNames);
legacyActivityWildcardModeRegex = this.GetWildcardRegex(legacyActivityOperationNames);
break;
}
}
Expand Down Expand Up @@ -231,7 +230,7 @@ internal TracerProviderSdk(

if (wildcardMode)
{
var regex = GetWildcardRegex(sources);
var regex = this.GetWildcardRegex(sources);

// Function which takes ActivitySource and returns true/false to indicate if it should be subscribed to
// or not.
Expand Down Expand Up @@ -264,12 +263,6 @@ internal TracerProviderSdk(

ActivitySource.AddActivityListener(listener);
this.listener = listener;

Regex GetWildcardRegex(IEnumerable<string> collection)
{
var pattern = '^' + string.Join("|", from name in collection select "(?:" + Regex.Escape(name).Replace("\\*", ".*") + ')') + '$';
return new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
}
}

internal Resource Resource { get; }
Expand Down
2 changes: 1 addition & 1 deletion test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ public void MeterSourcesWildcardSupportMatchTest(bool hasView)

var exportedItems = new List<Metric>();
var meterProviderBuilder = Sdk.CreateMeterProviderBuilder()
.AddMeter("AbcCompany.XyzProduct.*")
.AddMeter("AbcCompany.XyzProduct.Component?")
alanwest marked this conversation as resolved.
Show resolved Hide resolved
.AddMeter("DefCompany.*.ComponentC")
.AddMeter("GhiCompany.qweProduct.ComponentN") // Mixing of non-wildcard meter name and wildcard meter name.
.AddInMemoryExporter(exportedItems);
Expand Down