Serilog日志同步到redis中和自定义Enricher来增加额外的记录信息
Serilog 日志同步到redis队列中 后续可以通过队列同步到数据库、腾讯阿里等日志组件中,这里redis库用的新生命团队的NewLife.Redis组件 可以实现轻量级消息队列(轻量级消息队列RedisQueue (newlifex.com)),也可以自行替换熟悉的组件
类库目录 该类库需添加?Microsoft.AspNetCore.Http.Abstractions、NewLife.Redis、Newtonsoft.Json、Serilog包
RedisStreamSink.cs 中的代码? 定义RedisSink 将日志记录到redis队列中
using Microsoft.AspNetCore.Http; using NewLife.Caching; using Newtonsoft.Json; using Serilog.Core; using Serilog.Events; using Serilog.Formatting; using Serilog.Parsing; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.Json.Serialization; using System.Threading.Tasks; namespace SeriLog.Sinks.RedisStream.Ms { ////// 用于序列化数据 /// public class LogData public DateTimeOffset Timestamp { get; set; } public LogEventLevel Level { get; set; } public string Message { get; set; } public string RequestIP { get; set; } public string HostName { get; set; } public static LogData LogEventToLogData(LogEvent logEvent) var data = new LogData(); data.Timestamp = logEvent.Timestamp; data.Level = logEvent.Level; return data; public class RedisStreamSink : ILogEventSink private readonly ITextFormatter _formatter; private readonly FullRedis _redis; private readonly string _redisStreamName; public RedisStreamSink(FullRedis fullRedis, string redisStreamName, ITextFormatter textFormatter) _redis = fullRedis; _redisStreamName = redisStreamName; _formatter = textFormatter; public void Emit(LogEvent logEvent) string message =string.Empty; using (var writer = new StringWriter()) message = writer.ToString(); var data = LogData.LogEventToLogData(logEvent); data.Message = message.Replace("\r\n",""); //获取自定义需要记录的信息例如客户端ip地址和主机名 data.RequestIP = logEvent.Properties.TryGetValue("RequestIP", out LogEventPropertyValue? propertyIpValue) ? propertyIpValue.ToString() : string.Empty; data.HostName = logEvent.Properties.TryGetValue("HostName", out LogEventPropertyValue? propertyHostNameValue) ? propertyHostNameValue.ToString() : string.Empty; Console.WriteLine("===================================\r\n" + JsonConvert.SerializeObject(data)); //添加到redis 队列中 var queue = _redis.GetQueue<string>(_redisStreamName); } }
RedisStreamSinkExtensions.cs?中的代码
using Serilog.Configuration; using Serilog; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using NewLife.Caching; using Serilog.Formatting; namespace SeriLog.Sinks.RedisStream.Ms { public static class RedisStreamSinkExtensions //序列化时message中显示的内容 简化输出 private const string DefaultOutputTemplate = "(RequestId:{RequestId}){Message:j}{Exception}"; public static LoggerConfiguration RedisStreamSink( this LoggerSinkConfiguration loggerConfiguration, string redisStreamName, string outputTemplate = DefaultOutputTemplate, IFormatProvider formatProvider = null var formatter = new Serilog.Formatting.Display.MessageTemplateTextFormatter(outputTemplate, formatProvider); return loggerConfiguration.Sink(new RedisStreamSink(redis, redisStreamName, formatter)); } }
RequestInfoEnricher.cs 中的代码? 自定义添加RequestIP和Referer信息
using Microsoft.AspNetCore.Http; using NewLife.Model; using Serilog.Core; using Serilog.Events; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SeriLog.Sinks.RedisStream.Ms { public class RequestInfoEnricher : ILogEventEnricher private readonly IServiceProvider _serviceProvider; public RequestInfoEnricher(IServiceProvider serviceProvider) _serviceProvider = serviceProvider; public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) var httpContext = _serviceProvider.GetService()?.HttpContext; if (null != httpContext) //这里添加自定义需记录的信息 logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestIP", httpContext.Connection.RemoteIpAddress)); logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("Referer", httpContext.Request.Headers["Referer"])); } }
EnricherExtensions.cs 中的代码
using Serilog.Configuration; using Serilog; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SeriLog.Sinks.RedisStream.Ms { public static class EnricherExtensions public static LoggerConfiguration WithRequestInfo(this LoggerEnrichmentConfiguration enrich, IServiceProvider serviceProvider) if (enrich == null) throw new ArgumentNullException(nameof(enrich)); return enrich.With(new RequestInfoEnricher(serviceProvider)); } }
在需要用到的项目中添加?SeriLog.Sinks.RedisStream.Ms 项目引用
public static void Main(string[] args) var fullRedis = FullRedis.Create($"server=12⑦0.0.1:6379,db=1"); var builder = WebApplication.CreateBuilder(args); //这一步必须放在CreateLogger之前否则 RequestInfoEnricher中获取不到HttpContextAccessor builder.Services.AddSingleton(); Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .Enrich.WithProperty("HostName", Dns.GetHostName()) .WriteTo.RedisStreamSink(fullRedis, "logger") //logger 为队列的名称 builder.Host.UseSerilog(); .......后续忽略自行修改 }
以上就是土嘎嘎小编为大家整理的Serilog日志同步到redis中和自定义Enricher来增加额外的记录信息相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!