Serilog自定义文本颜色和日志控制台显示的分离

之前使用log4net,他不支持AOT,现在换Serilog使用。发现无法修改文本颜色,默认的样式不喜欢。

尝试错误写法

问了AI,尝试这种写法不行:

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()  // 🔥 关键:启用Debug级别
    .WriteTo.Console(
        
     outputTemplate: "\x1b[90;1m[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3}]\x1b[0m \u001b[34;1m{Message:lj}{NewLine}\x1b[0m{Exception}")

看起来好像可以在指定位置添加颜色,实则不行。
我想实现整行的文本输出用一种颜色。

最终写法

经过研究可以重新设置输出,直接上图上代码:

在这里插入图片描述

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()  // 🔥 关键:启用Debug级别
    .WriteTo.Console(new CustomColorFormatter())
        //theme: AnsiConsoleTheme.Code,
        //outputTemplate: "\x1b[90;1m[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3}]\x1b[0m \u001b[34;1m{Message:lj}{NewLine}\x1b[0m{Exception}")
    .WriteTo.File(
        path: "Logs/BSServer_.log",
        rollingInterval: RollingInterval.Day,
        retainedFileCountLimit: 30,           // 保留30个文件
        fileSizeLimitBytes: 10 * 1024 * 1024,  // 10MB
        rollOnFileSizeLimit: true,             // 超过大小也滚动
        shared: true,                          // 允许多进程共享
        flushToDiskInterval: TimeSpan.FromSeconds(30), // 30秒刷新到磁盘
        outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
    // ERROR级别日志单独写入错误文件
    .WriteTo.File(
        path: "Logs/BSServer_ERR_.log",
        rollingInterval: RollingInterval.Day,
        retainedFileCountLimit: 90,  // 错误日志保留更久
        restrictedToMinimumLevel: LogEventLevel.Error,  // 只记录Error及以上
        outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
.CreateLogger();


Debug("Debug测试颜色");
Info("Info测试颜色");
Warn("Warn测试颜色");
Error("Error测试颜色");

下面是实现的自定义格式接口

public class CustomColorFormatter : ITextFormatter
{
    public void Format(LogEvent logEvent, TextWriter output)
    {
        // 时间戳 - 灰色
        output.Write("\x1b[90m[");
        output.Write(logEvent.Timestamp.ToString("yyyy-MM-dd HH:mm:ss.fff"));
        output.Write("]\x1b[0m ");

        // 日志级别 - 不同级别不同颜色
        //var level = logEvent.Level.ToString().ToLower().PadRight(3);
        var levelColor = logEvent.Level switch
        {
            LogEventLevel.Verbose => "\x1b[37m",      // 白色
            LogEventLevel.Debug => "\x1b[90m",      // 青色加粗
            LogEventLevel.Information => "\x1b[37;1m", // 绿色加粗
            LogEventLevel.Warning => "\x1b[34;1m",    // 黄色加粗
            LogEventLevel.Error => "\x1b[31;1m",      // 红色加粗
            LogEventLevel.Fatal => "\x1b[35;1m",      // 紫色加粗
            _ => "\x1b[0m"
        };
        var levelShow = logEvent.Level switch
        {
            LogEventLevel.Verbose => "VER",      // 白色
            LogEventLevel.Debug => "DBG",      // 青色加粗
            LogEventLevel.Information => "INF", // 绿色加粗
            LogEventLevel.Warning => "WRN",    // 黄色加粗
            LogEventLevel.Error => "ERR",      // 红色加粗
            LogEventLevel.Fatal => "FAT",      // 紫色加粗
            _ => "OTH"
        };

        output.Write(levelColor);
        output.Write(levelShow);
        output.Write("\x1b[0m ");

        //内容颜色
        var txtColor = logEvent.Level switch
        {
            LogEventLevel.Verbose => "\x1b[37m",      // 白色
            LogEventLevel.Debug => "\x1b[90m",      // 青色加粗
            LogEventLevel.Information => "\x1b[37;2m", // 绿色加粗
            LogEventLevel.Warning => "\x1b[34;2m",    // 黄色加粗
            LogEventLevel.Error => "\x1b[31;2m",      // 红色加粗
            LogEventLevel.Fatal => "\x1b[35;2m",      // 紫色加粗
            _ => "\x1b[0m"
        };
        var txtShow = logEvent.RenderMessage();
        

        output.Write(txtColor);
        output.Write(txtShow);
        output.Write("\x1b[0m ");

        // 消息内容 - 可以按关键词设置不同颜色
        //FormatColoredMessage(logEvent.RenderMessage(), output);

        // 异常信息 - 红色
        if (logEvent.Exception != null)
        {
            output.Write("\x1b[31m\n");
            output.Write(logEvent.Exception);
            output.Write("\x1b[0m");
        }

        output.WriteLine();
    }

    
}

日志和显示分离

有时候有的希望只写log不输出。
我们可以通过过滤参数来实现

static bool enableConsole = true;
static LoggingLevelSwitch logLevel;

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.ControlledBy(logLevel)  // 🔥 关键:启用Debug级别
    .Filter.ByIncludingOnly(evt => enableConsole)
    .WriteTo.Console(new CustomColorFormatter())

我们可以封装一个函数

public static void Error(string str, bool showconsole = true)
{
	enableConsole = showconsole ;
	Log.Debug(info.str);
}

这样就可以实现只写LOG,显示通过参数来控制了。

有时鼠标点击窗口进行编辑会影响业务逻辑,可以参考控制台鼠标点击窗口程序会暂停运行的问题

最终完整代码类

//using log4net;
//using log4net.Core;
//using log4net.Repository.Hierarchy;
using Serilog;
using NetLibrary;
using System;
using System.Collections;
using System.IO;
using System.Threading;
using Serilog.Events;
using Serilog.Sinks.SystemConsole.Themes;
using Serilog.Core;
using Serilog.Formatting;

public class CustomColorFormatter : ITextFormatter
{
    public void Format(LogEvent logEvent, TextWriter output)
    {
        // 时间戳 - 灰色
        output.Write("\x1b[90m[");
        output.Write(logEvent.Timestamp.ToString("yyyy-MM-dd HH:mm:ss.fff"));
        output.Write("]\x1b[0m ");

        // 日志级别 - 不同级别不同颜色
        //var level = logEvent.Level.ToString().ToLower().PadRight(3);
        var levelColor = logEvent.Level switch
        {
            LogEventLevel.Verbose => "\x1b[37m",      // 白色
            LogEventLevel.Debug => "\x1b[90m",      // 青色加粗
            LogEventLevel.Information => "\x1b[37;1m", // 绿色加粗
            LogEventLevel.Warning => "\x1b[34;1m",    // 黄色加粗
            LogEventLevel.Error => "\x1b[31;1m",      // 红色加粗
            LogEventLevel.Fatal => "\x1b[35;1m",      // 紫色加粗
            _ => "\x1b[0m"
        };
        var levelShow = logEvent.Level switch
        {
            LogEventLevel.Verbose => "VER",      // 白色
            LogEventLevel.Debug => "DBG",      // 青色加粗
            LogEventLevel.Information => "INF", // 绿色加粗
            LogEventLevel.Warning => "WRN",    // 黄色加粗
            LogEventLevel.Error => "ERR",      // 红色加粗
            LogEventLevel.Fatal => "FAT",      // 紫色加粗
            _ => "OTH"
        };

        output.Write(levelColor);
        output.Write(levelShow);
        output.Write("\x1b[0m ");

        //内容颜色
        var txtColor = logEvent.Level switch
        {
            LogEventLevel.Verbose => "\x1b[37m",      // 白色
            LogEventLevel.Debug => "\x1b[90m",      // 青色加粗
            LogEventLevel.Information => "\x1b[37;2m", // 绿色加粗
            LogEventLevel.Warning => "\x1b[34;2m",    // 黄色加粗
            LogEventLevel.Error => "\x1b[31;2m",      // 红色加粗
            LogEventLevel.Fatal => "\x1b[35;2m",      // 紫色加粗
            _ => "\x1b[0m"
        };
        var txtShow = logEvent.RenderMessage();
        

        output.Write(txtColor);
        output.Write(txtShow);
        output.Write("\x1b[0m ");

        // 消息内容 - 可以按关键词设置不同颜色
        //FormatColoredMessage(logEvent.RenderMessage(), output);

        // 异常信息 - 红色
        if (logEvent.Exception != null)
        {
            output.Write("\x1b[31m\n");
            output.Write(logEvent.Exception);
            output.Write("\x1b[0m");
        }

        output.WriteLine();
    }

    
}

//Loger系统请勿擅自修改,可能引起掉线等严重问题

public class Loger
{

    static public bool DEBUG = false;  //显示不显示的输出.

    static Loger inst;

    static LoggingLevelSwitch logLevel;
    static bool enableConsole = true;
    //static Log.Logger logger;//= LogManager.GetLogger(" MMCEngine ");
    public Loger(string fname = "")
    {
        inst = this;
        Thread.CurrentThread.Name = "main";//为了让主线程名显示
                                           //string path = "log4net.config";
                                           //FileInfo file = new FileInfo(path);

        //log4net.GlobalContext.Properties["LogName"] = fname + "_";
        //logger = log4net.LogManager.GetLogger(" KCPBigSpace ");


        //log4net.Config.XmlConfigurator.Configure(file);

        //var customTheme = new Dictionary<ConsoleThemeStyle, string>
        //{
        //    // 关键:让文本继承级别颜色
        //    // 1. 关键:设置基础文本样式跟随级别
        //    [ConsoleThemeStyle.Text] = "",               // 重置,让文本继承级别颜色
        //    [ConsoleThemeStyle.SecondaryText] = "",      // 次要文本
        //    [ConsoleThemeStyle.TertiaryText] = "",       // 三级文本


        //    // 级别颜色定义
        //    [ConsoleThemeStyle.LevelDebug] = "\x1b[34m",        // Debug: 全行蓝色
        //    [ConsoleThemeStyle.LevelInformation] = "\x1b[32m",  // Info: 全行绿色
        //    [ConsoleThemeStyle.LevelWarning] = "\x1b[33m",      // Warning: 全行黄色
        //    [ConsoleThemeStyle.LevelError] = "\x1b[31m",        // Error: 全行红色
        //    [ConsoleThemeStyle.LevelFatal] = "\x1b[31;1m",      // Fatal: 全行红色加粗

        //};

        logLevel = new LoggingLevelSwitch(LogEventLevel.Information);

        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.ControlledBy(logLevel)  // 🔥 关键:启用Debug级别
            .Filter.ByIncludingOnly(evt => enableConsole)
            .WriteTo.Console(new CustomColorFormatter())
                //theme: AnsiConsoleTheme.Code,
                //outputTemplate: "\x1b[90;1m[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3}]\x1b[0m \u001b[34;1m{Message:lj}{NewLine}\x1b[0m{Exception}")
            .WriteTo.File(
                path: "Logs/BSServer_.log",
                rollingInterval: RollingInterval.Day,
                retainedFileCountLimit: 30,           // 保留30个文件
                fileSizeLimitBytes: 10 * 1024 * 1024,  // 10MB
                rollOnFileSizeLimit: true,             // 超过大小也滚动
                shared: true,                          // 允许多进程共享
                flushToDiskInterval: TimeSpan.FromSeconds(30), // 30秒刷新到磁盘
                outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
            // ERROR级别日志单独写入错误文件
            .WriteTo.File(
                path: "Logs/BSServer_ERR_.log",
                rollingInterval: RollingInterval.Day,
                retainedFileCountLimit: 90,  // 错误日志保留更久
                restrictedToMinimumLevel: LogEventLevel.Error,  // 只记录Error及以上
                outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
        .CreateLogger();


        //Debug("Debug测试颜色");
        //Info("Info测试颜色");
        //Warn("Warn测试颜色");
        //Error("Error测试颜色");
        UpdateShow();

    }

    public static void LogerUpdate()
    {
        if (DEBUG)
        {
            //Configure the root logger.
            //Hierarchy h = (Hierarchy)LogManager.GetRepository();
            //Logger rootLogger = h.Root;
            //rootLogger.Level = Level.Debug;

            logLevel.MinimumLevel = LogEventLevel.Debug;
        }
    }


    //public static void Flush()
    //{
    //    log4net.LogManager.Flush(10);
    //    log4net.LogManager.Shutdown();
    //}

    public static void NetErrorMsg(string str)
    {
        str = "[ServerMsg]" + str;
        //Log.Error(str);
        inst.WriteLine(LogEnum.ERROR, str);
    }
    public static void NetWarnMsg(string str)
    {
        str = "[ServerMsg]" + str;
        //Log.Warning(str);
        inst.WriteLine(LogEnum.WARN,str);
    }
    public static void NetInfoMsg(string str)
    {
        str = "[ServerMsg]" + str;
        //Log.Information(str);
        inst.WriteLine(LogEnum.INFO,str);
    }


    public static void Debug(string str,bool showconsole = true)
    {
        //Log.Debug(str);
        //Log.Debug("\x1b[90;1m" + str + "\x1b[0m");
        inst.WriteLine(LogEnum.DEBUG,str, showconsole);
    }
    public static void Info(string str, bool showconsole = true)
    {
        //Log.Information(str);
        //Log.Information("\x1b[37;1m"+str+ "\x1b[0m");
        inst.WriteLine(LogEnum.INFO,str, showconsole);

    }
    public static void Warn(string str, bool showconsole = true)
    {
        //Log.Warning(str);
        //Log.Warning("\x1b[34;1m" + str + "\x1b[0m");
        inst.WriteLine(LogEnum.WARN,str, showconsole);
    }
    public static void Error(string str, bool showconsole = true)
    {
        //Log.Error(str);
        //Log.Error("\x1b[31;1m" + str + "\x1b[0m");
        inst.WriteLine(LogEnum.ERROR,str, showconsole);
    }

    public struct ShowLogInfo
    {
        public LogEnum logEnum;
        public string str;
        public bool showconsole;
    }
    List<ShowLogInfo> showLogs = new List<ShowLogInfo>();
    //写入异步是怕卡死主进程
    void WriteLine(LogEnum logEnum, string str, bool showconsole = true)
    {

        showLogs.Add(new ShowLogInfo { logEnum = logEnum, str = str, showconsole = showconsole });

    }

    //*****这里写在异步里,是控制台输出的时候如果鼠标点击暂停了,那么可能导致进程卡住导致掉线等问题****
    async void UpdateShow()
    {
        while (true)
        {
            await Task.Delay(1);

            while (showLogs.Count > 0)
            {
                //lock (((ICollection)showLogs).SyncRoot)//如果lock了会卡掉网络
                try
                {
                    ShowLogInfo info = showLogs[0];
                    showLogs.RemoveAt(0);
                    enableConsole = info.showconsole || DEBUG;
                    switch (info.logEnum)
                    {
                        case LogEnum.DEBUG:
                            Log.Debug(info.str);
                            break;
                        case LogEnum.INFO:
                            Log.Information(info.str);
                            break;
                        case LogEnum.WARN:
                            Log.Warning(info.str);
                            break;
                        case LogEnum.ERROR:
                            Log.Error(info.str);
                            break;
                    }
                    //if (info.showconsole || DEBUG)
                    //{
                    //    bool changecolor = false;
                    //    if (info.logEnum == LogEnum.ERROR)
                    //    {
                    //        changecolor = true;
                    //        Console.ForegroundColor = ConsoleColor.Red;
                    //    }
                    //    else if (info.logEnum == LogEnum.WARN)
                    //    {
                    //        changecolor = true;
                    //        Console.ForegroundColor = ConsoleColor.Blue;
                    //    }
                    //    else if (info.logEnum == LogEnum.DEBUG)
                    //    {
                    //        changecolor = true;
                    //        Console.ForegroundColor = ConsoleColor.DarkGray;
                    //    }
                    //    Console.WriteLine(info.str);
                    //    if (changecolor)
                    //    {
                    //        Console.ResetColor();
                    //    }
                    //}
                }
                catch //(Exception e)
                {
                    //Console.WriteLine(e.Message);
                }
            }
        }
    }
}


本文结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Thinbug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值