66using System . Diagnostics . Tracing ;
77using System . Globalization ;
88using System . Linq ;
9+ using Microsoft . Extensions . Logging ;
910using Microsoft . IdentityModel . Abstractions ;
1011
1112namespace Microsoft . IdentityModel . Logging
@@ -42,6 +43,17 @@ internal static bool HeaderWritten
4243 set { _isHeaderWritten = value ; }
4344 }
4445
46+ /// <summary>
47+ /// Gets a boolean indicating whether logging is enabled at the specified LogLevel.
48+ /// </summary>
49+ /// <param name="logLevel">The log level</param>
50+ /// <param name="loggerContext">A <see cref="LoggerContext"/> that contains logging control including <see cref="ILogger"/>.</param>
51+ /// <returns><see langword="true"/> if logging is enabled at the specified level; otherwise, <see langword="false"/>.</returns>
52+ internal static bool IsEnabled ( LogLevel logLevel , LoggerContext loggerContext )
53+ {
54+ return loggerContext ? . Logger ? . IsEnabled ( logLevel ) ?? false ;
55+ }
56+
4557 /// <summary>
4658 /// Gets whether logging is enabled at the specified <see cref="EventLogLevel"/>."/>
4759 /// </summary>
@@ -269,7 +281,38 @@ public static Exception LogExceptionMessage(EventLevel eventLevel, Exception exc
269281
270282 EventLogLevel eventLogLevel = EventLevelToEventLogLevel ( eventLevel ) ;
271283 if ( Logger . IsEnabled ( eventLogLevel ) )
272- Logger . Log ( WriteEntry ( eventLogLevel , exception . InnerException , exception . Message , null ) ) ;
284+ Logger . Log ( WriteEntry ( eventLogLevel , exception . InnerException , exception . Message ) ) ;
285+
286+ return exception ;
287+ }
288+
289+ /// <summary>
290+ /// Logs an exception using the listeners that have been enabled.
291+ /// </summary>
292+ /// <param name="exception">The exception to log.</param>
293+ /// <param name="loggerContext">The <see cref="LoggerContext"/> contains information useful for logging and debugging.</param>
294+ public static Exception LogExceptionMessage ( Exception exception , LoggerContext loggerContext )
295+ {
296+ if ( exception == null )
297+ return null ;
298+
299+ LogExceptionMessage ( exception ) ;
300+
301+ if ( loggerContext ? . Logger == null )
302+ return exception ;
303+
304+ if ( ! loggerContext . Logger . IsEnabled ( LogLevel . Error ) )
305+ return exception ;
306+
307+ LogEntry entry = WriteEntry (
308+ EventLogLevel . Error ,
309+ exception . InnerException ,
310+ exception . Message ,
311+ loggerContext . CorrelationId ?? loggerContext . ActivityId . ToString ( ) ,
312+ exception . Message ,
313+ null ) ;
314+
315+ Log ( entry , loggerContext . Logger ) ;
273316
274317 return exception ;
275318 }
@@ -285,7 +328,33 @@ public static void LogInformation(string message, params object[] args)
285328 IdentityModelEventSource . Logger . WriteInformation ( message , args ) ;
286329
287330 if ( Logger . IsEnabled ( EventLogLevel . Informational ) )
288- Logger . Log ( WriteEntry ( EventLogLevel . Informational , null , message , args ) ) ;
331+ Logger . Log ( WriteEntry ( EventLogLevel . Informational , null , message , null , args ) ) ;
332+ }
333+
334+ /// <summary>
335+ /// Logs at the information level to the listeners that have been enabled.
336+ /// </summary>
337+ /// <param name="message">The log message.</param>
338+ /// <param name="loggerContext">A <see cref="LoggerContext"/> that contains logging control including <see cref="ILogger"/>.</param>
339+ /// <param name="args">An object array that contains zero or more objects to format.</param>
340+ public static void LogInformation ( string message , LoggerContext loggerContext , params object [ ] args )
341+ {
342+ LogInformation ( message , args ) ;
343+
344+ if ( loggerContext ? . Logger == null )
345+ return ;
346+
347+ if ( ! loggerContext . Logger . IsEnabled ( LogLevel . Information ) )
348+ return ;
349+
350+ LogEntry entry = WriteEntry (
351+ EventLevelToEventLogLevel ( EventLevel . Informational ) ,
352+ null ,
353+ message ,
354+ loggerContext . CorrelationId ?? loggerContext . ActivityId . ToString ( ) ,
355+ null ) ;
356+
357+ Log ( entry , loggerContext . Logger ) ;
289358 }
290359
291360 /// <summary>
@@ -299,7 +368,33 @@ public static void LogVerbose(string message, params object[] args)
299368 IdentityModelEventSource . Logger . WriteVerbose ( message , args ) ;
300369
301370 if ( Logger . IsEnabled ( EventLogLevel . Verbose ) )
302- Logger . Log ( WriteEntry ( EventLogLevel . Verbose , null , message , args ) ) ;
371+ Logger . Log ( WriteEntry ( EventLogLevel . Verbose , null , message , null , args ) ) ;
372+ }
373+
374+ /// <summary>
375+ /// Logs at the verbose level to the listeners that have been enabled.
376+ /// </summary>
377+ /// <param name="message">The log message.</param>
378+ /// <param name="loggerContext">A <see cref="LoggerContext"/> that contains logging control including <see cref="ILogger"/>.</param>
379+ /// <param name="args">An object array that contains zero or more objects to format.</param>
380+ public static void LogVerbose ( string message , LoggerContext loggerContext , params object [ ] args )
381+ {
382+ LogVerbose ( message , args ) ;
383+
384+ if ( loggerContext ? . Logger == null )
385+ return ;
386+
387+ if ( ! loggerContext . Logger . IsEnabled ( LogLevel . Debug ) )
388+ return ;
389+
390+ LogEntry entry = WriteEntry (
391+ EventLogLevel . Verbose ,
392+ null ,
393+ message ,
394+ loggerContext . CorrelationId ?? loggerContext . ActivityId . ToString ( ) ,
395+ null ) ;
396+
397+ Log ( entry , loggerContext . Logger ) ;
303398 }
304399
305400 /// <summary>
@@ -313,7 +408,43 @@ public static void LogWarning(string message, params object[] args)
313408 IdentityModelEventSource . Logger . WriteWarning ( message , args ) ;
314409
315410 if ( Logger . IsEnabled ( EventLogLevel . Warning ) )
316- Logger . Log ( WriteEntry ( EventLogLevel . Warning , null , message , args ) ) ;
411+ Logger . Log ( WriteEntry ( EventLogLevel . Warning , null , message , null , args ) ) ;
412+ }
413+
414+ /// <summary>
415+ /// Logs at the warning level to the listeners that have been enabled.
416+ /// </summary>
417+ /// <param name="message">The log message.</param>
418+ /// <param name="loggerContext">A <see cref="LoggerContext"/> that contains logging control including <see cref="ILogger"/>.</param>
419+ public static void LogWarning ( string message , LoggerContext loggerContext )
420+ {
421+ LogWarning ( message , loggerContext , null ) ;
422+ }
423+
424+ /// <summary>
425+ /// Logs at the warning level to the listeners that have been enabled.
426+ /// </summary>
427+ /// <param name="message">The log message.</param>
428+ /// <param name="loggerContext">A <see cref="LoggerContext"/> that contains logging control including <see cref="ILogger"/>.</param>
429+ /// <param name="args">An object array that contains zero or more objects to format.</param>
430+ public static void LogWarning ( string message , LoggerContext loggerContext , params object [ ] args )
431+ {
432+ LogWarning ( message , args ) ;
433+
434+ if ( loggerContext ? . Logger == null )
435+ return ;
436+
437+ if ( ! loggerContext . Logger . IsEnabled ( LogLevel . Warning ) )
438+ return ;
439+
440+ LogEntry entry = WriteEntry (
441+ EventLogLevel . Warning ,
442+ null ,
443+ message ,
444+ loggerContext . CorrelationId ?? loggerContext . ActivityId . ToString ( ) ,
445+ null ) ;
446+
447+ Log ( entry , loggerContext . Logger ) ;
317448 }
318449
319450 /// <summary>
@@ -337,7 +468,7 @@ public static void LogWarning(string message, params object[] args)
337468
338469 EventLogLevel eventLogLevel = EventLevelToEventLogLevel ( eventLevel ) ;
339470 if ( Logger . IsEnabled ( eventLogLevel ) )
340- Logger . Log ( WriteEntry ( eventLogLevel , innerException , message , null ) ) ;
471+ Logger . Log ( WriteEntry ( eventLogLevel , innerException , message ) ) ;
341472
342473 if ( innerException != null )
343474 {
@@ -487,7 +618,29 @@ public static object MarkAsUnsafeSecurityArtifact(object arg, Func<object, strin
487618 /// <param name="innerException"><see cref="Exception"/></param>
488619 /// <param name="message">The log message.</param>
489620 /// <param name="args">An object array that contains zero or more objects to format.</param>
490- private static LogEntry WriteEntry ( EventLogLevel eventLogLevel , Exception innerException , string message , params object [ ] args )
621+ private static LogEntry WriteEntry (
622+ EventLogLevel eventLogLevel ,
623+ Exception innerException ,
624+ string message ,
625+ params object [ ] args )
626+ {
627+ return WriteEntry ( eventLogLevel , innerException , message , ( string ) null , args ) ;
628+ }
629+
630+ /// <summary>
631+ /// Creates a <see cref="LogEntry"/> by using the provided event level, exception argument, string argument and arguments list.
632+ /// </summary>
633+ /// <param name="eventLogLevel"><see cref="EventLogLevel"/></param>
634+ /// <param name="innerException"><see cref="Exception"/></param>
635+ /// <param name="message">The log message.</param>
636+ /// <param name="correlationId">The CorrelationId is set by caller to coordinate logs between services.</param>
637+ /// <param name="args">An object array that contains zero or more objects to format.</param>
638+ private static LogEntry WriteEntry (
639+ EventLogLevel eventLogLevel ,
640+ Exception innerException ,
641+ string message ,
642+ string correlationId ,
643+ params object [ ] args )
491644 {
492645 if ( string . IsNullOrEmpty ( message ) )
493646 return null ;
@@ -505,23 +658,72 @@ private static LogEntry WriteEntry(EventLogLevel eventLogLevel, Exception innerE
505658
506659 LogEntry entry = new LogEntry ( ) ;
507660 entry . EventLogLevel = eventLogLevel ;
661+ entry . CorrelationId = correlationId ;
508662
509663 // Prefix header (library version, DateTime, whether PII is ON/OFF) to the first message logged by Wilson.
510664 if ( ! _isHeaderWritten )
511665 {
512- string headerMessage = string . Format ( CultureInfo . InvariantCulture , "Microsoft.IdentityModel Version: {0}. Date {1}. {2}" ,
513- typeof ( IdentityModelEventSource ) . Assembly . GetName ( ) . Version . ToString ( ) ,
514- DateTime . UtcNow ,
515- IdentityModelEventSource . ShowPII ? _piiOnLogMessage : _piiOffLogMessage ) ;
516-
517- entry . Message = headerMessage + Environment . NewLine + message ;
666+ entry . Message = ( correlationId == null ) ?
667+ string . Format (
668+ CultureInfo . InvariantCulture ,
669+ "Microsoft.IdentityModel Version: {0}. Date {1}. {2} Message: {3}" ,
670+ typeof ( IdentityModelEventSource ) . Assembly . GetName ( ) . Version . ToString ( ) ,
671+ DateTime . UtcNow ,
672+ IdentityModelEventSource . ShowPII ? _piiOnLogMessage : _piiOffLogMessage ,
673+ Environment . NewLine + message ) :
674+ string . Format (
675+ CultureInfo . InvariantCulture ,
676+ "Microsoft.IdentityModel Version: {0}. Date {1}. {2} Message: {3}, CorrelationId: {4}." ,
677+ typeof ( IdentityModelEventSource ) . Assembly . GetName ( ) . Version . ToString ( ) ,
678+ DateTime . UtcNow ,
679+ IdentityModelEventSource . ShowPII ? _piiOnLogMessage : _piiOffLogMessage ,
680+ Environment . NewLine + message ,
681+ correlationId ) ;
518682
519683 _isHeaderWritten = true ;
520684 }
521685 else
522- entry . Message = message ;
686+ entry . Message = ( correlationId == null ) ?
687+ message :
688+ string . Format ( CultureInfo . InvariantCulture , "{0}, CorrelationId: {1}." , message , correlationId ) ;
523689
524690 return entry ;
525691 }
692+
693+ private static void Log ( LogEntry entry , ILogger logger )
694+ {
695+ if ( entry != null )
696+ {
697+ switch ( entry . EventLogLevel )
698+ {
699+ case EventLogLevel . Critical :
700+ logger . LogCritical ( entry . Message ) ;
701+ break ;
702+
703+ case EventLogLevel . Error :
704+ logger . LogError ( entry . Message ) ;
705+ break ;
706+
707+ case EventLogLevel . Warning :
708+ logger . LogWarning ( entry . Message ) ;
709+ break ;
710+
711+ case EventLogLevel . Informational :
712+ logger . LogInformation ( entry . Message ) ;
713+ break ;
714+
715+ case EventLogLevel . Verbose :
716+ logger . LogDebug ( entry . Message ) ;
717+ break ;
718+
719+ case EventLogLevel . LogAlways :
720+ logger . LogTrace ( entry . Message ) ;
721+ break ;
722+
723+ default :
724+ break ;
725+ }
726+ }
727+ }
526728 }
527729}
0 commit comments