-
-
Notifications
You must be signed in to change notification settings - Fork 323
/
SerilogDataProvider.cs
133 lines (121 loc) · 4.54 KB
/
SerilogDataProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using System;
using Audit.Core;
using Audit.Serilog.Configuration;
using global::Serilog;
namespace Audit.Serilog.Providers
{
/// <summary>
/// Store Audit logs using Serilog.
/// </summary>
/// <remarks>
/// Settings:
/// Logger/LoggerBuilder: A way to obtain the Serilog ILog instance. Default is
/// LogManager.GetLogger(auditEvent.GetType()).
/// LogLevel/LogLevelBuilder: A way to obtain the log level for the audit events. Default is Error for exceptions and
/// Info for anything else.
/// LogBodyBuilder: A way to obtain the object to be logged. Default is the AuditEvent JSON including the EventId as a
/// custom field.
/// </remarks>
public class SerilogDataProvider : AuditDataProvider
{
/// <summary>
/// The Serilog ILog implementation to use
/// </summary>
public Setting<ILogger> Logger { get; set; }
/// <summary>
/// The Serilog Log Level to use
/// </summary>
public Setting<LogLevel?> LogLevel { get; set; }
/// <summary>
/// A function that given an audit event and an event id, returns the message to log
/// </summary>
public Func<AuditEvent, object, object> LogMessageBuilder { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="SerilogDataProvider" /> class.
/// </summary>
public SerilogDataProvider()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="SerilogDataProvider" /> class.
/// </summary>
/// <param name="config">Configurator instance.</param>
public SerilogDataProvider(Action<ISerilogConfigurator> config)
{
if (config == null)
{
return;
}
var logConfig = new SerilogConfigurator();
config.Invoke(logConfig);
Logger = logConfig._logger;
LogLevel = logConfig._logLevel;
LogMessageBuilder = logConfig._messageBuilder;
}
/// <summary>
/// Stores an event via Serilog.
/// </summary>
/// <param name="auditEvent">The audit event.</param>
/// <returns>Event Id.</returns>
public override object InsertEvent(AuditEvent auditEvent)
{
var eventId = Guid.NewGuid();
this.Log(auditEvent, eventId);
return eventId;
}
/// <summary>
/// Stores an event related to a previous event, via Serilog.
/// </summary>
/// <param name="eventId">The event id.</param>
/// <param name="auditEvent">The audit event.</param>
public override void ReplaceEvent(object eventId, AuditEvent auditEvent)
{
this.Log(auditEvent, eventId);
}
private ILogger GetLogger(AuditEvent auditEvent)
{
return this.Logger.GetValue(auditEvent) ?? global::Serilog.Log.ForContext(auditEvent.GetType());
}
private LogLevel GetLogLevel(AuditEvent auditEvent)
{
return this.LogLevel.GetValue(auditEvent) ??
(auditEvent.Environment?.Exception != null ? Serilog.LogLevel.Error : Serilog.LogLevel.Info);
}
private object GetLogObject(AuditEvent auditEvent, object eventId)
{
if (LogMessageBuilder == null)
{
if (eventId != null)
{
auditEvent.CustomFields["EventId"] = eventId;
}
return auditEvent.ToJson();
}
return LogMessageBuilder.Invoke(auditEvent, eventId);
}
private void Log(AuditEvent auditEvent, object eventId)
{
var logger = GetLogger(auditEvent);
LogLevel level = GetLogLevel(auditEvent);
var value = GetLogObject(auditEvent, eventId);
switch (level)
{
case Serilog.LogLevel.Debug:
logger.Debug("{Value}", value);
break;
case Serilog.LogLevel.Warn:
logger.Warning("{Value}", value);
break;
case Serilog.LogLevel.Error:
logger.Error("{Value}", value);
break;
case Serilog.LogLevel.Fatal:
logger.Fatal("{Value}", value);
break;
default:
logger.Information("{Value}", value);
break;
}
}
}
}