private void QueueMessage(LogEventDetails message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } // If the message is to be evaluated when it's actually logged (which may be in the future), as opposed to when it's queued (which is right now) // the push it straight onto the queue. Or, if the content is a string and not a lazily-evaluating Func then we can also queue it immediately. if ((MessageEvaluationBehaviour == MessageEvaluationBehaviourOptions.EvaluateWhenLogged) || (message.ContentGenerator == null)) { _messages.Enqueue(message); return; } // If the message is to be evaluated when queued (ie. right now) then we need to evaulate the ContentGenerator. This will be desirable if there // is any content that is time dependent (eg. "time to complete = {x}ms") or in cases where there are any references that are required by the // message evaluation that might be disposed of between now and when the message is recorded. Note: Just because the message content is being // evaluated immediately doesn't negate the benefit of a content generator delegate, there could be relative-expensive-to-log messages that // should only be written away in debug mode, which case a FilteredLogger might wrap a ThrottlingLogger instance so that the messages are only // evaluated if Debug-level messages are allowed through the filter. string messageContents; try { messageContents = message.ContentGenerator(); // We know that ContentGenerator is non-null (we checked for a null reference above) } catch { if (IndividualLogEntryErrorBehaviour == ErrorBehaviourOptions.ThrowException) { throw; } return; } _messages.Enqueue( new LogEventDetails( message.LogLevel, message.LogDate, message.ManagedThreadId, messageContents, message.OptionalException ) ); }
private static string FormatMessage(LogEventDetails message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } var detailedContent = new StringBuilder(); detailedContent.AppendFormat("[{0}] [Thread{1}] ", message.LogDate.ToString("yyyy-MM-dd HH:mm:ss.fff"), message.ManagedThreadId); if (message.LogLevel != LogLevel.Info) { // Don't bother displaying the text "Info", it's redundant (Debug, Warning or Error are useful content, though) detailedContent.AppendFormat("[{0}] ", message.LogLevel.ToString()); } var content = message.Content ?? message.ContentGenerator(); if (string.IsNullOrWhiteSpace(content)) { if (message.OptionalException == null) { detailedContent.Append("{Empty Message}"); } } else { detailedContent.Append(content); } if (message.OptionalException != null) { if (!string.IsNullOrWhiteSpace(content)) { detailedContent.Append(" - "); } detailedContent.Append(message.OptionalException.ToString()); } return(detailedContent.ToString()); }