diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 54f28fc566..849c72d016 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -54,6 +54,7 @@ body:
- OpenTelemetry.Resources.Container
- OpenTelemetry.Resources.Gcp
- OpenTelemetry.Resources.Host
+ - OpenTelemetry.Resources.OperatingSystem
- OpenTelemetry.Resources.Process
- OpenTelemetry.Resources.ProcessRuntime
- OpenTelemetry.Sampler.AWS
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
index e48fec3575..0c0b930633 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yml
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -54,6 +54,7 @@ body:
- OpenTelemetry.Resources.Container
- OpenTelemetry.Resources.Gcp
- OpenTelemetry.Resources.Host
+ - OpenTelemetry.Resources.OperatingSystem
- OpenTelemetry.Resources.Process
- OpenTelemetry.Resources.ProcessRuntime
- OpenTelemetry.Sampler.AWS
diff --git a/.github/codecov.yml b/.github/codecov.yml
index a8f7fd2412..b235a093c0 100644
--- a/.github/codecov.yml
+++ b/.github/codecov.yml
@@ -134,6 +134,11 @@ flags:
paths:
- src/OpenTelemetry.Resources.Host
+ unittests-Resources.OperatingSystem:
+ carryforward: true
+ paths:
+ - src/OpenTelemetry.Resources.OperatingSystem
+
unittests-Resources.Process:
carryforward: true
paths:
diff --git a/.github/component_owners.yml b/.github/component_owners.yml
index d6855b826a..cdcc10bc42 100644
--- a/.github/component_owners.yml
+++ b/.github/component_owners.yml
@@ -73,6 +73,9 @@ components:
src/OpenTelemetry.Resources.Host/:
- Kielek
- lachmatt
+ src/OpenTelemetry.Resources.OperatingSystem/:
+ - Kielek
+ - lachmatt
src/OpenTelemetry.Resources.Process/:
- Kielek
- lachmatt
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2ec5e2d6d6..2377e6c994 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -58,6 +58,7 @@ jobs:
resources-container: ['*/OpenTelemetry.Resources.Container*/**', '!**/*.md']
resources-gcp: ['*/OpenTelemetry.Resources.Gcp*/**', '!**/*.md']
resources-host: ['*/OpenTelemetry.Resources.Host*/**', '!**/*.md']
+ resources-operatingsystem: ['*/OpenTelemetry.Resources.OperatingSystem/**', '*/OpenTelemetry.Resources.OperatingSystem.Tests/**', '!**/*.md']
resources-process: ['*/OpenTelemetry.Resources.Process/**', '*/OpenTelemetry.Resources.Process.Tests/**', '!**/*.md']
resources-processruntime: ['*/OpenTelemetry.Resources.ProcessRuntime/**', '*/OpenTelemetry.Resources.ProcessRuntime.Tests/**', '!**/*.md']
sampler-aws: ['*/OpenTelemetry.Sampler.AWS**/**', '!**/*.md']
@@ -485,6 +486,17 @@ jobs:
project-name: Component[OpenTelemetry.Resources.Host]
code-cov-name: Resources.Host
+ build-test-resources-operatingsystem:
+ needs: detect-changes
+ if: |
+ contains(needs.detect-changes.outputs.changes, 'resources-operatingsystem')
+ || contains(needs.detect-changes.outputs.changes, 'build')
+ || contains(needs.detect-changes.outputs.changes, 'shared')
+ uses: ./.github/workflows/Component.BuildTest.yml
+ with:
+ project-name: Component[OpenTelemetry.Resources.OperatingSystem]
+ code-cov-name: Resources.OperatingSystem
+
build-test-resources-process:
needs: detect-changes
if: |
@@ -561,6 +573,7 @@ jobs:
|| contains(needs.detect-changes.outputs.changes, 'resources-azure')
|| contains(needs.detect-changes.outputs.changes, 'resources-container')
|| contains(needs.detect-changes.outputs.changes, 'resources-host')
+ || contains(needs.detect-changes.outputs.changes, 'resources-operatingsystem')
|| contains(needs.detect-changes.outputs.changes, 'resources-process')
|| contains(needs.detect-changes.outputs.changes, 'resources-processruntime')
|| contains(needs.detect-changes.outputs.changes, 'sampler-aws')
diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml
index b0673ac73a..11bc31a834 100644
--- a/.github/workflows/prepare-release.yml
+++ b/.github/workflows/prepare-release.yml
@@ -44,6 +44,7 @@ on:
- OpenTelemetry.Resources.Container
- OpenTelemetry.Resources.Gcp
- OpenTelemetry.Resources.Host
+ - OpenTelemetry.Resources.OperatingSystem
- OpenTelemetry.Resources.Process
- OpenTelemetry.Resources.ProcessRuntime
- OpenTelemetry.Sampler.AWS
diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln
index f7508674db..e86c0bd8ee 100644
--- a/opentelemetry-dotnet-contrib.sln
+++ b/opentelemetry-dotnet-contrib.sln
@@ -311,6 +311,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Pro
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Process.Tests", "test\OpenTelemetry.Resources.Process.Tests\OpenTelemetry.Resources.Process.Tests.csproj", "{A5EF701C-439E-407F-8BB4-394166000C6D}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.OperatingSystem", "src\OpenTelemetry.Resources.OperatingSystem\OpenTelemetry.Resources.OperatingSystem.csproj", "{F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.OperatingSystem.Tests", "test\OpenTelemetry.Resources.OperatingSystem.Tests\OpenTelemetry.Resources.OperatingSystem.Tests.csproj", "{62B7060A-C35B-4D49-A0C2-3BF02880A200}"
+EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Host", "src\OpenTelemetry.Resources.Host\OpenTelemetry.Resources.Host.csproj", "{033CA8D4-1529-413A-B244-07958D5F9A48}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Host.Tests", "test\OpenTelemetry.Resources.Host.Tests\OpenTelemetry.Resources.Host.Tests.csproj", "{36271347-2055-438E-9659-B71542A17A73}"
@@ -803,6 +807,14 @@ Global
{9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -927,6 +939,8 @@ Global
{BE40900A-2859-471D-8802-21DFD73DDAA7} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
{3A464E7A-42F3-44B0-B8D7-80521A7704A6} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA}
{9B994669-E839-4C42-A0F1-DF9DD058C1DC} = {3A464E7A-42F3-44B0-B8D7-80521A7704A6}
+ {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63}
+ {62B7060A-C35B-4D49-A0C2-3BF02880A200} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66}
diff --git a/src/OpenTelemetry.Resources.OperatingSystem/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Resources.OperatingSystem/.publicApi/PublicAPI.Shipped.txt
new file mode 100644
index 0000000000..7dc5c58110
--- /dev/null
+++ b/src/OpenTelemetry.Resources.OperatingSystem/.publicApi/PublicAPI.Shipped.txt
@@ -0,0 +1 @@
+#nullable enable
diff --git a/src/OpenTelemetry.Resources.OperatingSystem/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Resources.OperatingSystem/.publicApi/PublicAPI.Unshipped.txt
new file mode 100644
index 0000000000..46c3056f23
--- /dev/null
+++ b/src/OpenTelemetry.Resources.OperatingSystem/.publicApi/PublicAPI.Unshipped.txt
@@ -0,0 +1,2 @@
+OpenTelemetry.Resources.OperatingSystemResourceBuilderExtensions
+static OpenTelemetry.Resources.OperatingSystemResourceBuilderExtensions.AddOperatingSystemDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder!
diff --git a/src/OpenTelemetry.Resources.OperatingSystem/AssemblyInfo.cs b/src/OpenTelemetry.Resources.OperatingSystem/AssemblyInfo.cs
new file mode 100644
index 0000000000..a71b8adff5
--- /dev/null
+++ b/src/OpenTelemetry.Resources.OperatingSystem/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using System.Runtime.CompilerServices;
+
+#if SIGNED
+[assembly: InternalsVisibleTo("OpenTelemetry.Resources.OperatingSystem.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")]
+#else
+[assembly: InternalsVisibleTo("OpenTelemetry.Resources.OperatingSystem.Tests")]
+#endif
diff --git a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md
new file mode 100644
index 0000000000..940f68332a
--- /dev/null
+++ b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md
@@ -0,0 +1,8 @@
+# Changelog
+
+## Unreleased
+
+* Initial release of
+ `OpenTelemetry.ResourceDetectors.OperatingSystem`
+ project.
+ ([#1943](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1943))
diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj b/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj
new file mode 100644
index 0000000000..de79c48fe9
--- /dev/null
+++ b/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj
@@ -0,0 +1,25 @@
+
+
+
+
+ net6.0
+ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion)
+ OpenTelemetry Extensions - Operating System Resource Detector for .NET
+ Resources.OperatingSystem-
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs
new file mode 100644
index 0000000000..b0a6101bad
--- /dev/null
+++ b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs
@@ -0,0 +1,52 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using static OpenTelemetry.Resources.OperatingSystem.OperatingSystemSemanticConventions;
+
+namespace OpenTelemetry.Resources.OperatingSystem;
+
+///
+/// Operating system detector.
+///
+internal sealed class OperatingSystemDetector : IResourceDetector
+{
+ ///
+ /// Detects the resource attributes from the operating system.
+ ///
+ /// Resource with key-value pairs of resource attributes.
+ public Resource Detect()
+ {
+ var osType = GetOSType();
+
+ if (osType == null)
+ {
+ return Resource.Empty;
+ }
+
+ return new Resource(
+ [
+ new(AttributeOperatingSystemType, osType),
+ ]);
+ }
+
+ private static string? GetOSType()
+ {
+ var platform = Environment.OSVersion.Platform;
+ if (platform == PlatformID.Win32NT)
+ {
+ return OperatingSystemsValues.Windows;
+ }
+
+ if (platform == PlatformID.MacOSX)
+ {
+ return OperatingSystemsValues.Darwin;
+ }
+
+ if (platform == PlatformID.Unix)
+ {
+ return OperatingSystemsValues.Linux;
+ }
+
+ return null;
+ }
+}
diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourceBuilderExtensions.cs
new file mode 100644
index 0000000000..bab83370e9
--- /dev/null
+++ b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourceBuilderExtensions.cs
@@ -0,0 +1,24 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using OpenTelemetry.Internal;
+using OpenTelemetry.Resources.OperatingSystem;
+
+namespace OpenTelemetry.Resources;
+
+///
+/// Extension methods to simplify registering of operating system detectors.
+///
+public static class OperatingSystemResourceBuilderExtensions
+{
+ ///
+ /// Enables operating system detector.
+ ///
+ /// being configured.
+ /// The instance of being configured.
+ public static ResourceBuilder AddOperatingSystemDetector(this ResourceBuilder builder)
+ {
+ Guard.ThrowIfNull(builder);
+ return builder.AddDetector(new OperatingSystemDetector());
+ }
+}
diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemSemanticConventions.cs b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemSemanticConventions.cs
new file mode 100644
index 0000000000..356ad734da
--- /dev/null
+++ b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemSemanticConventions.cs
@@ -0,0 +1,18 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+namespace OpenTelemetry.Resources.OperatingSystem;
+
+internal static class OperatingSystemSemanticConventions
+{
+ public const string AttributeOperatingSystemType = "os.type";
+
+ public static class OperatingSystemsValues
+ {
+ public const string Windows = "windows";
+
+ public const string Linux = "linux";
+
+ public const string Darwin = "darwin";
+ }
+}
diff --git a/src/OpenTelemetry.Resources.OperatingSystem/README.md b/src/OpenTelemetry.Resources.OperatingSystem/README.md
new file mode 100644
index 0000000000..4c78424bff
--- /dev/null
+++ b/src/OpenTelemetry.Resources.OperatingSystem/README.md
@@ -0,0 +1,44 @@
+# Operating System Detectors
+
+[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.OperatingSyatem)](https://www.nuget.org/packages/OpenTelemetry.Resources.OperatingSyatem)
+[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.OperatingSyatem)](https://www.nuget.org/packages/OpenTelemetry.Resources.OperatingSyatem)
+[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.OperatingSyatem)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.OperatingSyatem)
+
+> [!IMPORTANT]
+> Resources detected by this packages are defined by [experimental semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/v1.26.0/docs/resource/os.md).
+> These resources can be changed without prior notification.
+
+## Getting Started
+
+You need to install the
+`OpenTelemetry.Resources.OperatingSystem` package to be able to use the
+Operating System Resource Detectors.
+
+```shell
+dotnet add package OpenTelemetry.Resources.OperatingSystem --prerelease
+```
+
+## Usage
+
+You can configure Operating System resource detector to
+the `TracerProvider` with the following example below.
+
+```csharp
+using OpenTelemetry;
+using OpenTelemetry.Resources;
+
+var tracerProvider = Sdk.CreateTracerProviderBuilder()
+ // other configurations
+ .ConfigureResource(resource => resource
+ .AddOperatingSystemDetector())
+ .Build();
+```
+
+The resource detectors will record the following metadata based on where
+your application is running:
+
+- **OperatingSystemDetector**: `os.type`.
+
+## References
+
+- [OpenTelemetry Project](https://opentelemetry.io/)
diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj
index e71582d2e8..c4d79207e0 100644
--- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj
+++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj
@@ -35,6 +35,7 @@
+
diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj
new file mode 100644
index 0000000000..c5b25f22ea
--- /dev/null
+++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Unit test project for Operating System Detector for OpenTelemetry
+
+ $(SupportedNetTargets)
+ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion)
+
+
+
+
+
+
+
diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs
new file mode 100644
index 0000000000..68cb378e34
--- /dev/null
+++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs
@@ -0,0 +1,30 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+using Xunit;
+
+namespace OpenTelemetry.Resources.OperatingSystem.Test;
+
+public class OperatingSystemDetectorTests
+{
+ [Fact]
+ public void TestOperatingSystemAttributes()
+ {
+ var resource = ResourceBuilder.CreateEmpty().AddOperatingSystemDetector().Build();
+
+ var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value);
+
+ var operatingSystems = new[]
+ {
+ OperatingSystemSemanticConventions.OperatingSystemsValues.Windows,
+ OperatingSystemSemanticConventions.OperatingSystemsValues.Linux,
+ OperatingSystemSemanticConventions.OperatingSystemsValues.Darwin,
+ };
+
+ Assert.Single(resourceAttributes);
+
+ Assert.True(resourceAttributes.ContainsKey(OperatingSystemSemanticConventions.AttributeOperatingSystemType));
+
+ Assert.Contains(resourceAttributes[OperatingSystemSemanticConventions.AttributeOperatingSystemType], operatingSystems);
+ }
+}