diff --git a/.devcontainer/devcontainer-lock.json b/.devcontainer/devcontainer-lock.json
new file mode 100644
index 00000000..405c47fe
--- /dev/null
+++ b/.devcontainer/devcontainer-lock.json
@@ -0,0 +1,9 @@
+{
+ "features": {
+ "ghcr.io/devcontainers/features/dotnet:2.5.0": {
+ "version": "2.5.0",
+ "resolved": "ghcr.io/devcontainers/features/dotnet@sha256:0fc16547ed4db6d7ff2a9f5981d2b93eb314e568affb9958029ad794f1f9a093",
+ "integrity": "sha256:0fc16547ed4db6d7ff2a9f5981d2b93eb314e568affb9958029ad794f1f9a093"
+ }
+ }
+}
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index ef4cdaf3..38d50b28 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,7 +1,12 @@
{
"name": "Exceptionless.Net",
- "image": "mcr.microsoft.com/vscode/devcontainers/dotnetcore:latest",
+ "image": "mcr.microsoft.com/devcontainers/dotnet:2.2.2-10.0-noble",
+ "features": {
+ "ghcr.io/devcontainers/features/dotnet:2.5.0": {
+ "version": "10.0"
+ }
+ },
"extensions": [
"ms-dotnettools.csharp",
"streetsidesoftware.code-spell-checker",
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 3de28d27..493751cb 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -10,3 +10,24 @@ updates:
semver-major-days: 7
semver-minor-days: 7
semver-patch-days: 7
+
+- package-ecosystem: github-actions
+ directory: "/"
+ schedule:
+ interval: weekly
+ cooldown:
+ default-days: 7
+
+- package-ecosystem: devcontainers
+ directory: "/"
+ schedule:
+ interval: weekly
+ cooldown:
+ default-days: 7
+
+- package-ecosystem: dotnet-sdk
+ directory: "/"
+ schedule:
+ interval: daily
+ cooldown:
+ default-days: 1
diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml
index dd6677c7..69d9c91c 100644
--- a/.github/workflows/build-linux.yml
+++ b/.github/workflows/build-linux.yml
@@ -3,16 +3,19 @@ on: [push, pull_request]
env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
DOTNET_NOLOGO: 1
+permissions:
+ contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v6
+ uses: actions/checkout@v7
with:
fetch-depth: 0
+ persist-credentials: false
- name: Setup .NET SDK
- uses: actions/setup-dotnet@v5
+ uses: actions/setup-dotnet@v6
with:
global-json-file: global.json
- name: Build Reason
@@ -20,7 +23,7 @@ jobs:
- name: Build Version
shell: bash
run: |
- dotnet tool install --global minver-cli --version 6.0.0
+ dotnet tool install --global minver-cli --version 7.0.0
version=$(minver --tag-prefix v)
echo "MINVERVERSIONOVERRIDE=$version" >> $GITHUB_ENV
- name: Build
diff --git a/.github/workflows/build-osx.yml b/.github/workflows/build-osx.yml
index 83852de2..79562b59 100644
--- a/.github/workflows/build-osx.yml
+++ b/.github/workflows/build-osx.yml
@@ -3,16 +3,19 @@ on: [push, pull_request]
env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
DOTNET_NOLOGO: 1
+permissions:
+ contents: read
jobs:
build:
runs-on: macOS-latest
steps:
- name: Checkout
- uses: actions/checkout@v6
+ uses: actions/checkout@v7
with:
fetch-depth: 0
+ persist-credentials: false
- name: Setup .NET SDK
- uses: actions/setup-dotnet@v5
+ uses: actions/setup-dotnet@v6
with:
global-json-file: global.json
- name: Build Reason
@@ -20,7 +23,7 @@ jobs:
- name: Build Version
shell: bash
run: |
- dotnet tool install --global minver-cli --version 6.0.0
+ dotnet tool install --global minver-cli --version 7.0.0
version=$(minver --tag-prefix v)
echo "MINVERVERSIONOVERRIDE=$version" >> $GITHUB_ENV
- name: Build
diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml
index 3efed70e..0c083e72 100644
--- a/.github/workflows/build-windows.yml
+++ b/.github/workflows/build-windows.yml
@@ -3,16 +3,20 @@ on: [push, pull_request]
env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
DOTNET_NOLOGO: 1
+permissions:
+ contents: read
+ packages: write
jobs:
build:
runs-on: windows-latest
steps:
- name: Checkout
- uses: actions/checkout@v6
+ uses: actions/checkout@v7
with:
fetch-depth: 0
+ persist-credentials: false
- name: Setup .NET SDK
- uses: actions/setup-dotnet@v5
+ uses: actions/setup-dotnet@v6
with:
global-json-file: global.json
- name: Build Reason
@@ -20,7 +24,7 @@ jobs:
- name: Build Version
shell: bash
run: |
- dotnet tool install --global minver-cli --version 6.0.0
+ dotnet tool install --global minver-cli --version 7.0.0
version=$(minver --tag-prefix v)
echo "MINVERVERSIONOVERRIDE=$version" >> $GITHUB_ENV
- name: Build
@@ -30,27 +34,24 @@ jobs:
- name: Package
if: github.event_name != 'pull_request'
run: dotnet pack --configuration Release --no-build Exceptionless.Net.Windows.slnx
- - name: Install GitHub Package Tool
- if: github.event_name != 'pull_request'
- run: dotnet tool install gpr -g
- name: Publish CI Packages
shell: bash
if: github.event_name != 'pull_request'
run: |
- for package in $(find -name "*.nupkg" | grep "minver" -v); do
+ while IFS= read -r -d '' package; do
echo "${0##*/}": Pushing $package...
# GitHub
- gpr push $package -k ${{ secrets.GITHUB_TOKEN }} || true
+ dotnet nuget push "$package" --source https://nuget.pkg.github.com/Exceptionless/index.json --api-key ${{ secrets.GITHUB_TOKEN }} --skip-duplicate || true
# Feedz (remove once GitHub supports anonymous access)
- dotnet nuget push $package --source https://f.feedz.io/exceptionless/exceptionless/nuget --api-key ${{ secrets.FEEDZ_KEY }} --skip-duplicate
- done
+ dotnet nuget push "$package" --source https://f.feedz.io/exceptionless/exceptionless/nuget --api-key ${{ secrets.FEEDZ_KEY }} --skip-duplicate
+ done < <(find . -name '*.nupkg' ! -path '*minver*' -print0)
- name: Publish Release Packages
shell: bash
if: startsWith(github.ref, 'refs/tags/v')
run: |
- for package in $(find -name "*.nupkg" | grep "minver" -v); do
+ while IFS= read -r -d '' package; do
echo "${0##*/}": Pushing $package...
- dotnet nuget push $package --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_KEY }} --skip-duplicate
- done
+ dotnet nuget push "$package" --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_KEY }} --skip-duplicate
+ done < <(find . -name '*.nupkg' ! -path '*minver*' -print0)
diff --git a/build/common.props b/build/common.props
index 904a13ee..73381537 100644
--- a/build/common.props
+++ b/build/common.props
@@ -41,7 +41,7 @@
-
+
diff --git a/global.json b/global.json
index 1e7fdfa9..61bcbdd7 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "10.0.100",
+ "version": "10.0.400",
"rollForward": "latestMinor"
}
}
diff --git a/samples/Exceptionless.SampleBlazorWebAssemblyApp/Exceptionless.SampleBlazorWebAssemblyApp.csproj b/samples/Exceptionless.SampleBlazorWebAssemblyApp/Exceptionless.SampleBlazorWebAssemblyApp.csproj
index 62ed9c0c..7a75ff24 100644
--- a/samples/Exceptionless.SampleBlazorWebAssemblyApp/Exceptionless.SampleBlazorWebAssemblyApp.csproj
+++ b/samples/Exceptionless.SampleBlazorWebAssemblyApp/Exceptionless.SampleBlazorWebAssemblyApp.csproj
@@ -7,8 +7,8 @@
-
-
+
+
diff --git a/samples/Exceptionless.SampleLambda/Exceptionless.SampleLambda.csproj b/samples/Exceptionless.SampleLambda/Exceptionless.SampleLambda.csproj
index 3cab80e0..b4fe70dc 100644
--- a/samples/Exceptionless.SampleLambda/Exceptionless.SampleLambda.csproj
+++ b/samples/Exceptionless.SampleLambda/Exceptionless.SampleLambda.csproj
@@ -8,8 +8,8 @@
true
-
-
+
+
diff --git a/samples/Exceptionless.SampleLambdaAspNetCore/Exceptionless.SampleLambdaAspNetCore.csproj b/samples/Exceptionless.SampleLambdaAspNetCore/Exceptionless.SampleLambdaAspNetCore.csproj
index fb9f477f..e1705570 100644
--- a/samples/Exceptionless.SampleLambdaAspNetCore/Exceptionless.SampleLambdaAspNetCore.csproj
+++ b/samples/Exceptionless.SampleLambdaAspNetCore/Exceptionless.SampleLambdaAspNetCore.csproj
@@ -5,8 +5,8 @@
Lambda
-
-
+
+
diff --git a/src/Exceptionless/Exceptionless.csproj b/src/Exceptionless/Exceptionless.csproj
index 21fc7e0d..3fe942bf 100644
--- a/src/Exceptionless/Exceptionless.csproj
+++ b/src/Exceptionless/Exceptionless.csproj
@@ -34,12 +34,12 @@
-
+
-
+
diff --git a/src/Exceptionless/Models/Collections/SettingsDictionary.cs b/src/Exceptionless/Models/Collections/SettingsDictionary.cs
index c67ac38e..7bc18c1f 100644
--- a/src/Exceptionless/Models/Collections/SettingsDictionary.cs
+++ b/src/Exceptionless/Models/Collections/SettingsDictionary.cs
@@ -158,25 +158,6 @@ protected override void OnChanged(ChangedEventArgs>
LogLevel value;
_minLogLevels.TryRemove(logger, out value);
}
-}
-
- foreach (var eventType in _eventTypes) {
- if (eventType.Key == null || !_typeSourceEnabled.TryGetValue(eventType.Key, out var sourceDictionary))
- continue;
-
- if (!args.Item.Key.StartsWith(eventType.Value))
- continue;
-
- var sourceKeysToRemove = new List();
- foreach (string key in sourceDictionary.Keys) {
- if (key.IsPatternMatch(args.Item.Key.Substring(eventType.Value.Length)))
- sourceKeysToRemove.Add(key);
- }
-
- foreach (var logger in sourceKeysToRemove) {
- bool value;
- sourceDictionary.TryRemove(logger, out value);
- }
}
base.OnChanged(args);
@@ -202,17 +183,10 @@ public LogLevel GetMinLogLevel(string source) {
return minLogLevel;
}
- private readonly ConcurrentDictionary> _typeSourceEnabled = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase);
-
public bool GetTypeAndSourceEnabled(string type, string source) {
if (type == null)
return true;
- if (source != null && _typeSourceEnabled.TryGetValue(type, out var sourceDictionary)) {
- if (sourceDictionary.TryGetValue(source, out bool sourceEnabled))
- return sourceEnabled;
- }
-
return GetTypeAndSourceSetting(type, source, "true").ToBoolean(true);
}
@@ -222,16 +196,7 @@ private string GetTypeAndSourceSetting(string type, string source, string defaul
if (type == null)
return defaultValue;
- string sourcePrefix;
- if (!_typeSourceEnabled.TryGetValue(type, out var sourceDictionary)) {
- sourceDictionary = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase);
- _typeSourceEnabled.TryAdd(type, sourceDictionary);
- sourcePrefix = "@@" + type + ":";
-
- _eventTypes.TryAdd(type, sourcePrefix);
- } else {
- sourcePrefix = _eventTypes[type];
- }
+ string sourcePrefix = _eventTypes.GetOrAdd(type, eventType => "@@" + eventType + ":");
// check for exact source match
if (TryGetValue(sourcePrefix + source, out string settingValue))
@@ -271,4 +236,4 @@ public static class KnownKeys {
public const string LogLevelPrefix = "@@log:";
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Platforms/Exceptionless.Extensions.Hosting/Exceptionless.Extensions.Hosting.csproj b/src/Platforms/Exceptionless.Extensions.Hosting/Exceptionless.Extensions.Hosting.csproj
index 471209f8..7993c4b1 100644
--- a/src/Platforms/Exceptionless.Extensions.Hosting/Exceptionless.Extensions.Hosting.csproj
+++ b/src/Platforms/Exceptionless.Extensions.Hosting/Exceptionless.Extensions.Hosting.csproj
@@ -15,15 +15,15 @@
-
+
-
+
-
+
diff --git a/src/Platforms/Exceptionless.Extensions.Logging/Exceptionless.Extensions.Logging.csproj b/src/Platforms/Exceptionless.Extensions.Logging/Exceptionless.Extensions.Logging.csproj
index 71c28a68..61794fa0 100644
--- a/src/Platforms/Exceptionless.Extensions.Logging/Exceptionless.Extensions.Logging.csproj
+++ b/src/Platforms/Exceptionless.Extensions.Logging/Exceptionless.Extensions.Logging.csproj
@@ -15,15 +15,15 @@
-
+
-
+
-
+
diff --git a/src/Platforms/Exceptionless.Log4net/Exceptionless.Log4net.csproj b/src/Platforms/Exceptionless.Log4net/Exceptionless.Log4net.csproj
index b9c23c6c..5d768a2f 100644
--- a/src/Platforms/Exceptionless.Log4net/Exceptionless.Log4net.csproj
+++ b/src/Platforms/Exceptionless.Log4net/Exceptionless.Log4net.csproj
@@ -25,7 +25,7 @@
-
+
diff --git a/src/Platforms/Exceptionless.MessagePack/Exceptionless.MessagePack.csproj b/src/Platforms/Exceptionless.MessagePack/Exceptionless.MessagePack.csproj
index b0c47148..b06c9fbb 100644
--- a/src/Platforms/Exceptionless.MessagePack/Exceptionless.MessagePack.csproj
+++ b/src/Platforms/Exceptionless.MessagePack/Exceptionless.MessagePack.csproj
@@ -25,6 +25,6 @@
-
+
diff --git a/src/Platforms/Exceptionless.NLog/Exceptionless.NLog.csproj b/src/Platforms/Exceptionless.NLog/Exceptionless.NLog.csproj
index 0cef187c..47620cd4 100644
--- a/src/Platforms/Exceptionless.NLog/Exceptionless.NLog.csproj
+++ b/src/Platforms/Exceptionless.NLog/Exceptionless.NLog.csproj
@@ -25,7 +25,7 @@
-
+
diff --git a/test/Exceptionless.MessagePack.Tests/Exceptionless.MessagePack.Tests.csproj b/test/Exceptionless.MessagePack.Tests/Exceptionless.MessagePack.Tests.csproj
index f30633be..596d794d 100644
--- a/test/Exceptionless.MessagePack.Tests/Exceptionless.MessagePack.Tests.csproj
+++ b/test/Exceptionless.MessagePack.Tests/Exceptionless.MessagePack.Tests.csproj
@@ -17,9 +17,9 @@
-
-
-
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/test/Exceptionless.TestHarness/Exceptionless.TestHarness.csproj b/test/Exceptionless.TestHarness/Exceptionless.TestHarness.csproj
index e54a4a95..2db77af8 100644
--- a/test/Exceptionless.TestHarness/Exceptionless.TestHarness.csproj
+++ b/test/Exceptionless.TestHarness/Exceptionless.TestHarness.csproj
@@ -16,7 +16,7 @@
-
+
diff --git a/test/Exceptionless.Tests/Configuration/ConfigurationTests.cs b/test/Exceptionless.Tests/Configuration/ConfigurationTests.cs
index d369f64f..fa7ad195 100644
--- a/test/Exceptionless.Tests/Configuration/ConfigurationTests.cs
+++ b/test/Exceptionless.Tests/Configuration/ConfigurationTests.cs
@@ -166,21 +166,41 @@ public void CanGetSettingsMultithreaded() {
[Fact]
public void CanGetLogSettingsMultithreaded() {
- var settings = new SettingsDictionary {
- { "@@log:*", "Info" },
- { "@@log:Source1", "Trace" },
- { "@@log:Source2", "Debug" },
- { "@@log:Source3", "Info" },
- { "@@log:Source4", "Info" }
- };
-
- var result = Parallel.For(0, 100, index => {
- var level = settings.GetMinLogLevel("Source1");
- _writer.WriteLine("Source1 log level: {0}", level);
- });
+ for (int attempt = 0; attempt < 1000; attempt++) {
+ var settings = new SettingsDictionary {
+ { "@@log:*", "Info" },
+ { "@@log:Source1", "Trace" },
+ { "@@log:Source2", "Debug" }
+ };
+
+ Parallel.For(0, 100, index => {
+ Assert.Equal(LogLevel.Trace, settings.GetMinLogLevel("Source1"));
+ Assert.Equal(LogLevel.Debug, settings.GetMinLogLevel("Source2"));
+ Assert.Equal(LogLevel.Info, settings.GetMinLogLevel("Other"));
+ });
+ }
+ }
- while (!result.IsCompleted)
- Thread.Yield();
+ [Theory]
+ [InlineData("usage")]
+ [InlineData("error")]
+ public void CanGetEventSettingsMultithreaded(string type) {
+ for (int attempt = 0; attempt < 1000; attempt++) {
+ var settings = new SettingsDictionary {
+ { "@@" + type + ":*", "true" },
+ { "@@" + type + ":Source1", "false" }
+ };
+
+ Parallel.For(0, 100, index => {
+ Assert.False(settings.GetTypeAndSourceEnabled(type, "Source1"));
+ Assert.True(settings.GetTypeAndSourceEnabled(type, "Other"));
+ });
+
+ settings["@@" + type + ":Source1"] = "true";
+ Assert.True(settings.GetTypeAndSourceEnabled(type, "Source1"));
+ settings["@@" + type + ":*"] = "false";
+ Assert.False(settings.GetTypeAndSourceEnabled(type, "Other"));
+ }
}
[Fact]
diff --git a/test/Exceptionless.Tests/Exceptionless.Tests.csproj b/test/Exceptionless.Tests/Exceptionless.Tests.csproj
index e1c0134d..9f9428df 100644
--- a/test/Exceptionless.Tests/Exceptionless.Tests.csproj
+++ b/test/Exceptionless.Tests/Exceptionless.Tests.csproj
@@ -39,11 +39,11 @@
-
+
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -61,4 +61,4 @@
PreserveNewest
-
\ No newline at end of file
+
diff --git a/test/Exceptionless.Tests/Properties/AssemblyInfo.cs b/test/Exceptionless.Tests/Properties/AssemblyInfo.cs
index 3c360368..8b3d919d 100644
--- a/test/Exceptionless.Tests/Properties/AssemblyInfo.cs
+++ b/test/Exceptionless.Tests/Properties/AssemblyInfo.cs
@@ -1,3 +1,4 @@
-using Xunit;
+using Xunit.Sdk;
+using Xunit.v3;
-[assembly: CollectionBehavior(DisableTestParallelization = true, MaxParallelThreads = 1)]
\ No newline at end of file
+[assembly: Parallelization(Mode = ParallelMode.None)]