Skip to content

Commit 9e355f3

Browse files
authored
fix: Remove dependency on Serilog.Expressions. (#2083) (#2082)
1 parent 398e727 commit 9e355f3

File tree

10 files changed

+115
-20
lines changed

10 files changed

+115
-20
lines changed

src/Agent/NewRelic/Agent/Core/Core.csproj

+2-4
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4040
</PackageReference>
4141
<PackageReference Include="Serilog" Version="3.0.1" />
42-
<PackageReference Include="Serilog.Expressions" Version="3.4.1" />
4342
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
4443
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
4544
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" />
@@ -101,7 +100,6 @@
101100
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'NewRelic.Parsing'" />
102101
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Newtonsoft.Json'" />
103102
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog'" />
104-
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog.Expressions'" />
105103
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog.Sinks.Async'" />
106104
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog.Sinks.Console'" />
107105
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog.Sinks.Debug'" />
@@ -126,8 +124,8 @@
126124
</ItemGroup>
127125

128126
<PropertyGroup>
129-
<ILRepackIncludeCount Condition="'$(TargetFramework)' == 'net462'">20</ILRepackIncludeCount>
130-
<ILRepackIncludeCount Condition="'$(TargetFramework)' == 'netstandard2.0'">17</ILRepackIncludeCount>
127+
<ILRepackIncludeCount Condition="'$(TargetFramework)' == 'net462'">19</ILRepackIncludeCount>
128+
<ILRepackIncludeCount Condition="'$(TargetFramework)' == 'netstandard2.0'">16</ILRepackIncludeCount>
131129
</PropertyGroup>
132130

133131
<Error Text="ILRepack of $(AssemblyName) ($(TargetFramework)) failed. A dependency is missing. Expected $(ILRepackIncludeCount) dependencies but found @(ILRepackInclude-&gt;Count())." Condition="@(ILRepackInclude-&gt;Count()) != $(ILRepackIncludeCount)" />

src/Agent/NewRelic/Agent/Core/Logging/AuditLog.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ public static void Log(string message)
3838

3939
public static LoggerConfiguration IncludeOnlyAuditLog(this LoggerConfiguration loggerConfiguration)
4040
{
41-
return loggerConfiguration.Filter.ByIncludingOnly($"{LogLevelExtensions.AuditLevel} is not null");
41+
return loggerConfiguration.Filter.ByIncludingOnly(logEvent => logEvent.Properties.ContainsKey(LogLevelExtensions.AuditLevel));
4242
}
4343

4444
public static LoggerConfiguration ExcludeAuditLog(this LoggerConfiguration loggerConfiguration)
4545
{
46-
return loggerConfiguration.Filter.ByIncludingOnly($"{LogLevelExtensions.AuditLevel} is null");
46+
return loggerConfiguration.Filter.ByIncludingOnly(logEvent => !logEvent.Properties.ContainsKey(LogLevelExtensions.AuditLevel));
4747
}
4848
}
4949
}

src/Agent/NewRelic/Agent/Core/Logging/LoggerBootstrapper.cs

+10-11
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@
77
using System.Text;
88
using Serilog;
99
using Serilog.Core;
10-
using Serilog.Formatting;
1110
using Logger = NewRelic.Agent.Core.Logging.Logger;
1211
using NewRelic.Agent.Core.Logging;
13-
using Serilog.Templates;
1412
using Serilog.Events;
1513
#if NETSTANDARD2_0
1614
using System.Runtime.InteropServices;
@@ -25,8 +23,9 @@ public static class LoggerBootstrapper
2523
//private static ILayout AuditLogLayout = new PatternLayout("%utcdate{yyyy-MM-dd HH:mm:ss,fff} NewRelic %level: %message\r\n");
2624
//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");
2725

28-
private static ExpressionTemplate AuditLogLayout = new ExpressionTemplate("{UtcDateTime(@t):yyyy-MM-dd HH:mm:ss,fff} NewRelic Audit: {@m}\n");
29-
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}");
26+
private const string AuditLogLayout = "{UTCTimestamp} NewRelic Audit: {Message:l}\n";
27+
28+
private const string FileLogLayout = "{UTCTimestamp} NewRelic {NRLogLevel,6}: [pid: {pid}, tid: {tid}] {Message:l}\n{Exception:l}";
3029

3130
private static LoggingLevelSwitch _loggingLevelSwitch = new LoggingLevelSwitch();
3231

@@ -40,7 +39,7 @@ public static void UpdateLoggingLevel(string newLogLevel)
4039
public static void Initialize()
4140
{
4241
var startupLoggerConfig = new LoggerConfiguration()
43-
.Enrich.With(new ThreadIdEnricher(), new ProcessIdEnricher(), new NrLogLevelEnricher())
42+
.Enrich.With(new ThreadIdEnricher(), new ProcessIdEnricher(), new NrLogLevelEnricher(), new UTCTimestampEnricher())
4443
.MinimumLevel.Information()
4544
.ConfigureInMemoryLogSink()
4645
.ConfigureEventLogSink();
@@ -61,8 +60,8 @@ public static void ConfigureLogger(ILogConfig config)
6160

6261
var loggerConfig = new LoggerConfiguration()
6362
.MinimumLevel.ControlledBy(_loggingLevelSwitch)
63+
.Enrich.With(new ThreadIdEnricher(), new ProcessIdEnricher(), new NrLogLevelEnricher(), new UTCTimestampEnricher())
6464
.ConfigureAuditLogSink(config)
65-
.Enrich.With(new ThreadIdEnricher(), new ProcessIdEnricher(), new NrLogLevelEnricher())
6665
.ConfigureFileSink(config)
6766
.ConfigureDebugSink();
6867

@@ -167,7 +166,7 @@ private static LoggerConfiguration ConfigureDebugSink(this LoggerConfiguration l
167166
{
168167
configuration
169168
.ExcludeAuditLog()
170-
.WriteTo.Debug(FileLogLayout);
169+
.WriteTo.Debug(outputTemplate: FileLogLayout);
171170
});
172171
#endif
173172
return loggerConfiguration;
@@ -184,7 +183,7 @@ private static LoggerConfiguration ConfigureConsoleSink(this LoggerConfiguration
184183
{
185184
configuration
186185
.ExcludeAuditLog()
187-
.WriteTo.Console(FileLogLayout);
186+
.WriteTo.Console(outputTemplate: FileLogLayout);
188187
})
189188
);
190189
}
@@ -248,9 +247,9 @@ private static LoggerConfiguration ConfigureAuditLogSink(this LoggerConfiguratio
248247
/// </summary>
249248
/// <param name="loggerConfiguration"></param>
250249
/// <param name="fileName">The name of the file this appender will write to.</param>
251-
/// <param name="textFormatter"></param>
250+
/// <param name="outputFormat"></param>
252251
/// <remarks>This does not call appender.ActivateOptions or add the appender to the logger.</remarks>
253-
private static LoggerConfiguration ConfigureRollingLogSink(this LoggerConfiguration loggerConfiguration, string fileName, ITextFormatter textFormatter)
252+
private static LoggerConfiguration ConfigureRollingLogSink(this LoggerConfiguration loggerConfiguration, string fileName, string outputFormat)
254253
{
255254
// check that the log file is accessible
256255
try
@@ -272,7 +271,7 @@ private static LoggerConfiguration ConfigureRollingLogSink(this LoggerConfigurat
272271
return loggerConfiguration
273272
.WriteTo
274273
.File(path: fileName,
275-
formatter: textFormatter,
274+
outputTemplate:outputFormat,
276275
fileSizeLimitBytes: 50 * 1024 * 1024,
277276
encoding: Encoding.UTF8,
278277
rollOnFileSizeLimit: true,

src/Agent/NewRelic/Agent/Core/Logging/NrLogLevelEnricher.cs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace NewRelic.Agent.Core
1010
/// <summary>
1111
/// Maps serilog log level to corresponding "legacy" log4net loglevel and adds the mapped value as a property named NRLogLevel
1212
/// </summary>
13+
[NrExcludeFromCodeCoverage]
1314
internal class NrLogLevelEnricher : ILogEventEnricher
1415
{
1516
[NrExcludeFromCodeCoverage]

src/Agent/NewRelic/Agent/Core/Logging/ProcessIdEnricher.cs

+8-1
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,21 @@
88

99
namespace NewRelic.Agent.Core
1010
{
11+
/// <summary>
12+
/// Adds a pid property to the log event containing the current process id
13+
/// </summary>
1114
[NrExcludeFromCodeCoverage]
1215
internal class ProcessIdEnricher : ILogEventEnricher
1316
{
1417
private static int _pid = new ProcessStatic().GetCurrentProcess().Id;
1518

19+
private static LogEventProperty _prop;
20+
1621
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
1722
{
18-
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("pid", _pid));
23+
_prop ??= propertyFactory.CreateProperty("pid", _pid);
24+
25+
logEvent.AddPropertyIfAbsent(_prop);
1926
}
2027
}
2128
}

src/Agent/NewRelic/Agent/Core/Logging/ThreadIdEnricher.cs

+10-2
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,21 @@
88

99
namespace NewRelic.Agent.Core
1010
{
11+
/// <summary>
12+
/// Adds a tid property to the log event containing the current managed thread id
13+
/// </summary>
1114
[NrExcludeFromCodeCoverage]
1215
internal class ThreadIdEnricher : ILogEventEnricher
1316
{
17+
18+
private static readonly ThreadLocal<LogEventProperty> _tidProperty = new ThreadLocal<LogEventProperty>();
19+
1420
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
1521
{
16-
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(
17-
"tid", Thread.CurrentThread.ManagedThreadId));
22+
if (!_tidProperty.IsValueCreated)
23+
_tidProperty.Value = propertyFactory.CreateProperty("tid", Thread.CurrentThread.ManagedThreadId);
24+
25+
logEvent.AddPropertyIfAbsent(_tidProperty.Value);
1826
}
1927
}
2028
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2020 New Relic, Inc. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
using System;
5+
using NewRelic.Core.CodeAttributes;
6+
using Serilog.Core;
7+
using Serilog.Events;
8+
9+
namespace NewRelic.Agent.Core
10+
{
11+
/// <summary>
12+
/// Formats the current UTC time for logging in the agent
13+
/// </summary>
14+
[NrExcludeFromCodeCoverage]
15+
public class UTCTimestampEnricher : ILogEventEnricher
16+
{
17+
public const string UTCTimestampPropertyName = "UTCTimestamp";
18+
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
19+
{
20+
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(UTCTimestampPropertyName,
21+
$"{DateTimeOffset.UtcNow:yyy-MM-dd HH:mm:ss,fff}"));
22+
}
23+
}
24+
}

src/Agent/NewRelic/Agent/Extensions/Providers/Wrapper/Owin/Owin.csproj

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
<AssemblyName>NewRelic.Providers.Wrapper.Owin</AssemblyName>
66
<Description>Owin 2 Wrapper Provider for New Relic .NET Agent</Description>
77
</PropertyGroup>
8+
<PropertyGroup>
9+
<NoWarn>NU1903</NoWarn> <!-- Microsoft.Owin 2.0 has a high security vulnerability, but we have to reference that pacakage -->
10+
</PropertyGroup>
811
<ItemGroup>
912
<PackageReference Include="Microsoft.Owin" Version="2.0.0" />
1013
</ItemGroup>

src/Agent/NewRelic/Agent/Extensions/Providers/Wrapper/WebApi1/WebApi1.csproj

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
<AssemblyName>NewRelic.Providers.Wrapper.WebApi1</AssemblyName>
66
<Description>Web API 1 Wrapper Provider for New Relic .NET Agent</Description>
77
</PropertyGroup>
8+
<PropertyGroup>
9+
<NoWarn>NU1903</NoWarn> <!-- System.Net.Http 2.0 has a high security vulnerability, but we have to reference that pacakage -->
10+
</PropertyGroup>
811
<ItemGroup>
912
<PackageReference Include="System.Net.Http" Version="2.0.20710.0" />
1013
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="4.0.20710.0" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2020 New Relic, Inc. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
using System.IO;
5+
using System.Linq;
6+
using System.Text.RegularExpressions;
7+
using NewRelic.Agent.IntegrationTestHelpers;
8+
using Xunit;
9+
using Xunit.Abstractions;
10+
11+
namespace NewRelic.Agent.IntegrationTests.AgentLogs
12+
{
13+
[NetFrameworkTest]
14+
public class LogFileFormatTests : NewRelicIntegrationTest<RemoteServiceFixtures.BasicMvcApplicationTestFixture>
15+
{
16+
private readonly RemoteServiceFixtures.BasicMvcApplicationTestFixture _fixture;
17+
18+
public LogFileFormatTests(RemoteServiceFixtures.BasicMvcApplicationTestFixture fixture, ITestOutputHelper output) : base(fixture)
19+
{
20+
_fixture = fixture;
21+
_fixture.TestLogger = output;
22+
_fixture.Actions
23+
(
24+
setupConfiguration: () =>
25+
{
26+
var configPath = fixture.DestinationNewRelicConfigFilePath;
27+
var configModifier = new NewRelicConfigModifier(configPath);
28+
configModifier.ForceTransactionTraces();
29+
},
30+
exerciseApplication: () =>
31+
{
32+
_fixture.Get();
33+
}
34+
);
35+
_fixture.Initialize();
36+
}
37+
38+
[Fact]
39+
public void Test()
40+
{
41+
// get the first log line and validate it's in the expected format
42+
var firstLogLine = _fixture.AgentLog.GetFileLines().First();
43+
44+
var match = Regex.Match(firstLogLine,
45+
@"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3} NewRelic .{6}: \[pid: \d{1,}, tid: \d{1,}\] .*");
46+
47+
Assert.True(match.Success);
48+
Assert.Single(match.Groups);
49+
Assert.Equal(firstLogLine, match.Groups[0].Value);
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)