如何创建自定义的日志记录---Net Core 3.1

最近写了一个webapi 的项目,发现项目里没有写日志。导致一些问题出现后,无法定位到。所以必须添加上日志,没办法谁让我写的代码没有测试那么多,出现的情况考虑的不是那么周全。闲话不多说。下面开始

首先呢Net Core 上Logging 是由几个接口的,ILoggerFactory,ILoggerProvider,ILogger。这三个之间的关系,很多文章都说过了。我这里就不再说了。我当时记得看过这样一句话。说的是ILoggerFactory 可以生成Logger,ILoggerProvider 也可以生成Logger,但是呢,生成的东西是不一样的。ILoggerFactory 生成的ILogger 内部是根据ILoggerProvider生成的,可以说,还是ILoggerProvider 生成的Logger.

在net core 是存在ILoggerFactory的实例

的名字就是LoggerFactory ,所以我们不用去做类实现它,那么我们需要做类去实现另外的两个。下面我摘出一下我的代码。

public class CustomLoggerConfiguration
    {
        public int EventId { get; set; }
        public LogLevel LogLevel { get; set; } = LogLevel.Information;
        public string FilePath { get; set; } = Path.Combine(AppContext.BaseDirectory, "log.txt");
    }

这个类是做了一下配置,主要是设置一下文件的存储路径

 

public class CustomLogger : ILogger
    {
        private readonly string _name;
        private readonly CustomLoggerConfiguration _config;

        public CustomLogger(string name, CustomLoggerConfiguration config) => (_name, _config) = (name, config);
        public IDisposable BeginScope<TState>(TState state)
        {
            return default;
        }

        public bool IsEnabled(LogLevel logLevel)
        {
            return logLevel == _config.LogLevel;
        }

        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }
            if (_config.EventId == 0 || _config.EventId == eventId.Id)
            {
                WriteToFile($"[{eventId.Id,2}: {logLevel,-12}]");

                WriteToFile($"     {_name} - {formatter(state, exception)}");
            }
        }
        public void WriteToFile(string content)
        {
            try
            {
                string logFile = _config.FilePath;

                FileStream fs;
                StreamWriter sw;
                if (File.Exists(logFile))
                    fs = new FileStream(logFile, FileMode.Append, FileAccess.Write);
                else
                    fs = new FileStream(logFile, FileMode.Create, FileAccess.Write);

                sw = new StreamWriter(fs);
                sw.WriteLine(content);
                sw.Close();
                fs.Close();
            }
            catch
            { }
        }
    }

这个类就是实现ILogger 的接口的类,主要就是实现接口,能够写入到文件中 

另外的两个类,CustomLogProvider ,CustomLogExtension 是参照官方文档上抄写的

public static class CustomLogExtensions
    {
        public static ILoggingBuilder AddCustomLogger(this ILoggingBuilder builder, CustomLoggerConfiguration configure)
        {
            ILoggerProvider provider = new CustomLogProvider(configure);
            builder.AddProvider(provider);
            return builder;
        }
        public static ILoggingBuilder AddCustomLogger(
         this ILoggingBuilder builder) =>
         builder.AddCustomLogger(
             new CustomLoggerConfiguration());

        public static ILoggingBuilder AddCustomLogger(
            this ILoggingBuilder builder,
            Action<CustomLoggerConfiguration> configure)
        {
            var config = new CustomLoggerConfiguration();
            configure(config);

            return builder.AddCustomLogger(config);
        }
    }
public class CustomLogProvider : ILoggerProvider
    {
        private readonly CustomLoggerConfiguration _config;
        private readonly ConcurrentDictionary<string, CustomLogger> _loggers =
        new ConcurrentDictionary<string, CustomLogger>();
        public CustomLogProvider(CustomLoggerConfiguration configure)
        {
            _config = configure;
        }
        public ILogger CreateLogger(string categoryName) =>
         _loggers.GetOrAdd(categoryName, name => new CustomLogger(name, _config));

        public void Dispose() => _loggers.Clear();
    }

下面就是最主要的了,如何使用这些类

需要在Program.cs 这个类里面进行操作,找到方法 

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
            .ConfigureLogging(builder =>
                builder.ClearProviders()
                .AddProvider(
                    new CustomLogProvider(
                        new CustomLoggerConfiguration
                        {
                            LogLevel = LogLevel.Error
                        }))
                .AddCustomLogger()
                .AddCustomLogger(configuration =>
                {
                    configuration.LogLevel = LogLevel.Warning;
                }))
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });

注意:这里我添加了三个loggerProvider,因为我写的实现的时候,写的一个provider 只能处理一种级别的日志,从代码中可以看出来,一个是LogLevel.Error 处理错误的。一个是处理警告的,还有一个是处理Information的,应该比较容易理解

由于依赖注入的关系,我们在需要用日志的地方,在他的构造函数中,直接注入ILogger<T> 就行了,比如下面的代码

public readonly IMongoCollection<ElementDtoNew> _collection;
        private readonly ILogger<ElementDtoNew> _logger;
        public ElementDtoNewService(IDatabaseSettings databaseSettings,ILogger<ElementDtoNew> logger)
        {
            var client = new MongoClient(databaseSettings.ConnectionString);
            var db = client.GetDatabase(databaseSettings.DatabaseName);

            var collection = db.ListCollectionNames();

            _logger = logger;
            _logger.LogInformation("Hello World!");
        }

这样记录就会写到你定义的位置了。

结语

写这篇文章的目的呢,其实就是让我自己记住,不要忘了,其实理解并不是很深,我好像看他的源码,我记得之前有人说,可以找到源码,但是我现在不知道在哪可以看到。

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值