From e4b08ac152fe12e88a124f099c6d7853e4c505fc Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 15 Feb 2024 12:48:15 -0800 Subject: [PATCH] [docs-logging] Add a logging doc for showing how to set up a dedicated pipeline for specific logs (#5356) --- OpenTelemetry.sln | 7 ++ ...catedLoggingServiceCollectionExtensions.cs | 73 +++++++++++++++++++ .../DedicatedLogging/IDedicatedLogger.cs | 12 +++ docs/logs/dedicated-pipeline/Program.cs | 47 ++++++++++++ docs/logs/dedicated-pipeline/README.md | 4 + .../appsettings.Development.json | 9 +++ docs/logs/dedicated-pipeline/appsettings.json | 14 ++++ .../dedicated-pipeline.csproj | 6 ++ 8 files changed, 172 insertions(+) create mode 100644 docs/logs/dedicated-pipeline/DedicatedLogging/DedicatedLoggingServiceCollectionExtensions.cs create mode 100644 docs/logs/dedicated-pipeline/DedicatedLogging/IDedicatedLogger.cs create mode 100644 docs/logs/dedicated-pipeline/Program.cs create mode 100644 docs/logs/dedicated-pipeline/README.md create mode 100644 docs/logs/dedicated-pipeline/appsettings.Development.json create mode 100644 docs/logs/dedicated-pipeline/appsettings.json create mode 100644 docs/logs/dedicated-pipeline/dedicated-pipeline.csproj diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index 0b9de051d0d..b3a52180514 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -340,6 +340,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "resources", "resources", "{ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "extending-the-sdk", "docs\resources\extending-the-sdk\extending-the-sdk.csproj", "{7BE494FC-4B0D-4340-A62A-9C9F3E7389FE}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dedicated-pipeline", "docs\logs\dedicated-pipeline\dedicated-pipeline.csproj", "{19545B37-8518-4BDD-AD49-00C031FB3C2A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -626,6 +628,10 @@ Global {7BE494FC-4B0D-4340-A62A-9C9F3E7389FE}.Debug|Any CPU.Build.0 = Debug|Any CPU {7BE494FC-4B0D-4340-A62A-9C9F3E7389FE}.Release|Any CPU.ActiveCfg = Release|Any CPU {7BE494FC-4B0D-4340-A62A-9C9F3E7389FE}.Release|Any CPU.Build.0 = Release|Any CPU + {19545B37-8518-4BDD-AD49-00C031FB3C2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19545B37-8518-4BDD-AD49-00C031FB3C2A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19545B37-8518-4BDD-AD49-00C031FB3C2A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19545B37-8518-4BDD-AD49-00C031FB3C2A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -680,6 +686,7 @@ Global {17A22B0E-6EC3-4A39-B955-0A486AD06699} = {52AF6D7D-9E66-4234-9A2C-5D16C6F22B40} {A115CE4C-71A8-4B95-96A5-C1DF46FD94C2} = {7C87CAF9-79D7-4C26-9FFB-F3F1FB6911F1} {7BE494FC-4B0D-4340-A62A-9C9F3E7389FE} = {A115CE4C-71A8-4B95-96A5-C1DF46FD94C2} + {19545B37-8518-4BDD-AD49-00C031FB3C2A} = {3862190B-E2C5-418E-AFDC-DB281FB5C705} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {55639B5C-0770-4A22-AB56-859604650521} diff --git a/docs/logs/dedicated-pipeline/DedicatedLogging/DedicatedLoggingServiceCollectionExtensions.cs b/docs/logs/dedicated-pipeline/DedicatedLogging/DedicatedLoggingServiceCollectionExtensions.cs new file mode 100644 index 00000000000..538f23b5cb4 --- /dev/null +++ b/docs/logs/dedicated-pipeline/DedicatedLogging/DedicatedLoggingServiceCollectionExtensions.cs @@ -0,0 +1,73 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.Extensions.DependencyInjection.Extensions; +using OpenTelemetry.Logs; + +namespace DedicatedLogging; + +public static class DedicatedLoggingServiceCollectionExtensions +{ + public static IServiceCollection AddDedicatedLogging( + this IServiceCollection services, + IConfiguration configuration, + Action configureOpenTelemetry) + { + ArgumentNullException.ThrowIfNull(configureOpenTelemetry); + + services.TryAddSingleton(sp => + { + var loggerFactory = LoggerFactory.Create(builder => + { + builder.AddConfiguration(configuration); + + builder.AddOpenTelemetry(configureOpenTelemetry); + }); + + return new DedicatedLoggerFactory(loggerFactory); + }); + + services.TryAdd(ServiceDescriptor.Singleton(typeof(IDedicatedLogger<>), typeof(DedicatedLogger<>))); + + return services; + } + + private sealed class DedicatedLogger : IDedicatedLogger + { + private readonly ILogger innerLogger; + + public DedicatedLogger(DedicatedLoggerFactory loggerFactory) + { + this.innerLogger = loggerFactory.CreateLogger(typeof(T).FullName!); + } + + public IDisposable? BeginScope(TState state) + where TState : notnull + => this.innerLogger.BeginScope(state); + + public bool IsEnabled(LogLevel logLevel) + => this.innerLogger.IsEnabled(logLevel); + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) + => this.innerLogger.Log(logLevel, eventId, state, exception, formatter); + } + + private sealed class DedicatedLoggerFactory : ILoggerFactory + { + private readonly ILoggerFactory innerLoggerFactory; + + public DedicatedLoggerFactory(ILoggerFactory loggerFactory) + { + this.innerLoggerFactory = loggerFactory; + } + + public void AddProvider(ILoggerProvider provider) + => this.innerLoggerFactory.AddProvider(provider); + + public ILogger CreateLogger(string categoryName) + => this.innerLoggerFactory.CreateLogger(categoryName); + + public void Dispose() + => this.innerLoggerFactory.Dispose(); + } +} diff --git a/docs/logs/dedicated-pipeline/DedicatedLogging/IDedicatedLogger.cs b/docs/logs/dedicated-pipeline/DedicatedLogging/IDedicatedLogger.cs new file mode 100644 index 00000000000..ba09f27e271 --- /dev/null +++ b/docs/logs/dedicated-pipeline/DedicatedLogging/IDedicatedLogger.cs @@ -0,0 +1,12 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace DedicatedLogging; + +public interface IDedicatedLogger : ILogger +{ +} + +public interface IDedicatedLogger : IDedicatedLogger +{ +} diff --git a/docs/logs/dedicated-pipeline/Program.cs b/docs/logs/dedicated-pipeline/Program.cs new file mode 100644 index 00000000000..ad671445cde --- /dev/null +++ b/docs/logs/dedicated-pipeline/Program.cs @@ -0,0 +1,47 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using DedicatedLogging; +using OpenTelemetry.Logs; + +var builder = WebApplication.CreateBuilder(args); + +builder.Logging.ClearProviders(); + +builder.Logging.AddOpenTelemetry(options => +{ + // Set up primary pipeline for common app logs + options.AddConsoleExporter(); +}); + +builder.Services.AddDedicatedLogging( + builder.Configuration.GetSection("DedicatedLogging"), // Bind configuration for dedicated logging pipeline + options => + { + // Set up secondary pipeline for dedicated logs + options.AddConsoleExporter(); + }); + +var app = builder.Build(); + +app.MapGet("/", (HttpContext context, ILogger logger, IDedicatedLogger dedicatedLogger) => +{ + // Standard log written + logger.FoodPriceChanged("artichoke", 9.99); + + // Dedicated log written + dedicatedLogger.RequestInitiated(context.Connection.RemoteIpAddress?.ToString() ?? "unknown"); + + return "Hello from OpenTelemetry Logs!"; +}); + +app.Run(); + +internal static partial class LoggerExtensions +{ + [LoggerMessage(LogLevel.Information, "Food `{name}` price changed to `{price}`.")] + public static partial void FoodPriceChanged(this ILogger logger, string name, double price); + + [LoggerMessage(LogLevel.Information, "Request initiated from `{ipAddress}`.")] + public static partial void RequestInitiated(this IDedicatedLogger logger, string ipAddress); +} diff --git a/docs/logs/dedicated-pipeline/README.md b/docs/logs/dedicated-pipeline/README.md new file mode 100644 index 00000000000..9e620e193ad --- /dev/null +++ b/docs/logs/dedicated-pipeline/README.md @@ -0,0 +1,4 @@ +# Dedicated pipeline + +This example shows how to create a dedicated logging pipeline for specific logs +which will be sent to a different location than normal application logs. diff --git a/docs/logs/dedicated-pipeline/appsettings.Development.json b/docs/logs/dedicated-pipeline/appsettings.Development.json new file mode 100644 index 00000000000..770d3e93146 --- /dev/null +++ b/docs/logs/dedicated-pipeline/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "DetailedErrors": true, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/docs/logs/dedicated-pipeline/appsettings.json b/docs/logs/dedicated-pipeline/appsettings.json new file mode 100644 index 00000000000..b16f05cea55 --- /dev/null +++ b/docs/logs/dedicated-pipeline/appsettings.json @@ -0,0 +1,14 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "DedicatedLogging": { + "LogLevel": { + "Default": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/docs/logs/dedicated-pipeline/dedicated-pipeline.csproj b/docs/logs/dedicated-pipeline/dedicated-pipeline.csproj new file mode 100644 index 00000000000..cebc8460c42 --- /dev/null +++ b/docs/logs/dedicated-pipeline/dedicated-pipeline.csproj @@ -0,0 +1,6 @@ + + + + + +