(精华)2020年9月15日 ASP.NET Core 日志底层详解

举报
愚公搬代码 发表于 2021/10/19 23:30:22 2021/10/19
【摘要】 1.跟踪日志的基本使用 //跟踪日志 public static class CoreLog { public static void Run() { using var...

1.跟踪日志的基本使用

//跟踪日志
public static class CoreLog
{
    public static void Run()
    {
        using var fileStream = File.OpenWrite("log.txt");
        // 发布订阅模式
        var source = new TraceSource("Trace", SourceLevels.Warning);//跟踪源
        source.Listeners.Add(new ConsoleTraceListener());//监听输出到控制台
        source.Listeners.Add(new TextWriterTraceListener(fileStream));//监听输出到文件,拥有缓冲机制
        var eventTypes = (TraceEventType[])Enum.GetValues(typeof(TraceEventType));//跟踪事件类型
        var eventId = 1;
        foreach (var traceEventType in eventTypes)
        {
            source.TraceEvent(traceEventType, eventId++,$"这是一条{traceEventType}消息");
            source.Flush();//清楚缓冲
        }
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

2.跟踪日志格式化输出到csv文件

public static class Sample05
{
    public static void Run()
    {
        const string filename = "log1.csv";
        File.AppendAllText(filename,$"SourceName,EventType,EventId,Message,N/A,ProcessId,N/A,ThreadId,DateTime,{Environment.NewLine}" );

        using var fileStream = new FileStream(filename,FileMode.Append);

        var listener = new DelimitedListTraceListener(fileStream)
        {
            Delimiter = ",",
            TraceOutputOptions = TraceOptions.DateTime | TraceOptions.ProcessId | TraceOptions.ThreadId
        };

        var source = new TraceSource("AppTrace", SourceLevels.All);
        source.Listeners.Add(new ConsoleTraceListener());
        source.Listeners.Add(listener);

        source.TraceEvent(TraceEventType.Information,1,$"这是一条{TraceEventType.Information}消息");
        source.Flush();


    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

3.诊断日志

//诊断日志
public static class Sample06
{
    public class Observer<T> : IObserver<T>
    {
        private readonly Action<T> _onNext;

        public Observer(Action<T> onNext)
        {
            _onNext = onNext;
        }

        public void OnCompleted() { }

        public void OnError(Exception error) { }

        public void OnNext(T value)
        {
            _onNext(value);
        }
    }

    public static void Run()
    {
        DiagnosticListener.AllListeners.Subscribe(new Observer<DiagnosticListener>(listener =>
        {
            if (listener.Name == "AppLog")
            {
                listener.Subscribe(new Observer<KeyValuePair<string, dynamic>>(eventData =>
                {
                    var (key, value) = eventData;
                    Console.WriteLine($"Name:{key}");
                    Console.WriteLine($"Value:{value}");
                }));
            }
        }));

        var source = new DiagnosticListener("AppLog");


        source.Write("Hello", new
        {
            Type = 1,
            Msg = "2020年5月11日"
        });


    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

安装包

Microsoft.Extensions.DiagnosticAdapter

  
 
  • 1

使用如下

public static class Sample08
{
    public class Observer<T> : IObserver<T>
    {
        private readonly Action<T> _onNext;

        public Observer(Action<T> onNext)
        {
            _onNext = onNext;
        }

        public void OnCompleted() { }

        public void OnError(Exception error) { }

        public void OnNext(T value)
        {
            _onNext(value);
        }
    }

    public class CustomSourceCollector
    {
        [DiagnosticName("Hello")]
        public void OnHello(int type, string msg)
        {
            Console.WriteLine($"Type:{type}");
            Console.WriteLine($"Msg:{msg}");
        }
    }

    public static void Run()
    {
        DiagnosticListener.AllListeners.Subscribe(new Observer<DiagnosticListener>(listener =>
        {
            if (listener.Name == "AppLog")
            {
                listener.SubscribeWithAdapter(new CustomSourceCollector());
            }
        }));

        var source = new DiagnosticListener("AppLog");


        source.Write("Hello", new
        {
            Type = 1,
            Msg = "2020年5月11日"
        });


    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

4.ILogger和ILoggerFactory的使用

public class Sample01
{
    public static void Run()
    {
        var serviceProvider = new ServiceCollection()
            .AddLogging(builder => builder
                .AddConsole()
                .AddDebug())
            .BuildServiceProvider();

        var logger = serviceProvider.GetRequiredService<ILogger<Sample01>>();//ILoggerFactory
            // .CreateLogger("ConsoleApp2.Sample01");

        var leveles = (LogLevel[])Enum.GetValues(typeof(LogLevel));

        var eventId = 1;
        foreach (var level in leveles)
        {
            logger.Log(level, eventId++,$"这是一条{level}消息");
        }

        Console.Read();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

5.AddTraceSource的使用

public class Sample02
{
    public static void Run()
    {
        var serviceProvider = new ServiceCollection()
            .AddLogging(builder =>
            {
                builder.AddTraceSource(
                        new SourceSwitch("Sample02", nameof(SourceLevels.All)),//发布
                        new DefaultTraceListener {LogFileName = "trace.log"});//消费
                builder.AddConsole();
                builder.SetMinimumLevel(LogLevel.Trace);
            })
            .BuildServiceProvider();
        var logger = serviceProvider.GetRequiredService<ILogger<Sample02>>();

        var leveles = (LogLevel[])Enum.GetValues(typeof(LogLevel));
        var eventId = 1;
        foreach (var level in leveles)
        {
            logger.Log(level, eventId++,$"这是一条{level}消息");
        }

        Console.Read();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

5.Filter日志过滤器的使用

public class Sample03
{
    public static void Run()
    {
        var serviceProvider = new ServiceCollection()
            .AddLogging(builder => builder
                .AddFilter((category, level) =>
                {
                    return category switch
                    {
                        "LoggerA" => level >= LogLevel.Debug,
                        "LoggerB" => level >= LogLevel.Warning,
                        "LoggerC" => level >= LogLevel.None,
                        _ => level >= LogLevel.Information
                    };
                })
                .AddConsole()
                .AddDebug())
            .BuildServiceProvider();

        var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
        var loggerA = loggerFactory.CreateLogger("LoggerA");
        var loggerB = loggerFactory.CreateLogger("LoggerB");
        var loggerC = loggerFactory.CreateLogger("LoggerC");

        var leveles = (LogLevel[])Enum.GetValues(typeof(LogLevel));

        var eventId = 1;
        foreach (var level in leveles)
        {
            eventId++;
            loggerA.Log(level, eventId,$"这是一条{level}消息");
            loggerB.Log(level, eventId,$"这是一条{level}消息");
            loggerC.Log(level, eventId,$"这是一条{level}消息");
        }

        Console.Read();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
public class Sample04
{
    public static void Run()
    {
        var serviceProvider = new ServiceCollection()
            .AddLogging(builder => builder
                .AddFilter((provider, category, level) =>
                {
                    if (provider == typeof(ConsoleLoggerProvider).FullName)
                    {
                        return level >= LogLevel.Debug;
                    }

                    if (provider == typeof(DebugLoggerProvider).FullName)
                    {
                        return level >= LogLevel.Warning;
                    }

                    return level >= LogLevel.Information;
                })
                .AddConsole()
                .AddDebug())
            .BuildServiceProvider();

        var logger = serviceProvider.GetRequiredService<ILogger<Sample04>>();

        var leveles = (LogLevel[])Enum.GetValues(typeof(LogLevel));

        var eventId = 1;
        foreach (var level in leveles)
        {
            logger.Log(level, eventId++,$"这是一条{level}消息");
        }

        Console.Read();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

6.配置文件过滤器的使用

public class Sample05
{
    public static void Run()
    {
        var config = new ConfigurationBuilder()
            .AddJsonFile("log.json")
            .Build();

        var serviceProvider = new ServiceCollection()
            .AddLogging(builder => builder
                .AddConfiguration(config)
                .AddConsole()
                .AddDebug())
            .BuildServiceProvider();

        var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
        var loggerA = loggerFactory.CreateLogger("LoggerA");
        var loggerB = loggerFactory.CreateLogger("LoggerB");
        var loggerC = loggerFactory.CreateLogger("LoggerC");

        var leveles = (LogLevel[])Enum.GetValues(typeof(LogLevel));

        var eventId = 1;
        foreach (var level in leveles)
        {
            eventId++;
            loggerA.Log(level, eventId,$"这是一条{level}消息");
            loggerB.Log(level, eventId,$"这是一条{level}消息");
            loggerC.Log(level, eventId,$"这是一条{level}消息");
        }

        Console.Read();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

7.日志注入

public class Sample06
{
    public static void Run()
    {
        var serviceProvider = new ServiceCollection()
            .AddLogging(builder => builder
                .SetMinimumLevel(LogLevel.Information)
                .AddConsole())
            .AddSingleton<GodLog>()
            .BuildServiceProvider();

        var logger = serviceProvider.GetRequiredService<GodLog>();
        logger.Log("Hello");
        Console.Read();
    }

    public class GodLog
    {
        private const string Template = "[{LogTime}]来自{Id}-{Name}的记录:{Context}";
        private static Action<ILogger, DateTime, int ,string, string, Exception> _logAction;
        private readonly ILogger _logger;

        public GodLog(ILogger<Sample06> logger)
        {
            _logger = logger;
            
            _logAction = LoggerMessage.Define<DateTime, int, string, string>(LogLevel.Information, 1, Template);
        }

        public void Log(string context)
        {
            _logAction(_logger, DateTime.Now, 1, "God", context, null);
        }
    }

    
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

7.ASP.NET CORE中使用日志上下文

public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.ConfigureLogging(builder =>
                        builder.AddConsole(options => options.IncludeScopes = true));

                    webBuilder.UseStartup<Startup>();
                });
    }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

基础创建

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
        {
            app.Use(async (context, next) =>
            {
                using (logger.BeginScope($"Request Trans {Guid.NewGuid()}"))
                {
                    logger.Log(LogLevel.Information,$"Request Begin at {DateTime.Now}");
                    await next();
                    logger.Log(LogLevel.Information, $"Request End at {DateTime.Now}");
                }
            });

            app.Run(async context =>
            {
                await Task.Delay(1000);
                await context.Response.WriteAsync("Hello");
            });

        }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

范围创建

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
    var scopeFactory = LoggerMessage.DefineScope<Guid>("Request Trans {Guid}");
    var requestLog =  LoggerMessage.Define<string, DateTime>(LogLevel.Information, 0, "Request {state} at {DateTime.Now}");

    app.Use(async (context, next) =>
    {
        using (scopeFactory(logger, Guid.NewGuid()))
        {
            requestLog(logger, "Begin", DateTime.Now, null);
            await next();
            requestLog(logger, "End", DateTime.Now, null);
        }
    });

    app.Run(async context =>
    {
        await Task.Delay(1000);
        await context.Response.WriteAsync("Hello");
    });

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

文章来源: codeboy.blog.csdn.net,作者:愚公搬代码,版权归原作者所有,如需转载,请联系作者。

原文链接:codeboy.blog.csdn.net/article/details/108412737

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。