任何人都知道SLF4J 通常如何实现结构化日志记录?
是否有任何开源已经可以处理这个问题?
直到今天,我们一直使用 NLog 版本 4.4.12(没有结构化日志记录)。但是,我们使用https://www.nuget.org/packages/NLog.StructuredLogging.Json/进行结构化日志记录。
使用此扩展的好处是您不需要模板化消息(包含用于记录其他参数/对象的索引或占位符)。该消息不包含要记录的其他对象(即匿名类型)的任何索引或占位符。
切换到支持开箱即用结构化日志记录的 NLog 4.6.5,我们希望摆脱额外的 NuGet 包。然而,我们的附加参数仅在使用模板化时记录带有实际索引/命名占位符的消息。
我们的消息中没有索引或占位符确实会导致我们的附加参数/对象无法通过 JSON 呈现。
是否有可能有非模板化的消息,但仍然使用 NLog 的结构化日志记录我们已经传递给它们以添加到 JSON 中的附加参数?
下面是一个例子(请注意,我们在 nlog 周围使用了一个额外的包装器)
日志版本:4.6.5
平台:.Net 4.5
当前 NLog 配置
// Arrange
var typeUsingLogger = typeof(NLogWrapperTest);
var nLogWrapper = new NLogWrapper(typeof(NLogWrapper));
var level = (LogLevel)Enum.Parse(typeof(LogLevel), nLevel.Name);
var message = $"{Guid.NewGuid()}"; // {{extendedLogProperties}} {{@extendedLogProperties}} {{@purchase}} {{badplaceholder}}
var innerException = new DivideByZeroException("bla inner exception");
var exception = new ArgumentNullException("bla out exception", innerException);
var extendedLogProperties = new
{
ClientID …Run Code Online (Sandbox Code Playgroud) 我可以在 .net core 中做到这一点
_logger.LogInformation("Token validated {clientId}", "MyId");
Run Code Online (Sandbox Code Playgroud)
然后像这样的日志库NLog就会知道有一个使用消息中的clientId值调用的属性,并且可以以特殊的方式呈现它。MyId
我试图做同样的事情,而不将属性包含在消息本身中,但无法成功解决它。这是我到目前为止所做的,它不会导致以下属性NLog:
LogEventInfo info = new LogEventInfo
{
Properties = {{"clientId", "MyId"}},
};
_logger.Log(Microsoft.Extensions.Logging.LogLevel.Information, "Token validated", info, null, info.MessageFormatter);
Run Code Online (Sandbox Code Playgroud)
这会导致消息没有属性。有没有更好的方法来做到这一点或者我做错了什么?
我正在使用 python日志记录模块以及python-json-logger,我想添加一些键:
{
"app_name": "myapp",
"env": "prod"
}
Run Code Online (Sandbox Code Playgroud)
自动查看我的所有日志,无需执行以下操作。
{
"app_name": "myapp",
"env": "prod"
}
Run Code Online (Sandbox Code Playgroud)
但要让它像我一样工作。:)
我们通过 Filebeat 将 Kubernetes 集群中运行的各种服务的日志发送到 Elasticsearch。其中一些服务是我们自己开发的,其他服务是第三方的。我们在索引中使用动态映射。我们遇到了一个问题,有时一个服务的日志使用的字段恰好与另一个服务的日志共享相同的名称,并且该字段中的数据类型不同。例如,在一项服务的日志中,该url字段可能是一个字符串,但在另一项服务中,它可能是一个结构化对象。然后我们在获取日志时遇到错误,内容如下:
{
"type": "mapper_parsing_exception",
"reason": "object mapping for [url] tried to parse field [url] as object, but found a concrete value"
}
Run Code Online (Sandbox Code Playgroud)
我们可以使用什么策略来避免这些冲突?
我尝试按以下方式使用 ILogger,
_logger.LogInformation("Logging info {someClass}", someClass);
Run Code Online (Sandbox Code Playgroud)
但输出只是对象名称。
我在这里做错了什么?
我想格式化结构化日志中的时间戳。目前我定义logback.xml如下:
<configuration>
<appender name="json" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<fieldNames>
<timestamp>timestamp</timestamp>
<logger>[ignore]</logger>
<version>[ignore]</version>
<levelValue>[ignore]</levelValue>
<stackTrace>exception</stackTrace>
</fieldNames>
</encoder>
</appender>
<root name="jsonLogger" level="DEBUG">
<appender-ref ref="json"/>
</root>
</configuration>
Run Code Online (Sandbox Code Playgroud)
使用<fieldNames>我可以更改时间戳字段的名称。
如何通过配置更改时间戳的模式logback.xml?