Your SIP trunks are the lifeline of your Asterisk PBX. Every inbound and outbound call flows through them. When a trunk goes down or degrades, your entire call center stops — and you might not even know until customers start complaining.
Most Asterisk administrators discover trunk problems reactively: a user reports one-way audio, calls start failing to a specific destination, or your provider sends an angry email about registration floods. By then, you've already lost revenue, burned customer trust, and wasted hours on blind troubleshooting.
This guide shows you how to monitor SIP trunks proactively — in real-time — so you catch issues before they impact a single call.
Why SIP Trunk Monitoring Matters
SIP trunks carry 100% of your external call traffic. Unlike internal extensions (where a failure affects one user), a trunk failure affects everyone. Here's what's at stake:
| Risk | Business Impact | Detection Without Monitoring |
|---|---|---|
| Trunk registration failure | All outbound calls fail | Minutes to hours |
| Quality degradation (jitter/loss) | Choppy audio, dropped calls | Complaints from customers |
| Capacity exhaustion | Busy signals, queued calls | Spike in abandoned calls |
| One-way audio (NAT issue) | Callers can't hear agents | Individual call complaints |
| Provider outage | Complete communication blackout | External notification |
| Toll fraud | Massive unexpected bills | End-of-month invoice shock |
The average cost of a SIP trunk outage for a 50-seat call center is $5,000–$15,000 per hour in lost productivity and missed revenue. Real-time monitoring reduces mean time to detection (MTTD) from hours to seconds.
What to Monitor: The 5 Pillars of SIP Trunk Health
Effective trunk monitoring covers five critical dimensions:
1. Registration Status
The most basic check — is your trunk registered with the provider? In Asterisk, registration status tells you whether the PBX can place and receive calls through a given trunk.
Key states:
- —Registered — trunk is active and ready
- —Unregistered — trunk lost registration (calls will fail)
- —Request Sent — registration attempt in progress
- —Auth Sent — authentication challenge received
- —Rejected — provider refused registration (wrong credentials, IP block)
- —No Authentication Required — IP-based trunk, no registration needed
CLI commands:
For chan_sip:
asterisk -rx "sip show registry"
# Output:
# Host Username Refresh State Reg.Time
# provider.com mytrunk 105 Registered Thu, 19 Mar 2026 06:00:01For chan_pjsip (modern Asterisk 16+):
asterisk -rx "pjsip show registrations"
# Output:
# <Registration/ServerURI> <Auth> <Status>
# trunk-provider/sip:provider.com trunk-auth RegisteredWhat to alert on: Any transition away from "Registered" should trigger an immediate alert. Registration failures are often the first symptom of credential issues, network problems, or provider outages.
2. Call Quality Metrics (RTP)
Registration being "OK" doesn't mean calls sound good. Real-time Protocol (RTP) metrics reveal the actual voice quality your callers experience.
Critical metrics:
| Metric | Acceptable | Degraded | Critical | Impact |
|---|---|---|---|---|
| Latency (one-way) | < 150ms | 150–300ms | > 300ms | Conversation delay, talk-over |
| Jitter | < 20ms | 20–50ms | > 50ms | Choppy audio, robotic voice |
| Packet Loss | < 0.5% | 0.5–2% | > 2% | Missing words, gaps in audio |
| MOS (Mean Opinion Score) | > 4.0 | 3.5–4.0 | < 3.5 | Perceived voice quality (1–5) |
| R-Factor | > 80 | 70–80 | < 70 | ITU-T G.107 quality score |
How to measure in Asterisk:
# During an active call, get RTP stats
asterisk -rx "rtp show stats"
# For PJSIP channels, get per-channel quality
asterisk -rx "pjsip show channels"
# Then for a specific channel:
asterisk -rx "core show channel PJSIP/trunk-provider-00000042"RTCP (Real-Time Control Protocol) provides quality feedback during calls. Enable it in your PJSIP configuration:
; pjsip.conf
[transport-udp]
type = transport
protocol = udp
bind = 0.0.0.0:5060
[trunk-provider]
type = endpoint
transport = transport-udp
; Enable RTCP for quality metrics
rtcp_mux = no3. Trunk Utilization and Capacity
Every SIP trunk has a channel limit (concurrent call capacity). Hitting that limit means new calls get busy signals or fail silently.
What to track:
- —Active channels — current concurrent calls through the trunk
- —Peak channels — highest concurrent calls in a time window
- —Channel limit — your contracted or configured maximum
- —Utilization percentage — active / limit × 100
Monitoring via AMI (Asterisk Manager Interface):
#!/usr/bin/env python3
"""Real-time SIP trunk utilization monitor via AMI"""
import socket
import re
import time
AMI_HOST = "127.0.0.1"
AMI_PORT = 5038
AMI_USER = "monitor"
AMI_SECRET = "your_ami_password"
def ami_command(sock, action, **params):
"""Send AMI action and read response"""
cmd = f"Action: {action}\r\n"
for k, v in params.items():
cmd += f"{k}: {v}\r\n"
cmd += "\r\n"
sock.send(cmd.encode())
time.sleep(0.5)
return sock.recv(65536).decode()
def get_trunk_channels(sock, trunk_name):
"""Count active channels for a specific trunk"""
response = ami_command(sock, "Command",
Command=f"core show channels concise")
channels = [l for l in response.split('\n')
if trunk_name in l and '!' in l]
return len(channels)
def monitor_trunks():
"""Main monitoring loop"""
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((AMI_HOST, AMI_PORT))
sock.recv(1024) # Welcome message
# Login
ami_command(sock, "Login",
Username=AMI_USER, Secret=AMI_SECRET)
trunks = {
"provider-a": {"limit": 30, "warn": 0.8},
"provider-b": {"limit": 60, "warn": 0.75},
}
while True:
for name, config in trunks.items():
active = get_trunk_channels(sock, name)
util = active / config["limit"] * 100
status = "OK"
if util >= 95:
status = "CRITICAL"
elif util >= config["warn"] * 100:
status = "WARNING"
print(f"[{time.strftime('%H:%M:%S')}] {name}: "
f"{active}/{config['limit']} ({util:.0f}%) [{status}]")
time.sleep(10) # Poll every 10 seconds
if __name__ == "__main__":
monitor_trunks()Capacity planning rule of thumb: If your trunk regularly exceeds 70% utilization during peak hours, it's time to add capacity. A trunk running at 90%+ will cause noticeable call failures.
4. Call Success Rates (ASR and NER)
Raw call volume means nothing without understanding how many calls actually connect.
Key ratios:
- —
ASR (Answer Seizure Ratio) = Answered calls / Total attempts × 100
- —Healthy: > 50% (varies by traffic type)
- —Outbound sales: 20–40% is normal
- —Inbound support: > 95% expected
- —
NER (Network Effectiveness Ratio) = (Answered + User Busy + No Answer) / Total × 100
- —Healthy: > 95%
- —Below 90% indicates network/trunk problems
- —
SER (SIP Error Rate) = 4xx/5xx/6xx responses / Total × 100
- —Healthy: < 2%
- —Above 5% requires investigation
SQL queries for CDR-based analysis:
-- ASR and NER by trunk (last 24 hours)
SELECT
dstchannel AS trunk,
COUNT(*) AS total_calls,
COUNT(*) FILTER (WHERE disposition = 'ANSWERED') AS answered,
ROUND(
COUNT(*) FILTER (WHERE disposition = 'ANSWERED')::numeric
/ NULLIF(COUNT(*), 0) * 100, 1
) AS asr_pct,
ROUND(
COUNT(*) FILTER (WHERE disposition IN ('ANSWERED', 'BUSY', 'NO ANSWER'))::numeric
/ NULLIF(COUNT(*), 0) * 100, 1
) AS ner_pct,
ROUND(
COUNT(*) FILTER (WHERE disposition = 'FAILED')::numeric
/ NULLIF(COUNT(*), 0) * 100, 1
) AS fail_pct
FROM cdr
WHERE calldate >= NOW() - INTERVAL '24 hours'
AND dstchannel LIKE 'PJSIP/trunk%'
GROUP BY dstchannel
ORDER BY total_calls DESC;
-- Hourly ASR trend for a specific trunk
SELECT
DATE_TRUNC('hour', calldate) AS hour,
COUNT(*) AS attempts,
COUNT(*) FILTER (WHERE disposition = 'ANSWERED') AS answered,
ROUND(
COUNT(*) FILTER (WHERE disposition = 'ANSWERED')::numeric
/ NULLIF(COUNT(*), 0) * 100, 1
) AS asr_pct
FROM cdr
WHERE calldate >= NOW() - INTERVAL '7 days'
AND dstchannel LIKE 'PJSIP/trunk-provider%'
GROUP BY DATE_TRUNC('hour', calldate)
ORDER BY hour DESC
LIMIT 168; -- 7 days of hourly data
-- SIP response code breakdown (requires extended CDR or CEL)
SELECT
hangupcause AS sip_code,
COUNT(*) AS occurrences,
ROUND(COUNT(*)::numeric / SUM(COUNT(*)) OVER () * 100, 1) AS pct
FROM cdr
WHERE calldate >= NOW() - INTERVAL '24 hours'
AND dstchannel LIKE 'PJSIP/trunk%'
AND disposition = 'FAILED'
GROUP BY hangupcause
ORDER BY occurrences DESC;5. Security and Anomaly Detection
SIP trunks are prime targets for toll fraud. Attackers who compromise your trunk can rack up thousands of dollars in international calls within minutes.
What to watch for:
- —Calls to premium-rate numbers (900, international premium)
- —Unusual call volume spikes (10x normal)
- —Calls outside business hours to unexpected destinations
- —Registration attempts from unknown IPs
- —Rapid-fire INVITE floods (DoS attacks)
Fraud detection query:
-- Suspicious international call patterns (last 6 hours)
SELECT
src,
dst,
COUNT(*) AS call_count,
SUM(billsec) AS total_seconds,
ROUND(SUM(billsec) / 60.0, 1) AS total_minutes
FROM cdr
WHERE calldate >= NOW() - INTERVAL '6 hours'
AND dstchannel LIKE 'PJSIP/trunk%'
AND LENGTH(dst) > 10 -- International format
AND dst NOT LIKE '1%' -- Exclude domestic (adjust for your country)
GROUP BY src, dst
HAVING COUNT(*) > 5
ORDER BY total_seconds DESC;Real-Time Monitoring Methods
Method 1: Asterisk CLI (Manual)
Best for quick spot-checks. Not suitable for continuous monitoring.
# All trunk registrations at a glance
asterisk -rx "pjsip show registrations"
# Current calls through a specific trunk
asterisk -rx "core show channels" | grep "trunk-provider"
# Trunk endpoint status
asterisk -rx "pjsip show endpoint trunk-provider"
# Active channel count
asterisk -rx "core show channels count"Method 2: AMI Event Subscription (Programmatic)
The Asterisk Manager Interface emits real-time events for every call, registration change, and channel state transition. This is the foundation of most monitoring systems.
Key events for trunk monitoring:
| AMI Event | What It Tells You |
|---|---|
Registry | Trunk registration status changed |
Newchannel | New call started on a trunk |
Hangup | Call ended (includes cause code) |
PeerStatus | SIP peer reachability changed |
RTCPReceived | Call quality metrics update |
ChanDestroyed | Channel destroyed (resource freed) |
ChallengeSent | Authentication challenge (security) |
AMI configuration (manager.conf):
[general]
enabled = yes
port = 5038
bindaddr = 127.0.0.1 ; Only local access
[monitor]
secret = your_strong_password
deny = 0.0.0.0/0.0.0.0
permit = 127.0.0.1/255.255.255.0
read = system,call,reporting
write = commandEvent-driven monitoring script:
#!/usr/bin/env python3
"""
Event-driven SIP trunk monitor using AMI.
Subscribes to real-time events and tracks trunk health.
"""
import socket
import re
from collections import defaultdict
from datetime import datetime
class TrunkMonitor:
def __init__(self, host="127.0.0.1", port=5038):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((host, port))
self.sock.recv(1024)
self.trunk_channels = defaultdict(int)
self.trunk_calls_total = defaultdict(int)
self.trunk_calls_failed = defaultdict(int)
self.registration_status = {}
def login(self, user, secret):
self._send(f"Action: Login\r\nUsername: {user}\r\n"
f"Secret: {secret}\r\nEvents: on\r\n\r\n")
return self._read()
def _send(self, msg):
self.sock.send(msg.encode())
def _read(self):
data = b""
while True:
chunk = self.sock.recv(4096)
data += chunk
if b"\r\n\r\n" in data:
break
return data.decode()
def process_events(self):
"""Main event loop — process AMI events in real-time"""
buffer = ""
while True:
data = self.sock.recv(4096).decode()
buffer += data
while "\r\n\r\n" in buffer:
event_text, buffer = buffer.split("\r\n\r\n", 1)
event = self._parse_event(event_text)
if event.get("Event") == "Registry":
self._handle_registry(event)
elif event.get("Event") == "Newchannel":
self._handle_new_channel(event)
elif event.get("Event") == "Hangup":
self._handle_hangup(event)
elif event.get("Event") == "PeerStatus":
self._handle_peer_status(event)
def _parse_event(self, text):
event = {}
for line in text.strip().split("\r\n"):
if ": " in line:
key, val = line.split(": ", 1)
event[key] = val
return event
def _handle_registry(self, event):
trunk = event.get("Username", "unknown")
status = event.get("Status", "unknown")
old_status = self.registration_status.get(trunk)
self.registration_status[trunk] = status
if old_status and old_status != status:
ts = datetime.now().strftime("%H:%M:%S")
print(f"[{ts}] REGISTRATION CHANGE: {trunk} "
f"{old_status} -> {status}")
if status != "Registered":
print(f" *** ALERT: Trunk {trunk} lost registration!")
def _handle_new_channel(self, event):
channel = event.get("Channel", "")
for trunk in self.trunk_channels:
if trunk in channel:
self.trunk_channels[trunk] += 1
self.trunk_calls_total[trunk] += 1
def _handle_hangup(self, event):
channel = event.get("Channel", "")
cause = event.get("Cause", "0")
for trunk in self.trunk_channels:
if trunk in channel:
self.trunk_channels[trunk] = max(0,
self.trunk_channels[trunk] - 1)
if cause not in ("16", "17", "18", "19"):
self.trunk_calls_failed[trunk] += 1
def _handle_peer_status(self, event):
peer = event.get("Peer", "")
status = event.get("PeerStatus", "")
ts = datetime.now().strftime("%H:%M:%S")
print(f"[{ts}] PEER STATUS: {peer} -> {status}")
if __name__ == "__main__":
monitor = TrunkMonitor()
monitor.login("monitor", "your_strong_password")
monitor.trunk_channels["trunk-provider-a"] = 0
monitor.trunk_channels["trunk-provider-b"] = 0
print("Monitoring SIP trunks... Press Ctrl+C to stop.")
monitor.process_events()Method 3: SNMP + External Monitoring (Nagios/Zabbix)
For organizations with existing monitoring infrastructure. Asterisk's res_snmp module exposes trunk metrics via SNMP.
Enable SNMP in Asterisk:
; res_snmp.conf
[general]
subagent = yes
enabled = yes# Load the SNMP module
asterisk -rx "module load res_snmp"
# Test SNMP query
snmpwalk -v2c -c public localhost .1.3.6.1.4.1.22736Nagios check script:
#!/bin/bash
# check_asterisk_trunk.sh - Nagios plugin for trunk monitoring
# Usage: check_asterisk_trunk.sh <trunk_name> <warn_channels> <crit_channels>
TRUNK=$1
WARN=${2:-20}
CRIT=${3:-28}
# Get active channels for trunk
CHANNELS=$(asterisk -rx "core show channels concise" 2>/dev/null | grep -c "$TRUNK")
REGISTERED=$(asterisk -rx "pjsip show registrations" 2>/dev/null | grep "$TRUNK" | grep -c "Registered")
if [ "$REGISTERED" -eq 0 ]; then
echo "CRITICAL - Trunk $TRUNK not registered | channels=$CHANNELS"
exit 2
fi
if [ "$CHANNELS" -ge "$CRIT" ]; then
echo "CRITICAL - Trunk $TRUNK: $CHANNELS active channels (>=$CRIT) | channels=$CHANNELS"
exit 2
elif [ "$CHANNELS" -ge "$WARN" ]; then
echo "WARNING - Trunk $TRUNK: $CHANNELS active channels (>=$WARN) | channels=$CHANNELS"
exit 1
else
echo "OK - Trunk $TRUNK: Registered, $CHANNELS active channels | channels=$CHANNELS"
exit 0
fiMethod 4: Prometheus + Grafana (Modern Stack)
Export Asterisk metrics to Prometheus and visualize in Grafana. The asterisk_exporter project provides a ready-made solution.
# docker-compose.yml for Asterisk trunk monitoring stack
version: '3.8'
services:
asterisk-exporter:
image: ghcr.io/cswiger/asterisk_exporter:latest
environment:
AMI_HOST: host.docker.internal
AMI_PORT: 5038
AMI_USER: monitor
AMI_SECRET: your_password
ports:
- "9200:9200"
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana:latest
environment:
GF_SECURITY_ADMIN_PASSWORD: admin
ports:
- "3000:3000"# prometheus.yml
scrape_configs:
- job_name: 'asterisk'
scrape_interval: 15s
static_configs:
- targets: ['asterisk-exporter:9200']This approach requires significant setup and maintenance — configuring exporters, writing PromQL queries, building dashboards, and setting up alerting rules. For smaller teams, a dedicated solution like Astervis eliminates this complexity entirely.
Tired of guessing what's happening in your queues?
Astervis gives you 30+ real-time charts, operator KPIs, and CRM integration for your Asterisk PBX. Self-hosted. Install in 5 minutes. From $119/mo flat — unlimited operators.
Method 5: Astervis — Purpose-Built Asterisk Analytics
Astervis provides real-time SIP trunk monitoring out of the box, with zero configuration:
What you get immediately after installation:
- —Live trunk status dashboard — registration state, active channels, and utilization for every trunk, updating in real-time
- —Call quality heatmaps — visualize quality degradation patterns across hours and days
- —ASR/NER tracking — automatic calculation with trend graphs and alerting
- —Trunk capacity alerts — get notified before you hit channel limits
- —Per-trunk CDR analytics — drill down into call patterns, peak hours, and failure rates
- —30+ pre-built charts — no PromQL, no dashboard building, no query writing
- —Operator performance tied to trunk routing — see which trunks your best operators use
- —CRM integration — correlate trunk performance with customer satisfaction (Bitrix24, AmoCRM)
Installation:
curl -fsSL https://api.astervis.io/api/releases/install.sh | bashOne command. Five minutes. Full trunk monitoring. Start your 14-day free trial →
Building a Trunk Monitoring Dashboard
Regardless of your tooling choice, your trunk monitoring dashboard should answer these questions at a glance:
Wallboard (Real-Time)
| Widget | Update Frequency | Purpose |
|---|---|---|
| Registration status (all trunks) | 10 seconds | Instant outage detection |
| Active channels per trunk | 5 seconds | Capacity awareness |
| Utilization gauge (%) | 5 seconds | Capacity warning |
| Live call quality (MOS/jitter) | Per call | Quality degradation |
| Failed calls (last 15 min) | 30 seconds | Trend detection |
Operational Dashboard (Hourly)
| Widget | Content |
|---|---|
| ASR trend (24h) | Line chart by trunk |
| Channel utilization heatmap | Trunk × Hour matrix |
| Top failure destinations | Bar chart of most-failed numbers |
| Quality score distribution | Histogram of MOS scores |
| Provider comparison | Side-by-side trunk metrics |
Strategic Dashboard (Weekly/Monthly)
| Widget | Content |
|---|---|
| Cost per trunk | Spending vs call volume |
| Reliability ranking | Which provider has best uptime |
| Capacity forecast | When you'll need more channels |
| Quality trend | MOS score trend over months |
| ROI analysis | Cost savings from monitoring |
Common SIP Trunk Problems and How to Detect Them
Problem 1: Silent Registration Failures
Symptoms: Outbound calls fail, but Asterisk shows no errors in console.
Detection:
# Check if registration is actually current
asterisk -rx "pjsip show registrations" | grep -v "Registered"
# Look for registration errors in logs
grep "Registration .* failed" /var/log/asterisk/messages | tail -20Root causes:
- —Credentials rotated by provider without notification
- —IP address changed (dynamic IP without DynDNS)
- —Provider firewall blocking your new IP
- —TLS certificate expired
Problem 2: Gradual Quality Degradation
Symptoms: Users report "calls sound worse lately" but can't pinpoint when it started.
Detection:
-- MOS score trend by week
SELECT
DATE_TRUNC('week', calldate) AS week,
ROUND(AVG(
CASE
WHEN billsec > 0 THEN
4.5 - (0.01 * EXTRACT(EPOCH FROM (end_time - answer_time) - billsec))
ELSE NULL
END
), 2) AS avg_estimated_mos,
COUNT(*) AS calls
FROM cdr
WHERE calldate >= NOW() - INTERVAL '90 days'
AND dstchannel LIKE 'PJSIP/trunk%'
AND disposition = 'ANSWERED'
GROUP BY DATE_TRUNC('week', calldate)
ORDER BY week;Root causes:
- —ISP changed routing paths
- —Provider overselling capacity
- —Network equipment degradation
- —Codec negotiation falling back to lower quality
Problem 3: Trunk Capacity Exhaustion
Symptoms: Some calls fail during peak hours, but not all.
Detection:
-- Find peak concurrent calls by hour
SELECT
DATE_TRUNC('hour', calldate) AS hour,
MAX(concurrent) AS peak_concurrent
FROM (
SELECT
calldate,
COUNT(*) OVER (
ORDER BY calldate
RANGE BETWEEN INTERVAL '0 seconds' PRECEDING
AND INTERVAL '0 seconds' FOLLOWING
) AS concurrent
FROM cdr
WHERE calldate >= NOW() - INTERVAL '7 days'
AND dstchannel LIKE 'PJSIP/trunk%'
) sub
GROUP BY DATE_TRUNC('hour', calldate)
ORDER BY peak_concurrent DESC
LIMIT 24;Solution: Set up utilization alerts at 70% and 90% thresholds. When 70% hits regularly during peak hours, start capacity planning.
Problem 4: Toll Fraud in Progress
Symptoms: Unexpected international calls, especially outside business hours.
Detection:
# Real-time: watch for international calls outside hours
asterisk -rx "core show channels concise" | \
awk -F'!' '{print $1, $7}' | \
grep -E '\+?(9[0-9]{2}|00[0-9]{3})' Immediate response:
# Block the trunk immediately
asterisk -rx "pjsip set endpoint trunk-name max_channels 0"
# Or hang up all trunk channels
asterisk -rx "channel request hangup all"Monitoring Checklist: Setting Up from Scratch
Follow this step-by-step checklist to implement trunk monitoring:
Step 1: Inventory your trunks
# List all configured trunks
asterisk -rx "pjsip show endpoints" | grep -E "Endpoint:|Contact:"
# Or for chan_sip:
asterisk -rx "sip show peers" | grep -v "^Name\|--\|^$"Step 2: Enable quality tracking
; pjsip.conf - add to each trunk endpoint
[trunk-provider]
type = endpoint
; ... existing config ...
allow = !all,opus,g722,ulaw,alaw ; Prefer high-quality codecs
trust_id_inbound = yes
send_rpid = yesStep 3: Configure AMI for monitoring access
; manager.conf
[monitor]
secret = strong_random_password_here
deny = 0.0.0.0/0.0.0.0
permit = 127.0.0.1/255.255.255.0
read = system,call,reporting
write = commandStep 4: Set up CDR database logging
; cdr.conf
[general]
enable = yes
unanswered = yes ; Log failed calls too
congestion = yes
; cdr_adaptive_odbc.conf or cdr_pgsql.conf
[global]
connection = asterisk
table = cdrStep 5: Implement monitoring (choose your path)
- —Quick & Easy: Astervis —
curl -fsSL https://api.astervis.io/api/releases/install.sh | bash(5 min) - —DIY + Grafana: Prometheus exporter + custom dashboards (2-3 days)
- —Enterprise: SNMP + Nagios/Zabbix integration (1-2 days if experienced)
Step 6: Configure alerts
Set thresholds for:
- —Registration status change → Immediate alert
- —Utilization > 70% → Warning
- —Utilization > 90% → Critical
- —ASR drop > 10% from baseline → Warning
- —MOS < 3.5 → Quality alert
- —International calls outside hours → Fraud alert
Step 7: Test your monitoring
# Simulate a registration failure (careful — this disconnects the trunk!)
# Only do this during maintenance windows
asterisk -rx "pjsip send unregister trunk-provider"
# Verify your alert fires, then re-register
asterisk -rx "pjsip send register trunk-provider"Comparison: SIP Trunk Monitoring Approaches
| Feature | CLI/Scripts | Grafana+Prometheus | Nagios/Zabbix | Astervis |
|---|---|---|---|---|
| Setup time | Minutes | 2–3 days | 1–2 days | 5 minutes |
| Real-time updates | Manual refresh | 15s intervals | 1–5 min polling | Live (WebSocket) |
| Registration alerts | Custom script | Custom rules | Plugin needed | Built-in |
| Call quality metrics | Limited | With RTP exporter | SNMP only | Full RTP analysis |
| Capacity tracking | grep + count | Custom PromQL | Custom check | Automatic |
| ASR/NER calculation | SQL queries | Custom dashboards | Not native | Pre-built charts |
| Fraud detection | Manual | Custom rules | Custom rules | Anomaly detection |
| Operator correlation | Not possible | Complex joins | Not native | Native integration |
| CRM integration | Not possible | Not possible | Not native | Bitrix24, AmoCRM |
| Maintenance | High | Medium | Medium | Zero (SaaS-like) |
| Cost | Free (+ time) | Free (+ time) | License varies | From $119/mo |
Key Takeaways
- —
Monitor all five pillars: registration, quality, capacity, success rates, and security. Missing any one creates a blind spot.
- —
Real-time beats polling: AMI event subscriptions catch problems in seconds, while periodic checks can miss intermittent issues.
- —
Baseline your metrics first: Spend a week collecting normal-state data before setting alert thresholds. Every environment is different.
- —
Automate your response: Don't just alert — have runbooks for each scenario. Better yet, automate failover to backup trunks.
- —
Correlate with business metrics: A trunk outage is a number. "47 customers couldn't reach support during a trunk failure" is a business impact that drives investment.
- —
Start simple, scale up: Begin with registration checks and basic utilization. Add quality metrics and fraud detection as you mature.
Whether you build your own monitoring stack or use a purpose-built tool like Astervis, the key is to start monitoring today. Every day without trunk visibility is a day you're gambling with your call center's reliability.
Ready to see your SIP trunks in real-time? Try Astervis free for 14 days →
Stop guessing. Start monitoring.
See your Asterisk call center's real performance — queue wait times, agent activity, trunk usage, and 30+ charts. Self-hosted on your server. Install in 5 minutes. No credit card required.
From $119/mo flat. Unlimited operators. 14-day free trial.
