Skip to content

Commit

Permalink
Update to latest (#4028)
Browse files Browse the repository at this point in the history
Co-authored-by: Martin Taillefer <[email protected]>
  • Loading branch information
geeknoid and Martin Taillefer authored Jun 2, 2023
1 parent 5881e19 commit a5738f6
Show file tree
Hide file tree
Showing 10 changed files with 274 additions and 279 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,11 @@ public LogFormatter(IOptions<LogFormatterOptions> options,
_theme = Throw.IfMemberNull(theme, theme.Value);
}

public void Write(LogEntry<LogEntryCompositeState> logEntry,
IExternalScopeProvider? scopeProvider,
TextWriter textWriter)
public void Write(LogEntry<LogEntryCompositeState> logEntry, TextWriter textWriter)
{
_ = Throw.IfNull(scopeProvider);

var writer = Throw.IfNull(textWriter);
var message = logEntry.Formatter?.Invoke(logEntry.State, logEntry.Exception);

if (_options.IncludeScopes)
{
if (WriteScopes(writer, scopeProvider))
{
writer.WriteLine();
}
}

if (_options.IncludeTimestamp)
{
WriteTimestamp(writer);
Expand Down Expand Up @@ -99,39 +87,23 @@ public void Write(LogEntry<LogEntryCompositeState> logEntry,
WriteException(writer, logEntry.Exception);
writer.WriteLine();
}
}

public void Dispose()
{
// Nothing to dispose.
}

internal bool WriteScopes(TextWriter writer, IExternalScopeProvider scopeProvider)
{
var isOneOrMultipleScopes = false;
var writeScope = WriteScope;

void WriteScope(object? scope, TextWriter state)
if (_options.IncludeDimensions && logEntry.State.State != null)
{
if (!isOneOrMultipleScopes)
foreach (var kvp in logEntry.State.State)
{
// Unfortunately there is no way how to know upfront if there
// is any scope to iterate over, so formatting has to be done
// from within the for each loop..
state.WriteLine();
isOneOrMultipleScopes = true;
if (kvp.Key != LoggingConsoleExporter.OriginalFormat)
{
writer.Colorize(" {0}={1}", _theme.Dimensions, kvp.Key, kvp.Value?.ToString());
writer.WriteLine();
}
}
else
{
writer.WriteSpace();
}

writer.Colorize("{{0}}", _theme.Dimmed, scope);
}
}

scopeProvider.ForEachScope(writeScope, writer);

return isOneOrMultipleScopes;
public void Dispose()
{
// Nothing to dispose.
}

internal void WriteTimestamp(TextWriter writer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,13 @@ public LogFormatterOptions()
/// Default set to <see langword="true"/>.
/// </remarks>
public bool IncludeExceptionStacktrace { get; set; } = true;

/// <summary>
/// Gets or sets a value indicating whether to display dimensions.
/// </summary>
/// <remarks>
/// Default set to <see langword="false"/>.
/// </remarks>
public bool IncludeDimensions { get; set; }
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ internal sealed class LogFormatterTheme
/// </summary>
/// <remarks>Default is <see cref="Colors.DarkRedOnNone"/>.</remarks>
public ColorSet ExceptionStackTrace { get; set; } = Colors.DarkRedOnNone;

/// <summary>
/// Gets or sets a value indicating what color to use for dimensions.
/// </summary>
/// <remarks>Default is <see cref="Colors.DarkGreenOnNone"/>.</remarks>
public ColorSet Dimensions { get; set; } = Colors.DarkGreenOnNone;
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@
using Microsoft.Shared.Pools;
#endif

using System.IO;
using OpenTelemetry;
using OpenTelemetry.Logs;

#if NET5_0_OR_GREATER
using System.IO;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Telemetry.Console.Internal;
using Microsoft.Shared.Diagnostics;
using MSOptions = Microsoft.Extensions.Options;
#endif

Expand All @@ -30,36 +28,39 @@ namespace Microsoft.Extensions.Telemetry.Console;
[SuppressMessage("Major Code Smell", "S106:Standard outputs should not be used directly to log anything", Justification = "We need to use here console logging.")]
internal sealed class LoggingConsoleExporter : BaseExporter<LogRecord>
{
private const string OriginalFormat = "{OriginalFormat}";
internal const string OriginalFormat = "{OriginalFormat}";

#if NET5_0_OR_GREATER
private readonly LogFormatter _consoleFormatter;
private readonly LoggingConsoleOptions _formatterOptions;

public LoggingConsoleExporter(MSOptions.IOptions<LoggingConsoleOptions> consoleLogFormatterOptions)
public LoggingConsoleExporter(MSOptions.IOptions<LoggingConsoleOptions> loggingConsoleOptions)
{
var formatterOptions = Throw.IfNullOrMemberNull(consoleLogFormatterOptions, consoleLogFormatterOptions?.Value);
_formatterOptions = loggingConsoleOptions.Value;

_consoleFormatter = new LogFormatter(
MSOptions.Options.Create(
new LogFormatterOptions
{
IncludeScopes = formatterOptions.IncludeScopes,
IncludeCategory = formatterOptions.IncludeCategory,
IncludeExceptionStacktrace = formatterOptions.IncludeExceptionStacktrace,
IncludeLogLevel = formatterOptions.IncludeLogLevel,
IncludeTimestamp = formatterOptions.IncludeTimestamp,
IncludeSpanId = formatterOptions.IncludeSpanId,
IncludeTraceId = formatterOptions.IncludeTraceId,
TimestampFormat = formatterOptions.TimestampFormat!,
UseUtcTimestamp = formatterOptions.UseUtcTimestamp
IncludeScopes = _formatterOptions.IncludeScopes,
IncludeCategory = _formatterOptions.IncludeCategory,
IncludeExceptionStacktrace = _formatterOptions.IncludeExceptionStacktrace,
IncludeLogLevel = _formatterOptions.IncludeLogLevel,
IncludeTimestamp = _formatterOptions.IncludeTimestamp,
IncludeSpanId = _formatterOptions.IncludeSpanId,
IncludeTraceId = _formatterOptions.IncludeTraceId,
TimestampFormat = _formatterOptions.TimestampFormat!,
UseUtcTimestamp = _formatterOptions.UseUtcTimestamp,
IncludeDimensions = _formatterOptions.IncludeDimensions,
}),
MSOptions.Options.Create(
new LogFormatterTheme
{
ColorsEnabled = formatterOptions.ColorsEnabled,
Dimmed = new ColorSet(formatterOptions.DimmedColor, formatterOptions.DimmedBackgroundColor),
Exception = new ColorSet(formatterOptions.ExceptionColor, formatterOptions.ExceptionBackgroundColor),
ExceptionStackTrace = new ColorSet(formatterOptions.ExceptionStackTraceColor, formatterOptions.ExceptionStackTraceBackgroundColor)
ColorsEnabled = _formatterOptions.ColorsEnabled,
Dimmed = new ColorSet(_formatterOptions.DimmedColor, _formatterOptions.DimmedBackgroundColor),
Exception = new ColorSet(_formatterOptions.ExceptionColor, _formatterOptions.ExceptionBackgroundColor),
ExceptionStackTrace = new ColorSet(_formatterOptions.ExceptionStackTraceColor, _formatterOptions.ExceptionStackTraceBackgroundColor),
Dimensions = new ColorSet(_formatterOptions.DimensionsColor, _formatterOptions.DimensionsBackgroundColor),
}));
}
#endif
Expand All @@ -77,6 +78,11 @@ string FormatLog(LogEntryCompositeState compositeState, Exception? exception) =>
using var textWriter = new StringWriter();
foreach (var logRecord in batch)
{
if (_formatterOptions.IncludeScopes)
{
WriteScopesLine(logRecord, textWriter);
}

formattedMessage = logRecord.FormattedMessage;
var logEntry = new LogEntry<LogEntryCompositeState>(
logRecord.LogLevel,
Expand All @@ -86,15 +92,12 @@ string FormatLog(LogEntryCompositeState compositeState, Exception? exception) =>
logRecord.Exception,
FormatLog);

var scopedProvider = new LoggerExternalScopeProvider();
_consoleFormatter.Write(logEntry, scopedProvider, textWriter);

WriteScopesLine(logRecord);
_consoleFormatter.Write(logEntry, textWriter);

var text = textWriter.ToString();
if (!string.IsNullOrWhiteSpace(text))
{
Write(text);
System.Console.Write(text);
}
}

Expand Down Expand Up @@ -135,26 +138,77 @@ private static string GetOriginalFormat(IReadOnlyCollection<KeyValuePair<string,
return string.Empty;
}

private static void WriteScopesLine(
LogRecord logRecord,
#if NET5_0_OR_GREATER
StringWriter writer)
#else
TextWriter writer)
#endif
{
var hasScopes = false;

logRecord.ForEachScope((scope, _) =>
{
foreach (var subScope in scope)
{
if (!hasScopes)
{
hasScopes = true;
writer.Write("Scope:");
}

var scopeText = string.IsNullOrEmpty(subScope.Key)
? $"{subScope.Value}"
: $"{subScope.Key}:{subScope.Value}";

writer.Write($" {scopeText}");
}
}, default(object));

if (hasScopes)
{
writer.WriteLine();
}
}

#if !NET5_0_OR_GREATER
private static void WriteDimensions(LogRecord logRecord)
{
if (logRecord.StateValues != null)
{
foreach (var kvp in logRecord.StateValues)
{
if (kvp.Key != LoggingConsoleExporter.OriginalFormat)
{
System.Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
}
}
}

private void WriteBatchOfLogRecords(Batch<LogRecord> batch)
{
foreach (var logRecord in batch)
{
WriteScopesLine(logRecord);
WriteScopesLine(logRecord, System.Console.Out);

var message = logRecord.FormattedMessage;
if (string.IsNullOrEmpty(message))
{
message = GetOriginalFormat(logRecord.StateValues);
}

WriteLine($"{logRecord.Timestamp:yyyy-MM-dd HH:mm:ss.fff} {logRecord.LogLevel} {logRecord.TraceId} {logRecord.SpanId} {message} {logRecord.CategoryName}/{logRecord.EventId}");
System.Console.WriteLine(
$"{logRecord.Timestamp:yyyy-MM-dd HH:mm:ss.fff} {logRecord.LogLevel} {logRecord.TraceId} {logRecord.SpanId} {message} {logRecord.CategoryName}/{logRecord.EventId}");

if (logRecord.Exception is not null)
{
var exceptionMessage = GetExceptionMessage(logRecord.Exception);
Write(exceptionMessage);
System.Console.Write(exceptionMessage);
}

WriteDimensions(logRecord);
}
}

Expand Down Expand Up @@ -194,50 +248,4 @@ private string GetExceptionMessage(Exception ex, string tabulation = "")
}
}
#endif

private void WriteScopesLine(LogRecord logRecord)
{
var isMultipleScopes = false;

void WriteScope(KeyValuePair<string, object?> scope)
{
var text = string.IsNullOrEmpty(scope.Key)
? $" {scope.Value}"
: $" {scope.Key}:{scope.Value}";

if (!isMultipleScopes)
{
isMultipleScopes = true;
Write($"Scope:{text}");
}
else
{
Write(text);
}
}

logRecord.ForEachScope((scope, _) =>
{
foreach (var subScope in scope)
{
WriteScope(subScope);
}
}, this);

if (logRecord.StateValues is not null)
{
foreach (var stateValue in logRecord.StateValues)
{
if (stateValue.Key != OriginalFormat)
{
WriteScope(stateValue);
}
}
}

if (isMultipleScopes)
{
WriteLine();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,22 @@ public class LoggingConsoleOptions
/// Gets or sets a value indicating what color to use for exception stack trace text background.
/// </summary>
public ConsoleColor? ExceptionStackTraceBackgroundColor { get; set; }

/// <summary>
/// Gets or sets a value indicating whether to include dimension name/value pairs with each log record.
/// </summary>
/// <remarks>Defaults to <see langword="false"/>.</remarks>
public bool IncludeDimensions { get; set; }

/// <summary>
/// Gets or sets a value indicating what color to use for dimension text.
/// </summary>
/// <remarks>Defaults to <see cref="ConsoleColor.DarkGreen"/>.</remarks>
public ConsoleColor DimensionsColor { get; set; } = ConsoleColor.DarkGreen;

/// <summary>
/// Gets or sets a value indicating what color to use for dimension text background.
/// </summary>
public ConsoleColor? DimensionsBackgroundColor { get; set; }
}
#endif
Loading

0 comments on commit a5738f6

Please sign in to comment.