我正在尝试设置 Serilog 以便将日志从 ASP.NET Core WebAPI 发送到 Amazon OpenSearch 的本地实例。我在控制台上看到日志,但 OpenSearch 中没有显示任何内容。
安装的第3方库:
OpenSearch 通过 Development Docker Compose 运行(无安全插件):
程序.cs
var logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200"))
{
AutoRegisterTemplate = true,
MinimumLogEventLevel = LogEventLevel.Information,
FailureCallback = FailureCallback,
EmitEventFailure = EmitEventFailureHandling.RaiseCallback | EmitEventFailureHandling.ThrowException
})
.CreateLogger();
builder.Logging.ClearProviders();
builder.Logging.AddSerilog(logger);
控制器类:
_logger.LogWarning("Example warning");
_logger.LogError("Example error");
FailureCallback
是空的。 OpenSearch 控制台没有显示任何问题。
可能出了什么问题?
我已经尝试过您的设置,以下是一些结果(注意仅使用稳定版本的软件):
使用 Docker-compose:
version: '3'
services:
opensearch-node1:
image: opensearchproject/opensearch:2.0.1
container_name: opensearch-node1
environment:
- cluster.name=opensearch-cluster
- node.name=opensearch-node1
- bootstrap.memory_lock=true # along with the memlock settings below, disables swapping
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # minimum and maximum Java heap size, recommend setting both to 50% of system RAM
- "DISABLE_INSTALL_DEMO_CONFIG=true" # disables execution of install_demo_configuration.sh bundled with security plugin, which installs demo certificates and security configurations to OpenSearch
- "DISABLE_SECURITY_PLUGIN=true" # disables security plugin entirely in OpenSearch by setting plugins.security.disabled: true in opensearch.yml
- "discovery.type=single-node" # disables bootstrap checks that are enabled when network.host is set to a non-loopback address
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536 # maximum number of open files for the OpenSearch user, set to at least 65536 on modern systems
hard: 65536
volumes:
- opensearch-data1:/usr/share/opensearch/data
ports:
- 9200:9200
- 9600:9600 # required for Performance Analyzer
networks:
- opensearch-net
opensearch-dashboards:
image: opensearchproject/opensearch-dashboards:2.0.1
container_name: opensearch-dashboards
ports:
- 5601:5601
expose:
- "5601"
environment:
- 'OPENSEARCH_HOSTS=["http://opensearch-node1:9200"]'
- "DISABLE_SECURITY_DASHBOARDS_PLUGIN=true" # disables security dashboards plugin in OpenSearch Dashboards
networks:
- opensearch-net
volumes:
opensearch-data1:
networks:
opensearch-net:
程序.cs
using Serilog;
using Serilog.Events;
using Serilog.Sinks.Elasticsearch;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Logging.ClearProviders();
Serilog.Debugging.SelfLog.Enable(msg => Console.WriteLine(msg));
ServicePointManager.ServerCertificateValidationCallback =
(source, certificate, chain, sslPolicyErrors) => true;
var logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200"))
{
AutoRegisterTemplate = true,
MinimumLogEventLevel = LogEventLevel.Information,
FailureCallback = e => Console.WriteLine("Unable to submit event " + e.MessageTemplate),
EmitEventFailure = EmitEventFailureHandling.RaiseCallback | EmitEventFailureHandling.ThrowException,
TypeName = "_doc",
InlineFields = false
})
.CreateLogger();
builder.Logging.ClearProviders();
builder.Logging.AddSerilog(logger);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
有一些事情可以帮助排除故障
Serilog.Debugging.SelfLog.Enable(msg => Console.WriteLine(msg));
- 将显示来自 Serilog 的真实错误(很可能您会看到 SSL)
ServicePointManager.ServerCertificateValidationCallback = (source, certificate, chain, sslPolicyErrors) => true;
- 暂时停止任何 SSL 问题(您可以稍后修复它们)
我遇到的下一件事是 Serilog 生成的 [_type] 字段的问题,并且 Elastic > v8.2 不接受该字段,这很可能会发生,因为您的缓冲区保留了旧记录。
虽然 Serilog 的最新测试版采用了 TypeName="_doc",但 AWS opensearch 2.0.1 还有另一个与“compatibility.override_main_response_version=true”设置有关的错误(请参阅此处的详细信息) https://github.com/opensearch-project/OpenSearch/pull/3530 - 基本上我建议将 AWS OpenSearch 回滚到 v2。
之后希望它能起作用:)
对我来说,问题是我没有提供 IndexFormat 属性的值(在
ElasticSearchSinkOptions
对象中)。相反,我将其放在端点中,就像通过 REST 插入数据时应该做的那样。总而言之,下面的代码为我解决了这个问题:
var jsonFormatter = new CompactJsonFormatter();
var loggerConfig = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.Map("Name", "**error**", (name, writeTo) =>
{
var currentYear = DateTime.Today.Year;
var currentWeek = calendar.GetWeekOfYear(DateTime.Now,
CalendarWeekRule.FirstDay,
DayOfWeek.Monday);
writeTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("<opensearch endpoint>"))
{
CustomFormatter = jsonFormatter,
TypeName = "_doc",
IndexFormat = $"my-index-{currentYear}-{currentWeek}",
MinimumLogEventLevel = LogEventLevel.Information,
EmitEventFailure = EmitEventFailureHandling.RaiseCallback |
EmitEventFailureHandling.ThrowException,
FailureCallback = e =>
Console.WriteLine(
"An error occured in Serilog ElasticSearch sink: " +
$"{e.Exception.Message} | {e.Exception.InnerException?.Message}")
});
});
Log.Logger = loggerConfig.CreateLogger();
当然,您还需要正确设置 OpenSearch,以便它可以自动将策略应用于您的索引等。
最近我也必须解决这个工作问题。我通过实现我自己的 OpenSearch Sink 来做到这一点。它位于我们公司的 GutHub 上:https://github.com/appfacterp/AppFact.SerilogOpenSearchSink