Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Elastic.Serilog.Enrichers.Web #444

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions build/scripts/Targets.fs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ let private validatePackages (arguments: ParseResults<Arguments>) =

let nugetPackages =
Paths.Output.GetFiles("*.nupkg")
|> Seq.sortByDescending (fun f -> f.CreationTimeUtc)
|> Seq.sortByDescending (_.CreationTimeUtc)
//skipping because system web fullframework not able to validate
|> Seq.filter (fun f -> not <| f.Name.StartsWith("Elastic.Serilog.Enrichers.Web."))
|> Seq.map (fun p -> Paths.RootRelative p.FullName)

let ciOnWindowsArgs = if runningOnCI && runningOnWindows then [ "-r"; "true" ] else []
Expand Down Expand Up @@ -285,7 +287,8 @@ let Setup (parsed: ParseResults<Arguments>) (subCommand: Arguments) =

cmd
Release.Name
(Some [ PristineCheck.Name; Test.Name; Integrate.Name ])
None
// (Some [ PristineCheck.Name; Test.Name; Integrate.Name ])
(Some [ GeneratePackages.Name; ValidatePackages.Name; GenerateReleaseNotes.Name; GenerateApiChanges.Name ])
<| fun _ -> release parsed

Expand Down
8 changes: 8 additions & 0 deletions ecs-dotnet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,11 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Extensions.Logging.Console.Example", "examples\Elastic.Extensions.Logging.Console.Example\Elastic.Extensions.Logging.Console.Example.csproj", "{9656A08E-9DA6-473A-B3F8-245AC7B81A28}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Extensions.Logging.Common", "src\Elastic.Extensions.Logging.Common\Elastic.Extensions.Logging.Common.csproj", "{5EDF109F-9DFF-4957-8864-BA2702FB78F6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Serilog.Sinks.Tests", "tests\Elastic.Serilog.Sinks.Tests\Elastic.Serilog.Sinks.Tests.csproj", "{933FD923-A2DC-49E3-B21E-8BA888DB5924}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Serilog.Enrichers.Web", "src\Elastic.Serilog.Enrichers.Web\Elastic.Serilog.Enrichers.Web.csproj", "{B6DCC4C4-1287-41BE-A19D-8F311C6E39F7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -304,6 +307,10 @@ Global
{933FD923-A2DC-49E3-B21E-8BA888DB5924}.Debug|Any CPU.Build.0 = Debug|Any CPU
{933FD923-A2DC-49E3-B21E-8BA888DB5924}.Release|Any CPU.ActiveCfg = Release|Any CPU
{933FD923-A2DC-49E3-B21E-8BA888DB5924}.Release|Any CPU.Build.0 = Release|Any CPU
{B6DCC4C4-1287-41BE-A19D-8F311C6E39F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6DCC4C4-1287-41BE-A19D-8F311C6E39F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6DCC4C4-1287-41BE-A19D-8F311C6E39F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6DCC4C4-1287-41BE-A19D-8F311C6E39F7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -350,6 +357,7 @@ Global
{9656A08E-9DA6-473A-B3F8-245AC7B81A28} = {05075402-8669-45BD-913A-BD40A29BBEAB}
{5EDF109F-9DFF-4957-8864-BA2702FB78F6} = {7610B796-BB3E-4CB2-8296-79BBFF6D23FC}
{933FD923-A2DC-49E3-B21E-8BA888DB5924} = {3582B07D-C2B0-49CC-B676-EAF806EB010E}
{B6DCC4C4-1287-41BE-A19D-8F311C6E39F7} = {7610B796-BB3E-4CB2-8296-79BBFF6D23FC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7F60C4BB-6216-4E50-B1E4-9C38EB484843}
Expand Down
2 changes: 1 addition & 1 deletion examples/aspnetcore-with-serilog/AspnetCoreExample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Elastic.Apm.SerilogEnricher\Elastic.Apm.SerilogEnricher.csproj" />
<ProjectReference Include="..\..\src\Elastic.CommonSchema.Serilog\Elastic.CommonSchema.Serilog.csproj" />
<ProjectReference Include="..\..\src\Elastic.Serilog.Enrichers.Web\Elastic.Serilog.Enrichers.Web.csproj" />
</ItemGroup>
</Project>
1 change: 1 addition & 0 deletions examples/aspnetcore-with-serilog/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.IO;
using Elastic.Apm.SerilogEnricher;
using Elastic.CommonSchema.Serilog;
using Elastic.Serilog.Enrichers.Web;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.302",
"version": "8.0.100",
"rollForward": "latestFeature",
"allowPrerelease": false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Elastic.CommonSchema.Serilog
public interface IEcsTextFormatterConfiguration : IEcsDocumentCreationOptions
{
/// <summary>
/// Expert option, its recommended to use <see cref="EnricherExtensions.WithEcsHttpContext"/> to ensure HttpContext gets mapped
/// Expert option, It's recommended to use install <c>Elastic.Serilog.Enrichers.Web</c> to ensure HttpContext gets mapped
/// to the appropriate ECS fields.
/// <para> Example: </para>
/// <code>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,11 @@
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<None Remove="Lib\UAParser.regexes.yaml" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Lib\UAParser.regexes.yaml">
<LogicalName>UAParser.regexes.yaml</LogicalName>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Elastic.CommonSchema\Elastic.CommonSchema.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Serilog" Version="2.9.0.0" />
<PackageReference Condition="$(DefineConstants.Contains(NETSTANDARD))" Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.1.0.0" />
<PackageReference Condition="$(DefineConstants.Contains(NETSTANDARD))" Include="Microsoft.AspNetCore.Http.Extensions" Version="2.1.0.0" />
<Reference Condition="$(DefineConstants.Contains(FULLFRAMEWORK))" Include="System.Web" />
<PackageReference Include="PolySharp" Version="1.13.2" PrivateAssets="all">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
11 changes: 6 additions & 5 deletions src/Elastic.CommonSchema.Serilog/LogEventConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Serilog.Events;
using static Elastic.CommonSchema.Serilog.SpecialProperties;

namespace Elastic.CommonSchema.Serilog
{
Expand Down Expand Up @@ -312,7 +313,7 @@ void Assign(string key, Action<Agent, string> assign)
private static Http? GetHttp(LogEvent e, IEcsTextFormatterConfiguration configuration)
{
if (e.TryGetScalarPropertyValue(SpecialKeys.HttpContext, out var httpContext)
&& httpContext.Value is HttpContextEnricher.HttpContextEnrichments enriched)
&& httpContext.Value is HttpContextEnrichments enriched)
return enriched.Http;

var http = configuration.MapHttpAdapter?.Http;
Expand Down Expand Up @@ -346,7 +347,7 @@ void Assign(string key, Action<Agent, string> assign)
private static Url? GetUrl(LogEvent e, IEcsTextFormatterConfiguration configuration)
{
if (e.TryGetScalarPropertyValue(SpecialKeys.HttpContext, out var httpContext)
&& httpContext.Value is HttpContextEnricher.HttpContextEnrichments enriched)
&& httpContext.Value is HttpContextEnrichments enriched)
return enriched.Url;

var url = configuration.MapHttpAdapter?.Url;
Expand Down Expand Up @@ -375,7 +376,7 @@ void Assign(string key, Action<Agent, string> assign)
private static UserAgent? GetUserAgent(LogEvent e, IEcsTextFormatterConfiguration configuration)
{
if (e.TryGetScalarPropertyValue(SpecialKeys.HttpContext, out var httpContext)
&& httpContext.Value is HttpContextEnricher.HttpContextEnrichments enriched)
&& httpContext.Value is HttpContextEnrichments enriched)
return enriched.UserAgent;

return configuration.MapHttpAdapter?.UserAgent;
Expand All @@ -384,7 +385,7 @@ void Assign(string key, Action<Agent, string> assign)
private static User? GetUser(LogEvent e, IEcsTextFormatterConfiguration configuration)
{
if (e.TryGetScalarPropertyValue(SpecialKeys.HttpContext, out var httpContext)
&& httpContext.Value is HttpContextEnricher.HttpContextEnrichments enriched)
&& httpContext.Value is HttpContextEnrichments enriched)
return enriched.User;

return configuration.MapHttpAdapter?.User;
Expand All @@ -393,7 +394,7 @@ void Assign(string key, Action<Agent, string> assign)
private static Client? GetClient(LogEvent e, IEcsTextFormatterConfiguration configuration)
{
if (e.TryGetScalarPropertyValue(SpecialKeys.HttpContext, out var httpContext)
&& httpContext.Value is HttpContextEnricher.HttpContextEnrichments enriched)
&& httpContext.Value is HttpContextEnrichments enriched)
return enriched.Client;

return configuration.MapHttpAdapter?.Client;
Expand Down
37 changes: 0 additions & 37 deletions src/Elastic.CommonSchema.Serilog/SpecialKeys.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,3 @@

namespace Elastic.CommonSchema.Serilog;

internal static class SpecialKeys
{
public const string DefaultLogger = "Elastic.CommonSchema.Serilog";

public const string SourceContext = nameof(SourceContext);
public const string EnvironmentUserName = nameof(EnvironmentUserName);
public const string Host = nameof(Host);
public const string ActionCategory = nameof(ActionCategory);
public const string ActionName = nameof(ActionName);
public const string ActionId = nameof(ActionId);
public const string ActionKind = nameof(ActionKind);
public const string ActionSeverity = nameof(ActionSeverity);
public const string EventId = nameof(EventId);
public const string ApplicationId = nameof(ApplicationId);
public const string ApplicationName = nameof(ApplicationName);
public const string ApplicationType = nameof(ApplicationType);
public const string ApplicationVersion = nameof(ApplicationVersion);
public const string ProcessName = nameof(ProcessName);
public const string ProcessId = nameof(ProcessId);
public const string ThreadId = nameof(ThreadId);
public const string MachineName = nameof(MachineName);
public const string Elapsed = nameof(Elapsed);
public const string ElapsedMilliseconds = nameof(ElapsedMilliseconds);
public const string Method = nameof(Method);
public const string RequestMethod = nameof(RequestMethod);
public const string Path = nameof(Path);
public const string RequestPath = nameof(RequestPath);
public const string StatusCode = nameof(StatusCode);
public const string Scheme = nameof(Scheme);
public const string ContentType = nameof(ContentType);
public const string QueryString = nameof(QueryString);
public const string RequestId = nameof(RequestId);
public const string HttpContext = nameof(HttpContext);

// a known ASP.NET key we don't want to emit under labels.*
public const string HostingRequestFinishedLog = nameof(HostingRequestFinishedLog);
}
54 changes: 54 additions & 0 deletions src/Elastic.CommonSchema.Serilog/SpecialProperties.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
namespace Elastic.CommonSchema.Serilog;

/// <summary> Defines known keys and types to read from serilog properties </summary>
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
public static class SpecialProperties
{
public class HttpContextEnrichments
{
public Client? Client { get; set; }
public Http? Http { get; set; }
public Server? Server { get; set; }
public Url? Url { get; set; }
public User? User { get; set; }
public UserAgent? UserAgent { get; set; }
}

public static class SpecialKeys
{
public const string DefaultLogger = "Elastic.CommonSchema.Serilog";

public const string SourceContext = nameof(SourceContext);
public const string EnvironmentUserName = nameof(EnvironmentUserName);
public const string Host = nameof(Host);
public const string ActionCategory = nameof(ActionCategory);
public const string ActionName = nameof(ActionName);
public const string ActionId = nameof(ActionId);
public const string ActionKind = nameof(ActionKind);
public const string ActionSeverity = nameof(ActionSeverity);
public const string EventId = nameof(EventId);
public const string ApplicationId = nameof(ApplicationId);
public const string ApplicationName = nameof(ApplicationName);
public const string ApplicationType = nameof(ApplicationType);
public const string ApplicationVersion = nameof(ApplicationVersion);
public const string ProcessName = nameof(ProcessName);
public const string ProcessId = nameof(ProcessId);
public const string ThreadId = nameof(ThreadId);
public const string MachineName = nameof(MachineName);
public const string Elapsed = nameof(Elapsed);
public const string ElapsedMilliseconds = nameof(ElapsedMilliseconds);
public const string Method = nameof(Method);
public const string RequestMethod = nameof(RequestMethod);
public const string Path = nameof(Path);
public const string RequestPath = nameof(RequestPath);
public const string StatusCode = nameof(StatusCode);
public const string Scheme = nameof(Scheme);
public const string ContentType = nameof(ContentType);
public const string QueryString = nameof(QueryString);
public const string RequestId = nameof(RequestId);
public const string HttpContext = nameof(HttpContext);

// a known ASP.NET key we don't want to emit under labels.*
public const string HostingRequestFinishedLog = nameof(HostingRequestFinishedLog);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

#if NETSTANDARD
using System.Linq;
#if NETCOREAPP
using System.Security.Claims;
using Elastic.CommonSchema;
using Elastic.CommonSchema.Serilog.Adapters;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Http.Features;
using UAParser;
using UserAgent = Elastic.CommonSchema.UserAgent;

namespace Elastic.CommonSchema.Serilog.Adapters
namespace Elastic.Serilog.Enrichers.Web.Adapters
{
/// <inheritdoc cref="IHttpAdapter"/>
public class HttpAdapter : IHttpAdapter
Expand Down Expand Up @@ -112,7 +114,7 @@ public Url? Url
Original = request.GetDisplayUrl(),
Full = request.GetDisplayUrl(),
Scheme = request.Scheme,
Query = request.QueryString.HasValue ? request.QueryString.Value.TrimStart('?') : null,
Query = request.QueryString.HasValue ? request.QueryString.Value?.TrimStart('?') : null,
Domain = request.Host.HasValue ? request.Host.Host : null,
Port = request.Host.HasValue ? request.Host.Port : null
};
Expand All @@ -127,14 +129,14 @@ public Server? Server
if (_httpContextAccessor?.HttpContext == null)
return null;

var ip4 = _httpContextAccessor.HttpContext.Connection.LocalIpAddress.MapToIPv4();
var ip4 = _httpContextAccessor.HttpContext.Connection.LocalIpAddress?.MapToIPv4();

var request = _httpContextAccessor.HttpContext.Request;

return new Server
{
Address = ip4.ToString(),
Ip = ip4.ToString(),
Address = ip4?.ToString(),
Ip = ip4?.ToString(),
Domain = request.Host.HasValue ? request.Host.Host : null
};
}
Expand All @@ -148,7 +150,7 @@ public Client? Client
if (_httpContextAccessor?.HttpContext == null)
return null;

var ip4 = _httpContextAccessor.HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress.MapToIPv4();
var ip4 = _httpContextAccessor.HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress?.MapToIPv4();

return new Client
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

#if !NETSTANDARD
#if FULLFRAMEWORK
using Elastic.CommonSchema;
using Elastic.CommonSchema.Serilog.Adapters;
using System.Web;

namespace Elastic.CommonSchema.Serilog.Adapters
namespace Elastic.Serilog.Enrichers.Web.Adapters
{
/// <inheritdoc cref="IHttpAdapter"/>
public class HttpAdapter : IHttpAdapter
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net8.0;net461</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Title>Elastic Common Schema (ECS) Serilog Enricher for Web proeprties</Title>
<Description>Serilog enricher for ASP.NET (Core) to inject more data in emitted Elastic Common Schema (ECS) documents.</Description>
<IsPackable>True</IsPackable>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Elastic.CommonSchema.Serilog\Elastic.CommonSchema.Serilog.csproj" />
<ProjectReference Include="..\Elastic.CommonSchema\Elastic.CommonSchema.csproj"/>
</ItemGroup>
<ItemGroup>
<FrameworkReference Condition="$(DefineConstants.Contains(NETCOREAPP))" Include="Microsoft.AspNetCore.App"/>
<Reference Condition="$(DefineConstants.Contains(FULLFRAMEWORK))" Include="System.Web" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Serilog" Version="2.9.0.0"/>
</ItemGroup>

<ItemGroup>
<None Remove="Lib\UAParser.regexes.yaml" />
<EmbeddedResource Include="Lib\UAParser.regexes.yaml" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System;
using Serilog;
using Serilog.Configuration;
#if NETSTANDARD
#if NETCOREAPP
using Microsoft.AspNetCore.Http;
#endif

namespace Elastic.CommonSchema.Serilog;
namespace Elastic.Serilog.Enrichers.Web;

/// <summary>
/// <see cref="LoggerEnrichmentConfiguration"/> Extensions to register ECS enrichers
/// </summary>
public static class EnricherExtensions
{
#if NETSTANDARD
#if NETCOREAPP
/// <summary>Include current HTTP context data on any ECS document created</summary>
/// <param name="enrichmentConfiguration">Logger enrichment configuration.</param>
/// <param name="httpContextAccessor"></param>
Expand Down
Loading
Loading