Skip to content

Instantly share code, notes, and snippets.

@madhub
Created October 18, 2022 18:26
Show Gist options
  • Save madhub/af30360b2f96b0932e1de3955c91c1c1 to your computer and use it in GitHub Desktop.
Save madhub/af30360b2f96b0932e1de3955c91c1c1 to your computer and use it in GitHub Desktop.
// usage
builder.Logging.AddConsole(options =>
    {
        options.FormatterName = "customName";
    })
    .AddConsoleFormatter<CustomFormatter, CustomOptions>(options1 =>
    {
        options1.IncludeScopes = true;
        options1.UseUtcTimestamp = true;
        options1.TimestampFormat = "[HH:mm:ss] ";
    }); ;

 public class CustomOptions : ConsoleFormatterOptions
    {
        public string? CustomPrefix { get; set; }
    }
    public sealed class CustomFormatter : ConsoleFormatter, IDisposable
    {
        private bool disposedValue;
        private readonly IOptionsMonitor<CustomOptions> options;

        public CustomFormatter(IOptionsMonitor<CustomOptions> options) : base("customName")
        {
            this.options = options;
        }

        public override void Write<TState>(in LogEntry<TState> logEntry, IExternalScopeProvider scopeProvider, TextWriter textWriter)
        {
            
            var description = logEntry.Formatter!(logEntry.State, logEntry.Exception);
            if (logEntry.Exception == null && description == null)
            {
                return;
            }

            

            IDictionary<string, string> dict = new Dictionary<string, string>();


            dict["TimeStamp"] = DateTimeOffset.UtcNow.ToString(options.CurrentValue.TimestampFormat ?? "yyyy-MM-ddTHH:mm:ss.fffZ");
            dict["LogLevel"] = GetLogLevelString(logEntry.LogLevel);
            dict["EventId"] = logEntry.EventId.ToString();
		    dict["Category"] = logEntry.Category;
            dict["TraceId"] = logEntry.Category;
            dict["SpanId"] = logEntry.Category;
            if (scopeProvider != null)
            {
                scopeProvider.ForEachScope((object scope, TextWriter state) =>
                {
                    IReadOnlyList<KeyValuePair<string, object>> scopeDictionary = scope as IReadOnlyList<KeyValuePair<string, object>>;
                    if (scopeDictionary is null)
                    {
                        return;
                    }
                    foreach (KeyValuePair<string, object> scopItem in scopeDictionary)
                    {
                        if (scopItem.Key.Equals("TraceId", StringComparison.InvariantCultureIgnoreCase) || scopItem.Key.Equals("SpanId", StringComparison.InvariantCultureIgnoreCase))
                        {
                            dict[scopItem.Key] = Convert.ToString(scopItem.Value, CultureInfo.InvariantCulture);
                        }

                    }
                }, null);
            }
            dict["description"] = description;
            IReadOnlyList<KeyValuePair<string, object>> stateDictionary = logEntry.State as IReadOnlyList<KeyValuePair<string, object>>;
            if (stateDictionary != null)
            {
                foreach (KeyValuePair<string, object> item in stateDictionary)
                {
                    //  ignore  message template & Also ignore any properties that are already set
                    if (item.Key != "{OriginalFormat}")
                        dict[item.Key] = Convert.ToString(item.Value, CultureInfo.InvariantCulture);

                }
            }
            

            textWriter.WriteLine(String.Join('|',dict.Values));
            //textWriter.WriteLine(JsonSerializer.Serialize(dict));
        }

        private static string GetLogLevelString(LogLevel logLevel)
        {
            return logLevel switch
            {
                LogLevel.Trace => "Trace",
                LogLevel.Debug => "Debug",
                LogLevel.Information => "Information",
                LogLevel.Warning => "Warning",
                LogLevel.Error => "Error",
                LogLevel.Critical => "Critical",
                _ => throw new ArgumentOutOfRangeException("logLevel"),
            };
        }
        private void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    // TODO: dispose managed state (managed objects)
                }

                // TODO: free unmanaged resources (unmanaged objects) and override finalizer
                // TODO: set large fields to null
                disposedValue = true;
            }
        }

        // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
        // ~CustomFormatter()
        // {
        //     // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
        //     Dispose(disposing: false);
        // }

        public void Dispose()
        {
            // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
            Dispose(disposing: true);
            GC.SuppressFinalize(this);
        }
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment