本片文章我们一起将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并设置到LokiOptions
var 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,我们可以将日志集中存储和查询,极大地提高了日志管理的效率。
在下一篇文章中,我们将继续扩展孢子记账项目的功能,实现更多的微服务功能。希望大家继续关注孢子记账项目的进展,一起学习和探索微服务架构的更多可能性!