Table of Contents

Getting Started

This guide covers installing Logsmith and writing your first log methods.

Installation

Logsmith supports three installation modes. Choose the one that fits your project:

<PackageReference Include="Logsmith" Version="1.0.0" />

This provides the runtime library (public types, sinks, LogManager) and the source generator. The generator is bundled as an analyzer and does not appear in your build output.

Standalone (zero runtime dependency)

<PackageReference Include="Logsmith.Generator" Version="1.0.0" />

Logsmith.Generator is a thin meta-package that depends on Logsmith for the generator and build assets only (no compile/runtime assets). It defaults to LogsmithMode=Standalone, and the generator emits all infrastructure types as internal into your assembly. No Logsmith DLLs appear in your build output.

Abstraction (library authors)

<PropertyGroup>
    <LogsmithMode>Abstraction</LogsmithMode>
</PropertyGroup>
<PackageReference Include="Logsmith" Version="1.0.0" PrivateAssets="all" />

See Operating Modes for details on all three modes.

Operating Modes Overview

Logsmith supports three modes, controlled by the <LogsmithMode> MSBuild property:

Mode Default for Runtime DLL Generated types Use case
Shared Logsmith package Yes, flows transitively Method bodies only Applications and multi-project solutions
Standalone Logsmith.Generator package No (PrivateAssets="all" required) All types as internal Libraries with zero transitive dependencies
Abstraction Explicit opt-in No (PrivateAssets="all" required) Public interfaces + internal infrastructure Libraries that expose logging contracts to consumers

When both packages are referenced transitively, Shared wins (NuGet evaluates Logsmith.props before Logsmith.Generator.props). Explicit <LogsmithMode> in your .csproj always takes precedence.

In Standalone or Abstraction mode, the Logsmith runtime DLL must not leak to consumers. The build emits LSMITH010 if PrivateAssets="all" is missing on the Logsmith package reference.

What Logsmith Is Not

  • Not a drop-in replacement for Microsoft.Extensions.Logging. The optional Logsmith.Extensions.Logging bridge routes MEL ILogger calls through Logsmith sinks, but MEL-native sink packages (Seq, Datadog, Application Insights, OpenTelemetry) expect MEL's ILoggerProvider ecosystem. Logsmith defines its own ILogSink contract for native sinks.
  • Not a runtime-configurable logging framework. Log levels can be changed at runtime (including via environment variable polling and config file watching), and sinks can be reconfigured, but message templates and parameter bindings are fixed at compile time. There is no runtime expression evaluator or dynamic template engine.

Quick Start

1. Initialize at startup

LogManager.Initialize(config =>
{
    config.MinimumLevel = LogLevel.Debug;
    config.AddConsoleSink();
    config.AddFileSink("logs/app.log", rollingInterval: RollingInterval.Daily);
    config.InternalErrorHandler = ex => Console.Error.WriteLine(ex);
});

2. Declare log methods

[LogCategory("Renderer")]
public static partial class RenderLog
{
    [LogMessage(LogLevel.Debug, "Draw call {drawCallId} completed in {elapsedMs}ms")]
    public static partial void DrawCallCompleted(int drawCallId, double elapsedMs);

    [LogMessage(LogLevel.Error, "Shader compilation failed: {shaderName}")]
    public static partial void ShaderFailed(string shaderName, Exception ex);
}

3. Call them

public class Renderer
{
    public void Draw(int id)
    {
        var sw = Stopwatch.StartNew();
        // ... rendering work ...
        sw.Stop();

        RenderLog.DrawCallCompleted(id, sw.Elapsed.TotalMilliseconds);
    }
}

No logger injection. No sink parameter. No service locator. The generated code dispatches through the static LogManager configured at startup.