Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
TODO
- make custom autoselect when just AddLogFormatter
- make API renames: ConsoleLogFormatterX
- const string on XFormatter.Name rather than getter
- overall perf check
- perf on compact and json (just for demo now)
  • Loading branch information
maryamariyan committed May 15, 2020
commit 881c00227fc71f90f15608f79219eaac4d13b9cb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ public ConsoleLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor<Micros
public void Dispose() { }
public void SetScopeProvider(Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { }
}
public readonly partial struct ConsoleMessage
{
public readonly System.ConsoleColor? Background;
public readonly string Content;
public readonly System.ConsoleColor? Foreground;
public ConsoleMessage(string message, System.ConsoleColor? background = default(System.ConsoleColor?), System.ConsoleColor? foreground = default(System.ConsoleColor?)) { throw null; }
}
public partial class DefaultLogFormatter : Microsoft.Extensions.Logging.Console.ILogFormatter, System.IDisposable
{
public DefaultLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Extensions.Logging.Console.DefaultLogFormatterOptions> options) { }
Expand Down Expand Up @@ -96,15 +103,9 @@ public JsonLogFormatterOptions() { }
}
public readonly partial struct LogMessageEntry
{
public readonly System.ConsoleColor? LevelBackground;
public readonly System.ConsoleColor? LevelForeground;
public readonly string LevelString;
public readonly bool LogAsError;
public readonly string Message;
public readonly System.ConsoleColor? MessageColor;
public readonly string TimeStamp;
public readonly System.Action<Microsoft.Extensions.Logging.Console.IConsole> WriteCallback;
public LogMessageEntry(string message, string timeStamp = null, string levelString = null, System.ConsoleColor? levelBackground = default(System.ConsoleColor?), System.ConsoleColor? levelForeground = default(System.ConsoleColor?), System.ConsoleColor? messageColor = default(System.ConsoleColor?), bool logAsError = false, System.Action<Microsoft.Extensions.Logging.Console.IConsole> writeCallback = null) { throw null; }
public readonly Microsoft.Extensions.Logging.Console.ConsoleMessage[] Messages;
public LogMessageEntry(Microsoft.Extensions.Logging.Console.ConsoleMessage[] messages, bool logAsError = false) { throw null; }
}
public partial class SystemdLogFormatter : Microsoft.Extensions.Logging.Console.ILogFormatter, System.IDisposable
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,14 @@ public virtual void EnqueueMessage(LogMessageEntry message)
}

// for testing
internal virtual void WriteMessage(LogMessageEntry message)
internal virtual void WriteMessage(LogMessageEntry entry)
{
var console = message.LogAsError ? ErrorConsole : Console;
// is giving user control on this thread over how long the output thread takes to write to console - something to consider
message.WriteCallback(console);
var console = entry.LogAsError ? ErrorConsole : Console;
foreach (var message in entry.Messages)
{
console.Write(message.Content, message.Background, message.Foreground);
}
console.Flush();
}

private void ProcessLogQueue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ internal class CompactLogFormatter : ILogFormatter, IDisposable
// ConsoleColor does not have a value to specify the 'Default' color
private readonly ConsoleColor? DefaultConsoleColor = null;

[ThreadStatic]
private static StringBuilder _logBuilder;

static CompactLogFormatter()
{
var logLevelString = GetLogLevelString(LogLevel.Information);
Expand Down Expand Up @@ -69,41 +66,36 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st

private LogMessageEntry FormatHelper<TState>(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider, TState scope)
{
List<Message> msgs = new List<Message>();
// todo fix later:
var logBuilder = _logBuilder;
_logBuilder = null;

if (logBuilder == null)
{
logBuilder = new StringBuilder();
}

// Example:
// INFO: ConsoleApp.Program[10]
// Request received
var messages = new List<ConsoleMessage>();

var logLevelColors = GetLogLevelConsoleColors(logLevel);
var logLevelString = GetLogLevelString(logLevel);
// category and event id
logBuilder.Append(_loglevelPadding);
logBuilder.Append(logName);
logBuilder.Append("[");
logBuilder.Append(eventId);
logBuilder.Append("]");
// logBuilder.AppendLine("]");

msgs.Add(new Message($"{logName}[{eventId}] ", null, null));
string timestamp = null;
var timestampFormat = FormatterOptions.TimestampFormat;
if (timestampFormat != null)
{
var dateTime = GetCurrentDateTime();
timestamp = dateTime.ToString(timestampFormat);
}
if (timestamp != null)
{
messages.Add(new ConsoleMessage(timestamp + " ", null, null));
}
if (logLevelString != null)
{
messages.Add(new ConsoleMessage(logLevelString,logLevelColors.Background, logLevelColors.Foreground));
}

messages.Add(new ConsoleMessage($"{logName}[{eventId}] ", null, null));
string originalFormat = null;
int count = 0;

if (scope != null)
{
logBuilder.Append(_messagePadding);
if (scope is IReadOnlyList<KeyValuePair<string, object>> kvpsx)
{
var strings = new List<KeyValuePair<string, object>>();
logBuilder.Append(" -> ");
foreach (var kvp in kvpsx)
{
if (kvp.Key.Contains("{OriginalFormat}"))
Expand All @@ -112,10 +104,7 @@ private LogMessageEntry FormatHelper<TState>(LogLevel logLevel, string logName,
}
else
{
//count++;
strings.Add(kvp);
logBuilder.Append(kvp.Value.ToString());
logBuilder.Append(", ");
}
}
int prevIndex = 0;
Expand All @@ -129,13 +118,10 @@ private LogMessageEntry FormatHelper<TState>(LogLevel logLevel, string logName,
if (curIndex != -1)
{
var curString = originalFormat.Substring(prevIndex, curIndex - prevIndex);
msgs.Add(new Message(curString, null, null));
msgs.Add(new Message(strings.ElementAt(count).Value.ToString(), null, ConsoleColor.Cyan));
messages.Add(new ConsoleMessage(curString, null, null));
messages.Add(new ConsoleMessage(strings.ElementAt(count).Value.ToString(), null, ConsoleColor.Cyan));
prevIndex += curIndex + strings.ElementAt(count).Key.Length + 2;
count++;
//strings.Add(kvp.Value.ToString());
logBuilder.Append(kvp.Value.ToString());
logBuilder.Append(", ");
}
}
}
Expand All @@ -144,7 +130,6 @@ private LogMessageEntry FormatHelper<TState>(LogLevel logLevel, string logName,
else if (scope is IReadOnlyList<KeyValuePair<string, string>> kvps)
{
var strings = new List<KeyValuePair<string, string>>();
logBuilder.Append(" -> ");
foreach (var kvp in kvps)
{
if (kvp.Key.Contains("{OriginalFormat}"))
Expand All @@ -153,10 +138,7 @@ private LogMessageEntry FormatHelper<TState>(LogLevel logLevel, string logName,
}
else
{
//count++;
strings.Add(kvp);
logBuilder.Append(kvp.Value);
logBuilder.Append(", ");
}
}
int prevIndex = 0;
Expand All @@ -170,142 +152,46 @@ private LogMessageEntry FormatHelper<TState>(LogLevel logLevel, string logName,
if (curIndex != -1)
{
var curString = originalFormat.Substring(prevIndex, curIndex - prevIndex);
msgs.Add(new Message(curString, null, null));
msgs.Add(new Message(strings.ElementAt(count).Value, null, ConsoleColor.Cyan));
messages.Add(new ConsoleMessage(curString, null, null));
messages.Add(new ConsoleMessage(strings.ElementAt(count).Value, null, ConsoleColor.Cyan));
prevIndex += curIndex + strings.ElementAt(count).Key.Length + 2;
count++;
logBuilder.Append(kvp.Value);
logBuilder.Append(", ");
}
}
}
}
}
else
{
logBuilder.Append("-> ");
logBuilder.Append(scope.ToString());
}
}

if (!string.IsNullOrEmpty(message))
{
// message
logBuilder.Append(_messagePadding);

var len = logBuilder.Length;
logBuilder.AppendLine(message);
if (originalFormat == null)
{
msgs.Add(new Message(message, null, null));
messages.Add(new ConsoleMessage(message, null, null));
}
else if (count == 0)
{
msgs.Add(new Message(originalFormat, null, null));
messages.Add(new ConsoleMessage(originalFormat, null, null));
}
}

// scope information
msgs.Add(new Message(" ", null, null));
GetScopeInformation(logBuilder, scopeProvider, msgs);
messages.Add(new ConsoleMessage(" ", null, null));
GetScopeInformation(scopeProvider, messages);

// Example:
// System.InvalidOperationException
// at Namespace.Class.Function() in File:line X
if (exception != null)
{
// exception message
logBuilder.Append(exception.ToString());
msgs.Add(new Message(" ", null, null));
msgs.Add(new Message(exception.ToString(), null, null));
// logBuilder.AppendLine(exception.ToString());
}

string timestamp = null;
var timestampFormat = FormatterOptions.TimestampFormat;
if (timestampFormat != null)
{
var dateTime = GetCurrentDateTime();
timestamp = dateTime.ToString(timestampFormat);
messages.Add(new ConsoleMessage(" ", null, null));
messages.Add(new ConsoleMessage(exception.ToString(), null, null));
// TODO: confirm exception message all in one line?
}

var formattedMessage = logBuilder.ToString();
logBuilder.Clear();
if (logBuilder.Capacity > 1024)
{
logBuilder.Capacity = 1024;
}
_logBuilder = logBuilder;

return new LogMessageEntry(
message: formattedMessage,
timeStamp: timestamp,
levelString: logLevelString,
levelBackground: logLevelColors.Background,
levelForeground: logLevelColors.Foreground,
messageColor: DefaultConsoleColor,
logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold,
writeCallback : console =>
{
if (timestamp != null || logLevelString != null)
{
console.Write("[", null, null);

if (timestamp != null)
{
console.Write(timestamp, null, null);
console.Write(" ", null, null);
}
if (logLevelString != null)
{
console.Write(logLevelString, logLevelColors.Background, logLevelColors.Foreground);
console.Write("", null, null);
}
console.Write("] ", null, null);
}

if (msgs.Count > 0)
{
foreach (var item in msgs)
{
console.Write(item.Content, item.Background, item.Foreground);
}
}

//console.Write(formattedMessage, DefaultConsoleColor, DefaultConsoleColor);
console.WriteLine(string.Empty, DefaultConsoleColor, DefaultConsoleColor);
console.Flush();
}
messages: messages.ToArray(),
logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold
);
}

internal struct LogEntry
{
internal LogEntry(Action<IConsole> action, Message[] messages, bool logAsError)
{
Messages = messages;
WriteCallback = action;
LogAsError = logAsError;
}

internal Message[] Messages;
internal Action<IConsole> WriteCallback;
internal bool LogAsError;
}

internal struct Message
{
internal Message(string message, ConsoleColor? background, ConsoleColor? foreground)
{
Content = message;
Background = background;
Foreground = foreground;
}
internal string Content;
internal ConsoleColor? Background;
internal ConsoleColor? Foreground;
}

private DateTime GetCurrentDateTime()
{
return FormatterOptions.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now;
Expand Down Expand Up @@ -360,34 +246,17 @@ private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel)
}
}

private void GetScopeInformation(StringBuilder stringBuilder, IExternalScopeProvider scopeProvider, List<Message> msgs)
private void GetScopeInformation(IExternalScopeProvider scopeProvider, List<ConsoleMessage> messages)
{
if (FormatterOptions.IncludeScopes && scopeProvider != null)
{
var initialLength = stringBuilder.Length;

scopeProvider.ForEachScope((scope, state) =>
{
var (builder, paddAt, messages) = state;
var padd = paddAt == builder.Length;
if (padd)
{
//messages.Add(new Message(_messagePadding, null, null));
builder.Append(_messagePadding);
}
messages.Add(new Message("=> ", null, null));
messages.Add(new Message(scope.ToString(), null, ConsoleColor.DarkGray));
messages.Add(new Message(" ", null, null));
builder.Append("=> ");
builder.Append(scope);
builder.Append(" ");

}, (stringBuilder, initialLength, msgs));
state.Add(new ConsoleMessage("=> ", null, null));
state.Add(new ConsoleMessage(scope.ToString(), null, ConsoleColor.DarkGray));
state.Add(new ConsoleMessage(" ", null, null));

if (stringBuilder.Length > initialLength)
{
// stringBuilder.AppendLine();
}
}, messages);
}
}

Expand Down
Loading