38.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--增加日志记录器
本片文章我们一起将Loki集成到孢子记账项目中,来实现日志的集中化存储和查询。Loki的部署和配置在第二部分 微服务基础工具与技术中的Loki这篇文章中已经进行了详细讲解,在这里就不再赘述,不清楚的同学可以先去看一下。
一、修改日志公共代码
在第三部分的 增加公共代码 这篇文章中我们已经将日志的公共代码进行了抽取,并进行了扩展,使其可以支持Loki的日志存储。但是这部分代码在使用时发现了一个问题,Loki日志配置选项 LokiOptions
中的 AppName
属性只能从配置中读取,而不能在每个微服务中单独定义。
那么,一定会有同学说,为什么不直接在每个微服务中定义一个 LokiOptions
的配置呢?这样确实可以实现,但是我们需要在每个微服务中都进行相同的配置,这样就会导致代码重复,维护起来也不方便,我们用的是微服务架构,应该尽量减少重复的代码和配置。因此我们需要对 LokiOptions
进行一些修改,使其可以在每个微服务中单独定义AppName
。方法很简单,我们在为每个微服务项目配置Nacos时,在配置文件里已经定义了一个ServiceName
的配置项,我们可以直接使用这个配置项来作为 LokiOptions
的 AppName
。我们先来看一下已有的Nacos配置代码:
// appsettings.json 或 appsettings.Development.json
{"nacos": {// more configurations..."ServiceName": "SPConfigService"// more configurations...},// more configurations...
}
有了这个配置项后,我们需要修改日志服务扩展类 LoggerServiceExtensions
使其支持从每个微服务的配置中读取 ServiceName
作为 AppName
。修改后的代码如下:
// more code...namespace SP.Common.Logger
{/// <summary>/// 日志服务扩展方法/// </summary>public static class LoggerServiceExtensions{/// <summary>/// 添加日志服务/// </summary>/// <param name="services">服务集合</param>/// <param name="configuration">配置</param>/// <returns>服务集合</returns>public static IServiceCollection AddLoggerService(this IServiceCollection services, IConfiguration configuration){// more code...// 从Nacos配置中获取ServiceName并设置到LokiOptionsvar serviceName = configuration.GetValue<string>("nacos:ServiceName");if (!string.IsNullOrEmpty(serviceName)){var lokiOptions = sp.GetRequiredService<IOptions<LokiOptions>>();lokiOptions.Value.AppName = serviceName;}// more code...}}
}
在上面的代码中,我们通过 IConfiguration
获取了 nacos:ServiceName
的配置项,并将其设置到 LokiOptions
的 AppName
属性中。这样就可以在每个微服务中单独定义 AppName
了。
二、微服务引入日志
在处理完日志公共代码后,我们需要在每个微服务中引入日志服务。我们以用户配置微服务SP.ConfigService
为例,来讲解一下如何在微服务中引入我们已经定义的日志服务,其他微服务引入的方式类似。代码很简单,只需要在 Program.cs
文件中添加日志服务的配置即可:
// more code...// 注入loki日志服务
builder.Services.AddLoggerService(builder.Configuration);// more code...
这样就完成了日志服务的引入。接下来,我们可以在微服务中使用日志服务来记录日志了。首先,我们要将日志服务注入到需要使用的类中,例如要在ConfigController
中的GetConfigs
方法中记录日志,我们可以这样做:
// more code...namespace SP.ConfigService.Controllers
{/// <summary>/// 用户配置控制器/// </summary>[Route("api/configs")][ApiController]public class ConfigController : ControllerBase{// more code.../// <summary>/// 日志/// </summary>private readonly ILogger<ConfigController> _logger;/// <summary>/// 用户配置控制器构造函数/// </summary>/// <param name="configServer">用户配置服务</param>/// <param name="logger">日志</param>public ConfigController(IConfigServer configServer, ILogger<ConfigController> logger){_configServer = configServer;_logger = logger;}/// <summary>/// 获取所有配置/// </summary>/// <returns>用户配置列表</returns>[HttpGet]public ActionResult<List<ConfigResponse>> GetConfigs(){_logger.LogInformation("我进来了!");List<ConfigResponse> configs = _configServer.GetConfig().Result;_logger.LogInformation("我又出来了!");return Ok(configs);}// more code...}
}
在上面的代码中,我们通过依赖注入将日志服务注入到 ConfigController
中,并在 GetConfigs
方法中使用 _logger.LogInformation
方法记录了两条日志。这样,当我们调用这个接口时,就会在Loki中看到对应的日志记录。如下图所示:
Tip:日志的级别可以根据需要进行调整,例如使用
_logger.LogError
记录错误日志,使用_logger.LogWarning
记录警告日志等。同时,日志不宜过于冗长,应该简洁明了,便于快速定位问题,也不宜过于频繁地记录日志,以免影响性能。
三、总结
通过以上的修改,我们成功地将Loki日志服务集成到了孢子记账项目中,并且实现了每个微服务可以单独定义日志的 AppName
。这样做不仅减少了代码重复,还提高了日志的可维护性和可读性。
在实际开发中,日志是非常重要的,它可以帮助我们快速定位问题和分析系统运行状态。通过使用Loki,我们可以将日志集中存储和查询,极大地提高了日志管理的效率。
的 AppName
。这样做不仅减少了代码重复,还提高了日志的可维护性和可读性。
在实际开发中,日志是非常重要的,它可以帮助我们快速定位问题和分析系统运行状态。通过使用Loki,我们可以将日志集中存储和查询,极大地提高了日志管理的效率。
在下一篇文章中,我们将继续扩展孢子记账项目的功能,实现更多的微服务功能。希望大家继续关注孢子记账项目的进展,一起学习和探索微服务架构的更多可能性!