diff --git a/src/Agent/NewRelic/Agent/Core/Core.csproj b/src/Agent/NewRelic/Agent/Core/Core.csproj index eb3592914e..d0a8c083bd 100644 --- a/src/Agent/NewRelic/Agent/Core/Core.csproj +++ b/src/Agent/NewRelic/Agent/Core/Core.csproj @@ -43,6 +43,7 @@ + @@ -60,7 +61,6 @@ - @@ -129,13 +129,14 @@ + 20 - 16 + 17 diff --git a/src/Agent/NewRelic/Agent/Core/Logging/LoggerBootstrapper.cs b/src/Agent/NewRelic/Agent/Core/Logging/LoggerBootstrapper.cs index fb3538e62b..71c27ae57f 100644 --- a/src/Agent/NewRelic/Agent/Core/Logging/LoggerBootstrapper.cs +++ b/src/Agent/NewRelic/Agent/Core/Logging/LoggerBootstrapper.cs @@ -11,8 +11,9 @@ using Logger = NewRelic.Agent.Core.Logging.Logger; using NewRelic.Agent.Core.Logging; using Serilog.Templates; -#if NETFRAMEWORK using Serilog.Events; +#if NETSTANDARD2_0 +using System.Runtime.InteropServices; #endif namespace NewRelic.Agent.Core @@ -107,35 +108,49 @@ private static LoggerConfiguration ConfigureInMemoryLogSink(this LoggerConfigura } /// - /// Add the Event Log sink if running on .NET Framework + /// Configure an Event Log sink if running on Windows. Logs messages at Warning level and above. Intended for + /// use during bootstrapping and as a fallback if the file logging sink can't be created. + /// + /// The Agent will create the event log source if it doesn't exist *and* if the app is running with + /// administrator privileges. Otherwise, it will silently do nothing. + /// + /// It is possible to manually create the event log source in an elevated Powershell window: + /// New-EventLog -LogName "Application" -Source "New Relic .NET Agent" + /// /// /// private static LoggerConfiguration ConfigureEventLogSink(this LoggerConfiguration loggerConfiguration) { -#if NETFRAMEWORK - const string eventLogName = "Application"; - const string eventLogSourceName = "New Relic .NET Agent"; - try - { - loggerConfiguration - .WriteTo.Logger(configuration => - { - configuration - .ExcludeAuditLog() - .WriteTo.EventLog( - source: eventLogSourceName, - logName: eventLogName, - restrictedToMinimumLevel: LogEventLevel.Warning, - outputTemplate: "{Level}: {Message}{NewLine}{Exception}", - manageEventSource: true // Serilog will create the event source if it doesn't exist *and* if the app is running with admin privileges - ); - }); - } - catch +#if NETSTANDARD2_0 + var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); +#else + var isWindows = true; +#endif + if (isWindows) { - // ignored -- there's nothing we can do at this point, as EventLog is our "fallback" logger and if it fails, we're out of luck + const string eventLogName = "Application"; + const string eventLogSourceName = "New Relic .NET Agent"; + try + { + loggerConfiguration + .WriteTo.Logger(configuration => + { + configuration + .ExcludeAuditLog() + .WriteTo.EventLog( + source: eventLogSourceName, + logName: eventLogName, + restrictedToMinimumLevel: LogEventLevel.Warning, + outputTemplate: "{Level}: {Message}{NewLine}{Exception}", + manageEventSource: true + ); + }); + } + catch + { + // ignored -- there's nothing we can do at this point, as EventLog is our "fallback" logger and if it fails, we're out of luck + } } -#endif return loggerConfiguration; } @@ -197,11 +212,10 @@ private static LoggerConfiguration ConfigureFileSink(this LoggerConfiguration lo catch (Exception ex) { Log.Logger.Warning(ex, "Unexpected exception when configuring file sink."); -#if NETFRAMEWORK + // Fallback to the event log sink if we cannot setup a file logger. Log.Logger.Warning("Falling back to EventLog sink."); loggerConfiguration.ConfigureEventLogSink(); -#endif } return loggerConfiguration;