Zetian.Monitoring

Real-time Metrics & Observability for SMTP Server

Prometheus Ready

Native Prometheus exporter with /metrics endpoint

OpenTelemetry

Full observability with distributed tracing

Real-time Metrics

Live server performance monitoring

Histograms & Percentiles

P95, P99 latency tracking

Low Overhead

Minimal performance impact < 1% CPU

Command Metrics

Detailed SMTP command statistics

Quick Start

Installation

# Install Zetian SMTP Server (required)
dotnet add package Zetian

# Install Monitoring Extension
dotnet add package Zetian.Monitoring

Basic Monitoring

using Zetian.Server;
using Zetian.Monitoring.Extensions;

// Create and start SMTP server
var server = SmtpServerBuilder.CreateBasic();

// Enable monitoring with default settings
server.EnableMonitoring();

await server.StartAsync();

// Get statistics
var stats = server.GetStatistics();
Console.WriteLine($"Active Sessions: {stats?.ActiveSessions}");
Console.WriteLine($"Messages/sec: {stats?.CurrentThroughput?.MessagesPerSecond}");

Prometheus Integration

// Enable Prometheus exporter on port 9090
server.EnablePrometheus(9090);

// With custom host (use "+" for all interfaces - requires admin)
server.EnablePrometheus("0.0.0.0", 9090);  // Listen on all IPv4
server.EnablePrometheus("localhost", 9090); // Listen on localhost only
server.EnablePrometheus("+", 9090);        // All interfaces (requires admin)

// Metrics available at http://localhost:9090/metrics

Available Metrics

Prometheus Metrics

MetricTypeDescription
zetian_sessions_totalCounterTotal SMTP sessions
zetian_messages_total{status}CounterTotal messages (delivered/rejected)
zetian_bytes_total{direction}CounterTotal bytes (in/out)
zetian_errors_total{type}CounterTotal errors by type
zetian_commands_total{command,status}CounterSMTP commands executed
zetian_authentications_total{mechanism,status}CounterAuthentication attempts
zetian_active_sessionsGaugeCurrent active sessions
zetian_uptime_secondsGaugeServer uptime
zetian_memory_bytesGaugeMemory usage
zetian_throughput_messages_per_secondGaugeCurrent message throughput
zetian_command_duration_milliseconds{command}HistogramCommand execution time
zetian_message_size_bytesHistogramMessage size distribution
zetian_session_duration_secondsSummarySession duration statistics

Server Statistics

// Get comprehensive statistics
var stats = server.GetStatistics();

// Basic metrics
Console.WriteLine($"Uptime: {stats.Uptime}");
Console.WriteLine($"Total Sessions: {stats.TotalSessions}");
Console.WriteLine($"Active Sessions: {stats.ActiveSessions}");
Console.WriteLine($"Total Messages: {stats.TotalMessagesReceived}");
Console.WriteLine($"Delivery Rate: {stats.DeliveryRate}%");
Console.WriteLine($"Rejection Rate: {stats.RejectionRate}%");

// Connection metrics
Console.WriteLine($"Connections Accepted: {stats.ConnectionMetrics.AcceptedCount}");
Console.WriteLine($"TLS Usage: {stats.ConnectionMetrics.TlsUsageRate}%");
Console.WriteLine($"Peak Concurrent: {stats.ConnectionMetrics.PeakConcurrentConnections}");

// Authentication metrics
Console.WriteLine($"Auth Success Rate: {stats.AuthenticationMetrics.SuccessRate}%");
Console.WriteLine($"Unique Users: {stats.AuthenticationMetrics.UniqueUsers}");

// Command metrics
foreach (var cmd in stats.CommandMetrics)
{
    Console.WriteLine($"{cmd.Key}: {cmd.Value.AverageDurationMs}ms avg, " +
                      $"{cmd.Value.SuccessRate}% success");
}

// Throughput
var throughput = stats.CurrentThroughput;
Console.WriteLine($"Messages/sec: {throughput.MessagesPerSecond}");
Console.WriteLine($"Bytes/sec: {throughput.BytesPerSecond}");
Console.WriteLine($"Commands/sec: {throughput.CommandsPerSecond}");

Advanced Configuration

Full Configuration

server.EnableMonitoring(builder => builder
    .EnablePrometheus(9090)
    .EnableOpenTelemetry("http://localhost:4317")
    .WithServiceName("smtp-production")
    .WithServiceVersion("1.0.0")
    .EnableDetailedMetrics()
    .EnableCommandMetrics()
    .EnableThroughputMetrics()
    .EnableHistograms()
    .WithUpdateInterval(TimeSpan.FromSeconds(10))
    .WithLabels(
        ("environment", "production"),
        ("region", "us-east-1"),
        ("instance", "smtp-01"))
    .WithCommandDurationBuckets(1, 5, 10, 25, 50, 100, 250, 500, 1000)
    .WithMessageSizeBuckets(1024, 10240, 102400, 1048576, 10485760));

Custom Metrics

// Record custom command metrics
server.RecordMetric("CUSTOM_CMD", success: true, durationMs: 42.5);

// Access metrics collector directly
var collector = server.GetMetricsCollector();
collector.RecordCommand("XCUSTOM", true, 15.3);
collector.RecordAuthentication(true, "CUSTOM_AUTH");
collector.RecordRejection("Custom rejection reason");

OpenTelemetry Integration

using OpenTelemetry;
using Zetian.Server;
using OpenTelemetry.Trace;
using OpenTelemetry.Metrics;
using Zetian.Monitoring.Extensions;

// Configure OpenTelemetry
var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddSource("Zetian.SMTP")
    .AddOtlpExporter(options =>
    {
        options.Endpoint = new Uri("http://localhost:4317");
    })
    .Build();

var meterProvider = Sdk.CreateMeterProviderBuilder()
    .AddMeter("Zetian.SMTP")
    .AddOtlpExporter(options =>
    {
        options.Endpoint = new Uri("http://localhost:4317");
    })
    .Build();

// Enable monitoring with OpenTelemetry
server.EnableMonitoring(builder => builder
    .EnableOpenTelemetry("http://localhost:4317")
    .WithServiceName("smtp-server")
    .WithServiceVersion("1.0.0"));

Deployment Examples

Docker Compose

services:
  smtp:
    image: zetian/smtp:latest
    ports:
      - "25:25"
      - "9090:9090"
  
  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    
  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"

Kubernetes

apiVersion: v1
kind: Service
metadata:
  name: smtp-server
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "9090"
    prometheus.io/path: "/metrics"

Performance Impact

Resource Usage

  • CPU: Less than 1% overhead
  • Memory: 10-50MB depending on traffic
  • Network: Minimal (metrics endpoint only)
  • Storage: No persistent storage required

Best Practices

  • Protect metrics endpoint in production
  • Use firewall rules for Prometheus port
  • Monitor for high cardinality metrics
  • Sanitize custom labels to prevent explosion

Grafana Dashboard

Import Dashboard

  1. 1. Import the Zetian SMTP Dashboard
  2. 2. Configure Prometheus data source
  3. 3. Set server variables

Key Panels

Overview - Sessions, messages, errors, uptime
Connections - Active/peak connections, TLS usage
Performance - Latency percentiles, throughput graphs
Commands - Execution counts and durations
Authentication - Success rates by mechanism
Rejections - Reasons and trends