Seq(Structured Events Query)是专为.NET平台设计的全功能日志服务器,核心特性包括:
# 下载安装包(来自https://datalust.co/download)
msiexec /i seq-2023.3-x64.msi
# 安装向导关键配置:
# - 选择安装路径(推荐C:\seq)
# - 设置管理员账户(用户名/密码)
# - 选择是否立即启动服务
# 验证服务状态
sc query seq
# 创建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
# 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
dotnet add package Serilog.Sinks.Seq
dotnet add package Serilog.Sinks.Console
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(); // 确保日志全部发送
}
// 使用占位符记录结构化数据
Log.Information("用户 {User} 登录系统", "admin");
// 记录异常(自动关联上下文)
try
{
throw new InvalidOperationException("测试异常");
}
catch (Exception ex)
{
Log.Error(ex, "发生异常");
}
dotnet add package NLog
dotnet add package NLog.Web.AspNetCore
dotnet add package NLog.Targets.Seq
<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>
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// 清除默认日志提供程序
services.ClearProviders();
// 配置NLog
services.AddLogging(loggingBuilder =>
{
loggingBuilder.SetMinimumLevel(LogLevel.Trace);
loggingBuilder.AddNLog(WebConstants.NLogConfigPath); // 指定nlog.config路径
});
// 其他服务配置...
}
}
// 在Seq界面创建API密钥(管理 > API密钥)
// 示例:为生产环境创建专用密钥
var apiKey = Environment.GetEnvironmentVariable("SEQ_API_KEY")
?? "default_key";
// 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" />
# 设置最大内存和缓存策略
docker run --name seq \
-e SEQ_CACHE_SYSTEMRAMTARGET="1024MB" \ # 最大内存
-e SEQ_METASTORE_SQLITE=true \ # 使用SQLite(轻量模式)
datalust/seq:2023.3
# 启用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
# 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
// 确保调用CloseAndFlush
try
{
// 应用程序逻辑
}
finally
{
Log.CloseAndFlush(); // Serilog
LogManager.Shutdown(); // NLog
}
// Serilog配置超时
.WriteTo.Seq(
serverUrl: "http://slow-seq:5341",
retryAttempts: 5,
retryDelay: TimeSpan.FromSeconds(10)
)
<target name="seq" xsi:type="Seq">
<property name="CorrelationId" value="${aspnet-TraceIdentifier}" />
<property name="RequestMethod" value="${aspnet-request-method}" />
target>
# seq-deployment.yaml
env:
- name: SEQ_DASHBOARDING__ENABLED
value: "true"
- name: SEQ_HEALTHCHECKS__ENABLED
value: "true"
// Serilog添加自定义属性
Log.ForContext("TenantId", "ACME")
.Information("请求处理完成");
通过本文的实践,你已掌握:
✅ 从零部署Seq日志平台
✅ Serilog与NLog的深度集成技巧
✅ 生产环境性能优化方案
✅ 容器化部署与高可用配置
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: