AgentSkillsCN

serilog

为 VanDaemon 实现结构化日志记录,并配置 Serilog 日志接收器。 适用于:为服务添加日志记录、配置日志接收器、借助结构化数据进行调试、设置日志丰富化时使用。

SKILL.md
--- frontmatter
name: serilog
description: |
  Implements structured logging and configures Serilog sinks for VanDaemon.
  Use when: Adding logging to services, configuring log sinks, debugging with structured data, setting up log enrichment.
allowed-tools: Read, Edit, Write, Glob, Grep, Bash

Serilog Skill

VanDaemon uses Serilog 8.x for structured logging with console and file sinks. Logs use semantic message templates with named properties for queryability. The API layer configures Serilog in Program.cs with rolling file output to logs/vandaemon-{Date}.txt.

Quick Start

Basic Structured Logging

csharp
// Inject ILogger<T> via constructor
private readonly ILogger<TankService> _logger;

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

// Use semantic message templates - property names in braces
_logger.LogInformation("Tank {TankId} updated to {Level}%", tankId, level);
_logger.LogWarning("Tank {TankName} below threshold: {CurrentLevel}% < {Threshold}%", 
    tank.Name, tank.CurrentLevel, tank.AlertLevel);

Exception Logging

csharp
try
{
    await plugin.SetStateAsync(controlId, state, ct);
}
catch (Exception ex)
{
    // Exception as FIRST parameter, then message template
    _logger.LogError(ex, "Failed to set state for control {ControlId}", controlId);
    throw;
}

Key Concepts

ConceptUsageExample
Message TemplateNamed placeholders for structured data"Processing {TankId}"
Log LevelSeverity filteringLogInformation, LogWarning, LogError
EnrichmentAutomatic context propertiesEnrich.FromLogContext()
SinkOutput destinationConsole, File, Seq

Common Patterns

Service Layer Logging

When: Logging business operations with context

csharp
public async Task<Tank> UpdateTankAsync(Tank tank, CancellationToken ct)
{
    _logger.LogDebug("Updating tank {TankId}: {TankName}", tank.Id, tank.Name);
    
    // Business logic...
    
    _logger.LogInformation("Tank {TankId} saved successfully", tank.Id);
    return tank;
}

Plugin Lifecycle Logging

When: Tracking plugin initialization and disposal

csharp
public async Task InitializeAsync(Dictionary<string, object> config, CancellationToken ct)
{
    _logger.LogInformation("Initializing {PluginName} v{Version}", Name, Version);
    
    if (!config.TryGetValue("MqttBroker", out var broker))
    {
        _logger.LogWarning("{PluginName} missing MqttBroker config, using default", Name);
    }
}

See Also

  • patterns - Structured logging patterns and enrichment
  • workflows - Configuration and debugging workflows

Related Skills

  • See the aspnet-core skill for middleware logging configuration
  • See the dotnet skill for DI registration patterns
  • See the docker skill for viewing container logs