.NET应用程序中集成Seq日志:从零到生产的实战指南

一、Seq日志平台快速入门

1. 什么是Seq?

Seq(Structured Events Query)是专为.NET平台设计的全功能日志服务器,核心特性包括:

  • 结构化日志存储:将日志事件解析为可查询的字段
  • 实时仪表盘:支持SQL式查询和自定义图表
  • 多语言支持:对C#/.NET的原生集成
  • 容器友好:提供Docker镜像和K8s部署方案

二、Seq部署实践

1. Windows系统部署

# 下载安装包(来自https://datalust.co/download)
msiexec /i seq-2023.3-x64.msi

# 安装向导关键配置:
# - 选择安装路径(推荐C:\seq)
# - 设置管理员账户(用户名/密码)
# - 选择是否立即启动服务

# 验证服务状态
sc query seq

2. Docker部署(生产推荐)

# 创建Docker数据卷并启动容器
docker volume create seq-data
docker run --name seq \
  -d \
  --restart=always \
  -e ACCEPT_EULA=Y \
  -v seq-data:/data \
  -p 5341:80 \  # Web管理界面端口
  -p 5342:5341 \  # 日志接收端口
  datalust/seq:2023.3

# 查看容器日志
docker logs seq

3. Kubernetes部署

# seq-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: seq
spec:
  replicas: 2
  selector:
    matchLabels:
      app: seq
  template:
    metadata:
      labels:
        app: seq
    spec:
      containers:
      - name: seq
        image: datalust/seq:latest
        env:
        - name: ACCEPT_EULA
          value: "Y"
        - name: SEQ_METASTORE_POSTGRES_CONNECTIONSTRING
          value: "Host=postgres;Database=seq"
        ports:
        - containerPort: 80
        resources:
          limits:
            memory: "2Gi"
            cpu: "1"
          requests:
            memory: "512Mi"
            cpu: "0.5"
---
# 服务暴露
apiVersion: v1
kind: Service
metadata:
  name: seq
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: seq

三、Serilog集成实战

1. 添加NuGet包

dotnet add package Serilog.Sinks.Seq
dotnet add package Serilog.Sinks.Console

2. 配置Serilog(Program.cs)

using Serilog;
using Serilog.Events;

// 创建日志记录器
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
    .Enrich.WithMachineName()  // 添加机器名
    .Enrich.WithThreadId()     // 添加线程ID
    .WriteTo.Console(  // 控制台输出(开发环境)
        outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"
    )
    .WriteTo.Seq(  // Seq输出
        "http://localhost:5341",
        apiKey: "YOUR_API_KEY",  // 从Seq界面获取
        controlLevelSwitch: new LoggingLevelSwitch { InitialLevel = LogEventLevel.Debug },
        period: TimeSpan.FromSeconds(10),  // 批量发送间隔
        batchPostingLimit: 50  // 每批最多50条
    )
    .CreateLogger();

try
{
    Log.Information("应用程序启动");
    
    // 你的业务代码
    var result = DoSomeWork();
    
    Log.Information("工作结果:{Result}", result);
}
catch (Exception ex)
{
    Log.Fatal(ex, "应用程序意外终止");
}
finally
{
    Log.CloseAndFlush();  // 确保日志全部发送
}

3. 结构化日志示例

// 使用占位符记录结构化数据
Log.Information("用户 {User} 登录系统", "admin");

// 记录异常(自动关联上下文)
try
{
    throw new InvalidOperationException("测试异常");
}
catch (Exception ex)
{
    Log.Error(ex, "发生异常");
}

四、NLog集成详解

1. 添加NuGet包

dotnet add package NLog
dotnet add package NLog.Web.AspNetCore
dotnet add package NLog.Targets.Seq

2. 配置nlog.config


<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Info"
      throwConfigExceptions="true">
  
  
  <extensions>
    <add assembly="NLog.Targets.Seq" />
  extensions>

  
  <variable name="layout" value="${longdate}|${level:uppercase=true}|${logger}|${message}${exception:format=message}" />

  <targets>
    
    <target name="console" xsi:type="Console" layout="${layout}" />

    
    <target name="seq" xsi:type="Seq"
            serverUrl="http://localhost:5341"
            apiKey="YOUR_API_KEY"
            batchSize="100"
            period="00:00:05"
            async="true">
      
      <property name="Environment" value="Development" />
      <property name="Application" value="MyApp" />
    target>
  targets>

  
  <rules>
    <logger name="*" minlevel="Debug" writeTo="console,seq" />
  rules>
nlog>

3. 启用NLog(Startup.cs)

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // 清除默认日志提供程序
        services.ClearProviders();
        
        // 配置NLog
        services.AddLogging(loggingBuilder =>
        {
            loggingBuilder.SetMinimumLevel(LogLevel.Trace);
            loggingBuilder.AddNLog(WebConstants.NLogConfigPath);  // 指定nlog.config路径
        });
        
        // 其他服务配置...
    }
}

五、高级配置与优化

1. API密钥管理

// 在Seq界面创建API密钥(管理 > API密钥)
// 示例:为生产环境创建专用密钥
var apiKey = Environment.GetEnvironmentVariable("SEQ_API_KEY") 
               ?? "default_key";

2. 性能调优

// Serilog批量发送配置
.WriteTo.Seq(
    serverUrl: "http://seq.prod:5341",
    apiKey: "PROD_KEY",
    period: TimeSpan.FromSeconds(30),  // 增大批量间隔
    batchPostingLimit: 1000,           // 增大批量大小
    queueLimit: 5000,                  // 增加队列容量
    retryAttempts: 3                   // 失败重试次数
)

// NLog异步配置
<target name="seq" xsi:type="Seq" async="true" />

3. 内存限制配置(Docker)

# 设置最大内存和缓存策略
docker run --name seq \
  -e SEQ_CACHE_SYSTEMRAMTARGET="1024MB" \  # 最大内存
  -e SEQ_METASTORE_SQLITE=true \          # 使用SQLite(轻量模式)
  datalust/seq:2023.3

六、生产环境部署注意事项

1. 安全配置

# 启用HTTPS(Docker)
docker run --name seq \
  -e ACCEPT_EULA=Y \
  -e SEQ_HTTPS__ENABLED=true \
  -e SEQ_HTTPS__CERTIFICATE__PATH=/certs/seq.pfx \
  -e SEQ_HTTPS__CERTIFICATE__PASSWORD="SecurePass123!" \
  datalust/seq:2023.3

2. 高可用部署(K8s)

# StatefulSet配置(带持久化)
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: seq
spec:
  serviceName: seq
  replicas: 3
  selector:
    matchLabels:
      app: seq
  template:
    metadata:
      labels:
        app: seq
    spec:
      containers:
      - name: seq
        image: datalust/seq:latest
        volumeMounts:
        - name: seq-data
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: seq-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 20Gi

七、常见问题与解决方案

1. 日志丢失问题

// 确保调用CloseAndFlush
try
{
    // 应用程序逻辑
}
finally
{
    Log.CloseAndFlush();  // Serilog
    LogManager.Shutdown();  // NLog
}

2. 连接超时处理

// Serilog配置超时
.WriteTo.Seq(
    serverUrl: "http://slow-seq:5341",
    retryAttempts: 5,
    retryDelay: TimeSpan.FromSeconds(10)
)

3. 日志格式混乱


<target name="seq" xsi:type="Seq">
  <property name="CorrelationId" value="${aspnet-TraceIdentifier}" />
  <property name="RequestMethod" value="${aspnet-request-method}" />
target>

八、扩展功能与生态集成

1. 与Prometheus监控集成

# seq-deployment.yaml
env:
- name: SEQ_DASHBOARDING__ENABLED
  value: "true"
- name: SEQ_HEALTHCHECKS__ENABLED
  value: "true"

2. 自定义字段与筛选

// Serilog添加自定义属性
Log.ForContext("TenantId", "ACME")
   .Information("请求处理完成");

通过本文的实践,你已掌握:
从零部署Seq日志平台
Serilog与NLog的深度集成技巧
生产环境性能优化方案
容器化部署与高可用配置

配置文件与资源

1. Docker Compose文件(开发环境)

version: '3.8'
services:
  seq:
    image: datalust/seq:2023.3
    ports:
      - "5341:80"
      - "5342:5341"
    volumes:
      - seq-data:/data
    environment:
      - ACCEPT_EULA=Y
      - [email protected]
      - SEQ_DEFAULT_ADMIN_PASSWORD=StrongPass123!
volumes:
  seq-data:

2. 推荐阅读

  • Seq官方文档
  • Serilog官方指南

你可能感兴趣的:(C#学习资料,.net)