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

基于ASP.NET Core构建Serilog Elasticsearch日志代理的实现示例咨询

基于ASP.NET Core搭建ELK日志代理实现方案

一、日志代理API搭建(ASP.NET Core)

1. 创建项目并引入依赖

新建ASP.NET Core Web API项目,安装以下NuGet包:

  • Serilog.AspNetCore:用于日志接收与转发处理
  • Serilog.Sinks.Elasticsearch:实现日志向ELK的转发
  • Microsoft.AspNetCore.Mvc.NewtonsoftJson:适配日志JSON格式的序列化/反序列化

2. 实现日志接收接口

创建LogsController提供批量日志接收的POST接口:

[ApiController]
[Route("api/[controller]")]
public class LogsController : ControllerBase
{
    private readonly ILogger<LogsController> _logger;

    public LogsController(ILogger<LogsController> logger)
    {
        _logger = logger;
    }

    [HttpPost("batch")]
    public IActionResult ReceiveBatchLogs([FromBody] List<LogEventDto> logEvents)
    {
        if (logEvents == null || !logEvents.Any())
        {
            return BadRequest("日志列表不能为空");
        }

        foreach (var logEvent in logEvents)
        {
            if (!Enum.TryParse<LogEventLevel>(logEvent.Level, out var level))
            {
                level = LogEventLevel.Information;
            }
            _logger.Log(level, logEvent.MessageTemplate, logEvent.Properties);
        }

        return Ok();
    }
}

// 日志传输DTO,对齐Serilog日志结构
public class LogEventDto
{
    public string Level { get; set; }
    public string MessageTemplate { get; set; }
    public Dictionary<string, object> Properties { get; set; }
    public DateTime Timestamp { get; set; }
}

3. 配置Serilog转发至ELK

在Program.cs中配置Serilog,将接收的日志转发到ELK:

var builder = WebApplication.CreateBuilder(args);

// 配置Serilog
builder.Host.UseSerilog((context, config) =>
{
    var elasticConfig = context.Configuration.GetSection("Elasticsearch");
    var elasticUri = elasticConfig["Uri"];
    var elasticUsername = elasticConfig["Username"];
    var elasticPassword = elasticConfig["Password"];

    config.ReadFrom.Configuration(context.Configuration)
          .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri(elasticUri))
          {
              AutoRegisterTemplate = true,
              IndexFormat = "logs-proxy-{0:yyyy.MM.dd}",
              ConnectionTimeout = TimeSpan.FromSeconds(10),
              BasicAuthCredentials = new BasicAuthCredentials(elasticUsername, elasticPassword)
          });
});

builder.Services.AddControllers()
                .AddNewtonsoftJson(options =>
                {
                    options.SerializerSettings.ContractResolver = new DefaultContractResolver();
                });

var app = builder.Build();

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

在appsettings.json中配置ELK连接信息:

{
  "Elasticsearch": {
    "Uri": "https://your-elk-address:9200",
    "Username": "elastic",
    "Password": "your-elk-password"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

二、控制台应用端调整Serilog配置

1. 引入HTTP Sink依赖

控制台应用安装NuGet包:Serilog.Sinks.Http

2. 替换原ELK Sink为HTTP Sink

修改原有日志配置扩展方法,改为向代理API批量发送日志:

private static LoggerConfiguration AddLogProxy(this LoggerConfiguration config, IConfigurationRoot configuration,
     string keyIdentifier)
{
    var proxyApiUrl = configuration["LogProxy:ApiUrl"];

    if (string.IsNullOrEmpty(proxyApiUrl))
    {
        Console.WriteLine("日志代理API地址未配置");
        return config;
    }

    config.WriteTo.Http(
        requestUri: $"{proxyApiUrl}/api/logs/batch",
        batchPostingLimit: 50,
        period: TimeSpan.FromSeconds(10),
        formatter: new CustomLogFormatter()
    );

    return config;
}

// 自定义格式化器,适配代理API的DTO结构
public class CustomLogFormatter : ITextFormatter
{
    public void Format(LogEvent logEvent, TextWriter output)
    {
        var logDto = new LogEventDto
        {
            Level = logEvent.Level.ToString(),
            MessageTemplate = logEvent.MessageTemplate.Text,
            Properties = logEvent.Properties.ToDictionary(kv => kv.Key, kv => kv.Value.ToString()),
            Timestamp = logEvent.Timestamp.DateTime
        };

        output.WriteLine(JsonConvert.SerializeObject(logDto));
    }
}

控制台应用appsettings.json添加代理地址配置:

{
  "LogProxy": {
    "ApiUrl": "https://your-proxy-api-address"
  }
}

三、关键注意事项

  • 批量策略调整:控制台端的batchPostingLimit(批量阈值)和period(发送间隔)可根据业务需求调整,平衡日志实时性与请求量
  • 格式一致性:确保控制台端的日志DTO与代理API接收的结构完全匹配,避免解析失败
  • 可靠性保障:可给代理API添加重试、熔断机制(如Polly),防止日志丢失
  • 安全防护:代理API可添加API Key认证,控制台端请求时携带密钥,比直接暴露ELK凭证更安全
  • 日志预处理:可在代理API层添加日志过滤、敏感信息脱敏等逻辑,统一管控日志内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 05:25:05