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

如何使用前缀语法从appsettings.json获取Serilog指定WriteTo对象

如何通过前缀语法从appsettings.json的Serilog配置中筛选特定WriteTo对象?

配置片段:

"Serilog": {
  "Using": [ "Serilog.Enrichers.Thread", "Serilog.Enrichers.Process", "Serilog.Enrichers.MachineName", "Serilog.Enrichers.FromLogContext" ],
  "Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
  "MinimumLevel": {
    "Default": "Information",
    "Override": {
      "Microsoft": "Warning",
      "System": "Warning"
    }
  },
  "WriteTo": [
    {
      "Name": "Console",
      "Args": {
        "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"
      }
    },
    {
      "Name": "ApplicationInsights",
      "Args": {
        "instrumentationKey": "your-instrumentation-key",
        "restrictedToMinimumLevel": "Information"
      }
    },
    {
      "Name": "Seq",
      "Args": {
        "serverUrl": "https://localhost:5341/",
        "apiKey": ""
      }
    }
  ]
}

我尝试用以下代码获取可筛选的数组,但返回的是三个空对象:

var ary = _config.GetSection("Serilog:WriteTo").GetChildren();

希望能用类似Serilog:WriteTo:Name='Seq'的前缀语法直接定位到该配置段并提取值,请问是否有这样的语法实现,或者更优的解决方案?


解决方案

.NET配置系统本身不支持直接通过带条件的前缀语法筛选数组元素,但可以通过以下几种方式实现需求:

1. 绑定到强类型对象后筛选

先定义与配置结构匹配的类,将整个WriteTo数组绑定为强类型列表,再通过LINQ筛选目标项:

// 定义对应配置类
public class SerilogWriteToItem
{
    public string Name { get; set; }
    public SerilogWriteToArgs Args { get; set; }
}

public class SerilogWriteToArgs
{
    public string OutputTemplate { get; set; }
    public string InstrumentationKey { get; set; }
    public string RestrictedToMinimumLevel { get; set; }
    public string ServerUrl { get; set; }
    public string ApiKey { get; set; }
}

// 绑定并筛选
var writeToItems = _config.GetSection("Serilog:WriteTo").Get<List<SerilogWriteToItem>>();
var seqConfig = writeToItems?.FirstOrDefault(item => item.Name == "Seq");

if (seqConfig != null)
{
    var seqServerUrl = seqConfig.Args.ServerUrl;
    // 处理Seq配置
}

2. 手动遍历子节点筛选

你之前得到空对象是因为GetChildren()返回的是数组中每个元素的配置节点,需要从节点中读取具体属性值,而非直接将节点视为对象。可以遍历这些节点并筛选:

var writeToSections = _config.GetSection("Serilog:WriteTo").GetChildren();
IConfigurationSection seqSection = null;

foreach (var section in writeToSections)
{
    var name = section.GetValue<string>("Name");
    if (name == "Seq")
    {
        seqSection = section;
        break;
    }
}

if (seqSection != null)
{
    var serverUrl = seqSection.GetValue<string>("Args:serverUrl");
    var apiKey = seqSection.GetValue<string>("Args:apiKey");
    // 提取所需配置值
}

3. 封装扩展方法复用

如果需要频繁筛选配置数组,可以封装一个扩展方法简化操作:

public static class ConfigurationExtensions
{
    public static IConfigurationSection GetArraySectionByKey(this IConfiguration config, string arrayPath, string keyName, string keyValue)
    {
        var arraySection = config.GetSection(arrayPath);
        foreach (var itemSection in arraySection.GetChildren())
        {
            var value = itemSection.GetValue<string>(keyName);
            if (value == keyValue)
            {
                return itemSection;
            }
        }
        return null;
    }
}

// 使用示例
var seqSection = _config.GetArraySectionByKey("Serilog:WriteTo", "Name", "Seq");
if (seqSection != null)
{
    // 处理配置
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:10:26