Skip to content

Commit cecbecf

Browse files
authored
Merge branch 'main' into feature/netstandard-odbc-instrumentation
2 parents 235bbb3 + 0ea3cee commit cecbecf

File tree

17 files changed

+85
-71
lines changed

17 files changed

+85
-71
lines changed

.github/copilot-instructions.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
When generating new source code files, always include the copyright header.
2+
3+
When writing unit tests, always use modern NUnit assertions.
4+
5+
We use JustMock.Lite, so use only mock configurations that are valid for that package.

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

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,6 @@ namespace NewRelic.Agent.Core
2020
public static class LoggerBootstrapper
2121
{
2222

23-
// Watch out! If you change the time format that the agent puts into its log files, other log parsers may fail.
24-
//private static ILayout AuditLogLayout = new PatternLayout("%utcdate{yyyy-MM-dd HH:mm:ss,fff} NewRelic %level: %message\r\n");
25-
//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");
26-
2723
private const string AuditLogLayout = "{UTCTimestamp} NewRelic Audit: {Message:l}\n";
2824

2925
private const string FileLogLayout = "{UTCTimestamp} NewRelic {NRLogLevel,6}: [pid: {pid}, tid: {tid}] {Message:l}\n{Exception:l}";
@@ -34,8 +30,16 @@ public static class LoggerBootstrapper
3430

3531
public static void SetLoggingLevel(string newLogLevel) => _loggingLevelSwitch.MinimumLevel = newLogLevel.MapToSerilogLogLevel();
3632

33+
private static bool _isWindows;
34+
3735
public static void Initialize()
3836
{
37+
#if NETSTANDARD2_0
38+
_isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
39+
#else
40+
_isWindows = true;
41+
#endif
42+
3943
var startupLoggerConfig = new LoggerConfiguration()
4044
.Enrich.With(new ThreadIdEnricher(), new ProcessIdEnricher(), new NrLogLevelEnricher(), new UTCTimestampEnricher())
4145
.MinimumLevel.Information()
@@ -52,22 +56,26 @@ public static void Initialize()
5256
/// <remarks>This should only be called once, as soon as you have a valid config.</remarks>
5357
public static void ConfigureLogger(ILogConfig config)
5458
{
59+
// if logging is disabled, we don't log anywhere
60+
if (!config.Enabled)
61+
{
62+
SetLoggingLevel("off"); // to short-circuit logging calls
63+
Log.Logger = Serilog.Core.Logger.None; // a logger that does nothing
64+
return;
65+
}
66+
5567
SetLoggingLevel(config.LogLevel);
5668

57-
AuditLog.IsAuditLogEnabled = config.IsAuditLogEnabled;
69+
AuditLog.IsAuditLogEnabled = config.IsAuditLogEnabled && !config.Console;
5870

5971
var loggerConfig = new LoggerConfiguration()
6072
.MinimumLevel.ControlledBy(_loggingLevelSwitch)
6173
.Enrich.With(new ThreadIdEnricher(), new ProcessIdEnricher(), new NrLogLevelEnricher(), new UTCTimestampEnricher())
74+
.ConfigureConsoleSink(config)
6275
.ConfigureAuditLogSink(config)
6376
.ConfigureFileSink(config)
6477
.ConfigureDebugSink();
6578

66-
if (config.Console)
67-
{
68-
loggerConfig = loggerConfig.ConfigureConsoleSink();
69-
}
70-
7179
// configure the global singleton logger instance (which remains specific to the Agent by way of ILRepack)
7280
var configuredLogger = loggerConfig.CreateLogger();
7381

@@ -90,6 +98,9 @@ private static void EchoInMemoryLogsToConfiguredLogger(ILogger configuredLogger)
9098
_inMemorySink.Dispose();
9199
}
92100

101+
/// <summary>
102+
/// Configures the in-memory log sink used during bootstrapping.
103+
/// </summary>
93104
private static LoggerConfiguration ConfigureInMemoryLogSink(this LoggerConfiguration loggerConfiguration)
94105
{
95106
// formatter not needed since this will be pushed to other sinks for output.
@@ -116,12 +127,7 @@ private static LoggerConfiguration ConfigureInMemoryLogSink(this LoggerConfigura
116127
/// <param name="loggerConfiguration"></param>
117128
private static LoggerConfiguration ConfigureEventLogSink(this LoggerConfiguration loggerConfiguration)
118129
{
119-
#if NETSTANDARD2_0
120-
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
121-
#else
122-
var isWindows = true;
123-
#endif
124-
if (isWindows)
130+
if (_isWindows)
125131
{
126132
const string eventLogName = "Application";
127133
const string eventLogSourceName = "New Relic .NET Agent";
@@ -169,8 +175,10 @@ private static LoggerConfiguration ConfigureDebugSink(this LoggerConfiguration l
169175
/// <summary>
170176
/// Configure the console sink
171177
/// </summary>
172-
private static LoggerConfiguration ConfigureConsoleSink(this LoggerConfiguration loggerConfiguration)
178+
private static LoggerConfiguration ConfigureConsoleSink(this LoggerConfiguration loggerConfiguration, ILogConfig config)
173179
{
180+
if (!config.Console) return loggerConfiguration;
181+
174182
return loggerConfiguration
175183
.WriteTo.Async(a =>
176184
a.Logger(configuration =>
@@ -185,14 +193,11 @@ private static LoggerConfiguration ConfigureConsoleSink(this LoggerConfiguration
185193
/// <summary>
186194
/// Configure the file log sink
187195
/// </summary>
188-
/// <param name="loggerConfiguration"></param>
189-
/// <param name="config">The configuration for the appender.</param>
190196
private static LoggerConfiguration ConfigureFileSink(this LoggerConfiguration loggerConfiguration, ILogConfig config)
191197
{
192-
if (!config.Enabled)
193-
{
194-
return loggerConfiguration;
195-
}
198+
// console logging disables all file logging output.
199+
if (config.Console) return loggerConfiguration;
200+
196201
string logFileName = config.GetFullLogFileName();
197202

198203
try
@@ -201,32 +206,36 @@ private static LoggerConfiguration ConfigureFileSink(this LoggerConfiguration lo
201206
.WriteTo
202207
.Async(a =>
203208
a.Logger(configuration =>
204-
{
205-
configuration
206-
.ExcludeAuditLog()
207-
.ConfigureRollingLogSink(logFileName, FileLogLayout, config);
208-
})
209-
);
209+
{
210+
configuration
211+
.ExcludeAuditLog()
212+
.ConfigureRollingLogSink(logFileName, FileLogLayout, config);
213+
})
214+
);
210215
}
211216
catch (Exception ex)
212217
{
213218
Log.Logger.Warning(ex, "Unexpected exception when configuring file sink.");
214219

215-
// Fallback to the event log sink if we cannot setup a file logger.
216-
Extensions.Logging.Log.FileLoggingHasFailed = true;
217-
Log.Logger.Warning("Falling back to EventLog sink.");
218-
loggerConfiguration.ConfigureEventLogSink();
220+
if (_isWindows)
221+
{
222+
// Fallback to the event log sink if we cannot setup a file logger.
223+
Extensions.Logging.Log.FileLoggingHasFailed = true;
224+
Log.Logger.Warning("Falling back to EventLog sink.");
225+
loggerConfiguration.ConfigureEventLogSink();
226+
}
219227
}
220228

221229
return loggerConfiguration;
222230
}
223231

224232
/// <summary>
225-
/// Setup the audit log file appender and attach it to a logger.
233+
/// Configure the audit log sink
226234
/// </summary>
227235
private static LoggerConfiguration ConfigureAuditLogSink(this LoggerConfiguration loggerConfiguration, ILogConfig config)
228236
{
229-
if (!config.IsAuditLogEnabled || !config.Enabled) return loggerConfiguration;
237+
// console logging disables all file logging output, including audit logs
238+
if (!config.IsAuditLogEnabled || config.Console) return loggerConfiguration;
230239

231240
string logFileName = config.GetFullLogFileName().Replace(".log", "_audit.log");
232241

@@ -242,13 +251,8 @@ private static LoggerConfiguration ConfigureAuditLogSink(this LoggerConfiguratio
242251
}
243252

244253
/// <summary>
245-
/// Sets up a rolling file appender using defaults shared for all our rolling file appenders.
254+
/// Configure the rolling log sink
246255
/// </summary>
247-
/// <param name="loggerConfiguration"></param>
248-
/// <param name="fileName">The name of the file this appender will write to.</param>
249-
/// <param name="outputFormat"></param>
250-
/// <param name="config"></param>
251-
/// <remarks>This does not call appender.ActivateOptions or add the appender to the logger.</remarks>
252256
private static LoggerConfiguration ConfigureRollingLogSink(this LoggerConfiguration loggerConfiguration, string fileName, string outputFormat, ILogConfig config)
253257
{
254258
// check that the log file is accessible

tests/Agent/IntegrationTests/ContainerApplications/AwsSdkTestApp/AwsSdkTestApp.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
<PrivateAssets>all</PrivateAssets>
1515
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1616
</PackageReference>
17-
<PackageReference Include="AWSSDK.SQS" Version="3.7.400.76" />
18-
<PackageReference Include="AWSSDK.DynamoDBv2" Version="3.7.405.2" />
17+
<PackageReference Include="AWSSDK.SQS" Version="3.7.400.79" />
18+
<PackageReference Include="AWSSDK.DynamoDBv2" Version="3.7.405.5" />
1919
<PackageReference Include="NewRelic.Agent.Api" Version="10.34.1" />
2020
</ItemGroup>
2121
</Project>

tests/Agent/IntegrationTests/ContainerIntegrationTests/Tests/AwsSdk/AwsSdkDynamoDBTest.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ public AwsSdkDynamoDBTest(AwsSdkContainerDynamoDBTestFixture fixture, ITestOutpu
3535
configModifier.ConfigureFasterMetricsHarvestCycle(15);
3636
configModifier.ConfigureFasterSpanEventsHarvestCycle(15);
3737
configModifier.ConfigureFasterTransactionTracesHarvestCycle(15);
38-
configModifier.LogToConsole();
39-
4038
},
4139
exerciseApplication: () =>
4240
{

tests/Agent/IntegrationTests/ContainerIntegrationTests/Tests/AwsSdk/AwsSdkMultiServiceTest.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ public AwsSdkMultiServiceTest(AwsSdkContainerMultiServiceTestFixture fixture, IT
3636
configModifier.ConfigureFasterMetricsHarvestCycle(15);
3737
configModifier.ConfigureFasterSpanEventsHarvestCycle(15);
3838
configModifier.ConfigureFasterTransactionTracesHarvestCycle(15);
39-
configModifier.LogToConsole();
40-
4139
},
4240
exerciseApplication: () =>
4341
{

tests/Agent/IntegrationTests/ContainerIntegrationTests/Tests/AwsSdk/AwsSdkSQSTest.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ protected AwsSdkSQSTestBase(AwsSdkContainerSQSTestFixture fixture, ITestOutputHe
4141
configModifier.ConfigureFasterMetricsHarvestCycle(15);
4242
configModifier.ConfigureFasterSpanEventsHarvestCycle(15);
4343
configModifier.ConfigureFasterTransactionTracesHarvestCycle(15);
44-
configModifier.LogToConsole();
45-
4644
},
4745
exerciseApplication: () =>
4846
{

tests/Agent/IntegrationTests/ContainerIntegrationTests/Tests/InfiniteTracingContainerTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ protected InfiniteTracingContainerTest(T fixture, ITestOutputHelper output) : ba
3333
configModifier.ConfigureFasterMetricsHarvestCycle(10);
3434
configModifier.ConfigureFasterTransactionTracesHarvestCycle(10);
3535
configModifier.SetLogLevel("Finest");
36-
configModifier.LogToConsole();
3736
},
3837
exerciseApplication: () =>
3938
{

tests/Agent/IntegrationTests/ContainerIntegrationTests/Tests/KafkaTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ protected LinuxKafkaTest(T fixture, ITestOutputHelper output) : base(fixture)
3434
var configModifier = new NewRelicConfigModifier(_fixture.DestinationNewRelicConfigFilePath);
3535
configModifier.SetLogLevel("debug");
3636
configModifier.ConfigureFasterMetricsHarvestCycle(10);
37-
configModifier.LogToConsole();
3837

3938
_fixture.RemoteApplication.SetAdditionalEnvironmentVariable("NEW_RELIC_KAFKA_TOPIC", _topicName);
4039
},

tests/Agent/IntegrationTests/ContainerIntegrationTests/Tests/LinuxContainerTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ protected LinuxContainerTest(T fixture, ITestOutputHelper output) : base(fixture
2222
{
2323
var configModifier = new NewRelicConfigModifier(_fixture.DestinationNewRelicConfigFilePath);
2424
configModifier.ConfigureFasterMetricsHarvestCycle(10);
25-
configModifier.LogToConsole();
2625
},
2726
exerciseApplication: () =>
2827
{

tests/Agent/IntegrationTests/ContainerIntegrationTests/Tests/MemcachedTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ protected LinuxMemcachedTest(T fixture, ITestOutputHelper output) : base(fixture
2626
var configModifier = new NewRelicConfigModifier(_fixture.DestinationNewRelicConfigFilePath);
2727
configModifier.SetLogLevel("debug");
2828
configModifier.ConfigureFasterMetricsHarvestCycle(10);
29-
configModifier.LogToConsole();
3029
},
3130
exerciseApplication: () =>
3231
{

tests/Agent/IntegrationTests/IntegrationTestHelpers/AgentLogBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public abstract class AgentLogBase
4444
public const string CustomEventDataLogLineRegex = DebugLogLinePrefixRegex + @"Request\(.{36}\): Invoked ""custom_event_data"" with : (.*)";
4545

4646
// Collector responses
47-
public const string ConnectResponseLogLineRegex = DebugLogLinePrefixRegex + @"Request\(.{36}\): Invocation of ""connect"" yielded response : {""return_value"":{""agent_run_id""(.*)";
47+
public const string ConnectResponseLogLineRegex = DebugLogLinePrefixRegex + @"Request\(.{36}\): Invocation of ""connect"" yielded response : {""return_value"":(.*)";
4848
public const string ErrorResponseLogLinePrefixRegex = ErrorLogLinePrefixRegex + @"Request\(.{36}\): ";
4949

5050
public const string ThreadProfileStartingLogLineRegex = InfoLogLinePrefixRegex + @"Starting a thread profiling session";
@@ -496,7 +496,7 @@ public IEnumerable<ConnectResponseData> GetConnectResponseDatas()
496496

497497
foreach (var match in matches)
498498
{
499-
var json = "{ \"agent_run_id\"" + match;
499+
var json = match;
500500
json = json?.Trim('[', ']');
501501
json = json.Remove(json.Length - 1); // remove the extra }
502502

tests/Agent/IntegrationTests/IntegrationTests/CSP/AspNetCoreLocalHSMDisabledAndServerSideHSMEnabledTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void Test()
4141
{
4242
// This test looks for the connect response body that was intended to be removed in P17, but was not. If it does get removed this will fail.
4343
// 12/14/23 - the response status changed from "Gone" to "Conflict". If this test fails in the future, be alert for it possibly changing back.
44-
var notConnectedLogLine = _fixture.AgentLog.TryGetLogLine(AgentLogBase.ErrorResponseLogLinePrefixRegex + "Received HTTP status code Conflict with message {\"exception\":{\"message\":\"Account Security Violation: *?");
44+
var notConnectedLogLine = _fixture.AgentLog.TryGetLogLine(AgentLogBase.ErrorResponseLogLinePrefixRegex + "Received HTTP status code Conflict *?");
4545
Assert.NotNull(notConnectedLogLine);
4646
}
4747
}

tests/Agent/IntegrationTests/IntegrationTests/CSP/AspNetCoreLocalHSMEnabledAndServerSideHSMDisabledTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public void Test()
4949
{
5050
// This test looks for the connect response body that was intended to be removed in P17, but was not. If it does get removed this will fail.
5151
// 12/14/23 - the response status changed from "Gone" to "Conflict". If this test fails in the future, be alert for it possibly changing back.
52-
var notConnectedLogLine = _fixture.AgentLog.TryGetLogLine(AgentLogBase.ErrorResponseLogLinePrefixRegex + "Received HTTP status code Conflict with message {\"exception\":{\"message\":\"Account Security Violation: *?");
52+
var notConnectedLogLine = _fixture.AgentLog.TryGetLogLine(AgentLogBase.ErrorResponseLogLinePrefixRegex + "Received HTTP status code Conflict *?");
5353
Assert.NotNull(notConnectedLogLine);
5454
}
5555
}

tests/Agent/IntegrationTests/IntegrationTests/CSP/HighSecurityModeServerDisabled.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public void Test()
4646
{
4747
// This test looks for the connect response body that was intended to be removed in P17, but was not. If it does get removed this will fail.
4848
// 12/14/23 - the response status changed from "Gone" to "Conflict". If this test fails in the future, be alert for it possibly changing back.
49-
var notConnectedLogLine = _fixture.AgentLog.TryGetLogLine(AgentLogBase.ErrorResponseLogLinePrefixRegex + "Received HTTP status code Conflict with message {\"exception\":{\"message\":\"Account Security Violation: *?");
49+
var notConnectedLogLine = _fixture.AgentLog.TryGetLogLine(AgentLogBase.ErrorResponseLogLinePrefixRegex + "Received HTTP status code Conflict *?");
5050
Assert.NotNull(notConnectedLogLine);
5151
}
5252
}

tests/Agent/IntegrationTests/IntegrationTests/CSP/HighSecurityModeServerEnabled.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public void Test()
4444
{
4545
// This test looks for the connect response body that was intended to be removed in P17, but was not. If it does get removed this will fail.
4646
// 12/14/23 - the response status changed from "Gone" to "Conflict". If this test fails in the future, be alert for it possibly changing back.
47-
var notConnectedLogLine = _fixture.AgentLog.TryGetLogLine(AgentLogBase.ErrorResponseLogLinePrefixRegex + "Received HTTP status code Conflict with message {\"exception\":{\"message\":\"Account Security Violation: *?");
47+
var notConnectedLogLine = _fixture.AgentLog.TryGetLogLine(AgentLogBase.ErrorResponseLogLinePrefixRegex + "Received HTTP status code Conflict *?");
4848
Assert.NotNull(notConnectedLogLine);
4949
}
5050
}

0 commit comments

Comments
 (0)