You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Web API无法连接Elasticsearch,求助问题排查

.NET Web API连接Elasticsearch日志报错问题排查与修复

问题背景

尝试使用Serilog为.NET Web API配置日志,将日志发送至Docker运行的Elasticsearch并在Kibana查看,但API连接Elasticsearch持续报错,不同版本的Serilog.Sinks.Elasticsearch包出现不同错误:

  • v10.0.0:产品校验失败,无法确认服务器是Elasticsearch
  • v8.4.1:连接被拒绝

现有配置

Program.cs日志配置

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(builder.Configuration)
    .Enrich.FromLogContext()
    .Enrich.WithMachineName()
    .Enrich.WithEnvironmentName()
    .Enrich.WithExceptionDetails()
    .WriteTo.Console()
    .WriteTo.Elasticsearch(ConfigureElasticSink(builder.Configuration))                
    .CreateLogger();

builder.Host.UseSerilog();

private static ElasticsearchSinkOptions ConfigureElasticSink(IConfiguration configuration)
{
    var elasticUri = configuration.GetValue<string>("ElasticConfiguration:Uri");
    
    return new ElasticsearchSinkOptions(elasticUri != null ? new Uri(elasticUri) : null)
    {
        AutoRegisterTemplate = true,
        IndexFormat = $"{Assembly.GetExecutingAssembly().GetName().Name?.ToLower().Replace(".","-")}-{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}-{DateTime.UtcNow:yyyy-MM--dd}",
        AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
        NumberOfReplicas = 1,
        NumberOfShards= 2,
        OverwriteTemplate = true,
        TemplateName = "DevProject",
        TypeName = null,
        BatchAction = ElasticOpType.Create
    };            
}

Docker Compose配置

elasticsearch:
  image: docker.elastic.co/elasticsearch/elasticsearch:8.12.1
  container_name: elasticsearch
  restart: always
  environment:
    - discovery.type=single-node
    - xpack.security.enabled=false 
  ports:
    - 9200:9200
  networks:
    - infrastructure
  volumes:
    - esdata:/usr/share/elasticsearch/data

kibana:
  image: docker.elastic.co/kibana/kibana:8.12.1
  container_name: kibana
  restart: always
  environment:
    - ELASTICSEARCH_URL=http://127.0.0.1:9200
  ports:
    - "5601:5601"
  networks:
    - infrastructure
  depends_on:
    - elasticsearch

volumes:
  esdata:

networks:
   infrastructure:
      name: infrastructure
      driver: bridge 

测试连接代码

[HttpGet("TestConnection")]
public async Task<IActionResult> TestConnection()
{
    var connectionSettings = new ConnectionConfiguration(_elasticsearchUri);
    var lowLevelClient = new ElasticLowLevelClient(connectionSettings);

    try
    {
        var response = await lowLevelClient.PingAsync<StringResponse>();

        if (response.Success)
        {
            return Ok("Elasticsearch connection successful.");
        }
        else
        {
            return StatusCode(500, "Failed to connect to Elasticsearch.");
        }
    }
    catch (Exception ex)
    {
        return StatusCode(500, $"Error connecting to Elasticsearch: {ex.Message}");
    }
}

修复步骤

1. 修正Docker网络访问地址

如果API运行在Docker容器中,不能用http://127.0.0.1:9200,因为容器内的127.0.0.1指向自身,而非宿主机的Elasticsearch容器。需改用容器名http://elasticsearch:9200,同一Docker网络内可通过容器名直接解析。

修改appsettings.json中的配置:

"ElasticConfiguration": {
  "Uri": "http://elasticsearch:9200"
}

若API在宿主机运行,确认宿主机9200端口可访问:执行curl http://127.0.0.1:9200,返回健康状态则正常。

2. 修复Serilog Sink配置错误

修正IndexFormat日期格式

原配置中日期部分多了一个连字符yyyy-MM--dd,改为yyyy-MM-dd:

IndexFormat = $"{Assembly.GetExecutingAssembly().GetName().Name?.ToLower().Replace(".","-")}-{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}-{DateTime.UtcNow:yyyy-MM-dd}",

禁用产品校验(针对v10.0.0版本报错)

Elasticsearch 8.x的产品校验逻辑变化,需在Sink配置中禁用:

private static ElasticsearchSinkOptions ConfigureElasticSink(IConfiguration configuration)
{
    var elasticUri = configuration.GetValue<string>("ElasticConfiguration:Uri");
    
    var sinkOptions = new ElasticsearchSinkOptions(new Uri(elasticUri))
    {
        AutoRegisterTemplate = true,
        IndexFormat = $"{Assembly.GetExecutingAssembly().GetName().Name?.ToLower().Replace(".","-")}-{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}-{DateTime.UtcNow:yyyy-MM-dd}",
        AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
        NumberOfReplicas = 1,
        NumberOfShards= 2,
        OverwriteTemplate = true,
        TemplateName = "DevProject",
        TypeName = null,
        BatchAction = ElasticOpType.Create
    };

    // 添加连接配置,禁用产品校验
    sinkOptions.ModifyConnectionSettings = conn => conn
        .DisableProductCheck();

    return sinkOptions;            
}

3. 修正测试连接代码

测试代码中同样需禁用产品校验,并确保使用正确的地址:

[HttpGet("TestConnection")]
public async Task<IActionResult> TestConnection()
{
    var connectionSettings = new ConnectionConfiguration(_elasticsearchUri)
        .DisableProductCheck(); // 添加此行
    var lowLevelClient = new ElasticLowLevelClient(connectionSettings);

    try
    {
        var response = await lowLevelClient.PingAsync<StringResponse>();

        if (response.Success)
        {
            return Ok("Elasticsearch connection successful.");
        }
        else
        {
            return StatusCode(500, "Failed to connect to Elasticsearch.");
        }
    }
    catch (Exception ex)
    {
        return StatusCode(500, $"Error connecting to Elasticsearch: {ex.Message}");
    }
}

4. 修复Kibana的Elasticsearch地址

Kibana运行在Docker中,同样需用容器名访问Elasticsearch,修改Docker Compose的Kibana配置:

kibana:
  image: docker.elastic.co/kibana/kibana:8.12.1
  container_name: kibana
  restart: always
  environment:
    - ELASTICSEARCH_URL=http://elasticsearch:9200 # 改为容器名
  ports:
    - "5601:5601"
  networks:
    - infrastructure
  depends_on:
    - elasticsearch

5. 确保版本兼容性

  • Elasticsearch 8.x 对应使用 Serilog.Sinks.Elasticsearch v10.x 版本,v8.x版本Sink不兼容Elasticsearch 8.x,建议升级到最新稳定版。

内容的提问来源于stack exchange,提问作者user1417294

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 18:59:59