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.MonitoringBasic 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/metricsAvailable Metrics
Prometheus Metrics
| Metric | Type | Description |
|---|---|---|
| zetian_sessions_total | Counter | Total SMTP sessions |
| zetian_messages_total{status} | Counter | Total messages (delivered/rejected) |
| zetian_bytes_total{direction} | Counter | Total bytes (in/out) |
| zetian_errors_total{type} | Counter | Total errors by type |
| zetian_commands_total{command,status} | Counter | SMTP commands executed |
| zetian_authentications_total{mechanism,status} | Counter | Authentication attempts |
| zetian_active_sessions | Gauge | Current active sessions |
| zetian_uptime_seconds | Gauge | Server uptime |
| zetian_memory_bytes | Gauge | Memory usage |
| zetian_throughput_messages_per_second | Gauge | Current message throughput |
| zetian_command_duration_milliseconds{command} | Histogram | Command execution time |
| zetian_message_size_bytes | Histogram | Message size distribution |
| zetian_session_duration_seconds | Summary | Session 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. Import the Zetian SMTP Dashboard
- 2. Configure Prometheus data source
- 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