Monitoring & Metrics Guide
Prometheus Metrics, Grafana Dashboards, and Alerting
OmniSGW by Omnitouch Network Services
Table of Contents
- Overview
- Metrics Exporter
- Available Metrics
- Prometheus Configuration
- Grafana Dashboards
- Alerting Rules
- Troubleshooting
Overview
OmniSGW exposes Prometheus-compatible metrics for comprehensive monitoring of network operations, session management, and system health.
Metrics Architecture
Metrics Exporter
Accessing Metrics
Metrics are exposed at the configured HTTP endpoint:
# Default endpoint (if configured)
curl http://127.0.0.40:42068/metrics
# Export to file
curl http://127.0.0.40:42068/metrics > metrics.txt
# Real-time monitoring
watch -n 5 'curl -s http://127.0.0.40:42068/metrics | head -30'
For metrics endpoint configuration (bind address, port, and poll interval), see the Configuration Guide.
Metrics Format
Metrics are in Prometheus text format:
# HELP teid_registry_count Total number of allocated TEIDs
# TYPE teid_registry_count gauge
teid_registry_count 1234
# HELP s11_inbound_messages_total Total number of inbound S11 messages
# TYPE s11_inbound_messages_total counter
s11_inbound_messages_total{message_type="create_session_request"} 5432
s11_inbound_messages_total{message_type="delete_session_request"} 5100
s11_inbound_messages_total{message_type="modify_bearer_request"} 12000
Available Metrics
Session Management Metrics
Active Sessions:
teid_registry_count
├── Description: Active S11/S5S8 TEID allocations
├── Type: Gauge
├── Range: 0 to max licensed capacity
└── Example: 1234 (1234 active sessions)
seid_registry_count
├── Description: Active PFCP sessions (per SGW-U peer)
├── Type: Gauge
├── Labels: peer_ip
└── Example: seid_registry_count{peer_ip="10.0.0.30"} 1234
active_ue_sessions
├── Description: Total active UE sessions
├── Type: Gauge
└── Example: 5000
active_bearers
├── Description: Total active bearers (default + dedicated)
├── Type: Gauge
└── Example: 5500 (1 default + 0.1 dedicated per session)
charging_id_registry_count
├── Description: Active charging IDs
├── Type: Gauge
└── Example: 5000
Message Counters
S11 (MME Interface):
s11_inbound_messages_total
├── Type: Counter (increasing)
├── Labels: message_type
├── Values:
│ ├── create_session_request
│ ├── delete_session_request
│ ├── modify_bearer_request
│ ├── create_bearer_request
│ ├── delete_bearer_request
│ ├── release_access_bearers_request
│ ├── downlink_data_notification
│ └── echo_request
└── Example: s11_inbound_messages_total{message_type="create_session_request"} 5432
S5/S8 (PGW Interface):
s5s8_inbound_messages_total
├── Type: Counter
├── Labels: message_type
├── Values: (same as S11 request types)
└── Example: s5s8_inbound_messages_total{message_type="create_session_request"} 4500
Sxa (SGW-U Interface):
sxa_inbound_messages_total
├── Type: Counter
├── Labels: message_type
├── Values:
│ ├── session_establishment_request
│ ├── session_modification_request
│ ├── session_deletion_request
│ ├── session_report_request
│ ├── association_setup_request
│ └── heartbeat_request
└── Example: sxa_inbound_messages_total{message_type="session_report_request"} 67000
Performance Metrics
Message Latency:
s11_inbound_duration_seconds
├── Type: Histogram (with buckets)
├── Description: S11 message processing time
├── Percentiles: _count, _sum, _bucket
└── Example: s11_inbound_duration_seconds_bucket{le="0.1"} 5000
s5s8_inbound_duration_seconds
├── Type: Histogram
├── Description: S5/S8 message processing time
sxa_inbound_duration_seconds
├── Type: Histogram
├── Description: Sxa message processing time
PFCP Association:
pfcp_association_status
├── Type: Gauge
├── Values: 1 (associated) or 0 (not associated)
├── Labels: peer_ip, node_id
└── Example: pfcp_association_status{peer_ip="10.0.0.30"} 1
pfcp_heartbeat_latency_ms
├── Type: Gauge
├── Description: Heartbeat round-trip time
├── Labels: peer_ip
└── Example: pfcp_heartbeat_latency_ms{peer_ip="10.0.0.30"} 15
Error Metrics
Protocol Errors:
s11_inbound_errors_total
├── Type: Counter
├── Labels: error_type
├── Values:
│ ├── parse_error
│ ├── validation_error
│ ├── timeout
│ └── other
└── Example: s11_inbound_errors_total{error_type="timeout"} 12
s5s8_inbound_errors_total
├── Type: Counter
├── Description: S5/S8 errors
sxa_inbound_errors_total
├── Type: Counter
├── Description: Sxa errors
Create Session Failures:
create_session_response_cause
├── Type: Counter
├── Labels: cause_code
├── Values: (3GPP cause codes)
├── Examples:
│ ├── cause_code="0": Success
│ ├── cause_code="16": No resources available
│ ├── cause_code="25": Semantics error
│ └── cause_code="49": No matching rule
Prometheus Configuration
Installation
# Download Prometheus
wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz
tar xzf prometheus-2.45.0.linux-amd64.tar.gz
cd prometheus-2.45.0.linux-amd64
Configuration File
prometheus.yml:
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
monitor: 'sgw-c-prod'
scrape_configs:
- job_name: 'sgw-c'
static_configs:
- targets: ['127.0.0.40:42068']
labels:
instance: 'sgw-c-prod-01'
- job_name: 'sgw-c-backup'
static_configs:
- targets: ['127.0.0.41:42068']
labels:
instance: 'sgw-c-prod-02'
alerting:
alertmanagers:
- static_configs:
- targets: ['127.0.0.50:9093']
Starting Prometheus
./prometheus --config.file=prometheus.yml \
--storage.tsdb.path=/var/lib/prometheus \
--web.console.libraries=consoles \
--web.console.templates=console_templates
Accessing Prometheus
http://localhost:9090
Grafana Dashboards
Installation
# Docker (easiest)
docker run -d \
--name=grafana \
-p 3000:3000 \
-e GF_SECURITY_ADMIN_PASSWORD=admin \
grafana/grafana
Adding Data Source
- Open Grafana: http://localhost:3000
- Configuration → Data Sources
- Add → Prometheus
- URL: http://prometheus:9090
Dashboard: Session Overview
Panels:
Row 1:
├── Active Sessions (Gauge)
├── Active Bearers (Gauge)
├── S11 Messages/sec (Graph)
└── S5/S8 Messages/sec (Graph)
Row 2:
├── Sxa Messages/sec (Graph)
├── S11 Latency p95 (Graph)
├── S5/S8 Latency p95 (Graph)
└── Sxa Latency p95 (Graph)
Row 3:
├── S11 Errors/min (Graph)
├── S5/S8 Errors/min (Graph)
├── Sxa Errors/min (Graph)
└── PFCP Associations (Status)
Dashboard: Interface Health
Panels:
Row 1:
├── S11 Peer Status (Status)
├── S5/S8 Peer Status (Status)
├── SGW-U Peer Status (Status list)
└── System Load (Gauge)
Row 2:
├── S11 Message Rate (Graph)
├── S5/S8 Message Rate (Graph)
├── Sxa Message Rate (Graph)
└── Error Rate (Graph)
Row 3:
├── Message Latency Histogram (Heatmap)
├── Session Creation Rate (Graph)
├── Session Termination Rate (Graph)
└── Bearer Creation Rate (Graph)
Dashboard: Capacity Planning
Panels:
Row 1:
├── Sessions vs Capacity (Gauge + Threshold)
├── Bearers vs Capacity (Gauge + Threshold)
├── PFCP Sessions Distribution (Bar Chart)
└── Sessions by APN (Pie Chart)
Row 2:
├── Session Growth Trend (Graph)
├── Bearer Growth Trend (Graph)
├── Peak Session Time (Heatmap)
└── Session Duration Distribution (Histogram)
Dashboard Query Examples
Active Sessions:
teid_registry_count
Session Creation Rate:
rate(s11_inbound_messages_total{message_type="create_session_request"}[5m])
S11 Latency (95th percentile):
histogram_quantile(0.95, rate(s11_inbound_duration_seconds_bucket[5m]))
Error Rate:
rate(s11_inbound_errors_total[5m]) +
rate(s5s8_inbound_errors_total[5m]) +
rate(sxa_inbound_errors_total[5m])
PFCP Association Status:
pfcp_association_status{peer_ip=~"10.0.0.3[0-2]"}
Alerting Rules
Alert Rules File
sgw-c-alerts.yml:
groups:
- name: sgw-c-alerts
interval: 30s
rules:
# Session capacity alerts
- alert: SGWCapacityHigh
expr: (teid_registry_count / 100000) > 0.8
for: 5m
annotations:
summary: "SGW session capacity above 80%"
description: "Sessions: {{ $value }} of 100000"
# Interface health alerts
- alert: S11PeerDown
expr: absent(s11_inbound_messages_total) > 0
for: 2m
annotations:
summary: "S11 interface unreachable"
- alert: PGWPeerDown
expr: create_session_response_cause{cause_code="49"} > 100
for: 2m
annotations:
summary: "PGW-C peer unreachable"
- alert: SGWUAssociationDown
expr: pfcp_association_status == 0
for: 1m
annotations:
summary: "SGW-U association lost"
description: "Peer: {{ $labels.peer_ip }}"
# Message latency alerts
- alert: S11LatencyHigh
expr: histogram_quantile(0.95, rate(s11_inbound_duration_seconds_bucket[5m])) > 1
for: 5m
annotations:
summary: "S11 latency above 1 second"
description: "p95: {{ $value }}s"
- alert: S5S8LatencyHigh
expr: histogram_quantile(0.95, rate(s5s8_inbound_duration_seconds_bucket[5m])) > 1
for: 5m
annotations:
summary: "S5/S8 latency above 1 second"
# Error rate alerts
- alert: S11ErrorRate
expr: rate(s11_inbound_errors_total[5m]) > 10
for: 3m
annotations:
summary: "High S11 error rate"
description: "{{ $value }} errors/sec"
- alert: SessionEstablishmentFailure
expr: rate(create_session_response_cause{cause_code!="0"}[5m]) > 20
for: 3m
annotations:
summary: "High session establishment failure rate"
description: "{{ $value }} failures/sec"
Configuring AlertManager
alertmanager.yml:
global:
resolve_timeout: 5m
route:
receiver: 'sgw-alerts'
group_by: ['alertname', 'instance']
group_wait: 30s
group_interval: 5m
repeat_interval: 12h
receivers:
- name: 'sgw-alerts'
webhook_configs:
- url: 'http://slack-webhook-url'
email_configs:
- to: 'noc@example.com'
from: 'sgw-alerts@example.com'
smarthost: 'smtp.example.com:587'
Alert Notification Examples
Slack Integration:
🚨 SGW Capacity High
Severity: Warning
Active Sessions: 85,000 / 100,000 (85%)
Time: 2025-12-10 15:30:00 UTC
Action: Monitor for capacity increase
Email Integration:
Subject: [ALERT] S11 Peer Unreachable
SGW-C S11 interface has not received messages for 2 minutes.
This may indicate:
- MME network connectivity issue
- SGW-C restart required
- S11 port configuration changed
Immediate Action Required: Check S11 status
Troubleshooting
Metrics Not Appearing
Problem: Metrics endpoint empty or 404
Diagnosis:
# Check metrics endpoint reachable
curl -v http://127.0.0.40:42068/metrics
# Check logs for metrics exporter errors
tail -f /var/log/sgw_c/sgw_c.log | grep -i metric
# Verify configuration
cat config/runtime.exs | grep metrics
Solutions:
- Restart SGW-C process
- Verify metrics IP/port not blocked by firewall
- Check bind address configuration
- Ensure sufficient memory for metrics collection
Missing Metrics for Specific Interface
Problem: S11 metrics show but S5/S8 or Sxa missing
Diagnosis:
- Check interface is configured
- Verify interface is active
- Monitor logs for connection errors
Solution:
- Verify peer reachability
- Check interface binding
- Review configuration
High Memory Usage
Problem: Metrics exporter consuming excessive memory
Diagnosis:
# Check process memory
ps aux | grep sgw_c | grep -v grep | awk '{print $6}'
# Monitor growth over time
watch -n 5 'ps aux | grep sgw_c'
Solutions:
- Reduce metrics poll interval
- Limit number of metric samples
- Implement metric retention policy
- Scale to multiple instances
Best Practices
Metrics Collection
- Scrape Interval: 15-30 seconds for balance
- Retention: 15-30 days of metrics storage
- Aggregation: Pre-aggregate high-cardinality metrics
- Sampling: Use percentiles for latency, not raw values
Dashboard Design
- Context: Include time range, instance, peer info
- Layering: Overview → Detail → Debug
- Alerting: Visual thresholds on capacity graphs
- Correlation: Link related metrics
Alerting Strategy
- Hierarchy: Critical → Warning → Info
- Escalation: Page on-call for critical alerts
- Threshold Tuning: Baseline then +20% for warning
- Regular Testing: Test alert paths monthly
Monitoring Guide - OmniSGW Metrics and Observability
Developed by Omnitouch Network Services
Documentation Version: 1.0 Last Updated: 2025-12-10