Skip to content

Commit cdac8b7

Browse files
authored
feat: Enable startup logging to Event Log for all applications on Windows. (#1969)
1 parent f4658ed commit cdac8b7

File tree

2 files changed

+43
-28
lines changed

2 files changed

+43
-28
lines changed

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
4444
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
4545
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" />
46+
<PackageReference Include="Serilog.Sinks.EventLog" Version="3.1.0" />
4647
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
4748
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
4849
<PackageReference Include="ILRepack" Version="2.0.16" />
@@ -60,7 +61,6 @@
6061
<PackageReference Include="Grpc" Version="2.46.6" />
6162
<PackageReference Include="Grpc.Core" Version="2.46.6" />
6263
<PackageReference Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" />
63-
<PackageReference Include="Serilog.Sinks.EventLog" Version="3.1.0" />
6464
</ItemGroup>
6565

6666
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
@@ -129,13 +129,14 @@
129129
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog.Sinks.Async'" />
130130
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog.Sinks.Console'" />
131131
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog.Sinks.Debug'" />
132+
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog.Sinks.EventLog'" />
132133
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'Serilog.Sinks.File'" />
133134
<ILRepackInclude Include="@(PossibleRefsForILRepack)" Condition="'%(FileName)' == 'ICSharpCode.SharpZipLib'" />
134135
</ItemGroup>
135136

136137
<PropertyGroup>
137138
<ILRepackIncludeCount Condition="'$(TargetFramework)' == 'net462'">20</ILRepackIncludeCount>
138-
<ILRepackIncludeCount Condition="'$(TargetFramework)' == 'netstandard2.0'">16</ILRepackIncludeCount>
139+
<ILRepackIncludeCount Condition="'$(TargetFramework)' == 'netstandard2.0'">17</ILRepackIncludeCount>
139140
</PropertyGroup>
140141

141142
<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/LoggerBootstrapper.cs

+40-26
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
using Logger = NewRelic.Agent.Core.Logging.Logger;
1212
using NewRelic.Agent.Core.Logging;
1313
using Serilog.Templates;
14-
#if NETFRAMEWORK
1514
using Serilog.Events;
15+
#if NETSTANDARD2_0
16+
using System.Runtime.InteropServices;
1617
#endif
1718

1819
namespace NewRelic.Agent.Core
@@ -107,35 +108,49 @@ private static LoggerConfiguration ConfigureInMemoryLogSink(this LoggerConfigura
107108
}
108109

109110
/// <summary>
110-
/// Add the Event Log sink if running on .NET Framework
111+
/// Configure an Event Log sink if running on Windows. Logs messages at Warning level and above. Intended for
112+
/// use during bootstrapping and as a fallback if the file logging sink can't be created.
113+
///
114+
/// The Agent will create the event log source if it doesn't exist *and* if the app is running with
115+
/// administrator privileges. Otherwise, it will silently do nothing.
116+
///
117+
/// It is possible to manually create the event log source in an elevated Powershell window:
118+
/// New-EventLog -LogName "Application" -Source "New Relic .NET Agent"
119+
///
111120
/// </summary>
112121
/// <param name="loggerConfiguration"></param>
113122
private static LoggerConfiguration ConfigureEventLogSink(this LoggerConfiguration loggerConfiguration)
114123
{
115-
#if NETFRAMEWORK
116-
const string eventLogName = "Application";
117-
const string eventLogSourceName = "New Relic .NET Agent";
118-
try
119-
{
120-
loggerConfiguration
121-
.WriteTo.Logger(configuration =>
122-
{
123-
configuration
124-
.ExcludeAuditLog()
125-
.WriteTo.EventLog(
126-
source: eventLogSourceName,
127-
logName: eventLogName,
128-
restrictedToMinimumLevel: LogEventLevel.Warning,
129-
outputTemplate: "{Level}: {Message}{NewLine}{Exception}",
130-
manageEventSource: true // Serilog will create the event source if it doesn't exist *and* if the app is running with admin privileges
131-
);
132-
});
133-
}
134-
catch
124+
#if NETSTANDARD2_0
125+
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
126+
#else
127+
var isWindows = true;
128+
#endif
129+
if (isWindows)
135130
{
136-
// 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
131+
const string eventLogName = "Application";
132+
const string eventLogSourceName = "New Relic .NET Agent";
133+
try
134+
{
135+
loggerConfiguration
136+
.WriteTo.Logger(configuration =>
137+
{
138+
configuration
139+
.ExcludeAuditLog()
140+
.WriteTo.EventLog(
141+
source: eventLogSourceName,
142+
logName: eventLogName,
143+
restrictedToMinimumLevel: LogEventLevel.Warning,
144+
outputTemplate: "{Level}: {Message}{NewLine}{Exception}",
145+
manageEventSource: true
146+
);
147+
});
148+
}
149+
catch
150+
{
151+
// 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
152+
}
137153
}
138-
#endif
139154
return loggerConfiguration;
140155
}
141156

@@ -197,11 +212,10 @@ private static LoggerConfiguration ConfigureFileSink(this LoggerConfiguration lo
197212
catch (Exception ex)
198213
{
199214
Log.Logger.Warning(ex, "Unexpected exception when configuring file sink.");
200-
#if NETFRAMEWORK
215+
201216
// Fallback to the event log sink if we cannot setup a file logger.
202217
Log.Logger.Warning("Falling back to EventLog sink.");
203218
loggerConfiguration.ConfigureEventLogSink();
204-
#endif
205219
}
206220

207221
return loggerConfiguration;

0 commit comments

Comments
 (0)