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

fix: Remove dependency on Serilog.Expressions. #2082

Merged
merged 7 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 2 additions & 4 deletions src/Agent/NewRelic/Agent/Core/Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Serilog" Version="3.0.1" />
<PackageReference Include="Serilog.Expressions" Version="3.4.1" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" />
Expand Down Expand Up @@ -101,7 +100,6 @@
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'NewRelic.Parsing'" />
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Newtonsoft.Json'" />
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog'" />
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog.Expressions'" />
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog.Sinks.Async'" />
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog.Sinks.Console'" />
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog.Sinks.Debug'" />
Expand All @@ -126,8 +124,8 @@
</ItemGroup>

<PropertyGroup>
<ILRepackIncludeCount Condition="'$(TargetFramework)' == 'net462'">20</ILRepackIncludeCount>
<ILRepackIncludeCount Condition="'$(TargetFramework)' == 'netstandard2.0'">17</ILRepackIncludeCount>
<ILRepackIncludeCount Condition="'$(TargetFramework)' == 'net462'">19</ILRepackIncludeCount>
<ILRepackIncludeCount Condition="'$(TargetFramework)' == 'netstandard2.0'">16</ILRepackIncludeCount>
</PropertyGroup>

<Error Text="ILRepack of $(AssemblyName) ($(TargetFramework)) failed. A dependency is missing. Expected $(ILRepackIncludeCount) dependencies but found @(ILRepackInclude-&gt;Count())." Condition="@(ILRepackInclude-&gt;Count()) != $(ILRepackIncludeCount)" />
Expand Down
4 changes: 2 additions & 2 deletions src/Agent/NewRelic/Agent/Core/Logging/AuditLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ public static void Log(string message)

public static LoggerConfiguration IncludeOnlyAuditLog(this LoggerConfiguration loggerConfiguration)
{
return loggerConfiguration.Filter.ByIncludingOnly($"{LogLevelExtensions.AuditLevel} is not null");
return loggerConfiguration.Filter.ByIncludingOnly(logEvent => logEvent.Properties.ContainsKey(LogLevelExtensions.AuditLevel));
}

public static LoggerConfiguration ExcludeAuditLog(this LoggerConfiguration loggerConfiguration)
{
return loggerConfiguration.Filter.ByIncludingOnly($"{LogLevelExtensions.AuditLevel} is null");
return loggerConfiguration.Filter.ByIncludingOnly(logEvent => !logEvent.Properties.ContainsKey(LogLevelExtensions.AuditLevel));
}
}
}
22 changes: 11 additions & 11 deletions src/Agent/NewRelic/Agent/Core/Logging/LoggerBootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@
using System.Text;
using Serilog;
using Serilog.Core;
using Serilog.Formatting;
using Logger = NewRelic.Agent.Core.Logging.Logger;
using NewRelic.Agent.Core.Logging;
using Serilog.Templates;
using Serilog.Events;
#if NETSTANDARD2_0
using System.Runtime.InteropServices;
Expand All @@ -25,8 +23,9 @@ public static class LoggerBootstrapper
//private static ILayout AuditLogLayout = new PatternLayout("%utcdate{yyyy-MM-dd HH:mm:ss,fff} NewRelic %level: %message\r\n");
//private static ILayout FileLogLayout = new PatternLayout("%utcdate{yyyy-MM-dd HH:mm:ss,fff} NewRelic %6level: [pid: %property{pid}, tid: %property{threadid}] %message\r\n");

private static ExpressionTemplate AuditLogLayout = new ExpressionTemplate("{UtcDateTime(@t):yyyy-MM-dd HH:mm:ss,fff} NewRelic Audit: {@m}\n");
private static ExpressionTemplate FileLogLayout = new ExpressionTemplate("{UtcDateTime(@t):yyyy-MM-dd HH:mm:ss,fff} NewRelic {NRLogLevel,6}: [pid: {pid}, tid: {tid}] {@m}\n{@x}");
private const string AuditLogLayout = "{UTCTimestamp} NewRelic Audit: {Message}\n";

private const string FileLogLayout = "{UTCTimestamp} NewRelic {NRLogLevel,6}: [pid: {pid}, tid: {tid}] {Message}\n{Exception}";

private static LoggingLevelSwitch _loggingLevelSwitch = new LoggingLevelSwitch();

Expand All @@ -40,7 +39,7 @@ public static void UpdateLoggingLevel(string newLogLevel)
public static void Initialize()
{
var startupLoggerConfig = new LoggerConfiguration()
.Enrich.With(new ThreadIdEnricher(), new ProcessIdEnricher(), new NrLogLevelEnricher())
.Enrich.With(new ThreadIdEnricher(), new ProcessIdEnricher(), new NrLogLevelEnricher(), new UTCTimestampEnricher())
.MinimumLevel.Information()
.ConfigureInMemoryLogSink()
.ConfigureEventLogSink();
Expand All @@ -61,8 +60,8 @@ public static void ConfigureLogger(ILogConfig config)

var loggerConfig = new LoggerConfiguration()
.MinimumLevel.ControlledBy(_loggingLevelSwitch)
.Enrich.With(new ThreadIdEnricher(), new ProcessIdEnricher(), new NrLogLevelEnricher(), new UTCTimestampEnricher())
.ConfigureAuditLogSink(config)
.Enrich.With(new ThreadIdEnricher(), new ProcessIdEnricher(), new NrLogLevelEnricher())
.ConfigureFileSink(config)
.ConfigureDebugSink();

Expand Down Expand Up @@ -167,7 +166,7 @@ private static LoggerConfiguration ConfigureDebugSink(this LoggerConfiguration l
{
configuration
.ExcludeAuditLog()
.WriteTo.Debug(FileLogLayout);
.WriteTo.Debug(outputTemplate: FileLogLayout);
});
#endif
return loggerConfiguration;
Expand All @@ -184,7 +183,7 @@ private static LoggerConfiguration ConfigureConsoleSink(this LoggerConfiguration
{
configuration
.ExcludeAuditLog()
.WriteTo.Console(FileLogLayout);
.WriteTo.Console(outputTemplate: FileLogLayout);
})
);
}
Expand Down Expand Up @@ -248,9 +247,9 @@ private static LoggerConfiguration ConfigureAuditLogSink(this LoggerConfiguratio
/// </summary>
/// <param name="loggerConfiguration"></param>
/// <param name="fileName">The name of the file this appender will write to.</param>
/// <param name="textFormatter"></param>
/// <param name="outputFormat"></param>
/// <remarks>This does not call appender.ActivateOptions or add the appender to the logger.</remarks>
private static LoggerConfiguration ConfigureRollingLogSink(this LoggerConfiguration loggerConfiguration, string fileName, ITextFormatter textFormatter)
private static LoggerConfiguration ConfigureRollingLogSink(this LoggerConfiguration loggerConfiguration, string fileName, string outputFormat)
{
// check that the log file is accessible
try
Expand All @@ -272,7 +271,8 @@ private static LoggerConfiguration ConfigureRollingLogSink(this LoggerConfigurat
return loggerConfiguration
.WriteTo
.File(path: fileName,
formatter: textFormatter,
outputTemplate:outputFormat,
//formatter: textFormatter,
tippmar-nr marked this conversation as resolved.
Show resolved Hide resolved
fileSizeLimitBytes: 50 * 1024 * 1024,
encoding: Encoding.UTF8,
rollOnFileSizeLimit: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace NewRelic.Agent.Core
/// <summary>
/// Maps serilog log level to corresponding "legacy" log4net loglevel and adds the mapped value as a property named NRLogLevel
/// </summary>
[NrExcludeFromCodeCoverage]
internal class NrLogLevelEnricher : ILogEventEnricher
{
[NrExcludeFromCodeCoverage]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,21 @@

namespace NewRelic.Agent.Core
{
/// <summary>
/// Adds a pid property to the log event containing the current process id
/// </summary>
[NrExcludeFromCodeCoverage]
internal class ProcessIdEnricher : ILogEventEnricher
{
private static int _pid = new ProcessStatic().GetCurrentProcess().Id;

private static LogEventProperty _prop;

public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("pid", _pid));
_prop ??= propertyFactory.CreateProperty("pid", _pid);

logEvent.AddPropertyIfAbsent(_prop);
}
}
}
15 changes: 13 additions & 2 deletions src/Agent/NewRelic/Agent/Core/Logging/ThreadIdEnricher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,24 @@

namespace NewRelic.Agent.Core
{
/// <summary>
/// Adds a tid property to the log event containing the current managed thread id
/// </summary>
[NrExcludeFromCodeCoverage]
internal class ThreadIdEnricher : ILogEventEnricher
{
private LogEventProperty _tidProperty;

public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(
"tid", Thread.CurrentThread.ManagedThreadId));
var threadId = Thread.CurrentThread.ManagedThreadId;

var prop = _tidProperty;

if (prop == null || (int?)((ScalarValue)prop.Value).Value != threadId)
_tidProperty = prop = propertyFactory.CreateProperty("tid", threadId);

logEvent.AddPropertyIfAbsent(prop);
tippmar-nr marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
24 changes: 24 additions & 0 deletions src/Agent/NewRelic/Agent/Core/Logging/UTCTimestampEnricher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2020 New Relic, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

using System;
using NewRelic.Core.CodeAttributes;
using Serilog.Core;
using Serilog.Events;

namespace NewRelic.Agent.Core
{
/// <summary>
/// Formats the current UTC time for logging in the agent
/// </summary>
[NrExcludeFromCodeCoverage]
public class UTCTimestampEnricher : ILogEventEnricher
{
public const string UTCTimestampPropertyName = "UTCTimestamp";
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(UTCTimestampPropertyName,
$"{DateTimeOffset.UtcNow:yyy-MM-dd HH:mm:ss,fff}"));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2020 New Relic, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using NewRelic.Agent.IntegrationTestHelpers;
using Xunit;
using Xunit.Abstractions;

namespace NewRelic.Agent.IntegrationTests.AgentLogs
{
[NetFrameworkTest]
public class LogFileFormatTests : NewRelicIntegrationTest<RemoteServiceFixtures.BasicMvcApplicationTestFixture>
{
private readonly RemoteServiceFixtures.BasicMvcApplicationTestFixture _fixture;

public LogFileFormatTests(RemoteServiceFixtures.BasicMvcApplicationTestFixture fixture, ITestOutputHelper output) : base(fixture)
{
_fixture = fixture;
_fixture.TestLogger = output;
_fixture.Actions
(
setupConfiguration: () =>
{
var configPath = fixture.DestinationNewRelicConfigFilePath;
var configModifier = new NewRelicConfigModifier(configPath);
configModifier.ForceTransactionTraces();
},
exerciseApplication: () =>
{
_fixture.Get();
}
);
_fixture.Initialize();
}

[Fact]
public void Test()
{
// get the first log line and validate it's in the expected format
var firstLogLine = _fixture.AgentLog.GetFileLines().First();

var match = Regex.Match(firstLogLine,
@"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3} NewRelic .{6}: \[pid: \d{1,}, tid: \d{1,}\] .*");

Assert.True(match.Success);
Assert.Single(match.Groups);
Assert.Equal(firstLogLine, match.Groups[0].Value);
}
}
}
Loading