目录
背景
传统方法
日志器即服务方法
实现日志器即服务
每个微服务日志器在其单独的表中
误差水平的控制
使用代码
内部日志
兴趣点
背景 传统方法在单体应用程序或来自不同供应商的独立应用程序的世界中,系统中日志信息的模式主要使用直接合并到应用程序中的日志器程序,并在每个应用程序中单独配置。
但是在微服务生态系统中,我们可以拥有数十个微服务,每个微服务都需要复杂的配置和安装才能使用标准方法进行日志,这为维护系统提供了一系列需要解决的问题。让我们来看看其中的一些。
- 您需要使用选定的日志器框架单独配置每个服务。
- 每个微服务都需要访问存储日志的数据库。
- 如果要更新日志器,则需要单独更新每个微服务。
另一方面,企业中的微服务越来越倾向于安装在云中,带有一些容器,甚至在不同的操作系统中。
另一个问题是关于安全性,您需要为每个服务授予对数据库系统的访问权限,以防您想日志到数据库。
日志器即服务方法那么如果微服务很好,为什么不使用相同的概念来创建我们的日志器系统呢?使用logger as a service给你带来很多好处,首先logger框架只安装在一个微服务中,其余的只需要使用一些网络协议将信息发送到logger,最大限度地减少数据库资源的暴露。
这种架构还具有以下优点:
首先,服务的更新只需要在一个服务中完成:logger微服务,如果你不改变与logger客户端的接口,你可以更新logger框架,甚至只在一个服务中改变其他无需接触系统的其余部分。
第二大优势是你只需要在这个唯一的服务中配置对数据库的访问,而不是在所有服务中。
这里的另一个好处是你可以将你的数据库隐藏在你的内部网很深的地方,日志器服务需要对公司内部网内的微服务开放,给定安全级别,但你的数据库将在一个完全隔离的子网中使用日志器微服务的服务。
而且,最后,还有一个很大的价值,因为日志器是一项服务,你不需要关心客户端正在运行什么,对你来说,它是访问你服务的人。
除了将日志器创建为服务的一般策略之外,我们还可以引入一些设计决策,使我们的服务比传统的服务框架更灵活。
每个微服务日志器在其单独的表中也许你在问日志器如何对来自数据库中不同服务的不同条目进行分类,在这个实现中,我们决定将每个微服务日志在不同的表中,为了管理这个,日志器请求有一个字段,每个服务都有一个特定的令牌。
令牌用于获取表的名称,链接它的信息位于我们应用程序的appsettings.json中,如果您使用的是.NET的早期版本,则位于web.config中)。如果令牌存在,则选择该表并且日志器将信息写入该表中。
在我们的方法中,我们尽可能简单地维护服务,我们作为示例使用的实现不管理错误级别,然后我们在客户端.dll(可以作为NuGet包实现)中利用它,您可以根据您的特定需要创建错误级别的管理,以及何时应将信息移至日志器或根据设置级别拒绝信息。
这在客户端服务中引入了某种级别的配置,但在应用程序的配置中管理设置字符串并不是什么大问题。
我们创建了一个日志器作为服务的实现,可以在Github中作为开源下载。我们在这里解释代码的基本部分。最后,我们创建的日志器是一个能够登录SQL Server数据库的简单服务。我们创建它作为示例,但如果需要,代码能够在生产环境中工作。
服务的代码基本上具有以下结构:
- 日志信息的服务
- 内部日志日志问题
- 添加对令牌的配置设置——要使用的每个客户端的表
- 访问数据库我们这里不讨论,因为它是微不足道的
服务非常简单:
///
/// Enter the info in the log.
/// if error returns a http 500 internal server error
/// and an HttpError based in the exception information
///
///
/// The information to be logged
///
/// null is ok
/// If error return a httpError Class
[HttpPost("LogEntryAsync")]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(typeof(ErrorManager), StatusCodes.Status500InternalServerError)]
[ProducesResponseType(typeof(ErrorManager), StatusCodes.Status400BadRequest)]
public async Task PostLogEntryAsync([FromBody] LogRequest request)
{
await bo.PostLogEntryAsync(request);
return Ok();
}
Log的对象如下:
///
/// The Log Request Class
///
public class LogRequest
{
///
/// Used to link the error to the user with the log
/// logged
///
[DataType(DataType.DateTime)]
public DateTime? CreatedDate { get; set; }
///
/// The name of the machine where log is emitted
///
[Required(AllowEmptyStrings = false)]
[StringLength(maximumLength: 255, MinimumLength = 5)]
public string MachineName { get; set; }
///
/// The register Level
///
[Required]
[StringLength(50, MinimumLength = 5)]
public string Level { get; set; }
///
/// The name of the logger,
/// this is the token used to localized the table
///
[Required(AllowEmptyStrings = false)]
[StringLength(maximumLength: 255, MinimumLength = 5)]
public string Logger { get; set; }
///
/// The message to be show
///
[Required(AllowEmptyStrings = true)]
public string Message { get; set; }
///
/// The exception Message to be logged
///
public string Exception { get; set; }
}
请求对象中有趣的事情是:
- CreatedTime: 是可选的。为什么?我们可以让日志输入日志发生的日期和时间,但您也可以从服务中设置日期时间。当您希望将友好消息与存储在日志器中的技术信息链接到用户时,这特别有用。
- MachineName:此字段允许您输入发送日志请求的机器的名称。当您可以拥有微服务的不同实例时,这在微服务中非常有用,以确切知道向哪台机器发送信息。
- Level:这是进入日志信息的级别。通常,值为ERROR FATAL,INFO等等,这是一个开放的领域。这个想法是您可以使用配置错误级别的客户端。例如,当用户使用NuGet包时,您可以在特定客户端中设置错误级别,并使每个客户端的错误级别不同。
- Logger:这是发送令牌以标识使用该服务的客户端的字段。这与appSettings.json结合使用以确定您要在哪个表中日志信息。
- Message和Exception:使用这两个字段输入要日志的信息。
这用于日志其正确的表错误,因为错误令牌形成错误的请求对象,数据库中缺少表等。内部日志器具有其正确的设置配置。
内部日志器也以防止应用程序中的错误循环的形式完成。
配置内部日志器的参数很简单,如以下代码所示:
{
"InternalLogSettings": {
"Table": "ServeLog",
"_Comment": "Log Level Values: DEBUG, ERROR",
"Level": "DEBUG",
"_Comment1": "Time Zone Examples: UTC, Eastern Standard Time",
"TimeZone": "UTC"
}
}
您可以选择不同的时区来输入日志注释。
另一个重要的事情是程序如何将令牌与Table名称匹配。这可以使用appSettings.json文件轻松完成。
{
"Tables": {
"TESTTOKEN": "TestLog",
"YOURTOKEN": "YourTableLog"
}
}
第一个条目用于内部日志器,您可以向不同表中的日志器添加更多条目,与您拥有的客户端数量一样。在示例中,我们添加了一个额外的条目。
兴趣点- 当你拥有一个由几十个微服务组成的生态系统时,安装在每个服务中的传统日志器可能会很痛苦。您需要单独配置每个,如果您是数据库日志器,您还有很多数据库工作要做。
- 另一方面,如果您使用创建一个功能为logger的微服务,则该logger是您环境中唯一可以像其他服务一样通过HTTP协议访问的其他微服务。使用此配置可以大大简化配置和访问数据库的问题。
- 我们在这里解释了一个示例,该示例允许您日志不同表中的每个服务,并使用软件客户端个性化您的日志器级别。
- 您可以在我们的示例中看到为生产服务做好准备的功能。您可以从GIT下载它。该代码作为开源项目提供。
- 您可以在https://youtu.be/3O1DymP8XOo 上看到与本文相关的视频 。
https://www.codeproject.com/Articles/5310980/NET-Core-Microservices-in-the-Enterprise-Logger-a