1
- using Exceptionless . Models ;
2
- using Microsoft . Extensions . Logging ;
3
- using System ;
1
+ using System ;
4
2
using System . Collections . Generic ;
3
+ using ExceptionlessLogLevel = Exceptionless . Logging . LogLevel ;
4
+ using Microsoft . Extensions . Logging ;
5
5
6
- namespace Exceptionless . Extensions . Logging
7
- {
8
- public class ExceptionlessLogger : ILogger
9
- {
10
- static readonly Dictionary < LogLevel , string > LOG_LEVELS = MapLogLevelsToExceptionlessNames ( ) ;
11
-
12
- static Dictionary < LogLevel , string > MapLogLevelsToExceptionlessNames ( )
13
- {
14
- Dictionary < LogLevel , string > mappings = new Dictionary < LogLevel , string > ( 7 ) ;
15
- mappings . Add ( LogLevel . Critical , global ::Exceptionless . Logging . LogLevel . Fatal . ToString ( ) ) ;
16
- mappings . Add ( LogLevel . Debug , global ::Exceptionless . Logging . LogLevel . Debug . ToString ( ) ) ;
17
- mappings . Add ( LogLevel . Error , global ::Exceptionless . Logging . LogLevel . Error . ToString ( ) ) ;
18
- mappings . Add ( LogLevel . Information , global ::Exceptionless . Logging . LogLevel . Info . ToString ( ) ) ;
19
- mappings . Add ( LogLevel . None , global ::Exceptionless . Logging . LogLevel . Off . ToString ( ) ) ;
20
- mappings . Add ( LogLevel . Trace , global ::Exceptionless . Logging . LogLevel . Trace . ToString ( ) ) ;
21
- mappings . Add ( LogLevel . Warning , global ::Exceptionless . Logging . LogLevel . Warn . ToString ( ) ) ;
22
-
23
- return mappings ;
24
- }
25
-
26
- ExceptionlessClient _Client ;
27
- string _Source ;
6
+ namespace Exceptionless . Extensions . Logging {
7
+ public class ExceptionlessLogger : ILogger {
8
+ private readonly ExceptionlessClient _client ;
9
+ private readonly string _source ;
28
10
29
11
/// <summary>
30
12
/// Initializes a new instance of the <see cref="ExceptionlessLogger"/> class.
31
13
/// </summary>
32
14
/// <param name="client">The <see cref="ExceptionlessClient"/> to be used by the logger.</param>
33
15
/// <param name="source">The source to tag events with, typically the category.</param>
34
- public ExceptionlessLogger ( ExceptionlessClient client , string source )
35
- {
36
- if ( client == null )
37
- throw new ArgumentNullException ( nameof ( client ) ) ;
38
-
39
- _Client = client ;
40
- _Source = source ;
16
+ public ExceptionlessLogger ( ExceptionlessClient client , string source ) {
17
+ _client = client ?? throw new ArgumentNullException ( nameof ( client ) ) ;
18
+ _source = source ;
41
19
}
42
20
21
+ /// <inheritdoc />
43
22
/// <summary>
44
23
/// Begins a logical operation scope.
45
24
/// </summary>The identifier for the scope.
46
25
/// <typeparam name="TState">The type of the state object.</typeparam>
47
26
/// <param name="state"></param>
48
- /// <returns>An <see cref="IDisposable"/> that ends the logical operation scope on dispose.</returns>
49
- public IDisposable BeginScope < TState > ( TState state )
50
- {
27
+ /// <returns>An <see cref="T:System.IDisposable" /> that ends the logical operation scope on dispose.</returns>
28
+ public IDisposable BeginScope < TState > ( TState state ) {
51
29
if ( state == null )
52
30
throw new ArgumentNullException ( nameof ( state ) ) ;
53
31
@@ -59,24 +37,29 @@ public IDisposable BeginScope<TState>(TState state)
59
37
object stateObj = state is string ? null : ( object ) state ;
60
38
61
39
// Log scope creation as an event so that there is a parent to tie events together
62
- ExceptionlessLoggingScope scope = new ExceptionlessLoggingScope ( description ) ;
40
+ var scope = new ExceptionlessLoggingScope ( description ) ;
63
41
LogScope ( scope , stateObj ) ;
64
42
65
43
// Add to stack to support nesting within execution context
66
44
ExceptionlessLoggingScope . Push ( scope ) ;
67
45
return scope ;
68
46
}
69
47
48
+ /// <inheritdoc />
70
49
/// <summary>
71
- /// Checks if the given <see cref="LogLevel"/> is enabled.
50
+ /// Checks if the given <see cref="T:Microsoft.Extensions.Logging. LogLevel" /> is enabled.
72
51
/// </summary>
73
52
/// <param name="logLevel">The level to be checked.</param>
74
53
/// <returns>Returns true if enabled.</returns>
75
- public bool IsEnabled ( LogLevel logLevel )
76
- {
77
- return true ;
54
+ public bool IsEnabled ( LogLevel logLevel ) {
55
+ if ( logLevel == LogLevel . None || ! _client . Configuration . IsValid )
56
+ return false ;
57
+
58
+ var minLogLevel = _client . Configuration . Settings . GetMinLogLevel ( _source ) ;
59
+ return logLevel . ToLogLevel ( ) >= minLogLevel ;
78
60
}
79
61
62
+ /// <inheritdoc />
80
63
/// <summary>
81
64
/// Writes a log entry.
82
65
/// </summary>
@@ -85,84 +68,80 @@ public bool IsEnabled(LogLevel logLevel)
85
68
/// <param name="eventId">Id of the event.</param>
86
69
/// <param name="state">The entry to be written. Can be also an object.</param>
87
70
/// <param name="exception">The exception related to this entry.</param>
88
- /// <param name="formatter">Function to create a <see cref="string"/> message of the <paramref name="state"/> and <paramref name="exception"/>.</param>
89
- public void Log < TState > ( LogLevel logLevel , EventId eventId , TState state , Exception exception , Func < TState , Exception , string > formatter )
90
- {
91
- // Create basic event from client
92
- EventBuilder eb = exception == null ? _Client . CreateEvent ( ) : _Client . CreateException ( exception ) ;
93
- eb . SetProperty ( Event . KnownDataKeys . Level , LOG_LEVELS [ logLevel ] ) ;
71
+ /// <param name="formatter">Function to create a <see cref="T:System.String" /> message of the <paramref name="state" /> and <paramref name="exception" />.</param>
72
+ public void Log < TState > ( LogLevel logLevel , EventId eventId , TState state , Exception exception , Func < TState , Exception , string > formatter ) {
73
+ if ( formatter == null )
74
+ throw new ArgumentNullException ( nameof ( formatter ) ) ;
94
75
95
- // Get formatted message
96
- eb . SetMessage ( formatter . Invoke ( state , exception ) ) ;
76
+ if ( ! IsEnabled ( logLevel ) )
77
+ return ;
97
78
98
- // Add category as source, if available
99
- if ( _Source != null )
100
- eb . SetSource ( _Source ) ;
79
+ string message = formatter ( state , exception ) ;
80
+ if ( String . IsNullOrEmpty ( message ) && exception == null )
81
+ return ;
82
+
83
+ var builder = exception == null ? _client . CreateLog ( _source , message , logLevel . ToLogLevel ( ) ) : _client . CreateException ( exception ) ;
84
+ builder . Target . Date = DateTimeOffset . Now ;
85
+
86
+ if ( ! String . IsNullOrEmpty ( message ) )
87
+ builder . SetMessage ( message ) ;
88
+
89
+ if ( exception != null )
90
+ builder . SetSource ( _source ) ;
101
91
102
92
// Add event id, if available
103
93
if ( eventId . Id != 0 )
104
- eb . SetProperty ( "Event Id " , eventId . Id ) ;
94
+ builder . SetProperty ( "EventId " , eventId . Id ) ;
105
95
106
96
// If within a scope, add scope's reference id
107
97
if ( ExceptionlessLoggingScope . Current != null )
108
- eb . SetEventReference ( "Parent" , ExceptionlessLoggingScope . Current . Id ) ;
98
+ builder . SetEventReference ( "Parent" , ExceptionlessLoggingScope . Current . Id ) ;
109
99
110
100
// The logging framework passes in FormattedLogValues, which implements IEnumerable<KeyValuePair<string, object>>;
111
101
// add each property and value as individual objects for proper visibility in Exceptionless
112
- IEnumerable < KeyValuePair < string , object > > stateProps = state as IEnumerable < KeyValuePair < string , object > > ;
113
- if ( stateProps != null )
114
- {
115
- foreach ( KeyValuePair < string , object > prop in stateProps )
116
- {
102
+ if ( state is IEnumerable < KeyValuePair < string , object > > stateProps ) {
103
+ foreach ( KeyValuePair < string , object > prop in stateProps ) {
117
104
// Logging the message template is superfluous
118
105
if ( prop . Key != "{OriginalFormat}" )
119
- eb . AddObject ( prop . Value , prop . Key ) ;
106
+ builder . AddObject ( prop . Value , prop . Key ) ;
120
107
}
121
- }
122
- // Otherwise, attach the entire object, using its type as the name
123
- else
124
- {
125
- eb . AddObject ( state ) ;
108
+ } else {
109
+ // Otherwise, attach the entire object, using its type as the name
110
+ builder . AddObject ( state ) ;
126
111
}
127
112
128
- // Add to client's queue
129
- eb . Submit ( ) ;
113
+ builder . Submit ( ) ;
130
114
}
131
115
132
116
/// <summary>
133
117
/// Writes a scope creation entry.
134
118
/// </summary>
135
119
/// <param name="newScope">The <see cref="ExceptionlessLoggingScope"/> being created.</param>
136
- private void LogScope ( ExceptionlessLoggingScope newScope , object state )
137
- {
138
- EventBuilder eb = _Client . CreateLog ( $ "Creating scope: { newScope . Description } .", global :: Exceptionless . Logging . LogLevel . Other ) ;
120
+ /// <param name=" state"></param>
121
+ private void LogScope ( ExceptionlessLoggingScope newScope , object state ) {
122
+ var builder = _client . CreateLog ( $ "Creating scope: { newScope . Description } .", ExceptionlessLogLevel . Other ) ;
139
123
140
124
// Set event reference id to that of scope object
141
- eb . SetReferenceId ( newScope . Id ) ;
125
+ builder . SetReferenceId ( newScope . Id ) ;
142
126
143
127
// If this is a nested scope, add parent's reference id
144
128
if ( ExceptionlessLoggingScope . Current != null )
145
- eb . SetEventReference ( "Parent" , ExceptionlessLoggingScope . Current . Id ) ;
129
+ builder . SetEventReference ( "Parent" , ExceptionlessLoggingScope . Current . Id ) ;
146
130
147
- if ( state != null )
148
- {
131
+ if ( state != null ) {
149
132
IEnumerable < KeyValuePair < string , object > > stateProps = state as IEnumerable < KeyValuePair < string , object > > ;
150
- if ( stateProps != null )
151
- {
152
- foreach ( KeyValuePair < string , object > prop in stateProps )
153
- {
133
+ if ( stateProps != null ) {
134
+ foreach ( KeyValuePair < string , object > prop in stateProps ) {
154
135
// Logging the message template is superfluous
155
136
if ( prop . Key != "{OriginalFormat}" )
156
- eb . AddObject ( prop . Value , prop . Key ) ;
137
+ builder . AddObject ( prop . Value , prop . Key ) ;
157
138
}
158
- }
159
- else
160
- {
161
- eb . AddObject ( state ) ;
139
+ } else {
140
+ builder . AddObject ( state ) ;
162
141
}
163
142
}
164
143
165
- eb . Submit ( ) ;
144
+ builder . Submit ( ) ;
166
145
}
167
146
}
168
- }
147
+ }
0 commit comments