Add Logs support for ASP.NET Core apps (#1133)
* Add OpenTelemetry Logs * Remove commented code * Rename OpenTelemetry.AutoInstrumentation.StartupBootstrapper to OpenTelemetry.AutoInstrumentation.AspNetCoreBootstrapper. * PR feedback * PR feedback
This commit is contained in:
parent
879cb17326
commit
aa32666cb5
|
@ -135,6 +135,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApplication.StackExchan
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApplication.GrpcNetClient", "test\test-applications\integrations\TestApplication.GrpcNetClient\TestApplication.GrpcNetClient.csproj", "{0605872C-AB2B-4167-9B00-A525090D10BE}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.AutoInstrumentation.AspNetCoreBootstrapper", "src\OpenTelemetry.AutoInstrumentation.AspNetCoreBootstrapper\OpenTelemetry.AutoInstrumentation.AspNetCoreBootstrapper.csproj", "{C1AEDAE0-6629-4C88-AB35-AB5B81FD50F6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -571,6 +573,18 @@ Global
|
|||
{0605872C-AB2B-4167-9B00-A525090D10BE}.Release|x64.Build.0 = Release|x64
|
||||
{0605872C-AB2B-4167-9B00-A525090D10BE}.Release|x86.ActiveCfg = Release|x86
|
||||
{0605872C-AB2B-4167-9B00-A525090D10BE}.Release|x86.Build.0 = Release|x86
|
||||
{C1AEDAE0-6629-4C88-AB35-AB5B81FD50F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C1AEDAE0-6629-4C88-AB35-AB5B81FD50F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C1AEDAE0-6629-4C88-AB35-AB5B81FD50F6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C1AEDAE0-6629-4C88-AB35-AB5B81FD50F6}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C1AEDAE0-6629-4C88-AB35-AB5B81FD50F6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C1AEDAE0-6629-4C88-AB35-AB5B81FD50F6}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C1AEDAE0-6629-4C88-AB35-AB5B81FD50F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C1AEDAE0-6629-4C88-AB35-AB5B81FD50F6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C1AEDAE0-6629-4C88-AB35-AB5B81FD50F6}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C1AEDAE0-6629-4C88-AB35-AB5B81FD50F6}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C1AEDAE0-6629-4C88-AB35-AB5B81FD50F6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C1AEDAE0-6629-4C88-AB35-AB5B81FD50F6}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -617,6 +631,7 @@ Global
|
|||
{E7C2D2CF-C965-449D-A02C-02F7837D0C6D} = {E409ADD3-9574-465C-AB09-4324D205CC7C}
|
||||
{671EB8F0-E164-4E9F-B423-27AF4B59D360} = {E409ADD3-9574-465C-AB09-4324D205CC7C}
|
||||
{0605872C-AB2B-4167-9B00-A525090D10BE} = {E409ADD3-9574-465C-AB09-4324D205CC7C}
|
||||
{C1AEDAE0-6629-4C88-AB35-AB5B81FD50F6} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {160A1D00-1F5B-40F8-A155-621B4459D78F}
|
||||
|
|
|
@ -205,6 +205,15 @@ partial class Build
|
|||
.EnableNoRestore()
|
||||
.SetFramework(TargetFramework.NETCOREAPP3_1)
|
||||
.SetOutput(TracerHomeDirectory / TargetFramework.NETCOREAPP3_1));
|
||||
|
||||
DotNetPublish(s => s
|
||||
.SetProject(Solution.GetProject(Projects.AutoInstrumentationAspNetCoreBootstrapper))
|
||||
.SetConfiguration(BuildConfiguration)
|
||||
.SetTargetPlatformAnyCPU()
|
||||
.EnableNoBuild()
|
||||
.EnableNoRestore()
|
||||
.SetFramework(TargetFramework.NETCOREAPP3_1)
|
||||
.SetOutput(TracerHomeDirectory / TargetFramework.NETCOREAPP3_1));
|
||||
});
|
||||
|
||||
Target PublishNativeProfiler => _ => _
|
||||
|
|
|
@ -5,6 +5,7 @@ public static class Projects
|
|||
public const string AutoInstrumentationNative = "OpenTelemetry.AutoInstrumentation.Native";
|
||||
public const string AutoInstrumentationStartupHook = "OpenTelemetry.AutoInstrumentation.StartupHook";
|
||||
public const string AutoInstrumentationAdditionalDeps = "OpenTelemetry.AutoInstrumentation.AdditionalDeps";
|
||||
public const string AutoInstrumentationAspNetCoreBootstrapper = "OpenTelemetry.AutoInstrumentation.AspNetCoreBootstrapper";
|
||||
|
||||
public static class Tests
|
||||
{
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
"OTEL_DOTNET_AUTO_TRACES_CONSOLE_EXPORTER_ENABLED": "true",
|
||||
"OTEL_DOTNET_AUTO_TRACES_PLUGINS": "Examples.AspNetCoreMvc.OtelSdkPlugin, Examples.AspNetCoreMvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"OTEL_SERVICE_NAME": "StartupHook.IISExpress",
|
||||
"OTEL_TRACES_EXPORTER": "otlp"
|
||||
"OTEL_TRACES_EXPORTER": "otlp",
|
||||
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "OpenTelemetry.AutoInstrumentation.AspNetCoreBootstrapper",
|
||||
"OTEL_DOTNET_AUTO_LOGS_CONSOLE_EXPORTER_ENABLED": "true",
|
||||
"OTEL_DOTNET_AUTO_LOGS_PARSE_STATE_VALUES": "true",
|
||||
"OTEL_DOTNET_AUTO_LOGS_INCLUDE_FORMATTED_MESSAGE": "true"
|
||||
},
|
||||
"use64Bit": true,
|
||||
"nativeDebugging": true
|
||||
|
@ -55,7 +59,12 @@
|
|||
"OTEL_DOTNET_AUTO_TRACES_CONSOLE_EXPORTER_ENABLED": "true",
|
||||
"OTEL_DOTNET_AUTO_TRACES_PLUGINS": "Examples.AspNetCoreMvc.OtelSdkPlugin, Examples.AspNetCoreMvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"OTEL_SERVICE_NAME": "StartupHook.Self-hosted",
|
||||
"OTEL_TRACES_EXPORTER": "otlp"
|
||||
"OTEL_TRACES_EXPORTER": "otlp",
|
||||
"OTEL_DOTNET_AUTO_HOME": "$(SolutionDir)bin\\tracer-home",
|
||||
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "OpenTelemetry.AutoInstrumentation.AspNetCoreBootstrapper",
|
||||
"OTEL_DOTNET_AUTO_LOGS_CONSOLE_EXPORTER_ENABLED": "true",
|
||||
"OTEL_DOTNET_AUTO_LOGS_PARSE_STATE_VALUES": "true",
|
||||
"OTEL_DOTNET_AUTO_LOGS_INCLUDE_FORMATTED_MESSAGE": "true"
|
||||
},
|
||||
"use64Bit": true,
|
||||
"nativeDebugging": true,
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
// <copyright file="BootstrapperHostingStartup.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 Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OpenTelemetry.AutoInstrumentation.Configuration;
|
||||
using OpenTelemetry.Logs;
|
||||
|
||||
[assembly: HostingStartup(typeof(OpenTelemetry.AutoInstrumentation.AspNetCoreBootstrapper.BootstrapperHostingStartup))]
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.AspNetCoreBootstrapper;
|
||||
|
||||
/// <summary>
|
||||
/// Add summary.
|
||||
/// </summary>
|
||||
public class BootstrapperHostingStartup : IHostingStartup
|
||||
{
|
||||
private readonly LogSettings settings;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BootstrapperHostingStartup"/> class.
|
||||
/// </summary>
|
||||
public BootstrapperHostingStartup()
|
||||
{
|
||||
settings = LogSettings.FromDefaultSources();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method gets called by the runtime to lightup ASP.NET Core OpenTelemetry Logs Collection.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IWebHostBuilder"/>.</param>
|
||||
public void Configure(IWebHostBuilder builder)
|
||||
{
|
||||
builder.ConfigureLogging(logging => logging.AddOpenTelemetry(options =>
|
||||
{
|
||||
if (settings.ConsoleExporterEnabled)
|
||||
{
|
||||
options.AddConsoleExporter();
|
||||
}
|
||||
|
||||
switch (settings.LogExporter)
|
||||
{
|
||||
case LogExporter.Otlp:
|
||||
#if NETCOREAPP3_1
|
||||
if (settings.Http2UnencryptedSupportEnabled)
|
||||
{
|
||||
// Adding the OtlpExporter creates a GrpcChannel.
|
||||
// This switch must be set before creating a GrpcChannel/HttpClient when calling an insecure gRPC service.
|
||||
// See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client
|
||||
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
|
||||
}
|
||||
#endif
|
||||
options.AddOtlpExporter(options =>
|
||||
{
|
||||
if (settings.OtlpExportProtocol.HasValue)
|
||||
{
|
||||
options.Protocol = settings.OtlpExportProtocol.Value;
|
||||
}
|
||||
});
|
||||
break;
|
||||
case LogExporter.None:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException($"Traces exporter '{settings.LogExporter}' is incorrect");
|
||||
}
|
||||
|
||||
options.ParseStateValues = settings.ParseStateValues;
|
||||
options.IncludeFormattedMessage = settings.IncludeFormattedMessage;
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp3.1</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.3.0" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs" Version="1.3.0-rc.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OpenTelemetry.AutoInstrumentation\OpenTelemetry.AutoInstrumentation.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.Metrics;
|
||||
using OpenTelemetry.Logs;
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.Configuration;
|
||||
|
||||
|
@ -51,7 +52,7 @@ public class ConfigurationKeys
|
|||
public const string FlushOnUnhandledException = "OTEL_DOTNET_AUTO_FLUSH_ON_UNHANDLEDEXCEPTION";
|
||||
|
||||
/// <summary>
|
||||
/// Configuration keys for trace exporter
|
||||
/// Configuration keys for traces.
|
||||
/// </summary>
|
||||
public static class Traces
|
||||
{
|
||||
|
@ -98,7 +99,7 @@ public class ConfigurationKeys
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configuration keys for metrics exporter
|
||||
/// Configuration keys for metrics.
|
||||
/// </summary>
|
||||
public static class Metrics
|
||||
{
|
||||
|
@ -144,6 +145,40 @@ public class ConfigurationKeys
|
|||
public const string AdditionalSources = "OTEL_DOTNET_AUTO_METRICS_ADDITIONAL_SOURCES";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configuration keys for logs.
|
||||
/// </summary>
|
||||
public static class Logs
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration key for the logs exporter to be used.
|
||||
/// Default is <c>"otlp"</c>.
|
||||
/// </summary>
|
||||
public const string Exporter = "OTEL_LOGS_EXPORTER";
|
||||
|
||||
/// <summary>
|
||||
/// Configuration key for whether the logs console exporter is enabled.
|
||||
/// </summary>
|
||||
public const string ConsoleExporterEnabled = "OTEL_DOTNET_AUTO_LOGS_CONSOLE_EXPORTER_ENABLED";
|
||||
|
||||
/// <summary>
|
||||
/// Configuration key for whether or not log state should be parsed into
|
||||
/// <see cref="LogRecord.StateValues"/> on generated <see cref="LogRecord"/>s.
|
||||
/// </summary>
|
||||
public const string ParseStateValues = "OTEL_DOTNET_AUTO_LOGS_PARSE_STATE_VALUES";
|
||||
|
||||
/// <summary>
|
||||
/// Configuration key for whether or not formatted log message
|
||||
/// should be included on generated <see cref="LogRecord"/>s.
|
||||
/// </summary>
|
||||
public const string IncludeFormattedMessage = "OTEL_DOTNET_AUTO_LOGS_INCLUDE_FORMATTED_MESSAGE";
|
||||
|
||||
/// <summary>
|
||||
/// Configuration key for colon (:) separated list of logs plugins represented by <see cref="System.Type.AssemblyQualifiedName"/>.
|
||||
/// </summary>
|
||||
public const string ProviderPlugins = "OTEL_DOTNET_AUTO_LOGS_PLUGINS";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configuration keys for Sdk
|
||||
/// </summary>
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// <copyright file="LogExporter.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.AutoInstrumentation.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Enum representing supported log exporters.
|
||||
/// </summary>
|
||||
public enum LogExporter
|
||||
{
|
||||
/// <summary>
|
||||
/// None exporter.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// OTLP exporter.
|
||||
/// </summary>
|
||||
Otlp,
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
// <copyright file="LogSettings.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;
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Log Settings
|
||||
/// </summary>
|
||||
public class LogSettings : Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LogSettings"/> class
|
||||
/// using the specified <see cref="IConfigurationSource"/> to initialize values.
|
||||
/// </summary>
|
||||
/// <param name="source">The <see cref="IConfigurationSource"/> to use when retrieving configuration values.</param>
|
||||
private LogSettings(IConfigurationSource source)
|
||||
: base(source)
|
||||
{
|
||||
LogExporter = ParseLogExporter(source);
|
||||
ConsoleExporterEnabled = source.GetBool(ConfigurationKeys.Logs.ConsoleExporterEnabled) ?? false;
|
||||
ParseStateValues = source.GetBool(ConfigurationKeys.Logs.ParseStateValues) ?? false;
|
||||
IncludeFormattedMessage = source.GetBool(ConfigurationKeys.Logs.IncludeFormattedMessage) ?? false;
|
||||
|
||||
var providerPlugins = source.GetString(ConfigurationKeys.Logs.ProviderPlugins);
|
||||
if (providerPlugins != null)
|
||||
{
|
||||
foreach (var pluginAssemblyQualifiedName in providerPlugins.Split(Constants.ConfigurationValues.DotNetQualifiedNameSeparator))
|
||||
{
|
||||
LogPlugins.Add(pluginAssemblyQualifiedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the logs exporter.
|
||||
/// </summary>
|
||||
public LogExporter LogExporter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the ParseStateValues is enabled.
|
||||
/// </summary>
|
||||
public bool ParseStateValues { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the IncludeFormattedMessage is enabled.
|
||||
/// </summary>
|
||||
public bool IncludeFormattedMessage { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the console exporter is enabled.
|
||||
/// </summary>
|
||||
public bool ConsoleExporterEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of plugins represented by <see cref="Type.AssemblyQualifiedName"/>.
|
||||
/// </summary>
|
||||
public IList<string> LogPlugins { get; } = new List<string>();
|
||||
|
||||
internal static LogSettings FromDefaultSources()
|
||||
{
|
||||
var configurationSource = new CompositeConfigurationSource
|
||||
{
|
||||
new EnvironmentConfigurationSource(),
|
||||
|
||||
#if NETFRAMEWORK
|
||||
// on .NET Framework only, also read from app.config/web.config
|
||||
new NameValueConfigurationSource(System.Configuration.ConfigurationManager.AppSettings)
|
||||
#endif
|
||||
};
|
||||
|
||||
return new LogSettings(configurationSource);
|
||||
}
|
||||
|
||||
private static LogExporter ParseLogExporter(IConfigurationSource source)
|
||||
{
|
||||
var logExporterEnvVar = source.GetString(ConfigurationKeys.Logs.Exporter)
|
||||
?? Constants.ConfigurationValues.Exporters.Otlp;
|
||||
|
||||
switch (logExporterEnvVar)
|
||||
{
|
||||
case null:
|
||||
case "":
|
||||
case Constants.ConfigurationValues.Exporters.Otlp:
|
||||
return LogExporter.Otlp;
|
||||
case Constants.ConfigurationValues.None:
|
||||
return LogExporter.None;
|
||||
default:
|
||||
throw new FormatException($"Log exporter '{logExporterEnvVar}' is not supported");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,5 +16,6 @@
|
|||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("OpenTelemetry.AutoInstrumentation.AspNetCoreBootstrapper")]
|
||||
[assembly: InternalsVisibleTo("OpenTelemetry.AutoInstrumentation.Tests")]
|
||||
[assembly: InternalsVisibleTo("IntegrationTests")]
|
||||
|
|
Loading…
Reference in New Issue