Merge branch 'main' into net7.0

This commit is contained in:
Alan West 2022-08-03 11:46:27 -07:00
commit 8dd0743174
No known key found for this signature in database
GPG Key ID: 10C64B6E349D00BC
312 changed files with 9948 additions and 6134 deletions

View File

@ -17,6 +17,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v1
with:
fetch-depth: 0 # fetching all
dotnet-version: '7.0.x'
include-prerelease: true

View File

@ -20,6 +20,8 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # fetching all
- uses: actions/setup-dotnet@v1
with:

View File

@ -23,6 +23,8 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # fetching all
- uses: actions/setup-dotnet@v1
with:

View File

@ -2,15 +2,8 @@
<ItemGroup>
<SolutionProjects Include="**\*.csproj" />
<!-- Windows specific projects -->
<SolutionProjects Remove="examples\AspNet\OpenTelemetry.Exporter.AspNet.csproj" Condition="'$(OS)' != 'Windows_NT'" />
<SolutionProjects Remove="src\OpenTelemetry.Instrumentation.AspNet\OpenTelemetry.Instrumentation.AspNet.csproj" Condition="'$(OS)' != 'Windows_NT'" />
<SolutionProjects Remove="test\OpenTelemetry.Instrumentation.AspNet.Tests\OpenTelemetry.Instrumentation.AspNet.Tests.csproj" Condition="'$(OS)' != 'Windows_NT'" />
<PackProjects Include="src\**\*.csproj" />
<!-- Windows specific projects -->
<PackProjects Remove="src\OpenTelemetry.Instrumentation.AspNet\OpenTelemetry.Instrumentation.AspNet.csproj" Condition="'$(OS)' != 'Windows_NT'" />
</ItemGroup>
<Target Name="Build">

View File

@ -29,6 +29,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7CB2F02E
build\docker-compose.net6.0.yml = build\docker-compose.net6.0.yml
build\docker-compose.netcoreapp3.1.yml = build\docker-compose.netcoreapp3.1.yml
build\finalize-publicapi.ps1 = build\finalize-publicapi.ps1
build\GlobalAttrExclusions.txt = build\GlobalAttrExclusions.txt
build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png
build\OpenTelemetry.prod.loose.ruleset = build\OpenTelemetry.prod.loose.ruleset
build\OpenTelemetry.prod.ruleset = build\OpenTelemetry.prod.ruleset
@ -72,10 +73,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Cons
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Zipkin.Tests", "test\OpenTelemetry.Exporter.Zipkin.Tests\OpenTelemetry.Exporter.Zipkin.Tests.csproj", "{1D778D2E-9523-450E-A6E0-A36897C7E78E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet", "src\OpenTelemetry.Instrumentation.AspNet\OpenTelemetry.Instrumentation.AspNet.csproj", "{B9EEACDD-CAFA-4B75-A18D-898E7DE21B17}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet.Tests", "test\OpenTelemetry.Instrumentation.AspNet.Tests\OpenTelemetry.Instrumentation.AspNet.Tests.csproj", "{55CBAADE-7040-46D6-A845-F207B4F0E281}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests", "test\OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests\OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj", "{7C4026CA-6434-4762-8B77-D657EAEE1325}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{F1D0972B-38CF-49C2-9F4B-4C5DE02FB71D}"
@ -126,8 +123,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.ZPages.Tests", "test\OpenTelemetry.Exporter.ZPages.Tests\OpenTelemetry.Exporter.ZPages.Tests.csproj", "{98F9556B-116F-49B5-9211-BB1D418446FF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.AspNet", "examples\AspNet\Examples.AspNet.csproj", "{9A4E3A68-904B-4835-A3C8-F664B73098DB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Console", "examples\Console\Examples.Console.csproj", "{FF3E6E08-E8E4-4523-B526-847CD989279F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.AspNetCore", "examples\AspNetCore\Examples.AspNetCore.csproj", "{0935622B-9377-4056-8343-AE6ECDC274CF}"
@ -198,12 +193,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "reporting-exceptions", "doc
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "customizing-the-sdk", "docs\trace\customizing-the-sdk\customizing-the-sdk.csproj", "{64E3D8BB-93AB-4571-93F7-ED8D64DFFD06}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus", "src\OpenTelemetry.Exporter.Prometheus\OpenTelemetry.Exporter.Prometheus.csproj", "{52158A12-E7EF-45A1-859F-06F9B17410CB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule", "src\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj", "{F38E511B-1877-4E8A-8051-7879FC7DF8A4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests", "test\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj", "{4D7201BC-7124-4401-AD65-FAB58A053D45}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "learning-more-instruments", "docs\metrics\learning-more-instruments\learning-more-instruments.csproj", "{E7F491CC-C37E-4A56-9CA7-8F77F59E0614}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "getting-started", "docs\metrics\getting-started\getting-started.csproj", "{EA60B549-F712-4ABE-8E44-FCA83B78C06E}"
@ -216,8 +205,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "customizing-the-sdk", "docs
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Tests.Stress", "test\OpenTelemetry.Tests.Stress\OpenTelemetry.Tests.Stress.csproj", "{2770158A-D220-414B-ABC6-179371323579}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus.Tests", "test\OpenTelemetry.Exporter.Prometheus.Tests\OpenTelemetry.Exporter.Prometheus.Tests.csproj", "{380EE686-91F1-45B3-AEEB-755F0E5B068F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs", "src\OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs\OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs.csproj", "{6E1A5FA3-E024-4972-9EDC-11E36C5A0D6F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApp.AspNetCore.6.0", "test\TestApp.AspNetCore.6.0\TestApp.AspNetCore.6.0.csproj", "{0076C657-564F-4787-9FFF-52D9D55166E8}"
@ -234,6 +221,26 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Pr
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "correlation", "docs\logs\correlation\correlation.csproj", "{9A07D215-90AC-4BAF-BCDB-73D74FD3A5C5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Tests.Stress.Logs", "test\OpenTelemetry.Tests.Stress.Logs\OpenTelemetry.Tests.Stress.Logs.csproj", "{4298057B-24E0-47B3-BB76-C17E81AF6B39}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.LoggingExtensions", "examples\LoggingExtensions\Examples.LoggingExtensions.csproj", "{F5EFF065-7AF5-4D7D-8038-CC419ABD8777}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Serilog", "src\OpenTelemetry.Extensions.Serilog\OpenTelemetry.Extensions.Serilog.csproj", "{0D85558E-15B9-4251-BDBD-9CB7933B57E2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Serilog.Tests", "test\OpenTelemetry.Extensions.Serilog.Tests\OpenTelemetry.Extensions.Serilog.Tests.csproj", "{6A2C122A-C1CD-4B6B-AE09-2ABB7D3C50CE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.EventSource", "src\OpenTelemetry.Extensions.EventSource\OpenTelemetry.Extensions.EventSource.csproj", "{7AFB4975-9680-4668-9F5E-C3F0CA41E982}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.EventSource.Tests", "test\OpenTelemetry.Extensions.EventSource.Tests\OpenTelemetry.Extensions.EventSource.Tests.csproj", "{304FCFFF-97DE-484B-8D8C-612C644426E5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus.AspNetCore", "src\OpenTelemetry.Exporter.Prometheus.AspNetCore\OpenTelemetry.Exporter.Prometheus.AspNetCore.csproj", "{921CF401-4C2F-4C6D-A750-0B5DC457C1F1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus.HttpListener", "src\OpenTelemetry.Exporter.Prometheus.HttpListener\OpenTelemetry.Exporter.Prometheus.HttpListener.csproj", "{6B0232B7-5F29-4FB5-B383-1AA02DFE1089}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests", "test\OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests\OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj", "{FBD12B0B-6731-4DD4-9C13-86F34593E974}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus.HttpListener.Tests", "test\OpenTelemetry.Exporter.Prometheus.HttpListener.Tests\OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj", "{4EF4364F-6E64-43CE-BED1-E6FE01024899}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -304,14 +311,6 @@ Global
{1D778D2E-9523-450E-A6E0-A36897C7E78E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D778D2E-9523-450E-A6E0-A36897C7E78E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D778D2E-9523-450E-A6E0-A36897C7E78E}.Release|Any CPU.Build.0 = Release|Any CPU
{B9EEACDD-CAFA-4B75-A18D-898E7DE21B17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B9EEACDD-CAFA-4B75-A18D-898E7DE21B17}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B9EEACDD-CAFA-4B75-A18D-898E7DE21B17}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B9EEACDD-CAFA-4B75-A18D-898E7DE21B17}.Release|Any CPU.Build.0 = Release|Any CPU
{55CBAADE-7040-46D6-A845-F207B4F0E281}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{55CBAADE-7040-46D6-A845-F207B4F0E281}.Debug|Any CPU.Build.0 = Debug|Any CPU
{55CBAADE-7040-46D6-A845-F207B4F0E281}.Release|Any CPU.ActiveCfg = Release|Any CPU
{55CBAADE-7040-46D6-A845-F207B4F0E281}.Release|Any CPU.Build.0 = Release|Any CPU
{7C4026CA-6434-4762-8B77-D657EAEE1325}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7C4026CA-6434-4762-8B77-D657EAEE1325}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C4026CA-6434-4762-8B77-D657EAEE1325}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -324,10 +323,6 @@ Global
{98F9556B-116F-49B5-9211-BB1D418446FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98F9556B-116F-49B5-9211-BB1D418446FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98F9556B-116F-49B5-9211-BB1D418446FF}.Release|Any CPU.Build.0 = Release|Any CPU
{9A4E3A68-904B-4835-A3C8-F664B73098DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9A4E3A68-904B-4835-A3C8-F664B73098DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9A4E3A68-904B-4835-A3C8-F664B73098DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A4E3A68-904B-4835-A3C8-F664B73098DB}.Release|Any CPU.Build.0 = Release|Any CPU
{FF3E6E08-E8E4-4523-B526-847CD989279F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF3E6E08-E8E4-4523-B526-847CD989279F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF3E6E08-E8E4-4523-B526-847CD989279F}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -408,18 +403,6 @@ Global
{64E3D8BB-93AB-4571-93F7-ED8D64DFFD06}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64E3D8BB-93AB-4571-93F7-ED8D64DFFD06}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64E3D8BB-93AB-4571-93F7-ED8D64DFFD06}.Release|Any CPU.Build.0 = Release|Any CPU
{52158A12-E7EF-45A1-859F-06F9B17410CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{52158A12-E7EF-45A1-859F-06F9B17410CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{52158A12-E7EF-45A1-859F-06F9B17410CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{52158A12-E7EF-45A1-859F-06F9B17410CB}.Release|Any CPU.Build.0 = Release|Any CPU
{F38E511B-1877-4E8A-8051-7879FC7DF8A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F38E511B-1877-4E8A-8051-7879FC7DF8A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F38E511B-1877-4E8A-8051-7879FC7DF8A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F38E511B-1877-4E8A-8051-7879FC7DF8A4}.Release|Any CPU.Build.0 = Release|Any CPU
{4D7201BC-7124-4401-AD65-FAB58A053D45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D7201BC-7124-4401-AD65-FAB58A053D45}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D7201BC-7124-4401-AD65-FAB58A053D45}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D7201BC-7124-4401-AD65-FAB58A053D45}.Release|Any CPU.Build.0 = Release|Any CPU
{E7F491CC-C37E-4A56-9CA7-8F77F59E0614}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E7F491CC-C37E-4A56-9CA7-8F77F59E0614}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7F491CC-C37E-4A56-9CA7-8F77F59E0614}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -444,10 +427,6 @@ Global
{2770158A-D220-414B-ABC6-179371323579}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2770158A-D220-414B-ABC6-179371323579}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2770158A-D220-414B-ABC6-179371323579}.Release|Any CPU.Build.0 = Release|Any CPU
{380EE686-91F1-45B3-AEEB-755F0E5B068F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{380EE686-91F1-45B3-AEEB-755F0E5B068F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{380EE686-91F1-45B3-AEEB-755F0E5B068F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{380EE686-91F1-45B3-AEEB-755F0E5B068F}.Release|Any CPU.Build.0 = Release|Any CPU
{6E1A5FA3-E024-4972-9EDC-11E36C5A0D6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6E1A5FA3-E024-4972-9EDC-11E36C5A0D6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6E1A5FA3-E024-4972-9EDC-11E36C5A0D6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -480,6 +459,46 @@ Global
{9A07D215-90AC-4BAF-BCDB-73D74FD3A5C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9A07D215-90AC-4BAF-BCDB-73D74FD3A5C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A07D215-90AC-4BAF-BCDB-73D74FD3A5C5}.Release|Any CPU.Build.0 = Release|Any CPU
{4298057B-24E0-47B3-BB76-C17E81AF6B39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4298057B-24E0-47B3-BB76-C17E81AF6B39}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4298057B-24E0-47B3-BB76-C17E81AF6B39}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4298057B-24E0-47B3-BB76-C17E81AF6B39}.Release|Any CPU.Build.0 = Release|Any CPU
{F5EFF065-7AF5-4D7D-8038-CC419ABD8777}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F5EFF065-7AF5-4D7D-8038-CC419ABD8777}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F5EFF065-7AF5-4D7D-8038-CC419ABD8777}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F5EFF065-7AF5-4D7D-8038-CC419ABD8777}.Release|Any CPU.Build.0 = Release|Any CPU
{0D85558E-15B9-4251-BDBD-9CB7933B57E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0D85558E-15B9-4251-BDBD-9CB7933B57E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0D85558E-15B9-4251-BDBD-9CB7933B57E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0D85558E-15B9-4251-BDBD-9CB7933B57E2}.Release|Any CPU.Build.0 = Release|Any CPU
{6A2C122A-C1CD-4B6B-AE09-2ABB7D3C50CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6A2C122A-C1CD-4B6B-AE09-2ABB7D3C50CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6A2C122A-C1CD-4B6B-AE09-2ABB7D3C50CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6A2C122A-C1CD-4B6B-AE09-2ABB7D3C50CE}.Release|Any CPU.Build.0 = Release|Any CPU
{7AFB4975-9680-4668-9F5E-C3F0CA41E982}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7AFB4975-9680-4668-9F5E-C3F0CA41E982}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7AFB4975-9680-4668-9F5E-C3F0CA41E982}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7AFB4975-9680-4668-9F5E-C3F0CA41E982}.Release|Any CPU.Build.0 = Release|Any CPU
{304FCFFF-97DE-484B-8D8C-612C644426E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{304FCFFF-97DE-484B-8D8C-612C644426E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{304FCFFF-97DE-484B-8D8C-612C644426E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{304FCFFF-97DE-484B-8D8C-612C644426E5}.Release|Any CPU.Build.0 = Release|Any CPU
{921CF401-4C2F-4C6D-A750-0B5DC457C1F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{921CF401-4C2F-4C6D-A750-0B5DC457C1F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{921CF401-4C2F-4C6D-A750-0B5DC457C1F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{921CF401-4C2F-4C6D-A750-0B5DC457C1F1}.Release|Any CPU.Build.0 = Release|Any CPU
{6B0232B7-5F29-4FB5-B383-1AA02DFE1089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B0232B7-5F29-4FB5-B383-1AA02DFE1089}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B0232B7-5F29-4FB5-B383-1AA02DFE1089}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B0232B7-5F29-4FB5-B383-1AA02DFE1089}.Release|Any CPU.Build.0 = Release|Any CPU
{FBD12B0B-6731-4DD4-9C13-86F34593E974}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FBD12B0B-6731-4DD4-9C13-86F34593E974}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FBD12B0B-6731-4DD4-9C13-86F34593E974}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FBD12B0B-6731-4DD4-9C13-86F34593E974}.Release|Any CPU.Build.0 = Release|Any CPU
{4EF4364F-6E64-43CE-BED1-E6FE01024899}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4EF4364F-6E64-43CE-BED1-E6FE01024899}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4EF4364F-6E64-43CE-BED1-E6FE01024899}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4EF4364F-6E64-43CE-BED1-E6FE01024899}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -489,7 +508,6 @@ Global
{E69578EB-B456-4062-A645-877CD964528B} = {F1D0972B-38CF-49C2-9F4B-4C5DE02FB71D}
{C1542297-8763-4DF4-957C-489ED771C21D} = {7CB2F02E-03FA-4FFF-89A5-C51F107623FD}
{D2E73927-5966-445C-94E9-EFE6F269C8D5} = {7CB2F02E-03FA-4FFF-89A5-C51F107623FD}
{9A4E3A68-904B-4835-A3C8-F664B73098DB} = {E359BB2B-9AEC-497D-B321-7DF2450C3B8E}
{FF3E6E08-E8E4-4523-B526-847CD989279F} = {E359BB2B-9AEC-497D-B321-7DF2450C3B8E}
{0935622B-9377-4056-8343-AE6ECDC274CF} = {E359BB2B-9AEC-497D-B321-7DF2450C3B8E}
{2C7DD1DA-C229-4D9E-9AF0-BCD5CD3E4948} = {7CB2F02E-03FA-4FFF-89A5-C51F107623FD}
@ -517,6 +535,7 @@ Global
{41B784AA-3301-4126-AF9F-1D59BD04B0BF} = {3277B1C0-BDFE-4460-9B0D-D9A661FB48DB}
{6C7A1595-36D6-4229-BBB5-5A6B5791791D} = {3862190B-E2C5-418E-AFDC-DB281FB5C705}
{9A07D215-90AC-4BAF-BCDB-73D74FD3A5C5} = {3862190B-E2C5-418E-AFDC-DB281FB5C705}
{F5EFF065-7AF5-4D7D-8038-CC419ABD8777} = {E359BB2B-9AEC-497D-B321-7DF2450C3B8E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {55639B5C-0770-4A22-AB56-859604650521}

View File

@ -53,7 +53,6 @@ Here are the most commonly used components:
Here are the [instrumentation
libraries](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library):
* [ASP.NET](./src/OpenTelemetry.Instrumentation.AspNet/README.md)
* [ASP.NET Core](./src/OpenTelemetry.Instrumentation.AspNetCore/README.md)
* [Grpc.Net.Client](./src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md)
* [HTTP clients](./src/OpenTelemetry.Instrumentation.Http/README.md)
@ -67,7 +66,8 @@ libraries](https://github.com/open-telemetry/opentelemetry-specification/blob/ma
* [Jaeger](./src/OpenTelemetry.Exporter.Jaeger/README.md)
* [OTLP](./src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md)
(OpenTelemetry Protocol)
* [Prometheus](./src/OpenTelemetry.Exporter.Prometheus/README.md)
* [Prometheus HttpListener](./src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md)
* [Prometheus AspNetCore](./src/OpenTelemetry.Exporter.Prometheus.AspNetCore/README.md)
* [Zipkin](./src/OpenTelemetry.Exporter.Zipkin/README.md)
See the [OpenTelemetry registry](https://opentelemetry.io/registry/?s=net) for
@ -111,13 +111,13 @@ If you have trouble accessing the doc, please get in touch on
* [Alan West](https://github.com/alanwest), New Relic
* [Cijo Thomas](https://github.com/cijothomas), Microsoft
* [Mikel Blanchard](https://github.com/CodeBlanch), Microsoft
* [Utkarsh Umesan Pillai](https://github.com/utpilla), Microsoft
[Approvers](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver)
([@open-telemetry/dotnet-approvers](https://github.com/orgs/open-telemetry/teams/dotnet-approvers)):
* [Reiley Yang](https://github.com/reyang), Microsoft
* [Robert Paj&#x105;k](https://github.com/pellared), Splunk
* [Utkarsh Umesan Pillai](https://github.com/utpilla), Microsoft
[Emeritus
Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/community-membership.md#emeritus-maintainerapprovertriager):

View File

@ -37,17 +37,15 @@
<GrpcAspNetCorePkgVer>[2.43.0,3.0)</GrpcAspNetCorePkgVer>
<GrpcAspNetCoreServerPkgVer>[2.43.0, 3.0)</GrpcAspNetCoreServerPkgVer>
<GrpcToolsPkgVer>[2.44.0,3.0)</GrpcToolsPkgVer>
<MicrosoftAspNetMvcPkgVer>[5.2.7,6.0)</MicrosoftAspNetMvcPkgVer>
<MicrosoftAspNetWebApiWebHostPkgVer>[5.2.7,6.0)</MicrosoftAspNetWebApiWebHostPkgVer>
<MicrosoftAspNetWebPagesPkgVer>[3.2.7,4.0)</MicrosoftAspNetWebPagesPkgVer>
<MicrosoftExtensionsHostingPkgVer>[3.1.6,5.0)</MicrosoftExtensionsHostingPkgVer>
<MicrosoftExtensionsLoggingPkgVer>[6.0.0,)</MicrosoftExtensionsLoggingPkgVer>
<MicrosoftExtensionsLoggingAbstractionsPkgVer>[6.0.0,)</MicrosoftExtensionsLoggingAbstractionsPkgVer>
<MicrosoftNETTestSdkPkgVer>[16.10.0]</MicrosoftNETTestSdkPkgVer>
<NewtonsoftJsonPkgVer>[12.0.2,13.0)</NewtonsoftJsonPkgVer>
<MoqPkgVer>[4.14.5,5.0)</MoqPkgVer>
<RabbitMQClientPkgVer>[6.1.0,7.0)</RabbitMQClientPkgVer>
<RuntimeInstrumentationPkgVer>[1.0.0-rc.2,2.0)</RuntimeInstrumentationPkgVer>
<SwashbuckleAspNetCorePkgVer>[6.2.3]</SwashbuckleAspNetCorePkgVer>
<SystemTextJsonPkgVer>6.0.5</SystemTextJsonPkgVer>
<XUnitRunnerVisualStudioPkgVer>[2.4.3,3.0)</XUnitRunnerVisualStudioPkgVer>
<XUnitPkgVer>[2.4.1,3.0)</XUnitPkgVer>
</PropertyGroup>

View File

@ -35,6 +35,7 @@
<PackageOutputPath Condition="$(Build_ArtifactStagingDirectory) != ''">$(Build_ArtifactStagingDirectory)</PackageOutputPath>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<!--<MinVerVerbosity>detailed</MinVerVerbosity>-->
<ApiCompatExcludeAttributeList>$(RepoRoot)\build\GlobalAttrExclusions.txt</ApiCompatExcludeAttributeList>
</PropertyGroup>
<Target Name="AssemblyVersionTarget" AfterTargets="MinVer" Condition="'$(MinVerVersion)'!='' AND '$(BuildNumber)' != ''">

View File

@ -22,7 +22,7 @@
Please sort alphabetically.
Refer to https://docs.microsoft.com/nuget/concepts/package-versioning for semver syntax.
-->
<MinVerPkgVer>[2.3.0,3.0)</MinVerPkgVer>
<MinVerPkgVer>[4.1.0,5.0)</MinVerPkgVer>
<GoogleProtobufPkgVer>[3.19.4,4.0)</GoogleProtobufPkgVer>
<GrpcPkgVer>[2.44.0,3.0)</GrpcPkgVer>
<GrpcNetClientPkgVer>[2.43.0,3.0)</GrpcNetClientPkgVer>
@ -40,6 +40,7 @@
<MicrosoftSourceLinkGitHubPkgVer>[1.0.0,2.0)</MicrosoftSourceLinkGitHubPkgVer>
<OpenTracingPkgVer>[0.12.1,0.13)</OpenTracingPkgVer>
<OTelPreviousStableVer>1.3.0</OTelPreviousStableVer>
<SerilogPkgVer>[2.8.0,3.0)</SerilogPkgVer>
<StyleCopAnalyzersPkgVer>[1.2.0-beta.354,2.0)</StyleCopAnalyzersPkgVer>
<SystemCollectionsImmutablePkgVer>1.4.0</SystemCollectionsImmutablePkgVer>
<SystemDiagnosticSourcePkgVer>7.0.0-preview.4.22229.4</SystemDiagnosticSourcePkgVer>

View File

@ -0,0 +1,4 @@
// These attributes should be excluded from ApiCompat checks.
T:System.Runtime.CompilerServices.CompilerGeneratedAttribute
T:System.Runtime.CompilerServices.NullableContextAttribute

View File

@ -30,9 +30,7 @@ public class Program
builder.AddOpenTelemetry(options =>
{
options.IncludeScopes = true;
options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(
serviceName: "MyService",
serviceVersion: "1.0.0"));
options.ConfigureResource(r => r.AddService(serviceName: "MyService", serviceVersion: "1.0.0"));
options.AddConsoleExporter();
});
});

View File

@ -52,26 +52,25 @@ var loggerFactory = LoggerFactory.Create(builder =>
For more information on Processors, please review [Extending the SDK](../extending-the-sdk/README.md#processor)
### SetResourceBuilder
### ConfigureResource
[Resource](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md)
is the immutable representation of the entity producing the telemetry.
If no `Resource` is explicitly configured, the default is to use a resource
indicating this [Telemetry
SDK](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/resource/semantic_conventions#telemetry-sdk).
The `SetResourceBuilder` method on `OpenTelemetryLoggerOptions` can be used to
set a single `ResourceBuilder`. If `SetResourceBuilder` is called multiple
times, only the last is kept. It is not possible to change the resource builder
The `ConfigureResource` method on `OpenTelemetryLoggerOptions` can be used to
configure the `ResourceBuilder`. It is not possible to change the resources
*after* creating the `LoggerFactory`.
The snippet below shows configuring a custom `ResourceBuilder` to the provider.
The snippet below shows configuring the `ResourceBuilder` of the provider.
```csharp
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddOpenTelemetry(options =>
{
options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(
options.ConfigureResource(r => r.AddService(
serviceName: "MyService",
serviceVersion: "1.0.0"
));

View File

@ -35,9 +35,10 @@ In a typical application, a single `MeterProvider` is created at application
startup and disposed at application shutdown. It is important to ensure that the
provider is not disposed too early. Actual mechanism depends on the application
type. For example, in a typical ASP.NET application, `MeterProvider` is created
in `Application_Start`, and disposed in `Application_End` (both methods part of
Global.asax.cs file) as shown [here](../../../examples/AspNet/Global.asax.cs). In
a typical ASP.NET Core application, `MeterProvider` lifetime is managed by
in `Application_Start`, and disposed in `Application_End` (both methods are a
part of the Global.asax.cs file) as shown
[here](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/examples/AspNet/Global.asax.cs).
In a typical ASP.NET Core application, `MeterProvider` lifetime is managed by
leveraging the built-in Dependency Injection container as shown
[here](../../../examples/AspNetCore/Program.cs).
@ -422,7 +423,8 @@ Refer to the individual exporter docs to learn how to use them:
* [In-memory](../../../src/OpenTelemetry.Exporter.InMemory/README.md)
* [OTLP](../../../src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md)
(OpenTelemetry Protocol)
* [Prometheus](../../../src/OpenTelemetry.Exporter.Prometheus/README.md)
* [Prometheus HttpListener](../../../src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md)
* [Prometheus AspNetCore](../../../src/OpenTelemetry.Exporter.Prometheus.AspNetCore/README.md)
### Resource

View File

@ -12,7 +12,8 @@ OpenTelemetry .NET SDK has provided the following built-in metric exporters:
* [InMemory](../../../src/OpenTelemetry.Exporter.InMemory/README.md)
* [Console](../../../src/OpenTelemetry.Exporter.Console/README.md)
* [OpenTelemetryProtocol](../../../src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md)
* [Prometheus](../../../src/OpenTelemetry.Exporter.Prometheus/README.md)
* [Prometheus HttpListener](../../../src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md)
* [Prometheus AspNetCore](../../../src/OpenTelemetry.Exporter.Prometheus.AspNetCore/README.md)
Custom exporters can be implemented to send telemetry data to places which are
not covered by the built-in exporters:

View File

@ -31,7 +31,7 @@ public class Program
{
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter("MyCompany.MyProduct.MyLibrary")
.AddPrometheusExporter(options => { options.StartHttpListener = true; })
.AddPrometheusHttpListener()
.Build();
Console.WriteLine("Press any key to exit");

View File

@ -23,10 +23,10 @@ dotnet run
```
Add a reference to [Prometheus
Exporter](../../../src/OpenTelemetry.Exporter.Prometheus/README.md):
Exporter Http Listener](../../../src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md):
```sh
dotnet add package --prerelease OpenTelemetry.Exporter.Prometheus
dotnet add package --prerelease OpenTelemetry.Exporter.Prometheus.HttpListener
```
Now, we are going to make some small tweaks to the example in the
@ -46,12 +46,13 @@ And replace the below line:
with
```csharp
.AddPrometheusExporter(options => { options.StartHttpListener = true; })
.AddPrometheusHttpListener()
```
With `AddPrometheusExporter()`, OpenTelemetry `PrometheusExporter` will export
`PrometheusHttpListener` is a wrapper that contains `PrometheusExporter`. With
`AddPrometheusHttpListener()`, OpenTelemetry `PrometheusExporter` will export
data via the endpoint defined by
[PrometheusExporterOptions.HttpListenerPrefixes](../../../src/OpenTelemetry.Exporter.Prometheus/README.md#httplistenerprefixes),
[PrometheusHttpListenerOptions.UriPrefixes](../../../src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md#uriprefixes),
which is `http://localhost:9464/` by default.
```mermaid
@ -60,7 +61,7 @@ graph LR
subgraph SDK
MeterProvider
MetricReader[BaseExportingMetricReader]
PrometheusExporter["PrometheusExporter<br/>(http://localhost:9464/)"]
PrometheusHttpListener["PrometheusHttpListener<br/>(http://localhost:9464/)"]
end
subgraph API
@ -69,7 +70,7 @@ end
Instrument --> | Measurements | MeterProvider
MeterProvider --> | Metrics | MetricReader --> | Pull | PrometheusExporter
MeterProvider --> | Metrics | MetricReader --> | Pull | PrometheusHttpListener
```
Also, for our learning purpose, use a while-loop to keep increasing the counter
@ -99,7 +100,7 @@ web browser:
![Browser UI](https://user-images.githubusercontent.com/17327289/151633547-736c6d91-62d2-4e66-a53f-2e16c44bfabc.png)
Now, we understand how we can configure `PrometheusExporter` to export metrics.
Now, we understand how we can configure `PrometheusHttpListener` to export metrics.
Next, we are going to learn about how to use Prometheus to collect the metrics.
## Collect metrics using Prometheus
@ -156,7 +157,7 @@ values we have set in `otel.yml`.
Congratulations!
Now we know how to configure Prometheus server and deploy OpenTelemetry
`PrometheusExporter` to export our metrics. Next, we are going to explore a tool
`PrometheusHttpListener` to export our metrics. Next, we are going to explore a tool
called Grafana, which has powerful visualizations for the metrics.
## Explore metrics using Grafana
@ -201,7 +202,7 @@ subgraph Prometheus
PrometheusDatabase
end
PrometheusExporter["PrometheusExporter<br/>(listening at #quot;http://localhost:9464/#quot;)"] -->|HTTP GET| PrometheusScraper{{"Prometheus scraper<br/>(polling #quot;http://localhost:9464/metrics#quot; every 10 seconds)"}}
PrometheusHttpListener["PrometheusHttpListener<br/>(listening at #quot;http://localhost:9464/#quot;)"] -->|HTTP GET| PrometheusScraper{{"Prometheus scraper<br/>(polling #quot;http://localhost:9464/metrics#quot; every 10 seconds)"}}
PrometheusScraper --> PrometheusDatabase[("Prometheus TSDB (time series database)")]
PrometheusDatabase -->|http://localhost:9090/graph| PrometheusUI["Browser<br/>(Prometheus Dashboard)"]
PrometheusDatabase -->|http://localhost:9090/api/| Grafana[Grafana Server]

View File

@ -1,5 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus\OpenTelemetry.Exporter.Prometheus.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus.HttpListener\OpenTelemetry.Exporter.Prometheus.HttpListener.csproj" />
</ItemGroup>
</Project>

View File

@ -15,9 +15,9 @@ processors, etc. Naturally, almost all the customizations must be done on the
Building a `TracerProvider` is done using `TracerProviderBuilder` which must be
obtained by calling `Sdk.CreateTracerProviderBuilder()`. `TracerProviderBuilder`
exposes various methods which configures the provider it is going to build. These
includes methods like `SetSampler`, `AddProcessor` etc, and are explained in
subsequent sections of this document. Once configuration is done, calling
exposes various methods which configures the provider it is going to build.
These includes methods like `SetSampler`, `AddProcessor` etc, and are explained
in subsequent sections of this document. Once configuration is done, calling
`Build()` on the `TracerProviderBuilder` builds the `TracerProvider` instance.
Once built, changes to its configuration is not allowed, with the exception of
adding more processors. In most cases, a single `TracerProvider` is created at
@ -38,9 +38,10 @@ In a typical application, a single `TracerProvider` is created at application
startup and disposed at application shutdown. It is important to ensure that the
provider is not disposed too early. Actual mechanism depends on the application
type. For example, in a typical ASP.NET application, `TracerProvider` is created
in `Application_Start`, and disposed in `Application_End` (both methods part of
Global.asax.cs file) as shown [here](../../../examples/AspNet/Global.asax.cs). In
a typical ASP.NET Core application, `TracerProvider` lifetime is managed by
in `Application_Start`, and disposed in `Application_End` (both methods are a
part of the Global.asax.cs file) as shown
[here](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/examples/AspNet/Global.asax.cs).
In a typical ASP.NET Core application, `TracerProvider` lifetime is managed by
leveraging the built-in Dependency Injection container as shown
[here](../../../examples/AspNetCore/Program.cs).
@ -98,13 +99,12 @@ using var tracerProvider = Sdk.CreateTracerProviderBuilder()
See [Program.cs](./Program.cs) for complete example.
**Note**
A common mistake while configuring `TracerProvider` is forgetting to add
all `ActivitySources` to the provider. It is recommended to leverage the
**Note** A common mistake while configuring `TracerProvider` is forgetting to
add all `ActivitySources` to the provider. It is recommended to leverage the
wild card subscription model where it makes sense. For example, if your
application is expecting to enable tracing from a number of libraries
from a company "Abc", the you can use `AddSource("Abc.*")` to enable
all sources whose name starts with "Abc.".
application is expecting to enable tracing from a number of libraries from a
company "Abc", the you can use `AddSource("Abc.*")` to enable all sources whose
name starts with "Abc.".
### Instrumentation
@ -124,5 +124,5 @@ all sources whose name starts with "Abc.".
## Context Propagation
// TODO: OpenTelemetry Sdk contents about Context.
// TODO: Links to built-in instrumentations doing Propagation.
// TODO: OpenTelemetry Sdk contents about Context. // TODO: Links to built-in
instrumentations doing Propagation.

View File

@ -17,16 +17,28 @@
using System;
using System.Diagnostics;
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
internal class MyFilteringProcessor : BaseProcessor<Activity>
/// <summary>
/// A custom processor for filtering <see cref="Activity"/> instances.
/// </summary>
/// <remarks>
/// Note: <see cref="CompositeProcessor{T}"/> is used as the base class because
/// the SDK needs to understand that <c>MyFilteringProcessor</c> wraps an inner
/// processor. Without that understanding some features such as <see
/// cref="Resource"/> would be unavailable because the SDK needs to push state
/// about the parent <see cref="TracerProvider"/> to all processors in the
/// chain.
/// </remarks>
internal sealed class MyFilteringProcessor : CompositeProcessor<Activity>
{
private readonly Func<Activity, bool> filter;
private readonly BaseProcessor<Activity> processor;
public MyFilteringProcessor(BaseProcessor<Activity> processor, Func<Activity, bool> filter)
: base(new[] { processor })
{
this.filter = filter ?? throw new ArgumentNullException(nameof(filter));
this.processor = processor ?? throw new ArgumentNullException(nameof(processor));
}
public override void OnEnd(Activity activity)
@ -35,7 +47,7 @@ internal class MyFilteringProcessor : BaseProcessor<Activity>
// only if the Filter returns true.
if (this.filter(activity))
{
this.processor.OnEnd(activity);
base.OnEnd(activity);
}
}
}

View File

@ -102,7 +102,6 @@ The [OpenTelemetry .NET Github repo](../../../README.md#getting-started) ships
the following instrumentation libraries. The individual docs for them describes
the library they instrument, and steps for enabling them.
* [ASP.NET](../../../src/OpenTelemetry.Instrumentation.AspNet/README.md)
* [ASP.NET
Core](../../../src/OpenTelemetry.Instrumentation.AspNetCore/README.md)
* [gRPC
@ -175,7 +174,10 @@ Writing an instrumentation library typically involves 3 steps.
method, it should call the `AddInstrumentation` method, and `AddSource`
method to enable its ActivitySource for the provider. An example
instrumentation using this approach is [SqlClient
instrumentation](../../../src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs)
instrumentation](../../../src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs).
**CAUTION**: The instrumentation libraries requiring state management
are usually hard to auto-instrument. Therefore, they take the risk of not
being supported by [OpenTelemetry .NET Automatic Instrumentation](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation).
2. If the instrumentation library does not requires any state management
tied to that of `TracerProvider`, then providing `TracerProviderBuilder`
@ -200,8 +202,7 @@ activities does not by default runs through the sampler, and will have their
`Kind` set to internal and they'll have empty ActivitySource name associated
with it.
Some common examples of such libraries include
[ASP.NET](../../../src/OpenTelemetry.Instrumentation.AspNet/README.md), [ASP.NET
Some common examples of such libraries include [ASP.NET
Core](../../../src/OpenTelemetry.Instrumentation.AspNetCore/README.md), [HTTP
client .NET Core](../../../src/OpenTelemetry.Instrumentation.Http/README.md) .
Instrumentation libraries for these are already provided in this repo. The

View File

@ -1,40 +0,0 @@
// <copyright file="WebApiConfig.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System.Net.Http.Formatting;
using System.Web.Http;
namespace Examples.AspNet
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter());
}
}
}

View File

@ -1,37 +0,0 @@
// <copyright file="HomeController.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System.Web.Mvc;
namespace Examples.AspNet.Controllers
{
public class HomeController : Controller
{
// For testing traditional routing. Ex: https://localhost:XXXX/
public ActionResult Index()
{
return this.View();
}
[Route("about_attr_route/{customerId}")] // For testing attribute routing. Ex: https://localhost:XXXX/about_attr_route
public ActionResult About(int? customerId)
{
this.ViewBag.Message = $"Your application description page for customer {customerId}.";
return this.View();
}
}
}

View File

@ -1,217 +0,0 @@
// <copyright file="WeatherForecastController.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Web.Http;
using Examples.AspNet.Models;
using OpenTelemetry;
namespace Examples.AspNet.Controllers
{
public class WeatherForecastController : ApiController
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching",
};
[HttpGet] // For testing traditional routing. Ex: https://localhost:XXXX/api/weatherforecast
public async Task<IEnumerable<WeatherForecast>> Get()
{
// Build some dependency spans.
await RequestGoogleHomPageViaHttpClient().ConfigureAwait(false);
await this.RequestInvalidViaHttpClient().ConfigureAwait(false);
await this.RequestValidThatReturnsFailedViaHttpClient().ConfigureAwait(false);
await this.RequestValidThatSpawnsSubSpansViaHttpClient().ConfigureAwait(false);
return GetWeatherForecast();
}
[Route("subroute/{customerId}")] // For testing attribute routing. Ex: https://localhost:XXXX/subroute/10
[HttpGet]
public async Task<IEnumerable<WeatherForecast>> Get(int customerId)
{
if (customerId < 0)
{
throw new ArgumentException();
}
// Making http calls here to serve as an example of
// how dependency calls will be captured and treated
// automatically as child of incoming request.
RequestGoogleHomPageViaHttpWebRequestLegacySync();
await RequestGoogleHomPageViaHttpWebRequestLegacyAsync().ConfigureAwait(false);
RequestGoogleHomPageViaHttpWebRequestLegacyAsyncResult();
return GetWeatherForecast();
}
/// <summary>
/// For testing large async operation which causes IIS to jump threads and results in lost AsyncLocals.
/// </summary>
[Route("data")]
[HttpGet]
public async Task<string> GetData()
{
Baggage.SetBaggage("key1", "value1");
using var rng = RandomNumberGenerator.Create();
var requestData = new byte[1024 * 1024 * 100];
rng.GetBytes(requestData);
using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, this.Url.Content("~/data"));
request.Content = new ByteArrayContent(requestData);
using var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responseData = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
return responseData.SequenceEqual(responseData) ? "match" : "mismatch";
}
[Route("data")]
[HttpPost]
public async Task<HttpResponseMessage> PostData()
{
string value1 = Baggage.GetBaggage("key1");
if (string.IsNullOrEmpty(value1))
{
throw new InvalidOperationException("Key1 was not found on Baggage.");
}
var stream = await this.Request.Content.ReadAsStreamAsync().ConfigureAwait(false);
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(stream),
};
result.Content.Headers.ContentType = this.Request.Content.Headers.ContentType;
return result;
}
private static IEnumerable<WeatherForecast> GetWeatherForecast()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)],
})
.ToArray();
}
// Test successful dependency collection via HttpClient.
private static async Task RequestGoogleHomPageViaHttpClient()
{
using var request = new HttpClient();
using var response = await request.GetAsync("http://www.google.com").ConfigureAwait(false);
response.EnsureSuccessStatusCode();
}
// Test dependency collection via legacy HttpWebRequest sync.
private static void RequestGoogleHomPageViaHttpWebRequestLegacySync()
{
var request = WebRequest.Create("http://www.google.com/?sync");
using var response = request.GetResponse();
}
// Test dependency collection via legacy HttpWebRequest async.
private static async Task RequestGoogleHomPageViaHttpWebRequestLegacyAsync()
{
var request = (HttpWebRequest)WebRequest.Create($"http://www.google.com/?async");
using var response = await request.GetResponseAsync().ConfigureAwait(false);
}
// Test dependency collection via legacy HttpWebRequest IAsyncResult.
private static void RequestGoogleHomPageViaHttpWebRequestLegacyAsyncResult()
{
var request = (HttpWebRequest)WebRequest.Create($"http://www.google.com/?async");
var asyncResult = request.BeginGetResponse(null, null);
using var response = request.EndGetResponse(asyncResult);
}
// Test exception dependency collection via HttpClient.
private async Task RequestInvalidViaHttpClient()
{
try
{
using var request = new HttpClient();
// This request is not available over SSL and will throw a handshake exception.
using var response = await request.GetAsync(this.Url.Content("~/subroute/10").Replace("http", "https")).ConfigureAwait(false);
Debug.Fail("Unreachable");
}
catch
{
}
}
// Test exception dependency collection via HttpClient.
private async Task RequestValidThatReturnsFailedViaHttpClient()
{
using var request = new HttpClient();
// This request will return a 500 error because customerId should be >= 0;
using var response = await request.GetAsync(this.Url.Content("~/subroute/-1")).ConfigureAwait(false);
Debug.Assert(response.StatusCode == HttpStatusCode.InternalServerError, "response.StatusCode is InternalServerError");
}
// Test successful dependency collection via HttpClient.
private async Task RequestValidThatSpawnsSubSpansViaHttpClient()
{
using var request = new HttpClient();
// This request will return successfully and cause a bunch of sub-spans;
using var response = await request.GetAsync(this.Url.Content("~/subroute/10")).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
}
}
}

View File

@ -1,157 +0,0 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{9A4E3A68-904B-4835-A3C8-F664B73098DB}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>OpenTelemetry.Exporter.AspNet</RootNamespace>
<AssemblyName>OpenTelemetry.Exporter.AspNet</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<UseIISExpress>true</UseIISExpress>
<Use64BitIISExpress />
<IISExpressSSLPort>
</IISExpressSSLPort>
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile />
<IsPackable>false</IsPackable>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Configuration" />
<Reference Include="System.Web" />
</ItemGroup>
<ItemGroup>
<Content Include="Global.asax" />
<Content Include="Web.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="App_Start\RouteConfig.cs" />
<Compile Include="App_Start\WebApiConfig.cs" />
<Compile Include="Controllers\HomeController.cs" />
<Compile Include="Controllers\WeatherForecastController.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
<Compile Include="Models\WeatherForecast.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SuppressInstrumentationHttpModule.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\_ViewStart.cshtml" />
<Content Include="Views\Home\Index.cshtml" />
<Content Include="Views\Shared\_Layout.cshtml" />
<Content Include="Views\Web.config" />
<Content Include="Views\Home\About.cshtml" />
<None Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</None>
<None Include="Web.Release.config">
<DependentUpon>Web.config</DependentUpon>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.WebHost" Version="$(MicrosoftAspNetWebApiWebHostPkgVer)" />
<PackageReference Include="Microsoft.AspNet.Mvc" Version="$(MicrosoftAspNetMvcPkgVer)" />
<PackageReference Include="Microsoft.AspNet.WebPages" Version="$(MicrosoftAspNetWebPagesPkgVer)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Api\OpenTelemetry.Api.csproj">
<Project>{99f8a331-05e9-45a5-89ba-4c54e825e5b2}</Project>
<Name>OpenTelemetry.Api</Name>
</ProjectReference>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.AspNet\OpenTelemetry.Instrumentation.AspNet.csproj">
<Project>{b9eeacdd-cafa-4b75-a18d-898e7de21b17}</Project>
<Name>OpenTelemetry.Instrumentation.AspNet</Name>
</ProjectReference>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Jaeger\OpenTelemetry.Exporter.Jaeger.csproj">
<Project>{8d47e3cf-9ae3-42fe-9084-feb72d9ad769}</Project>
<Name>OpenTelemetry.Exporter.Jaeger</Name>
</ProjectReference>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.Http\OpenTelemetry.Instrumentation.Http.csproj">
<Project>{412c64d1-43d6-4e4c-8ad8-e20e63b415bd}</Project>
<Name>OpenTelemetry.Instrumentation.Http</Name>
</ProjectReference>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry\OpenTelemetry.csproj">
<Project>{ae3e3df5-4083-4c6e-a840-8271b0acde7e}</Project>
<Name>OpenTelemetry</Name>
</ProjectReference>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Console\OpenTelemetry.Exporter.Console.csproj">
<Project>{1afff251-3b0c-47ca-be94-937083732c0a}</Project>
<Name>OpenTelemetry.Exporter.Console</Name>
</ProjectReference>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Zipkin\OpenTelemetry.Exporter.Zipkin.csproj">
<Project>{7edae7fa-b44e-42ca-80fa-7df2faa2c5dd}</Project>
<Name>OpenTelemetry.Exporter.Zipkin</Name>
</ProjectReference>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.OpenTelemetryProtocol\OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj">
<Project>{a38ac295-2745-4b85-8b6b-dca864cedd5b}</Project>
<Name>OpenTelemetry.Exporter.OpenTelemetryProtocol</Name>
</ProjectReference>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus\OpenTelemetry.Exporter.Prometheus.csproj">
<Project>{52158a12-e7ef-45a1-859f-06f9b17410cb}</Project>
<Name>OpenTelemetry.Exporter.Prometheus</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="Exists('$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets')" />
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>
<Target Name="SkipBuildWithoutVisualStudio">
<Message Text="Skipping build because Visual Studio is not available." Condition="!Exists('$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets')" />
<CallTarget Targets="$(BuildDependsOnOriginalValue)" Condition="Exists('$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets')" />
</Target>
<PropertyGroup>
<BuildDependsOnOriginalValue>$(BuildDependsOn)</BuildDependsOnOriginalValue>
<BuildDependsOn>SkipBuildWithoutVisualStudio</BuildDependsOn>
</PropertyGroup>
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>0</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:56171/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@ -1 +0,0 @@
<%@ Application Codebehind="Global.asax.cs" Inherits="Examples.AspNet.WebApiApplication" Language="C#" %>

View File

@ -1,111 +0,0 @@
// <copyright file="Global.asax.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System;
using System.Configuration;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using OpenTelemetry;
using OpenTelemetry.Exporter;
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;
namespace Examples.AspNet
{
#pragma warning disable SA1649 // File name should match first type name
public class WebApiApplication : HttpApplication
#pragma warning restore SA1649 // File name should match first type name
{
private IDisposable tracerProvider;
private IDisposable meterProvider;
protected void Application_Start()
{
var builder = Sdk.CreateTracerProviderBuilder()
.AddAspNetInstrumentation()
.AddHttpClientInstrumentation();
switch (ConfigurationManager.AppSettings["UseExporter"].ToLowerInvariant())
{
case "jaeger":
builder.AddJaegerExporter(jaegerOptions =>
{
jaegerOptions.AgentHost = ConfigurationManager.AppSettings["JaegerHost"];
jaegerOptions.AgentPort = int.Parse(ConfigurationManager.AppSettings["JaegerPort"]);
});
break;
case "zipkin":
builder.AddZipkinExporter(zipkinOptions =>
{
zipkinOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["ZipkinEndpoint"]);
});
break;
case "otlp":
builder.AddOtlpExporter(otlpOptions =>
{
otlpOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["OtlpEndpoint"]);
});
break;
default:
builder.AddConsoleExporter(options => options.Targets = ConsoleExporterOutputTargets.Debug);
break;
}
this.tracerProvider = builder.Build();
// Metrics
// Note: Tracerprovider is needed for metrics to work
// https://github.com/open-telemetry/opentelemetry-dotnet/issues/2994
var meterBuilder = Sdk.CreateMeterProviderBuilder()
.AddAspNetInstrumentation();
switch (ConfigurationManager.AppSettings["UseMetricsExporter"].ToLowerInvariant())
{
case "otlp":
meterBuilder.AddOtlpExporter(otlpOptions =>
{
otlpOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["OtlpEndpoint"]);
});
break;
case "prometheus":
meterBuilder.AddPrometheusExporter();
break;
default:
meterBuilder.AddConsoleExporter((exporterOptions, metricReaderOptions) =>
{
exporterOptions.Targets = ConsoleExporterOutputTargets.Debug;
});
break;
}
this.meterProvider = meterBuilder.Build();
GlobalConfiguration.Configure(WebApiConfig.Register);
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
protected void Application_End()
{
this.tracerProvider?.Dispose();
this.meterProvider?.Dispose();
}
}
}

View File

@ -1,50 +0,0 @@
// <copyright file="AssemblyInfo.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Examples.AspNet")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Examples.AspNet")]
[assembly: AssemblyCopyright("Copyright @ 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("9a4e3a68-904b-4835-a3c8-f664b73098db")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -1,58 +0,0 @@
// <copyright file="SuppressInstrumentationHttpModule.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System;
using System.Web;
using OpenTelemetry;
namespace Examples.AspNet
{
/// <summary>
/// A demo <see cref="IHttpModule"/> which will suppress ASP.NET
/// instrumentation if a request contains "suppress=true" on the query
/// string. Suppressed spans will not be processed/exported by the
/// OpenTelemetry SDK.
/// </summary>
public class SuppressInstrumentationHttpModule : IHttpModule
{
private IDisposable suppressionScope;
public void Init(HttpApplication context)
{
context.BeginRequest += this.Application_BeginRequest;
context.EndRequest += this.Application_EndRequest;
}
public void Dispose()
{
}
private void Application_BeginRequest(object sender, EventArgs e)
{
var context = ((HttpApplication)sender).Context;
if (context.Request.QueryString["suppress"] == "true")
{
this.suppressionScope = SuppressInstrumentationScope.Begin();
}
}
private void Application_EndRequest(object sender, EventArgs e)
{
this.suppressionScope?.Dispose();
}
}
}

View File

@ -1,7 +0,0 @@
@{
ViewBag.Title = "About";
}
<h2>@ViewBag.Title.</h2>
<h3>@ViewBag.Message</h3>
<p>Use this area to provide additional information.</p>

View File

@ -1,31 +0,0 @@
@{
ViewBag.Title = "Home Page";
}
<div class="jumbotron">
<h1>ASP.NET</h1>
<p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p>
<p><a href="https://asp.net" class="btn btn-primary btn-lg">Learn more &raquo;</a></p>
</div>
<div class="row">
<div class="col-md-4">
<h2>Getting started</h2>
<p>
ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that
enables a clean separation of concerns and gives you full control over markup
for enjoyable, agile development.
</p>
<p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301865">Learn more &raquo;</a></p>
</div>
<div class="col-md-4">
<h2>Get more libraries</h2>
<p>NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.</p>
<p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301866">Learn more &raquo;</a></p>
</div>
<div class="col-md-4">
<h2>Web Hosting</h2>
<p>You can easily find a web hosting company that offers the right mix of features and price for your applications.</p>
<p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301867">Learn more &raquo;</a></p>
</div>
</div>

View File

@ -1,36 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
</ul>
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
@RenderSection("scripts", required: false)
</body>
</html>

View File

@ -1,42 +0,0 @@
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
</namespaces>
</pages>
</system.web.webPages.razor>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.webServer>
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
<system.web>
<compilation>
<assemblies>
<add assembly="System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" />
</assemblies>
</compilation>
</system.web>
</configuration>

View File

@ -1,3 +0,0 @@
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information on using web.config transformation visit https://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an attribute "name" that has a value of "MyDB".
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<system.web>
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
</configuration>

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information on using web.config transformation visit https://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an attribute "name" that has a value of "MyDB".
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
</configuration>

View File

@ -1,62 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="webpages:Version" value="3.0.0.0"/>
<add key="webpages:Enabled" value="false"/>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
<add key="UseExporter" value="console"/>
<add key="UseMetricsExporter" value="console"/>
<add key="JaegerHost" value="localhost"/>
<add key="JaegerPort" value="6831"/>
<add key="ZipkinEndpoint" value="http://localhost:9411/api/v2/spans"/>
<add key="OtlpEndpoint" value="http://localhost:4317"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.8"/>
<httpRuntime targetFramework="4.8"
maxRequestLength="2147483647"
executionTimeout="300" />
</system.web>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
<remove name="OPTIONSVerbHandler"/>
<remove name="TRACEVerbHandler"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
</handlers>
<modules>
<add name="SuppressInstrumentationHttpModule" type="Examples.AspNet.SuppressInstrumentationHttpModule" preCondition="integratedMode,managedHandler"/>
<add name="TelemetryHttpModule" type="OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule" preCondition="integratedMode,managedHandler"/>
</modules>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="4294967295" />
</requestFiltering>
</security>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.ValueTuple" publicKeyToken="CC7B13FFCD2DDD51" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="CC7B13FFCD2DDD51" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="B03F5F7F11D50A3A" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="CC7B13FFCD2DDD51" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="CC7B13FFCD2DDD51" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -8,6 +8,7 @@
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="$(SwashbuckleAspNetCorePkgVer)" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="$(RuntimeInstrumentationPkgVer)" />
</ItemGroup>
<ItemGroup>
@ -18,7 +19,7 @@
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.AspNetCore\OpenTelemetry.Instrumentation.AspNetCore.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.Http\OpenTelemetry.Instrumentation.Http.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Jaeger\OpenTelemetry.Exporter.Jaeger.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus\OpenTelemetry.Exporter.Prometheus.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus.AspNetCore\OpenTelemetry.Exporter.Prometheus.AspNetCore.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Zipkin\OpenTelemetry.Exporter.Zipkin.csproj" />
</ItemGroup>
</Project>

View File

@ -24,27 +24,28 @@ using OpenTelemetry.Trace;
var builder = WebApplication.CreateBuilder(args);
var serviceName = "AspNetCoreExampleService";
// OpenTelemetry
var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "unknown";
// Switch between Zipkin/Jaeger/OTLP by setting UseExporter in appsettings.json.
var tracingExporter = builder.Configuration.GetValue<string>("UseTracingExporter").ToLowerInvariant();
var resourceBuilder = tracingExporter switch
var serviceName = tracingExporter switch
{
"jaeger" => ResourceBuilder.CreateDefault().AddService(builder.Configuration.GetValue<string>("Jaeger:ServiceName"), serviceVersion: assemblyVersion, serviceInstanceId: Environment.MachineName),
"zipkin" => ResourceBuilder.CreateDefault().AddService(builder.Configuration.GetValue<string>("Zipkin:ServiceName"), serviceVersion: assemblyVersion, serviceInstanceId: Environment.MachineName),
"otlp" => ResourceBuilder.CreateDefault().AddService(builder.Configuration.GetValue<string>("Otlp:ServiceName"), serviceVersion: assemblyVersion, serviceInstanceId: Environment.MachineName),
_ => ResourceBuilder.CreateDefault().AddService(serviceName, serviceVersion: assemblyVersion, serviceInstanceId: Environment.MachineName),
"jaeger" => builder.Configuration.GetValue<string>("Jaeger:ServiceName"),
"zipkin" => builder.Configuration.GetValue<string>("Zipkin:ServiceName"),
"otlp" => builder.Configuration.GetValue<string>("Otlp:ServiceName"),
_ => "AspNetCoreExampleService",
};
Action<ResourceBuilder> configureResource = r => r.AddService(
serviceName, serviceVersion: assemblyVersion, serviceInstanceId: Environment.MachineName);
// Traces
builder.Services.AddOpenTelemetryTracing(options =>
{
options
.SetResourceBuilder(resourceBuilder)
.ConfigureResource(configureResource)
.SetSampler(new AlwaysOnSampler())
.AddHttpClientInstrumentation()
.AddAspNetCoreInstrumentation();
@ -88,7 +89,7 @@ builder.Logging.ClearProviders();
builder.Logging.AddOpenTelemetry(options =>
{
options.SetResourceBuilder(resourceBuilder);
options.ConfigureResource(configureResource);
var logExporter = builder.Configuration.GetValue<string>("UseLogExporter").ToLowerInvariant();
switch (logExporter)
{
@ -112,13 +113,16 @@ builder.Services.Configure<OpenTelemetryLoggerOptions>(opt =>
});
// Metrics
var metricsExporter = builder.Configuration.GetValue<string>("UseMetricsExporter").ToLowerInvariant();
builder.Services.AddOpenTelemetryMetrics(options =>
{
options.SetResourceBuilder(resourceBuilder)
options.ConfigureResource(configureResource)
.AddRuntimeInstrumentation()
.AddHttpClientInstrumentation()
.AddAspNetCoreInstrumentation();
var metricsExporter = builder.Configuration.GetValue<string>("UseMetricsExporter").ToLowerInvariant();
switch (metricsExporter)
{
case "prometheus":
@ -159,9 +163,7 @@ app.UseAuthorization();
app.MapControllers();
var metricsExporter = builder.Configuration.GetValue<string>("UseMetricsExporter").ToLowerInvariant();
if (metricsExporter == "prometheus")
if (metricsExporter.Equals("prometheus", StringComparison.OrdinalIgnoreCase))
{
app.UseOpenTelemetryPrometheusScrapingEndpoint();
}

View File

@ -3,7 +3,6 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<NoWarn>$(NoWarn),CS0618</NoWarn>
</PropertyGroup>
@ -34,7 +33,7 @@
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Zipkin\OpenTelemetry.Exporter.Zipkin.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Jaeger\OpenTelemetry.Exporter.Jaeger.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.InMemory\OpenTelemetry.Exporter.InMemory.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus\OpenTelemetry.Exporter.Prometheus.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus.HttpListener\OpenTelemetry.Exporter.Prometheus.HttpListener.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs\OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs.csproj" />
</ItemGroup>
</Project>

View File

@ -39,7 +39,7 @@ namespace Examples.Console
// and use Console exporter.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("Samples.SampleClient", "Samples.SampleServer")
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("console-test"))
.ConfigureResource(res => res.AddService("console-test"))
.AddProcessor(new MyProcessor()) // This must be added before ConsoleExporter
.AddConsoleExporter()
.Build();

View File

@ -34,7 +34,7 @@ namespace Examples.Console
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddHttpClientInstrumentation()
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("http-service-example"))
.ConfigureResource(r => r.AddService("http-service-example"))
.AddSource("http-client-test")
.AddConsoleExporter()
.Build();

View File

@ -51,7 +51,7 @@ namespace Examples.Console
// and use InMemory exporter.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("Samples.SampleClient", "Samples.SampleServer")
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("inmemory-test"))
.ConfigureResource(r => r.AddService("inmemory-test"))
.AddInMemoryExporter(exportedItems)
.Build();

View File

@ -56,7 +56,7 @@ namespace Examples.Console
// Enable OpenTelemetry for the sources "Samples.SampleServer" and "Samples.SampleClient"
// and use the Jaeger exporter.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("jaeger-test"))
.ConfigureResource(r => r.AddService("jaeger-test"))
.AddSource("Samples.SampleClient", "Samples.SampleServer")
.AddJaegerExporter(o =>
{

View File

@ -33,7 +33,7 @@ namespace Examples.Console
using var meter = new Meter("TestMeter");
var providerBuilder = Sdk.CreateMeterProviderBuilder()
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("myservice"))
.ConfigureResource(r => r.AddService("myservice"))
.AddMeter(meter.Name); // All instruments from this meter are enabled.
if (options.UseExporter.Equals("otlp", StringComparison.OrdinalIgnoreCase))

View File

@ -28,7 +28,7 @@ namespace Examples.Console
// and use a single pipeline with a custom MyProcessor, and Console exporter.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("MyCompany.MyProduct.MyWebServer")
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyServiceName"))
.ConfigureResource(r => r.AddService("MyServiceName"))
.AddConsoleExporter()
.Build();

View File

@ -31,7 +31,7 @@ namespace Examples.Console
// and use Console exporter.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("MyCompany.MyProduct.MyWebServer")
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyServiceName"))
.ConfigureResource(r => r.AddService("MyServiceName"))
.AddConsoleExporter()
.Build();

View File

@ -71,7 +71,7 @@ namespace Examples.Console
// and use OTLP exporter.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("Samples.SampleClient", "Samples.SampleServer")
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("otlp-test"))
.ConfigureResource(r => r.AddService("otlp-test"))
.AddOtlpExporter(opt =>
{
// If endpoint was not specified, the proper one will be selected according to the protocol.

View File

@ -51,12 +51,8 @@ internal class TestPrometheusExporter
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter(MyMeter.Name)
.AddMeter(MyMeter2.Name)
.AddPrometheusExporter(options =>
{
options.StartHttpListener = true;
options.HttpListenerPrefixes = new string[] { $"http://localhost:{port}/" };
options.ScrapeResponseCacheDurationMilliseconds = 0;
})
.AddPrometheusHttpListener(
options => options.UriPrefixes = new string[] { $"http://localhost:{port}/" })
.Build();
var process = Process.GetCurrentProcess();

View File

@ -39,7 +39,7 @@ namespace Examples.Console
// and use the Zipkin exporter.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("Samples.SampleClient", "Samples.SampleServer")
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("zipkin-test"))
.ConfigureResource(r => r.AddService("zipkin-test"))
.AddZipkinExporter(o =>
{
o.Endpoint = new Uri(zipkinUri);

View File

@ -45,7 +45,7 @@ namespace Examples.GrpcService
{
case "jaeger":
services.AddOpenTelemetryTracing((builder) => builder
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(this.Configuration.GetValue<string>("Jaeger:ServiceName")))
.ConfigureResource(r => r.AddService(this.Configuration.GetValue<string>("Jaeger:ServiceName")))
.AddAspNetCoreInstrumentation()
.AddJaegerExporter(jaegerOptions =>
{

View File

@ -1,4 +1,4 @@
// <copyright file="RouteConfig.cs" company="OpenTelemetry Authors">
// <copyright file="ExampleEventSource.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -14,23 +14,20 @@
// limitations under the License.
// </copyright>
using System.Web.Mvc;
using System.Web.Routing;
using System.Diagnostics.Tracing;
namespace Examples.AspNet
namespace Examples.LoggingExtensions;
[EventSource(Name = EventSourceName)]
internal sealed class ExampleEventSource : EventSource
{
public class RouteConfig
public const string EventSourceName = "OpenTelemetry-ExampleEventSource";
public static ExampleEventSource Log { get; } = new();
[Event(1, Message = "Example event written with '{0}' reason", Level = EventLevel.Informational)]
public void ExampleEvent(string reason)
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
this.WriteEvent(1, reason);
}
}

View File

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Console\OpenTelemetry.Exporter.Console.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Extensions.Serilog\OpenTelemetry.Extensions.Serilog.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Extensions.EventSource\OpenTelemetry.Extensions.EventSource.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,58 @@
// <copyright file="Program.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System.Diagnostics.Tracing;
using Examples.LoggingExtensions;
using OpenTelemetry.Logs;
using OpenTelemetry.Resources;
using Serilog;
var resourceBuilder = ResourceBuilder.CreateDefault().AddService("Examples.LoggingExtensions");
var openTelemetryLoggerProvider = new OpenTelemetryLoggerProvider(options =>
{
options.IncludeFormattedMessage = true;
options
.SetResourceBuilder(resourceBuilder)
.AddConsoleExporter();
});
// Creates an OpenTelemetryEventSourceLogEmitter for routing ExampleEventSource
// events into logs
using var openTelemetryEventSourceLogEmitter = new OpenTelemetryEventSourceLogEmitter(
openTelemetryLoggerProvider, // <- Events will be written to openTelemetryLoggerProvider
(name) => name == ExampleEventSource.EventSourceName ? EventLevel.Informational : null,
disposeProvider: false); // <- Do not dispose the provider with OpenTelemetryEventSourceLogEmitter since in this case it is shared with Serilog
// Configure Serilog global logger
Log.Logger = new LoggerConfiguration()
.WriteTo.OpenTelemetry(
openTelemetryLoggerProvider, // <- Register OpenTelemetry Serilog sink writing to openTelemetryLoggerProvider
disposeProvider: false) // <- Do not dispose the provider with Serilog since in this case it is shared with OpenTelemetryEventSourceLogEmitter
.CreateLogger();
ExampleEventSource.Log.ExampleEvent("Startup complete");
// Note: Serilog ForContext API is used to set "CategoryName" on log messages
ILogger programLogger = Log.Logger.ForContext<Program>();
programLogger.Information("Application started {Greeting} {Location}", "Hello", "World");
// Note: For Serilog this call flushes all logs
Log.CloseAndFlush();
// Manually dispose OpenTelemetryLoggerProvider since it is being shared
openTelemetryLoggerProvider.Dispose();

View File

@ -0,0 +1,10 @@
# OpenTelemetry Logging Extensions Example
This project contains examples of the `LogEmitter` API being used to extend
existing logging platforms to write into OpenTelemetry logs.
* Serilog: Using OpenTelemetry.Extensions.Serilog
## References
* [OpenTelemetry Project](https://opentelemetry.io/)

View File

@ -0,0 +1 @@
static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity activity, System.Exception ex, in System.Diagnostics.TagList tags) -> void

View File

@ -0,0 +1 @@
static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity activity, System.Exception ex, in System.Diagnostics.TagList tags) -> void

View File

@ -2,6 +2,14 @@
## Unreleased
## 1.4.0-alpha.1
Released 2022-Aug-02
* Add `Activity.RecordException` overload accepting additional attributes to
add to the `ActivityEvent`.
[#3433](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3433)
## 1.3.0
Released 2022-Jun-03
@ -159,7 +167,7 @@ Released 2021-Jan-29
the `Status` (otel.status_code) tag (added on `Activity` using the `SetStatus`
extension) will now be set as the `UNSET`, `OK`, or `ERROR` string
representation instead of the `0`, `1`, or `2` integer representation.
([#1579](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1579) &
([#1579](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1579)
[#1620](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1620))
* Metrics API/SDK support is in an experimental state and is not recommended for
production use. All metric APIs have been marked with the `Obsolete`
@ -262,7 +270,7 @@ Released 2020-08-28
header
([#1048](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1048))
* Removed `DistributedContext` as it is no longer part of the spec
([#1048](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1048)))
([#1048](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1048))
* Renaming from `ot` to `otel`
([#1046](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1046))
* Added `RuntimeContext` API

View File

@ -44,7 +44,7 @@ namespace OpenTelemetry.Trace
ActivityStatusTagEnumerator state = default;
ActivityTagsEnumeratorFactory<ActivityStatusTagEnumerator>.Enumerate(activity, ref state);
ActivityTagsEnumeratorFactory<ActivityStatusTagEnumerator>.Enumerate(activity, ref state, null);
if (!state.StatusCode.HasValue)
{
@ -72,7 +72,7 @@ namespace OpenTelemetry.Trace
ActivitySingleTagEnumerator state = new ActivitySingleTagEnumerator(tagName);
ActivityTagsEnumeratorFactory<ActivitySingleTagEnumerator>.Enumerate(activity, ref state);
ActivityTagsEnumeratorFactory<ActivitySingleTagEnumerator>.Enumerate(activity, ref state, null);
return state.Value;
}
@ -91,7 +91,7 @@ namespace OpenTelemetry.Trace
ActivityFirstTagEnumerator state = new ActivityFirstTagEnumerator(tagName);
ActivityTagsEnumeratorFactory<ActivityFirstTagEnumerator>.Enumerate(activity, ref state);
ActivityTagsEnumeratorFactory<ActivityFirstTagEnumerator>.Enumerate(activity, ref state, null);
if (state.Value == null)
{
@ -109,14 +109,15 @@ namespace OpenTelemetry.Trace
/// <typeparam name="T">The struct <see cref="IActivityEnumerator{T}"/> implementation to use for the enumeration.</typeparam>
/// <param name="activity">Activity instance.</param>
/// <param name="tagEnumerator">Tag enumerator.</param>
/// <param name="maxTags">Maximum number of tags to enumerate.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")]
public static void EnumerateTags<T>(this Activity activity, ref T tagEnumerator)
public static void EnumerateTags<T>(this Activity activity, ref T tagEnumerator, int? maxTags = null)
where T : struct, IActivityEnumerator<KeyValuePair<string, object>>
{
Debug.Assert(activity != null, "Activity should not be null");
ActivityTagsEnumeratorFactory<T>.Enumerate(activity, ref tagEnumerator);
ActivityTagsEnumeratorFactory<T>.Enumerate(activity, ref tagEnumerator, maxTags);
}
/// <summary>
@ -125,14 +126,15 @@ namespace OpenTelemetry.Trace
/// <typeparam name="T">The struct <see cref="IActivityEnumerator{T}"/> implementation to use for the enumeration.</typeparam>
/// <param name="activity">Activity instance.</param>
/// <param name="linkEnumerator">Link enumerator.</param>
/// <param name="maxLinks">Maximum number of links to enumerate.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")]
public static void EnumerateLinks<T>(this Activity activity, ref T linkEnumerator)
public static void EnumerateLinks<T>(this Activity activity, ref T linkEnumerator, int? maxLinks = null)
where T : struct, IActivityEnumerator<ActivityLink>
{
Debug.Assert(activity != null, "Activity should not be null");
ActivityLinksEnumeratorFactory<T>.Enumerate(activity, ref linkEnumerator);
ActivityLinksEnumeratorFactory<T>.Enumerate(activity, ref linkEnumerator, maxLinks);
}
/// <summary>
@ -141,12 +143,13 @@ namespace OpenTelemetry.Trace
/// <typeparam name="T">The struct <see cref="IActivityEnumerator{T}"/> implementation to use for the enumeration.</typeparam>
/// <param name="activityLink">ActivityLink instance.</param>
/// <param name="tagEnumerator">Tag enumerator.</param>
/// <param name="maxTags">Maximum number of tags to enumerate.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")]
public static void EnumerateTags<T>(this ActivityLink activityLink, ref T tagEnumerator)
public static void EnumerateTags<T>(this ActivityLink activityLink, ref T tagEnumerator, int? maxTags = null)
where T : struct, IActivityEnumerator<KeyValuePair<string, object>>
{
ActivityTagsEnumeratorFactory<T>.Enumerate(activityLink, ref tagEnumerator);
ActivityTagsEnumeratorFactory<T>.Enumerate(activityLink, ref tagEnumerator, maxTags);
}
/// <summary>
@ -155,14 +158,15 @@ namespace OpenTelemetry.Trace
/// <typeparam name="T">The struct <see cref="IActivityEnumerator{T}"/> implementation to use for the enumeration.</typeparam>
/// <param name="activity">Activity instance.</param>
/// <param name="eventEnumerator">Event enumerator.</param>
/// <param name="maxEvents">Maximum number of events to enumerate.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")]
public static void EnumerateEvents<T>(this Activity activity, ref T eventEnumerator)
public static void EnumerateEvents<T>(this Activity activity, ref T eventEnumerator, int? maxEvents = null)
where T : struct, IActivityEnumerator<ActivityEvent>
{
Debug.Assert(activity != null, "Activity should not be null");
ActivityEventsEnumeratorFactory<T>.Enumerate(activity, ref eventEnumerator);
ActivityEventsEnumeratorFactory<T>.Enumerate(activity, ref eventEnumerator, maxEvents);
}
/// <summary>
@ -171,12 +175,13 @@ namespace OpenTelemetry.Trace
/// <typeparam name="T">The struct <see cref="IActivityEnumerator{T}"/> implementation to use for the enumeration.</typeparam>
/// <param name="activityEvent">ActivityEvent instance.</param>
/// <param name="tagEnumerator">Tag enumerator.</param>
/// <param name="maxTags">Maximum number of tags to enumerate.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")]
public static void EnumerateTags<T>(this ActivityEvent activityEvent, ref T tagEnumerator)
public static void EnumerateTags<T>(this ActivityEvent activityEvent, ref T tagEnumerator, int? maxTags = null)
where T : struct, IActivityEnumerator<KeyValuePair<string, object>>
{
ActivityTagsEnumeratorFactory<T>.Enumerate(activityEvent, ref tagEnumerator);
ActivityTagsEnumeratorFactory<T>.Enumerate(activityEvent, ref tagEnumerator, maxTags);
}
private struct ActivitySingleTagEnumerator : IActivityEnumerator<KeyValuePair<string, object>>
@ -265,7 +270,7 @@ namespace OpenTelemetry.Trace
private static readonly DictionaryEnumerator<string, object, TState>.ForEachDelegate ForEachTagValueCallbackRef = ForEachTagValueCallback;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Enumerate(Activity activity, ref TState state)
public static void Enumerate(Activity activity, ref TState state, int? maxTags)
{
var tagObjects = activity.TagObjects;
@ -274,6 +279,12 @@ namespace OpenTelemetry.Trace
return;
}
if (maxTags.HasValue)
{
SkipAllocationFreeEnumeration(tagObjects, ref state, maxTags.Value);
return;
}
ActivityTagObjectsEnumerator(
tagObjects,
ref state,
@ -281,7 +292,7 @@ namespace OpenTelemetry.Trace
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Enumerate(ActivityLink activityLink, ref TState state)
public static void Enumerate(ActivityLink activityLink, ref TState state, int? maxTags)
{
var tags = activityLink.Tags;
@ -290,6 +301,12 @@ namespace OpenTelemetry.Trace
return;
}
if (maxTags.HasValue)
{
SkipAllocationFreeEnumeration(tags, ref state, maxTags.Value);
return;
}
ActivityTagsCollectionEnumerator(
tags,
ref state,
@ -297,7 +314,7 @@ namespace OpenTelemetry.Trace
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Enumerate(ActivityEvent activityEvent, ref TState state)
public static void Enumerate(ActivityEvent activityEvent, ref TState state, int? maxTags)
{
var tags = activityEvent.Tags;
@ -306,12 +323,31 @@ namespace OpenTelemetry.Trace
return;
}
if (maxTags.HasValue)
{
SkipAllocationFreeEnumeration(tags, ref state, maxTags.Value);
return;
}
ActivityTagsCollectionEnumerator(
tags,
ref state,
ForEachTagValueCallbackRef);
}
// TODO: When a limit has been configured an allocation-free enumerator is not used.
// Need to either:
// 1) modify the dynamically generated code to only enumerate up to the max number of items, or
// 2) wait until .NET 7 is released and do this more easily with the new enumerator functions
private static void SkipAllocationFreeEnumeration(IEnumerable<KeyValuePair<string, object>> tags, ref TState state, int maxTags)
{
var enumerator = tags.GetEnumerator();
for (var i = 0; enumerator.MoveNext() && i < maxTags; ++i)
{
state.ForEach(enumerator.Current);
}
}
private static bool ForEachTagValueCallback(ref TState state, KeyValuePair<string, object> item)
=> state.ForEach(item);
}
@ -328,7 +364,7 @@ namespace OpenTelemetry.Trace
private static readonly ListEnumerator<ActivityLink, TState>.ForEachDelegate ForEachLinkCallbackRef = ForEachLinkCallback;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Enumerate(Activity activity, ref TState state)
public static void Enumerate(Activity activity, ref TState state, int? maxLinks)
{
var activityLinks = activity.Links;
@ -337,6 +373,21 @@ namespace OpenTelemetry.Trace
return;
}
// TODO: When a limit has been configured an allocation-free enumerator is not used.
// Need to either:
// 1) modify the dynamically generated code to only enumerate up to the max number of items, or
// 2) wait until .NET 7 is released and do this more easily with the new enumerator functions
if (maxLinks.HasValue)
{
var enumerator = activityLinks.GetEnumerator();
for (var i = 0; enumerator.MoveNext() && i < maxLinks; ++i)
{
state.ForEach(enumerator.Current);
}
return;
}
ActivityLinksEnumerator(
activityLinks,
ref state,
@ -359,7 +410,7 @@ namespace OpenTelemetry.Trace
private static readonly ListEnumerator<ActivityEvent, TState>.ForEachDelegate ForEachEventCallbackRef = ForEachEventCallback;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Enumerate(Activity activity, ref TState state)
public static void Enumerate(Activity activity, ref TState state, int? maxEvents)
{
var activityEvents = activity.Events;
@ -368,6 +419,21 @@ namespace OpenTelemetry.Trace
return;
}
// TODO: When a limit has been configured an allocation-free enumerator is not used.
// Need to either:
// 1) modify the dynamically generated code to only enumerate up to the max number of items, or
// 2) wait until .NET 7 is released and do this more easily with the new enumerator functions
if (maxEvents.HasValue)
{
var enumerator = activityEvents.GetEnumerator();
for (var i = 0; enumerator.MoveNext() && i < maxEvents; ++i)
{
state.ForEach(enumerator.Current);
}
return;
}
ActivityEventsEnumerator(
activityEvents,
ref state,

View File

@ -25,6 +25,9 @@ namespace System.Runtime.CompilerServices
/// <summary>
/// Allows capturing of the expressions passed to a method.
/// </summary>
/// <remarks>
/// Borrowed from: <see href="https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CallerArgumentExpressionAttribute.cs"/>.
/// </remarks>
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
#pragma warning disable SA1402 // File may only contain a single type
#pragma warning disable SA1649 // File name should match first type name

View File

@ -153,8 +153,7 @@ required only for the following scenarios:
[Propagators](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md),
to inject and extract context data. Some of the most common libraries
requiring this include
[HttpClient](../OpenTelemetry.Instrumentation.Http/README.md),
[ASP.NET](../OpenTelemetry.Instrumentation.AspNet/README.md), [ASP.NET
[HttpClient](../OpenTelemetry.Instrumentation.Http/README.md), [ASP.NET
Core](../OpenTelemetry.Instrumentation.AspNetCore/README.md). This repo
already provides instrumentation for these common libraries. If your library
is not built on top of these, and want to leverage propagators, follow the
@ -394,8 +393,8 @@ OpenTelemetry defines a concept called
[Status](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status)
to be associated with `Activity`. Starting with [DiagnosticSource
6.0](https://www.nuget.org/packages/System.Diagnostics.DiagnosticSource/6.0.0),
`SetStatus` API on `Activity` can be used to set the status and description
as shown below:
`SetStatus` API on `Activity` can be used to set the status and description as
shown below:
```csharp
activity?.SetStatus(ActivityStatusCode.Ok);
@ -467,16 +466,16 @@ runtime itself, as part of the
package. This means, users can instrument their applications/libraries to emit
metrics by simply using the `System.Diagnostics.DiagnosticSource` package. This
package can be used in applications targeting any of the officially supported
versions of [.NET](https://dotnet.microsoft.com/download/dotnet) and
[.NET Framework](https://dotnet.microsoft.com/download/dotnet-framework) (an
older Windows-based .NET implementation).
versions of [.NET](https://dotnet.microsoft.com/download/dotnet) and [.NET
Framework](https://dotnet.microsoft.com/download/dotnet-framework) (an older
Windows-based .NET implementation).
## Instrumenting a library/application with .NET Metrics API
### Basic metric usage
1. Install the `System.Diagnostics.DiagnosticSource` package version
`6.0.0` or above to your application or library.
1. Install the `System.Diagnostics.DiagnosticSource` package version `6.0.0` or
above to your application or library.
```xml
<ItemGroup>
@ -496,9 +495,8 @@ older Windows-based .NET implementation).
The above requires import of the `System.Diagnostics.Metrics` namespace.
**Note:**
It is important to note that `Meter` instances are created by using its
constructor, and *not* by calling a `GetMeter` method on the
**Note:** It is important to note that `Meter` instances are created by
using its constructor, and *not* by calling a `GetMeter` method on the
`MeterProvider`. This is an important distinction from the [OpenTelemetry
specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#get-a-meter),
where `Meter`s are obtained from `MeterProvider`.
@ -528,8 +526,7 @@ describes more kinds of instruments.
This component uses an
[EventSource](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventsource)
with the name "OpenTelemetry-Api" for its internal logging.
Please refer to [SDK
with the name "OpenTelemetry-Api" for its internal logging. Please refer to [SDK
troubleshooting](../OpenTelemetry/README.md#troubleshooting) for instructions on
seeing these internal logs.

View File

@ -69,14 +69,26 @@ namespace OpenTelemetry.Trace
}
/// <summary>
/// Record Exception.
/// Adds an activity event containing information from the specified exception.
/// </summary>
/// <param name="activity">Activity instance.</param>
/// <param name="ex">Exception to be recorded.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void RecordException(this Activity activity, Exception ex)
{
if (ex == null)
activity?.RecordException(ex, default);
}
/// <summary>
/// Adds an activity event containing information from the specified exception and additional tags.
/// </summary>
/// <param name="activity">Activity instance.</param>
/// <param name="ex">Exception to be recorded.</param>
/// <param name="tags">Additional tags to record on the event.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void RecordException(this Activity activity, Exception ex, in TagList tags)
{
if (ex == null || activity == null)
{
return;
}
@ -92,7 +104,12 @@ namespace OpenTelemetry.Trace
tagsCollection.Add(SemanticConventions.AttributeExceptionMessage, ex.Message);
}
activity?.AddEvent(new ActivityEvent(SemanticConventions.AttributeExceptionEventName, default, tagsCollection));
foreach (var tag in tags)
{
tagsCollection[tag.Key] = tag.Value;
}
activity.AddEvent(new ActivityEvent(SemanticConventions.AttributeExceptionEventName, default, tagsCollection));
}
}
}

View File

@ -2,6 +2,16 @@
## Unreleased
## 1.4.0-alpha.1
Released 2022-Aug-02
* The `MetricReaderOptions` defaults can be overridden using
`OTEL_METRIC_EXPORT_INTERVAL` and `OTEL_METRIC_EXPORT_TIMEOUT`
environmental variables as defined in the
[specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/sdk-environment-variables.md#periodic-exporting-metricreader).
([#3424](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3424))
## 1.3.0
Released 2022-Jun-03
@ -51,7 +61,7 @@ Released 2022-Mar-30
* Added StatusCode, StatusDescription support to
`ConsoleActivityExporter`.
([#2929](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2929)
[#3061](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3061))
[#3061](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3061))
* `AddConsoleExporter` extension method by default sets up exporter
to export metrics every 10 seconds.

View File

@ -42,7 +42,11 @@ namespace OpenTelemetry.Exporter
this.WriteLine($"{"LogRecord.TraceFlags:",-RightPaddingLength}{logRecord.TraceFlags}");
}
this.WriteLine($"{"LogRecord.CategoryName:",-RightPaddingLength}{logRecord.CategoryName}");
if (logRecord.CategoryName != null)
{
this.WriteLine($"{"LogRecord.CategoryName:",-RightPaddingLength}{logRecord.CategoryName}");
}
this.WriteLine($"{"LogRecord.LogLevel:",-RightPaddingLength}{logRecord.LogLevel}");
if (logRecord.FormattedMessage != null)
@ -62,7 +66,7 @@ namespace OpenTelemetry.Exporter
// Special casing {OriginalFormat}
// See https://github.com/open-telemetry/opentelemetry-dotnet/pull/3182
// for explanation.
var valueToTransform = logRecord.StateValues[i].Key.Equals("{OriginalValue}")
var valueToTransform = logRecord.StateValues[i].Key.Equals("{OriginalFormat}")
? new KeyValuePair<string, object>("OriginalFormat (a.k.a Body)", logRecord.StateValues[i].Value)
: logRecord.StateValues[i];
@ -76,13 +80,13 @@ namespace OpenTelemetry.Exporter
if (logRecord.EventId != default)
{
this.WriteLine($"{"LogRecord.EventId:",-RightPaddingLength}{logRecord.EventId.Id}");
if (string.IsNullOrEmpty(logRecord.EventId.Name))
if (!string.IsNullOrEmpty(logRecord.EventId.Name))
{
this.WriteLine($"{"LogRecord.EventName:",-RightPaddingLength}{logRecord.EventId.Name}");
}
}
if (logRecord.Exception is { })
if (logRecord.Exception != null)
{
this.WriteLine($"{"LogRecord.Exception:",-RightPaddingLength}{logRecord.Exception?.Message}");
}

View File

@ -21,6 +21,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\EnvironmentVariableHelper.cs" Link="Includes\EnvironmentVariableHelper.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\OpenTelemetrySdkEventSource.cs" Link="Includes\OpenTelemetrySdkEventSource.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\PeriodicExportingMetricReaderHelper.cs" Link="Includes\PeriodicExportingMetricReaderHelper.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\ServiceProviderExtensions.cs" Link="Includes\ServiceProviderExtensions.cs" />

View File

@ -23,6 +23,30 @@ used:
* [Metrics](../../docs/metrics/getting-started/Program.cs)
* [Traces](../../docs/trace/getting-started/Program.cs)
## Configuration
See the
[`TestConsoleExporter.cs`](../../examples/Console/TestConsoleExporter.cs) for
an example of how to use the exporter for exporting traces to a collection.
You can configure the `ConsoleExporter` through `Options` types properties
and environment variables.
The `Options` type setters take precedence over the environment variables.
## Environment Variables
The following environment variables can be used to override the default
values of the `PeriodicExportingMetricReaderOptions`
(following the [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/sdk-environment-variables.md#periodic-exporting-metricreader).
| Environment variable | `PeriodicExportingMetricReaderOptions` property |
| ------------------------------| ------------------------------------------------|
| `OTEL_METRIC_EXPORT_INTERVAL` | `ExportIntervalMilliseconds` |
| `OTEL_METRIC_EXPORT_TIMEOUT` | `ExportTimeoutMilliseconds` |
`FormatException` is thrown in case of an invalid value for any of the
supported environment variables.
## References
* [OpenTelemetry Project](https://opentelemetry.io/)

View File

@ -2,6 +2,19 @@
## Unreleased
## 1.4.0-alpha.1
Released 2022-Aug-02
* `InMemoryExporter` will now buffer scopes when exporting `LogRecord`
([#3360](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3360))
* The `MetricReaderOptions` defaults can be overridden using
`OTEL_METRIC_EXPORT_INTERVAL` and `OTEL_METRIC_EXPORT_TIMEOUT`
environmental variables as defined in the
[specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/sdk-environment-variables.md#periodic-exporting-metricreader).
([#3424](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3424))
## 1.3.0
Released 2022-Jun-03

View File

@ -14,7 +14,6 @@
// limitations under the License.
// </copyright>
using System;
using System.Collections.Generic;
namespace OpenTelemetry.Exporter
@ -23,19 +22,21 @@ namespace OpenTelemetry.Exporter
where T : class
{
private readonly ICollection<T> exportedItems;
private readonly Func<Batch<T>, ExportResult> onExport;
private readonly ExportFunc onExport;
public InMemoryExporter(ICollection<T> exportedItems)
{
this.exportedItems = exportedItems;
this.onExport = (Batch<T> batch) => this.DefaultExport(batch);
this.onExport = this.DefaultExport;
}
internal InMemoryExporter(Func<Batch<T>, ExportResult> exportFunc)
internal InMemoryExporter(ExportFunc exportFunc)
{
this.onExport = exportFunc;
}
internal delegate ExportResult ExportFunc(in Batch<T> batch);
public override ExportResult Export(in Batch<T> batch) => this.onExport(batch);
private ExportResult DefaultExport(in Batch<T> batch)

View File

@ -27,7 +27,25 @@ namespace OpenTelemetry.Logs
Guard.ThrowIfNull(loggerOptions);
Guard.ThrowIfNull(exportedItems);
return loggerOptions.AddProcessor(new SimpleLogRecordExportProcessor(new InMemoryExporter<LogRecord>(exportedItems)));
var logExporter = new InMemoryExporter<LogRecord>(
exportFunc: (in Batch<LogRecord> batch) => ExportLogRecord(in batch, exportedItems));
return loggerOptions.AddProcessor(new SimpleLogRecordExportProcessor(logExporter));
}
private static ExportResult ExportLogRecord(in Batch<LogRecord> batch, ICollection<LogRecord> exportedItems)
{
if (exportedItems == null)
{
return ExportResult.Failure;
}
foreach (var log in batch)
{
exportedItems.Add(log.Copy());
}
return ExportResult.Success;
}
}
}

View File

@ -145,7 +145,7 @@ namespace OpenTelemetry.Metrics
configureMetricReader?.Invoke(metricReaderOptions);
var metricExporter = new InMemoryExporter<Metric>(
exportFunc: metricBatch => ExportMetricSnapshot(metricBatch, exportedItems));
exportFunc: (in Batch<Metric> metricBatch) => ExportMetricSnapshot(in metricBatch, exportedItems));
var metricReader = PeriodicExportingMetricReaderHelper.CreatePeriodicExportingMetricReader(
metricExporter,

View File

@ -17,6 +17,24 @@ See the
[`TestInMemoryExporter.cs`](../../examples/Console/TestInMemoryExporter.cs) for
an example of how to use the exporter for exporting traces to a collection.
You can configure the `InMemoryExporter` through `Options` types properties
and environment variables.
The `Options` type setters take precedence over the environment variables.
## Environment Variables
The following environment variables can be used to override the default
values of the `PeriodicExportingMetricReaderOptions`
(following the [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/sdk-environment-variables.md#periodic-exporting-metricreader).
| Environment variable | `PeriodicExportingMetricReaderOptions` property |
| ------------------------------| ------------------------------------------------|
| `OTEL_METRIC_EXPORT_INTERVAL` | `ExportIntervalMilliseconds` |
| `OTEL_METRIC_EXPORT_TIMEOUT` | `ExportTimeoutMilliseconds` |
`FormatException` is thrown in case of an invalid value for any of the
supported environment variables.
## References
* [OpenTelemetry Project](https://opentelemetry.io/)

View File

@ -2,6 +2,10 @@
## Unreleased
## 1.4.0-alpha.1
Released 2022-Aug-02
## 1.3.0
Released 2022-Jun-03
@ -209,11 +213,11 @@ Released 2021-Jan-29
Simple exporter, and settings for batch exporting properties.
* Jaeger will now set the `error` tag when `otel.status_code` is set to `ERROR`.
([#1579](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1579) &
([#1579](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1579)
[#1620](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1620))
* Jaeger will no longer send the `otel.status_code` tag if the value is `UNSET`.
([#1609](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1609) &
([#1609](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1609)
[#1620](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1620))
* Span Event.Name will now be populated as the `event` field on Jaeger Logs
@ -265,14 +269,14 @@ Released 2020-Sep-15
Released 2020-08-28
* Changed `JaegerExporter` to use `BatchExportActivityProcessor` by default
* Changed `JaegerExporter` to use `BatchExportActivityProcessor` by default.
([#1125](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1125))
* Span links will now be sent as `FOLLOWS_FROM` reference type. Previously they
were sent as `CHILD_OF`.
([#970](https://github.com/open-telemetry/opentelemetry-dotnet/pull/970))
* Fixed issue when span has both the `net.peer.name` and `net.peer.port`
attributes but did not include `net.peer.port` in the `peer.service` field
([#1195](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1195)).
attributes but did not include `net.peer.port` in the `peer.service` field.
([#1195](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1195))
* Renamed extension method from `UseJaegerExporter` to `AddJaegerExporter`.

View File

@ -2,6 +2,10 @@
## Unreleased
## 1.4.0-alpha.1
Released 2022-Aug-02
## 1.3.0-rc.2
Released 2022-June-1

View File

@ -2,6 +2,22 @@
## Unreleased
## 1.4.0-alpha.1
Released 2022-Aug-02
* Adds support for limiting the length and count of attributes exported from
the OTLP exporter. These
[Attribute Limits](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#attribute-limits)
are configured via the environment variables defined in the specification.
([#3376](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3376))
* The `MetricReaderOptions` defaults can be overridden using
`OTEL_METRIC_EXPORT_INTERVAL` and `OTEL_METRIC_EXPORT_TIMEOUT`
environmental variables as defined in the
[specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/sdk-environment-variables.md#periodic-exporting-metricreader).
([#3424](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3424))
## 1.3.0
Released 2022-Jun-03
@ -19,7 +35,7 @@ Released 2022-May-16
* Support `HttpProtobuf` protocol with logs & added `HttpClientFactory`
option
([#3225](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3225))
([#3225](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3225))
* Removes net5.0 target and replaced with net6.0
as .NET 5.0 is going out of support.
@ -242,8 +258,8 @@ Released 2021-Apr-23
* Null values in string arrays are preserved according to
[spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/common.md).
([#1919](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1919)) and
([#1945](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1945)).
([#1919](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1919)
[#1945](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1945))
* When using OpenTelemetry.Extensions.Hosting you can now bind
`OtlpExporterOptions` to `IConfiguration` using the `Configure` extension (ex:

View File

@ -0,0 +1,46 @@
// <copyright file="EnvironmentVariableConfiguration.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System;
using OpenTelemetry.Internal;
namespace OpenTelemetry.Configuration;
internal class EnvironmentVariableConfiguration
{
public static void InitializeDefaultConfigurationFromEnvironment(SdkConfiguration sdkConfiguration)
{
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#attribute-limits
SetIntConfigValue("OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT", value => sdkConfiguration.AttributeValueLengthLimit = value);
SetIntConfigValue("OTEL_ATTRIBUTE_COUNT_LIMIT", value => sdkConfiguration.AttributeCountLimit = value);
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#span-limits
SetIntConfigValue("OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT", value => sdkConfiguration.SpanAttributeValueLengthLimit = value);
SetIntConfigValue("OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT", value => sdkConfiguration.SpanAttributeCountLimit = value);
SetIntConfigValue("OTEL_SPAN_EVENT_COUNT_LIMIT", value => sdkConfiguration.SpanEventCountLimit = value);
SetIntConfigValue("OTEL_SPAN_LINK_COUNT_LIMIT", value => sdkConfiguration.SpanLinkCountLimit = value);
SetIntConfigValue("OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT", value => sdkConfiguration.EventAttributeCountLimit = value);
SetIntConfigValue("OTEL_LINK_ATTRIBUTE_COUNT_LIMIT", value => sdkConfiguration.LinkAttributeCountLimit = value);
}
private static void SetIntConfigValue(string key, Action<int> setter)
{
if (EnvironmentVariableHelper.LoadNumeric(key, out var result))
{
setter(result);
}
}
}

View File

@ -0,0 +1,69 @@
// <copyright file="SdkConfiguration.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
namespace OpenTelemetry.Configuration;
internal class SdkConfiguration
{
private int? spanAttributeValueLengthLimit;
private int? spanAttributeCountLimit;
private int? eventAttributeCountLimit;
private int? linkAttributeCountLimit;
private SdkConfiguration()
{
EnvironmentVariableConfiguration.InitializeDefaultConfigurationFromEnvironment(this);
}
public static SdkConfiguration Instance { get; private set; } = new SdkConfiguration();
public int? AttributeValueLengthLimit { get; set; }
public int? AttributeCountLimit { get; set; }
public int? SpanAttributeValueLengthLimit
{
get => this.spanAttributeValueLengthLimit ?? this.AttributeValueLengthLimit;
set => this.spanAttributeValueLengthLimit = value;
}
public int? SpanAttributeCountLimit
{
get => this.spanAttributeCountLimit ?? this.AttributeCountLimit;
set => this.spanAttributeCountLimit = value;
}
public int? SpanEventCountLimit { get; set; }
public int? SpanLinkCountLimit { get; set; }
public int? EventAttributeCountLimit
{
get => this.eventAttributeCountLimit ?? this.SpanAttributeCountLimit;
set => this.eventAttributeCountLimit = value;
}
public int? LinkAttributeCountLimit
{
get => this.linkAttributeCountLimit ?? this.SpanAttributeCountLimit;
set => this.linkAttributeCountLimit = value;
}
internal static void Reset()
{
Instance = new SdkConfiguration();
}
}

View File

@ -24,6 +24,7 @@ using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using Google.Protobuf;
using Google.Protobuf.Collections;
using OpenTelemetry.Configuration;
using OpenTelemetry.Internal;
using OpenTelemetry.Trace;
using OtlpCollector = Opentelemetry.Proto.Collector.Trace.V1;
@ -154,7 +155,7 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation
};
TagEnumerationState otlpTags = default;
activity.EnumerateTags(ref otlpTags);
activity.EnumerateTags(ref otlpTags, SdkConfiguration.Instance.SpanAttributeCountLimit);
if (activity.Kind == ActivityKind.Client || activity.Kind == ActivityKind.Producer)
{
@ -181,7 +182,7 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation
otlpSpan.Status = activity.ToOtlpStatus(ref otlpTags);
EventEnumerationState otlpEvents = default;
activity.EnumerateEvents(ref otlpEvents);
activity.EnumerateEvents(ref otlpEvents, SdkConfiguration.Instance.SpanEventCountLimit);
if (otlpEvents.Created)
{
otlpSpan.Events.AddRange(otlpEvents.Events);
@ -189,13 +190,14 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation
}
LinkEnumerationState otlpLinks = default;
activity.EnumerateLinks(ref otlpLinks);
activity.EnumerateLinks(ref otlpLinks, SdkConfiguration.Instance.SpanLinkCountLimit);
if (otlpLinks.Created)
{
otlpSpan.Links.AddRange(otlpLinks.Links);
otlpLinks.Links.Return();
}
// TODO: The drop counts should be set when necessary.
// Activity does not limit number of attributes, events, links, etc so drop counts are always zero.
return otlpSpan;
@ -259,7 +261,7 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation
};
TagEnumerationState otlpTags = default;
activityLink.EnumerateTags(ref otlpTags);
activityLink.EnumerateTags(ref otlpTags, SdkConfiguration.Instance.LinkAttributeCountLimit);
if (otlpTags.Created)
{
otlpLink.Attributes.AddRange(otlpTags.Tags);
@ -279,7 +281,7 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation
};
TagEnumerationState otlpTags = default;
activityEvent.EnumerateTags(ref otlpTags);
activityEvent.EnumerateTags(ref otlpTags, SdkConfiguration.Instance.EventAttributeCountLimit);
if (otlpTags.Created)
{
otlpEvent.Attributes.AddRange(otlpTags.Tags);
@ -355,7 +357,7 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation
this.Created = true;
}
if (OtlpKeyValueTransformer.Instance.TryTransformTag(activityTag, out var attribute))
if (OtlpKeyValueTransformer.Instance.TryTransformTag(activityTag, out var attribute, SdkConfiguration.Instance.AttributeValueLengthLimit))
{
PooledList<OtlpCommon.KeyValue>.Add(ref this.Tags, attribute);

View File

@ -30,7 +30,7 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClie
return;
}
if (options.Endpoint.Scheme.Equals("http", StringComparison.InvariantCultureIgnoreCase))
if (options.Endpoint.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase))
{
if (AppContext.TryGetSwitch(
"System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", out var unencryptedIsSupported) == false

View File

@ -25,9 +25,6 @@ namespace OpenTelemetry.Metrics
/// </summary>
public static class OtlpMetricExporterExtensions
{
private const int DefaultExportIntervalMilliseconds = 60000;
private const int DefaultExportTimeoutMilliseconds = 30000;
/// <summary>
/// Adds <see cref="OtlpMetricExporter"/> to the <see cref="MeterProviderBuilder"/> using default options.
/// </summary>
@ -111,9 +108,7 @@ namespace OpenTelemetry.Metrics
var metricReader = PeriodicExportingMetricReaderHelper.CreatePeriodicExportingMetricReader(
metricExporter,
metricReaderOptions,
DefaultExportIntervalMilliseconds,
DefaultExportTimeoutMilliseconds);
metricReaderOptions);
return builder.AddReader(metricReader);
}

View File

@ -18,9 +18,9 @@ dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
## Configuration
You can configure the `OtlpExporter` through `OtlpExporterOptions`
properties and environment variables. The `OtlpExporterOptions`
setters take precedence over the environment variables.
You can configure the `OtlpExporter` through `Options` types properties
and environment variables.
The `Options` type setters take precedence over the environment variables.
## Options Properties
@ -63,6 +63,15 @@ values of the `OtlpExporterOptions`
| `OTEL_EXPORTER_OTLP_TIMEOUT` | `TimeoutMilliseconds` |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | `Protocol` (`grpc` or `http/protobuf`)|
The following environment variables can be used to override the default
values of the `PeriodicExportingMetricReaderOptions`
(following the [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/sdk-environment-variables.md#periodic-exporting-metricreader).
| Environment variable | `PeriodicExportingMetricReaderOptions` property |
| ------------------------------| ------------------------------------------------|
| `OTEL_METRIC_EXPORT_INTERVAL` | `ExportIntervalMilliseconds` |
| `OTEL_METRIC_EXPORT_TIMEOUT` | `ExportTimeoutMilliseconds` |
`FormatException` is thrown in case of an invalid value for any of the
supported environment variables.

View File

@ -1,27 +1,17 @@
Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions
Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions
OpenTelemetry.Exporter.PrometheusExporter
OpenTelemetry.Exporter.PrometheusExporter.Collect.get -> System.Func<int, bool>
OpenTelemetry.Exporter.PrometheusExporter.Collect.set -> void
OpenTelemetry.Exporter.PrometheusExporter.PrometheusExporter(OpenTelemetry.Exporter.PrometheusExporterOptions options) -> void
OpenTelemetry.Exporter.PrometheusExporterOptions
OpenTelemetry.Exporter.PrometheusExporterOptions.HttpListenerPrefixes.get -> System.Collections.Generic.IReadOnlyCollection<string>
OpenTelemetry.Exporter.PrometheusExporterOptions.HttpListenerPrefixes.set -> void
OpenTelemetry.Exporter.PrometheusExporterOptions.PrometheusExporterOptions() -> void
OpenTelemetry.Exporter.PrometheusExporterOptions.ScrapeEndpointPath.get -> string
OpenTelemetry.Exporter.PrometheusExporterOptions.ScrapeEndpointPath.set -> void
OpenTelemetry.Exporter.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.get -> int
OpenTelemetry.Exporter.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.set -> void
OpenTelemetry.Exporter.PrometheusExporterOptions.StartHttpListener.get -> bool
OpenTelemetry.Exporter.PrometheusExporterOptions.StartHttpListener.set -> void
OpenTelemetry.Exporter.Prometheus.PrometheusExporterOptions
OpenTelemetry.Exporter.Prometheus.PrometheusExporterOptions.PrometheusExporterOptions() -> void
OpenTelemetry.Exporter.Prometheus.PrometheusExporterOptions.ScrapeEndpointPath.get -> string
OpenTelemetry.Exporter.Prometheus.PrometheusExporterOptions.ScrapeEndpointPath.set -> void
OpenTelemetry.Exporter.Prometheus.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.get -> int
OpenTelemetry.Exporter.Prometheus.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.set -> void
OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions
override OpenTelemetry.Exporter.PrometheusExporter.Dispose(bool disposing) -> void
override OpenTelemetry.Exporter.PrometheusExporter.Export(in OpenTelemetry.Batch<OpenTelemetry.Metrics.Metric> metrics) -> OpenTelemetry.ExportResult
static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder app) -> Microsoft.AspNetCore.Builder.IApplicationBuilder
static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, OpenTelemetry.Metrics.MeterProvider meterProvider, System.Func<Microsoft.AspNetCore.Http.HttpContext, bool> predicate, string path, System.Action<Microsoft.AspNetCore.Builder.IApplicationBuilder> configureBranchedPipeline) -> Microsoft.AspNetCore.Builder.IApplicationBuilder
static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, string path) -> Microsoft.AspNetCore.Builder.IApplicationBuilder
static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, System.Func<Microsoft.AspNetCore.Http.HttpContext, bool> predicate) -> Microsoft.AspNetCore.Builder.IApplicationBuilder
static OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions.AddPrometheusExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action<OpenTelemetry.Exporter.PrometheusExporterOptions> configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder
static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder
static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string path) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder
static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string path = null, OpenTelemetry.Metrics.MeterProvider meterProvider = null, System.Action<Microsoft.AspNetCore.Builder.IApplicationBuilder> configureBranchedPipeline = null) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder
static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string path) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder
static OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions.AddPrometheusExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action<OpenTelemetry.Exporter.Prometheus.PrometheusExporterOptions> configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder

View File

@ -13,10 +13,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System.Runtime.CompilerServices;
#if SIGNED
[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.AspNet.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")]
[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")]
#else
[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.AspNet.Tests")]
[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests")]
#endif

View File

@ -2,6 +2,13 @@
## Unreleased
* Split up Prometheus projects based on its hosting mechanism,
HttpListener and AspNetCore, into their own projects
and assemblies.
([#3430](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3430)
[#3503](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3503)
[#3507](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3507))
* Added `IEndpointRouteBuilder` extension methods to help with Prometheus
middleware configuration on ASP.NET Core
([#3295](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3295))
@ -75,8 +82,8 @@ Released 2021-Sep-23
Released 2021-Sep-13
* Bug fixes
([#2289](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2289))
([#2309](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2309))
([#2289](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2289)
[#2309](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2309))
## 1.2.0-alpha2

View File

@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- OmniSharp/VS Code requires TargetFrameworks to be in descending order for IntelliSense and analysis. -->
<TargetFrameworks>net6.0</TargetFrameworks>
<Description>ASP.NET Core middleware for hosting OpenTelemetry .NET Prometheus Exporter</Description>
<PackageTags>$(PackageTags);prometheus;metrics</PackageTags>
<MinVerTagPrefix>core-</MinVerTagPrefix>
</PropertyGroup>
<!--Do not run ApiCompat as this package has never released a stable version.
Remove this property once we have released a stable version.-->
<PropertyGroup>
<RunApiCompat>false</RunApiCompat>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\ExceptionExtensions.cs" Link="Includes\ExceptionExtensions.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\Guard.cs" Link="Includes\Guard.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus.HttpListener\Internal\PrometheusCollectionManager.cs" Link="Includes/PrometheusCollectionManager.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus.HttpListener\Internal\PrometheusExporter.cs" Link="Includes/PrometheusExporter.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus.HttpListener\Internal\PrometheusExporterEventSource.cs" Link="Includes/PrometheusExporterEventSource.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus.HttpListener\Internal\PrometheusSerializer.cs" Link="Includes/PrometheusSerializer.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus.HttpListener\Internal\PrometheusSerializerExt.cs" Link="Includes/PrometheusSerializerExt.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry\OpenTelemetry.csproj" />
</ItemGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>

View File

@ -14,12 +14,9 @@
// limitations under the License.
// </copyright>
#if NETCOREAPP3_1_OR_GREATER
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry.Exporter;
using OpenTelemetry.Exporter.Prometheus;
using OpenTelemetry.Internal;
using OpenTelemetry.Metrics;
@ -93,8 +90,8 @@ namespace Microsoft.AspNetCore.Builder
/// <param name="app">The <see cref="IApplicationBuilder"/> to add
/// middleware to.</param>
/// <param name="meterProvider">Optional <see cref="MeterProvider"/>
/// containing a <see cref="PrometheusExporter"/> otherwise the primary
/// SDK provider will be resolved using application services.</param>
/// containing a Prometheus exporter otherwise the primary SDK provider
/// will be resolved using application services.</param>
/// <param name="predicate">Optional predicate for deciding if a given
/// <see cref="HttpContext"/> should be branched. If supplied <paramref
/// name="path"/> is ignored.</param>
@ -151,4 +148,3 @@ namespace Microsoft.AspNetCore.Builder
}
}
}
#endif

View File

@ -14,13 +14,10 @@
// limitations under the License.
// </copyright>
#if NETCOREAPP3_1_OR_GREATER
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry.Exporter;
using OpenTelemetry.Exporter.Prometheus;
using OpenTelemetry.Internal;
using OpenTelemetry.Metrics;
@ -70,8 +67,8 @@ namespace Microsoft.AspNetCore.Builder
/// If not provided then <see cref="PrometheusExporterOptions.ScrapeEndpointPath"/>
/// is used.</param>
/// <param name="meterProvider">Optional <see cref="MeterProvider"/>
/// containing a <see cref="PrometheusExporter"/> otherwise the primary
/// SDK provider will be resolved using application services.</param>
/// containing a Prometheus exporter otherwise the primary SDK provider
/// will be resolved using application services.</param>
/// <param name="configureBranchedPipeline">Optional callback to
/// configure the branched pipeline. Called before registration of the
/// Prometheus middleware.</param>
@ -109,4 +106,3 @@ namespace Microsoft.AspNetCore.Builder
}
}
}
#endif

View File

@ -15,11 +15,14 @@
// </copyright>
using System;
using OpenTelemetry.Exporter;
using OpenTelemetry.Exporter.Prometheus;
using OpenTelemetry.Internal;
namespace OpenTelemetry.Metrics
{
/// <summary>
/// Extension methods to simplify registering a PrometheusExporter.
/// </summary>
public static class PrometheusExporterMeterProviderBuilderExtensions
{
/// <summary>
@ -47,9 +50,11 @@ namespace OpenTelemetry.Metrics
{
configure?.Invoke(options);
var exporter = new PrometheusExporter(options);
var reader = new BaseExportingMetricReader(exporter);
reader.TemporalityPreference = MetricReaderTemporalityPreference.Cumulative;
var exporter = new PrometheusExporter(scrapeEndpointPath: options.ScrapeEndpointPath, scrapeResponseCacheDurationMilliseconds: options.ScrapeResponseCacheDurationMilliseconds);
var reader = new BaseExportingMetricReader(exporter)
{
TemporalityPreference = MetricReaderTemporalityPreference.Cumulative,
};
return builder.AddReader(reader);
}

View File

@ -14,7 +14,6 @@
// limitations under the License.
// </copyright>
#if NETCOREAPP3_1_OR_GREATER
using System;
using System.Diagnostics;
using System.Threading.Tasks;
@ -102,4 +101,3 @@ namespace OpenTelemetry.Exporter.Prometheus
}
}
}
#endif

View File

@ -0,0 +1,52 @@
// <copyright file="PrometheusExporterOptions.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using OpenTelemetry.Internal;
namespace OpenTelemetry.Exporter.Prometheus
{
/// <summary>
/// Prometheus exporter options.
/// </summary>
public class PrometheusExporterOptions
{
internal const string DefaultScrapeEndpointPath = "/metrics";
private int scrapeResponseCacheDurationMilliseconds = 300;
/// <summary>
/// Gets or sets the path to use for the scraping endpoint. Default value: "/metrics".
/// </summary>
public string ScrapeEndpointPath { get; set; } = DefaultScrapeEndpointPath;
/// <summary>
/// Gets or sets the cache duration in milliseconds for scrape responses. Default value: 300.
/// </summary>
/// <remarks>
/// Note: Specify 0 to disable response caching.
/// </remarks>
public int ScrapeResponseCacheDurationMilliseconds
{
get => this.scrapeResponseCacheDurationMilliseconds;
set
{
Guard.ThrowIfOutOfRange(value, min: 0);
this.scrapeResponseCacheDurationMilliseconds = value;
}
}
}
}

View File

@ -1,23 +1,29 @@
# Prometheus Exporter for OpenTelemetry .NET
# Prometheus Exporter AspNetCore for OpenTelemetry .NET
[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Prometheus.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Prometheus)
[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Prometheus.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Prometheus)
[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Prometheus.AspNetCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Prometheus.AspNetCore)
[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Prometheus.AspNetCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Prometheus.AspNetCore)
An [OpenTelemetry Prometheus exporter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk_exporters/prometheus.md)
for configuring an ASP.NET Core application with an endpoint for Prometheus
to scrape.
## Prerequisite
* [Get Prometheus](https://prometheus.io/docs/introduction/first_steps/)
## Steps to enable OpenTelemetry.Exporter.Prometheus
## Steps to enable OpenTelemetry.Exporter.Prometheus.AspNetCore
### Step 1: Install Package
```shell
dotnet add package OpenTelemetry.Exporter.Prometheus
dotnet add package OpenTelemetry.Exporter.Prometheus.AspNetCore
```
### Step 2: Configure OpenTelemetry MeterProvider
* When using OpenTelemetry.Extensions.Hosting package on .NET Core 3.1+:
* When using
[OpenTelemetry.Extensions.Hosting](../OpenTelemetry.Extensions.Hosting/README.md)
package on .NET Core 3.1+:
```csharp
services.AddOpenTelemetryMetrics(builder =>
@ -28,18 +34,19 @@ dotnet add package OpenTelemetry.Exporter.Prometheus
* Or configure directly:
Call the `AddPrometheusExporter` `MeterProviderBuilder` extension to
Call the `MeterProviderBuilder.AddPrometheusExporter` extension to
register the Prometheus exporter.
```csharp
using var meterProvider = Sdk.CreateMeterProviderBuilder()
var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddPrometheusExporter()
.Build();
builder.Services.AddSingleton(meterProvider);
```
### Step 3: Configure Prometheus Scraping Endpoint
* On .NET Core 3.1+ register Prometheus scraping middleware using the
* Register Prometheus scraping middleware using the
`UseOpenTelemetryPrometheusScrapingEndpoint` extension:
```csharp
@ -72,54 +79,22 @@ dotnet add package OpenTelemetry.Exporter.Prometheus
}
```
* On .NET Framework an HTTP listener is automatically started which will respond
to scraping requests. See the [Configuration](#configuration) section for
details on the settings available. This may also be turned on in .NET Core (it
is OFF by default) when the ASP.NET Core pipeline is not available for
middleware registration.
## Configuration
The `PrometheusExporter` can be configured using the `PrometheusExporterOptions`
properties. Refer to
[`TestPrometheusExporter.cs`](../../examples/Console/TestPrometheusExporter.cs)
for example use.
### StartHttpListener
Set to `true` to start an HTTP listener which will respond to Prometheus scrape
requests using the [HttpListenerPrefixes](#httplistenerprefixes) and
[ScrapeEndpointPath](#scrapeendpointpath) options.
Defaults:
* On .NET Framework this is `true` by default.
* On .NET Core 3.1+ this is `false` by default. Users running ASP.NET Core
should use the `UseOpenTelemetryPrometheusScrapingEndpoint` extension to
register the scraping middleware instead of using the listener.
### HttpListenerPrefixes
Defines the prefixes which will be used by the listener when `StartHttpListener`
is `true`. The default value is `["http://localhost:9464/"]`. You may specify
multiple endpoints.
For details see:
[HttpListenerPrefixCollection.Add(String)](https://docs.microsoft.com/dotnet/api/system.net.httplistenerprefixcollection.add)
properties.
### ScrapeEndpointPath
Defines the path for the Prometheus scrape endpoint for
either the HTTP listener or the middleware registered by
Defines the path for the Prometheus scrape endpoint for the middleware
registered by
`UseOpenTelemetryPrometheusScrapingEndpoint`. Default value: `"/metrics"`.
### ScrapeResponseCacheDurationMilliseconds
Configures scrape endpoint response caching. Multiple scrape requests within the
cache duration time period will receive the same previously generated response.
The default value is `10000` (10 seconds). Set to `0` to disable response
caching.
The default value is `300`. Set to `0` to disable response caching.
## Troubleshooting

View File

@ -0,0 +1,8 @@
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.UriPrefixes.get -> System.Collections.Generic.IReadOnlyCollection<string>
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.UriPrefixes.set -> void
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.PrometheusHttpListenerOptions() -> void
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.ScrapeEndpointPath.get -> string
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.ScrapeEndpointPath.set -> void
OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions
static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action<OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions> configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder

View File

@ -0,0 +1,8 @@
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.UriPrefixes.get -> System.Collections.Generic.IReadOnlyCollection<string>
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.UriPrefixes.set -> void
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.PrometheusHttpListenerOptions() -> void
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.ScrapeEndpointPath.get -> string
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.ScrapeEndpointPath.set -> void
OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions
static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action<OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions> configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder

View File

@ -17,9 +17,9 @@
using System.Runtime.CompilerServices;
#if SIGNED
[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.HttpListener.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")]
[assembly: InternalsVisibleTo("Benchmarks, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")]
[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")]
#else
[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.HttpListener.Tests")]
[assembly: InternalsVisibleTo("Benchmarks")]
[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.Tests")]
#endif

View File

@ -0,0 +1,99 @@
# Changelog
## Unreleased
* Split up Prometheus projects based on its hosting mechanism,
HttpListener and AspNetCore, into their own projects
and assemblies.
([#3430](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3430)
[#3503](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3503)
[#3507](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3507))
* Fixed bug
[#2840](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2840) by
allowing `+` and `*` to be used in the URI prefixes (e.g. `"http://*:9184"`).
([#3521](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3521))
## 1.3.0-rc.2
Released 2022-June-1
## 1.3.0-beta.2
Released 2022-May-16
## 1.3.0-beta.1
Released 2022-Apr-15
* Added `IApplicationBuilder` extension methods to help with Prometheus
middleware configuration on ASP.NET Core
([#3029](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3029))
* Changed Prometheus exporter to return 204 No Content and log a warning event
if there are no metrics to collect.
* Removes .NET Framework 4.6.1. The minimum .NET Framework
version supported is .NET 4.6.2. ([#3190](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3190))
## 1.2.0-rc5
Released 2022-Apr-12
## 1.2.0-rc4
Released 2022-Mar-30
## 1.2.0-rc3
Released 2022-Mar-04
## 1.2.0-rc2
Released 2022-Feb-02
* Update default `httpListenerPrefixes` for PrometheusExporter to be `http://localhost:9464/`.
([#2783](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2783))
## 1.2.0-rc1
Released 2021-Nov-29
* Bug fix for handling Histogram with empty buckets.
([#2651](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2651))
## 1.2.0-beta2
Released 2021-Nov-19
* Added scrape endpoint response caching feature &
`ScrapeResponseCacheDurationMilliseconds` option
([#2610](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2610))
## 1.2.0-beta1
Released 2021-Oct-08
## 1.2.0-alpha4
Released 2021-Sep-23
## 1.2.0-alpha3
Released 2021-Sep-13
* Bug fixes
([#2289](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2289)
[#2309](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2309))
## 1.2.0-alpha2
Released 2021-Aug-24
* Revamped to support the new Metrics API/SDK.
Supports Counter, Gauge and Histogram.
## 1.0.0-rc1.1
Released 2020-Nov-17
* Initial release

View File

@ -25,7 +25,7 @@ namespace OpenTelemetry.Exporter.Prometheus
internal sealed class PrometheusCollectionManager
{
private readonly PrometheusExporter exporter;
private readonly int scrapeResponseCacheDurationInMilliseconds;
private readonly int scrapeResponseCacheDurationMilliseconds;
private readonly Func<Batch<Metric>, ExportResult> onCollectRef;
private byte[] buffer = new byte[85000]; // encourage the object to live in LOH (large object heap)
private int globalLockState;
@ -38,7 +38,7 @@ namespace OpenTelemetry.Exporter.Prometheus
public PrometheusCollectionManager(PrometheusExporter exporter)
{
this.exporter = exporter;
this.scrapeResponseCacheDurationInMilliseconds = this.exporter.Options.ScrapeResponseCacheDurationMilliseconds;
this.scrapeResponseCacheDurationMilliseconds = this.exporter.ScrapeResponseCacheDurationMilliseconds;
this.onCollectRef = this.OnCollect;
}
@ -53,8 +53,8 @@ namespace OpenTelemetry.Exporter.Prometheus
// If we are within {ScrapeResponseCacheDurationMilliseconds} of the
// last successful collect, return the previous view.
if (this.previousDataViewGeneratedAtUtc.HasValue
&& this.scrapeResponseCacheDurationInMilliseconds > 0
&& this.previousDataViewGeneratedAtUtc.Value.AddMilliseconds(this.scrapeResponseCacheDurationInMilliseconds) >= DateTime.UtcNow)
&& this.scrapeResponseCacheDurationMilliseconds > 0
&& this.previousDataViewGeneratedAtUtc.Value.AddMilliseconds(this.scrapeResponseCacheDurationMilliseconds) >= DateTime.UtcNow)
{
Interlocked.Increment(ref this.readerCount);
this.ExitGlobalLock();
@ -91,7 +91,7 @@ namespace OpenTelemetry.Exporter.Prometheus
this.ExitGlobalLock();
CollectionResponse response;
bool result = this.ExecuteCollect();
var result = this.ExecuteCollect();
if (result)
{
this.previousDataViewGeneratedAtUtc = DateTime.UtcNow;
@ -169,14 +169,14 @@ namespace OpenTelemetry.Exporter.Prometheus
private bool ExecuteCollect()
{
this.exporter.OnExport = this.onCollectRef;
bool result = this.exporter.Collect(Timeout.Infinite);
var result = this.exporter.Collect(Timeout.Infinite);
this.exporter.OnExport = null;
return result;
}
private ExportResult OnCollect(Batch<Metric> metrics)
{
int cursor = 0;
var cursor = 0;
try
{
@ -191,7 +191,7 @@ namespace OpenTelemetry.Exporter.Prometheus
}
catch (IndexOutOfRangeException)
{
int bufferSize = this.buffer.Length * 2;
var bufferSize = this.buffer.Length * 2;
// there are two cases we might run into the following condition:
// 1. we have many metrics to be exported - in this case we probably want

View File

@ -15,48 +15,40 @@
// </copyright>
using System;
using OpenTelemetry.Exporter.Prometheus;
using OpenTelemetry.Internal;
using OpenTelemetry.Metrics;
namespace OpenTelemetry.Exporter
namespace OpenTelemetry.Exporter.Prometheus
{
/// <summary>
/// Exporter of OpenTelemetry metrics to Prometheus.
/// </summary>
[ExportModes(ExportModes.Pull)]
public class PrometheusExporter : BaseExporter<Metric>, IPullMetricExporter
internal sealed class PrometheusExporter : BaseExporter<Metric>, IPullMetricExporter
{
internal const string HttpListenerStartFailureExceptionMessage = "PrometheusExporter http listener could not be started.";
internal readonly PrometheusExporterOptions Options;
private readonly PrometheusExporterHttpServer metricsHttpServer;
private Func<int, bool> funcCollect;
private Func<Batch<Metric>, ExportResult> funcExport;
private bool disposed;
private bool disposed = false;
/// <summary>
/// Initializes a new instance of the <see cref="PrometheusExporter"/> class.
/// </summary>
/// <param name="options">Options for the exporter.</param>
public PrometheusExporter(PrometheusExporterOptions options)
/// <param name="scrapeEndpointPath">Scraping endpoint.</param>
/// <param name="scrapeResponseCacheDurationMilliseconds">
/// The cache duration in milliseconds for scrape responses. Default value: 0.
/// </param>
public PrometheusExporter(string scrapeEndpointPath = null, int scrapeResponseCacheDurationMilliseconds = 0)
{
this.Options = options;
if (options.StartHttpListener)
{
try
{
this.metricsHttpServer = new PrometheusExporterHttpServer(this);
this.metricsHttpServer.Start();
}
catch (Exception ex)
{
throw new InvalidOperationException(HttpListenerStartFailureExceptionMessage, ex);
}
}
Guard.ThrowIfOutOfRange(scrapeResponseCacheDurationMilliseconds, min: 0);
this.ScrapeEndpointPath = scrapeEndpointPath ?? "/metrics";
this.ScrapeResponseCacheDurationMilliseconds = scrapeResponseCacheDurationMilliseconds;
this.CollectionManager = new PrometheusCollectionManager(this);
}
/// <summary>
/// Gets or sets the Collect delegate.
/// </summary>
public Func<int, bool> Collect
{
get => this.funcCollect;
@ -69,20 +61,28 @@ namespace OpenTelemetry.Exporter
set => this.funcExport = value;
}
internal Action OnDispose { get; set; }
internal PrometheusCollectionManager CollectionManager { get; }
internal int ScrapeResponseCacheDurationMilliseconds { get; }
internal string ScrapeEndpointPath { get; }
/// <inheritdoc/>
public override ExportResult Export(in Batch<Metric> metrics)
{
return this.OnExport(metrics);
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
this.metricsHttpServer?.Dispose();
this.OnDispose?.Invoke();
}
this.disposed = true;

View File

@ -20,6 +20,7 @@ using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices;
using OpenTelemetry.Internal;
namespace OpenTelemetry.Exporter.Prometheus
{
@ -39,11 +40,7 @@ namespace OpenTelemetry.Exporter.Prometheus
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int WriteDouble(byte[] buffer, int cursor, double value)
{
#if NETCOREAPP3_1_OR_GREATER
if (double.IsFinite(value))
#else
if (!double.IsInfinity(value) && !double.IsNaN(value))
#endif
if (MathHelper.IsFinite(value))
{
#if NETCOREAPP3_1_OR_GREATER
Span<char> span = stackalloc char[128];

Some files were not shown because too many files have changed in this diff Show More