Skip to content

Prometheus-compatible metrics exporter for Rust servers. Exposes server performance data and custom plugin metrics via HTTP endpoint for monitoring and observability.

License

Notifications You must be signed in to change notification settings

maintc/RustExporter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Mainloot Logo

πŸ“Š RustExporter Plugin

Prometheus-compatible metrics exporter for Rust servers with extensible plugin API.

πŸ“– Description

RustExporter is a Carbon plugin that exposes server metrics via an HTTP endpoint in Prometheus format. It provides comprehensive built-in server metrics and a powerful API for other plugins to register and track custom metrics. Perfect for building monitoring dashboards, alerting systems, and gaining deep insights into your Rust server's performance and player activity.

✨ Features

Built-in Server Metrics

  • πŸ“ˆ Server FPS - Real-time frames per second
  • πŸ’Ύ Memory Usage - Total memory consumption in bytes
  • πŸ‘₯ Player Count - Active players on the server
  • πŸ€– Bot Count - NPCs and AI entities
  • πŸ”§ Entity Count - Total server entities
  • ⏱️ Uptime - Server runtime in seconds
  • 🌐 Client Ping Statistics - Comprehensive ping metrics (average, percentiles, min/max, std dev, buckets)

Extensible Metrics API

  • πŸ“Š Histograms - Track distributions (request durations, response sizes, etc.)
  • πŸ”’ Gauges - Monitor values that go up and down (memory, connections, queue sizes)
  • βž• Counters - Track cumulative values (total requests, errors, events)
  • 🏷️ Label Support - Add dimensions to metrics for powerful filtering and aggregation
  • πŸ”„ Auto-Registration - Metrics automatically register on first use
  • 🧡 Thread-Safe - Safe for concurrent access from multiple plugins

Integration Ready

  • πŸ“‘ Prometheus Format - Industry-standard exposition format (text/plain)
  • 🌐 HTTP Endpoint - Simple /metrics endpoint for scraping
  • πŸ“Š Grafana Compatible - Build beautiful dashboards
  • πŸ”” Alert Manager Ready - Configure alerts based on your metrics
  • πŸ†” Server Identity Labels - Automatic server identification for multi-server setups

πŸš€ Installation

  1. Download RustExporter.cs and place it in your carbon/plugins folder
  2. Edit the generated config at carbon/configs/RustExporter.json
  3. Set your desired port (default: 28066) and bind address (default: localhost)
  4. For external Prometheus access, set BindAddress to "*"
  5. Reload the plugin: c.reload RustExporter

βš™οΈ Configuration

{
  "Port": 28066,
  "BindAddress": "localhost"
}

Configuration Options

Option Description Default
Port HTTP port for metrics endpoint 28066
BindAddress IP address to bind to. Use "localhost" for local access only, "*" to bind to all interfaces (public access) "localhost"

After loading, the plugin will be accessible at:

http://your-server-ip:28066/metrics

⚠️ Security Note: The default BindAddress of "localhost" means the metrics endpoint is only accessible from the server itself. To allow external access (e.g., from Prometheus), set BindAddress to "*". Consider using firewall rules to restrict access to trusted IPs.

πŸ“Š Built-in Metrics

All built-in metrics include an identity label with your server's identity (from server.identity or hostname).

Metric Name Type Description
rust_server_fps gauge Current server FPS
rust_server_memory_usage_bytes gauge Memory usage in bytes
rust_server_pop gauge Active player count
rust_server_bots gauge Bot/NPC count
rust_server_entities gauge Total entity count
rust_server_uptime counter Server uptime in seconds
rust_client_ping_average_ms gauge Average client ping in milliseconds
rust_client_ping_p50_ms gauge Median (50th percentile) client ping
rust_client_ping_p75_ms gauge 75th percentile client ping
rust_client_ping_p90_ms gauge 90th percentile client ping
rust_client_ping_p95_ms gauge 95th percentile client ping
rust_client_ping_p99_ms gauge 99th percentile client ping
rust_client_ping_min_ms gauge Minimum client ping
rust_client_ping_max_ms gauge Maximum client ping
rust_client_ping_stddev_ms gauge Standard deviation of client ping
rust_client_ping_bucket gauge Players by ping range (with range label)

Example Output

# HELP rust_server_fps Current server FPS
# TYPE rust_server_fps gauge
rust_server_fps{identity="my-rust-server"} 60.5

# HELP rust_server_memory_usage_bytes Current memory usage in bytes
# TYPE rust_server_memory_usage_bytes gauge
rust_server_memory_usage_bytes{identity="my-rust-server"} 4294967296

# HELP rust_server_pop Current player count
# TYPE rust_server_pop gauge
rust_server_pop{identity="my-rust-server"} 42

# HELP rust_server_uptime Server uptime in seconds
# TYPE rust_server_uptime counter
rust_server_uptime{identity="my-rust-server"} 86400.12345

# HELP rust_client_ping_average_ms Average client ping in milliseconds
# TYPE rust_client_ping_average_ms gauge
rust_client_ping_average_ms{identity="my-rust-server"} 65

# HELP rust_client_ping_p95_ms 95th percentile client ping in milliseconds
# TYPE rust_client_ping_p95_ms gauge
rust_client_ping_p95_ms{identity="my-rust-server"} 120

# HELP rust_client_ping_bucket Players by ping range
# TYPE rust_client_ping_bucket gauge
rust_client_ping_bucket{identity="my-rust-server",range="0-50"} 15
rust_client_ping_bucket{identity="my-rust-server",range="50-100"} 20
rust_client_ping_bucket{identity="my-rust-server",range="100-150"} 5
rust_client_ping_bucket{identity="my-rust-server",range="150-200"} 2
rust_client_ping_bucket{identity="my-rust-server",range="200+"} 0

πŸ”Œ Plugin Developer API

RustExporter provides hook methods that other plugins can call to register and update custom metrics.

Hook Methods Overview

Method Purpose Auto-Registers
RegisterHistogram Create a histogram metric No
RegisterGauge Create a gauge metric No
RegisterCounter Create a counter metric No
ObserveHistogram Record histogram value Yes
SetGauge Set gauge value Yes
IncCounter Increment counter Yes
DecCounter Decrement counter Yes

Metric Types Explained

πŸ“Š Histograms

Track the distribution of values. Perfect for measuring request durations, response sizes, or any value where you care about percentiles and averages.

Default Buckets: [0.5, 1, 5, 10, 30, 60, 300, 500, 900, +Inf]

Use Cases:

  • API request duration
  • Command execution time
  • Event processing latency
  • Item craft durations

πŸ”’ Gauges

Represent values that can go up or down. Snapshot of current state.

Use Cases:

  • Active connections
  • Queue sizes
  • Current temperature
  • Available resources
  • Cache size

βž• Counters

Monotonically increasing values (can decrement with DecCounter). Track cumulative totals.

Use Cases:

  • Total HTTP requests
  • Total errors
  • Items crafted
  • Players joined (all-time)
  • Events triggered

πŸ“ Usage Examples

Example 1: Basic Counter (No Labels)

[PluginReference]
private Plugin RustExporter;

private void OnPlayerConnected(BasePlayer player)
{
    // Increment player join counter
    RustExporter?.Call("IncCounter", "total_player_joins");
}

Example 2: Gauge with Labels

[PluginReference]
private Plugin RustExporter;

private void UpdateQueueSize(string queueType, int size)
{
    var labels = new Dictionary<string, string>
    {
        ["queue_type"] = queueType,
        ["priority"] = "high"
    };
    
    RustExporter?.Call("SetGauge", "queue_size", (double)size, labels);
}

// Usage:
UpdateQueueSize("crafting", 15);
UpdateQueueSize("respawn", 3);

Resulting metrics:

queue_size{identity="my-server",queue_type="crafting",priority="high"} 15
queue_size{identity="my-server",queue_type="respawn",priority="high"} 3

Example 3: Histogram with Custom Buckets

[PluginReference]
private Plugin RustExporter;

private void Init()
{
    // Register histogram with custom buckets for command execution time
    var buckets = new double[] { 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0 };
    var labels = new Dictionary<string, string>
    {
        ["command_type"] = "admin"
    };
    
    RustExporter?.Call("RegisterHistogram", "command_duration_seconds", buckets, labels);
}

private void OnCommandExecuted(string command, float duration)
{
    var labels = new Dictionary<string, string>
    {
        ["command_type"] = "admin"
    };
    
    RustExporter?.Call("ObserveHistogram", "command_duration_seconds", (double)duration, labels);
}

Example 4: Tracking Plugin-Specific Metrics

[Info("MyAwesomePlugin", "YourName", "1.0.0")]
public class MyAwesomePlugin : CarbonPlugin
{
    [PluginReference]
    private Plugin RustExporter;

    private void Init()
    {
        // Register metrics on plugin load
        RustExporter?.Call("RegisterCounter", "myplug_events_processed", 0L);
        RustExporter?.Call("RegisterGauge", "myplug_active_sessions", 0.0);
    }

    private void OnEventProcessed(string eventType)
    {
        var labels = new Dictionary<string, string>
        {
            ["event_type"] = eventType
        };
        
        RustExporter?.Call("IncCounter", "myplug_events_processed", 1L, labels);
    }

    private void UpdateActiveSessions(int count)
    {
        RustExporter?.Call("SetGauge", "myplug_active_sessions", (double)count);
    }
}

Example 5: Decrementing Counters

[PluginReference]
private Plugin RustExporter;

private void OnResourceGathered()
{
    // Increment total gathered
    RustExporter?.Call("IncCounter", "resources_gathered");
}

private void OnResourceConsumed()
{
    // Decrement available resources (counter won't go below 0)
    RustExporter?.Call("DecCounter", "resources_available");
}

🏷️ Working with Labels

Labels add dimensions to your metrics, allowing you to filter and aggregate in Prometheus/Grafana.

Best Practices:

  • Keep label cardinality reasonable (avoid unique player IDs as labels)
  • Use consistent label names across metrics
  • Common label examples: type, status, method, outcome, category
  • The identity label is automatically added to all metrics

Example with multiple labels:

var labels = new Dictionary<string, string>
{
    ["plugin_name"] = "MyPlugin",
    ["action_type"] = "purchase",
    ["item_category"] = "weapon",
    ["outcome"] = "success"
};

RustExporter?.Call("IncCounter", "plugin_actions_total", 1L, labels);

Resulting metric:

plugin_actions_total{identity="my-server",plugin_name="MyPlugin",action_type="purchase",item_category="weapon",outcome="success"} 156

πŸ“ˆ Prometheus Integration

Prometheus Configuration

Add this to your prometheus.yml:

scrape_configs:
  - job_name: 'rust-servers'
    static_configs:
      - targets: ['your-server-ip:28066']
        labels:
          environment: 'production'
          region: 'us-west'

Example Prometheus Queries

# Average FPS across all servers
avg(rust_server_fps)

# Player count by server
sum by (identity) (rust_server_pop)

# Memory usage in GB
rust_server_memory_usage_bytes / 1024 / 1024 / 1024

# Rate of player joins per minute
rate(total_player_joins[1m]) * 60

# 95th percentile command execution time
histogram_quantile(0.95, rate(command_duration_seconds_bucket[5m]))

# Servers with low FPS (below 30)
rust_server_fps < 30

# Average client ping across all servers
avg(rust_client_ping_average_ms)

# Servers with high ping (95th percentile > 150ms)
rust_client_ping_p95_ms > 150

# Count of players with good ping (< 50ms)
sum by (identity) (rust_client_ping_bucket{range="0-50"})

# Percentage of players with poor ping (> 150ms)
(rust_client_ping_bucket{range="150-200"} + rust_client_ping_bucket{range="200+"}) / rust_server_pop * 100

πŸ“Š Grafana Dashboard Ideas

Performance Dashboard

  • FPS graph (line chart)
  • Memory usage (line chart with threshold alerts)
  • Entity count trends
  • Uptime counter

Player Activity Dashboard

  • Active player count (gauge visualization)
  • Player joins/leaves rate (stat panel)
  • Geographic distribution (if tracking via labels)
  • Peak hours heatmap

Network Performance Dashboard

  • Average ping over time (line chart)
  • Ping percentiles (P50, P95, P99) multi-line chart
  • Players by ping bucket (bar chart/stacked bar chart)
  • Ping standard deviation trend
  • High ping alerts (P95 > threshold)

Plugin Metrics Dashboard

  • Custom event rates
  • Error counters
  • Queue sizes
  • Processing latencies (histogram percentiles)

πŸ”§ Advanced Features

Automatic Metric Registration

You don't need to register metrics before using them. Just call the observe/set/increment methods directly:

// This automatically registers the counter if it doesn't exist
RustExporter?.Call("IncCounter", "my_new_metric");

Thread Safety

All metric operations are thread-safe and can be called from any plugin at any time without coordination.

Server Identity

The identity label is automatically added to all metrics using:

  1. server.identity ConVar (if set)
  2. server.hostname (if identity not set)
  3. "rust-server" (fallback)

This allows you to run multiple servers and distinguish them in Prometheus.

Histogram Buckets

Default buckets are optimized for duration measurements in seconds:

[0.5, 1, 5, 10, 30, 60, 300, 500, 900, +Inf]

For different use cases, provide custom buckets:

// For millisecond-level response times
var buckets = new double[] { 0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0 };

// For item counts/quantities
var buckets = new double[] { 1, 5, 10, 25, 50, 100, 500, 1000, 5000, 10000 };

RustExporter?.Call("RegisterHistogram", "my_metric", buckets);

πŸ“‹ Requirements

  • βœ… Carbon Mod installed and running
  • βœ… Network access to the configured port
  • βœ… Prometheus/Grafana (optional, for visualization)

πŸ’‘ Support & FAQ

Q: Do I need Prometheus to use this plugin?

No, but it's recommended. The plugin exposes metrics via HTTP that any tool can consume. You can even just browse to http://your-server:28066/metrics to see the raw data.

Q: Will this impact server performance?

Minimal impact. The HTTP server runs on a separate thread, and metric updates are simple in-memory operations. Scraping the metrics endpoint is a lightweight operation.

Q: Can I use this with multiple servers?

βœ… Yes! The identity label automatically distinguishes servers. Configure Prometheus to scrape all your servers.

Q: What happens if I don't register a metric before using it?

βœ… Automatic registration! The observe/set/increment methods will automatically register metrics with default settings.

Q: Can I reset counters?

No. Counters are meant to be monotonically increasing. If you need resetable values, use a gauge instead.

Q: How do I delete a metric?

Not supported. Metrics persist for the lifetime of the plugin. If you need temporary metrics, use unique label combinations instead.

Q: What's the difference between a counter and a gauge?

  • Counter: Tracks totals that only go up (e.g., total requests, total errors). Can be decremented with DecCounter.
  • Gauge: Tracks current values that fluctuate (e.g., current players, memory usage, queue size).

Q: How many metrics can I create?

Thousands. Each unique combination of metric name and labels creates a new time series. Keep label cardinality reasonable to avoid excessive memory usage.

Q: Can other plugins see metrics from different plugins?

No. Metrics are write-only from plugins. Only the /metrics HTTP endpoint exposes them, and only Prometheus (or similar tools) read them.

🎯 Use Cases

Server Operators

  • Monitor server health (FPS, memory, entities)
  • Track player counts and trends
  • Set up alerts for low FPS or high memory usage
  • Compare performance across multiple servers

Plugin Developers

  • Track plugin-specific events and metrics
  • Measure command execution times
  • Monitor queue sizes and processing rates
  • Debug performance issues with histogram percentiles
  • A/B test features by tracking success rates

Community Admins

  • Display live server stats on websites
  • Create public dashboards for players
  • Track and display server uptime
  • Monitor and optimize server performance

Made with ❀️ by mainloot | Join our Discord

About

Prometheus-compatible metrics exporter for Rust servers. Exposes server performance data and custom plugin metrics via HTTP endpoint for monitoring and observability.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Languages