Zetian.Monitoring 1.0.5

Prefix Reserved
dotnet add package Zetian.Monitoring --version 1.0.5
                    
NuGet\Install-Package Zetian.Monitoring -Version 1.0.5
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Zetian.Monitoring" Version="1.0.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Zetian.Monitoring" Version="1.0.5" />
                    
Directory.Packages.props
<PackageReference Include="Zetian.Monitoring" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Zetian.Monitoring --version 1.0.5
                    
#r "nuget: Zetian.Monitoring, 1.0.5"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Zetian.Monitoring@1.0.5
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Zetian.Monitoring&version=1.0.5
                    
Install as a Cake Addin
#tool nuget:?package=Zetian.Monitoring&version=1.0.5
                    
Install as a Cake Tool

Zetian.Monitoring - Real-time Metrics & Observability

NuGet-Version NuGet-Download License

Comprehensive monitoring and observability solution for Zetian SMTP Server with Prometheus, OpenTelemetry, and real-time metrics collection.

⚡ Features

  • 💾 Low Overhead - Minimal performance impact
  • 🔄 Zero-downtime - Hot-reload metrics without restart
  • 📉 Histograms & Percentiles - P95, P99 latency tracking
  • 📈 Command Metrics - Detailed SMTP command statistics
  • 📊 Real-time Metrics - Live server performance monitoring
  • 🏷️ Custom Labels & Tags - Add metadata to metrics and traces
  • 🚀 Performance Tracking - Throughput, latency, and resource usage
  • 📍 Distributed Tracing - Trace requests across services with OpenTelemetry
  • 🎯 Prometheus Ready - Native Prometheus exporter with /metrics endpoint
  • 🔭 OpenTelemetry - Full observability with distributed tracing (traces + metrics)

📦 Installation

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

# Install Monitoring Extension
dotnet add package Zetian.Monitoring

🚀 Quick Start

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 (default host: localhost)
server.EnablePrometheus(9090);

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

// Or with builder pattern
server.EnableMonitoring(builder => builder
    .EnablePrometheus(9090)  // Uses default host: localhost
    .WithUpdateInterval(TimeSpan.FromSeconds(5)));

// With custom host in builder
server.EnableMonitoring(builder => builder
    .EnablePrometheus("0.0.0.0", 9090)
    .WithPrometheusHost("0.0.0.0")  // Alternative way
    .WithUpdateInterval(TimeSpan.FromSeconds(5)));

// Metrics available at http://localhost:9090/metrics (or your configured host)

Advanced 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));

📊 Available 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_connections_total{status} Counter Connection attempts
zetian_tls_upgrades_total{status} Counter TLS upgrades
zetian_rejections_total{reason} Counter Message rejections
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_throughput_bytes_per_second Gauge Current bytes 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}");

🔧 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");

📈 Grafana Dashboard

Import Dashboard

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

Key Panels

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

🔭 OpenTelemetry Integration

Simple Setup

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

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

// Enable monitoring with OpenTelemetry (automatic tracing & metrics)
server.EnableMonitoring(builder => builder
    .EnableOpenTelemetry("http://localhost:4317") // OTLP endpoint
    .WithServiceName("smtp-production")
    .WithServiceVersion("1.0.0"));

await server.StartAsync();

With Both Prometheus and OpenTelemetry

server.EnableMonitoring(builder => builder
    .EnablePrometheus(9090)                       // Prometheus on port 9090
    .EnableOpenTelemetry("http://localhost:4317") // OpenTelemetry OTLP
    .WithServiceName("smtp-server")
    .WithServiceVersion("1.0.0")
    .EnableDetailedMetrics()
    .EnableCommandMetrics()
    .WithLabels(
        ("environment", "production"),
        ("region", "us-east-1")));

Custom Tracing

// Start a custom activity (span) for your operations
using (var activity = server.StartActivity("custom.operation"))
{
    activity?.SetTag("operation.type", "batch_process");
    activity?.SetTag("batch.size", 100);
    
    // Your custom logic here
    ProcessBatch();
    
    activity?.SetTag("result", "success");
}

// Trace message processing with custom attributes
server.MessageReceived += (sender, e) =>
{
    using var activity = server.StartActivity("message.custom_processing");
    activity?.SetTag("message.size", e.Message.Size);
    activity?.SetTag("sender.host", e.Message.From?.Host);
    activity?.SetTag("sender.address", e.Message.From?.Address);
    
    // Custom processing logic
    if (e.Message.Size > 10_000_000)
    {
        activity?.AddEvent(new ActivityEvent("large_message_detected"));
    }
};

⚙️ Configuration Options

public class MonitoringConfiguration
{
    // Prometheus settings
    public bool EnablePrometheus { get; set; }
    public int? PrometheusPort { get; set; }
    
    // OpenTelemetry settings  
    public bool EnableOpenTelemetry { get; set; }
    public string? OpenTelemetryEndpoint { get; set; }
    
    // Update settings
    public TimeSpan UpdateInterval { get; set; } = TimeSpan.FromSeconds(10);
    
    // Feature toggles
    public bool EnableDetailedMetrics { get; set; } = true;
    public bool EnableCommandMetrics { get; set; } = true;
    public bool EnableThroughputMetrics { get; set; } = true;
    public bool EnableHistograms { get; set; } = true;
    
    // Service identification
    public string ServiceName { get; set; } = "Zetian.SMTP";
    public string ServiceVersion { get; set; } = "1.0.0";
    
    // Custom labels for all metrics
    public Dictionary<string, string> CustomLabels { get; }
}

📊 Monitoring Best Practices

  1. Monitor trends - Use Grafana for long-term trend analysis
  2. Configure alerting - Set up Prometheus alerts for critical metrics
  3. Enable only needed metrics - Disable unused features to reduce overhead
  4. Optimize histogram buckets - Adjust buckets based on your traffic patterns
  5. Use custom labels - Add environment, region, instance for multi-server setups
  6. Set appropriate update intervals - Balance between real-time data and performance

🎯 Performance Impact

  • Storage: No persistent storage required
  • Network: Minimal (metrics endpoint only)
  • CPU Overhead: < 1% with default settings
  • Memory Usage: ~10-50MB depending on traffic

🔒 Security

  • Monitor for high cardinality metrics
  • Sanitize custom labels to prevent metric explosion
  • Metrics endpoint should be protected in production
  • Use authentication/firewall rules for Prometheus endpoint

📚 Integration Examples

With Docker

FROM mcr.microsoft.com/dotnet/runtime:9.0
EXPOSE 25 9090
# SMTP on 25, Metrics on 9090

With Kubernetes

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

With 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"

📋 Requirements

  • .NET 8.0, 9.0, or 10.0
  • OpenTelemetry packages
  • Zetian SMTP Server package
  • Prometheus.NET for metrics export

📚 Documentation & Support

📄 License

MIT License - see LICENSE


Built with ❤️ for the .NET community

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.5 411,393 12/1/2025
1.0.4 76 11/1/2025
1.0.3 166 10/30/2025
1.0.2 149 10/29/2025
1.0.1 178 10/29/2025
1.0.0 146 10/29/2025

All changes are detailed at https://zetian.soferity.com/changelog.