Managing a call center powered by Asterisk means more than keeping trunks online. The real challenge is understanding how each operator performs—who resolves issues on the first call, who keeps hold times low, and who consistently delivers fast, quality service. Without systematic performance tracking, you are flying blind.
This guide covers everything you need to know about tracking operator performance in Asterisk call centers: the essential KPIs, where the data lives inside Asterisk, how to extract actionable metrics with SQL and CLI commands, and how modern analytics platforms eliminate the manual work.
Why Operator Performance Tracking Matters
Call center labor represents 60–70% of total operating costs. A single underperforming operator handling 80 calls per day can cost thousands in lost customers and wasted wages annually. Conversely, identifying and replicating the habits of top performers can lift overall team productivity by 15–25%.
Without tracking, common problems fester silently:
- —Uneven workload distribution — some operators take 3x more calls while others idle
- —High abandonment on specific agents — callers hang up waiting for slow handlers
- —Excessive hold and wrap-up times — operators put callers on hold to avoid work
- —No accountability — without data, coaching conversations are subjective
- —Missed SLA targets — you do not know which operators drag down your service level
Asterisk generates enormous amounts of raw data through CDR records, queue logs, and channel events. The challenge is turning that raw data into operator-level insights.
Essential Operator KPIs for Asterisk Call Centers
Before diving into extraction methods, define what you need to track. These are the KPIs that matter most for Asterisk-based operations:
Call Volume Metrics
| KPI | What It Measures | Formula | Target Range |
|---|---|---|---|
| Calls Handled | Total calls answered by operator | Count of CONNECT events | Varies by role |
| Calls Missed | Rings that went unanswered | Count of RINGNOANSWER events | < 5% of offered |
| Calls Transferred | Calls escalated to another agent | Count of TRANSFER events | < 10% |
| Calls per Hour | Productivity rate | Calls Handled / Hours Worked | 8–15 (inbound) |
Time-Based Metrics
| KPI | What It Measures | Formula | Target Range |
|---|---|---|---|
| Average Handle Time (AHT) | Total time per call including wrap-up | (Talk + Hold + Wrap-up) / Calls | 3–7 minutes |
| Average Talk Time | Actual conversation duration | Sum of billsec / Calls | 2–5 minutes |
| Average Hold Time | Time caller spends on hold | Sum of hold events / Calls | < 60 seconds |
| Average Wrap-up Time | Post-call work duration | AHT – Talk – Hold | < 60 seconds |
| Ring Time (Before Answer) | How fast operator picks up | Time between RINGNOANSWER/CONNECT | < 15 seconds |
| Occupancy Rate | Percentage of time on calls vs. available | (Talk + Hold + Wrap-up) / Logged-in Time | 75–85% |
Quality Metrics
| KPI | What It Measures | Formula | Target Range |
|---|---|---|---|
| First Call Resolution (FCR) | Issues resolved without callback | 1 – (Repeat callers / Total callers) | > 70% |
| Abandon Rate (per agent) | Callers who hang up in agent's queue | Abandoned / Offered | < 5% |
| Service Level | Calls answered within threshold | Answered in X sec / Total | > 80% in 20s |
| Transfer Rate | Calls requiring escalation | Transfers / Handled | < 10% |
Where Operator Data Lives in Asterisk
Asterisk stores performance-relevant data in several locations. Understanding each source is critical for accurate tracking.
1. Queue Log (/var/log/asterisk/queue_log)
The queue log is the primary source for operator-level queue performance. Every queue event is logged with a timestamp, queue name, and agent identifier.
Key events for operator tracking:
ADDMEMBER — Agent logged into queue
REMOVEMEMBER — Agent logged out
RINGNOANSWER — Queue offered call, agent did not answer
CONNECT — Agent answered (includes hold time and ring time)
COMPLETECALLER — Caller hung up first (includes hold time, talk time)
COMPLETEAGENT — Agent hung up first (includes hold time, talk time)
TRANSFER — Agent transferred call
PAUSE — Agent paused (break/lunch)
UNPAUSE — Agent returned from pause
ABANDON — Caller abandoned before agent answered
Example queue_log entry for a completed call:
1710806400|1710806389.42|support|SIP/agent101|COMPLETEAGENT|18|145|1
This tells you: agent SIP/agent101 in the support queue answered after 18 seconds of hold time, talked for 145 seconds, and was the one who ended the call. The position in queue was 1.
2. CDR (Call Detail Records)
CDR provides call-level data with duration, disposition, and channel information. Stored in /var/log/asterisk/cdr-csv/ or in a database (MySQL, PostgreSQL) if configured with cdr_adaptive_odbc.
Useful CDR fields for operator tracking:
src — Caller number
dst — Dialed number/extension
dcontext — Destination context
channel — Originating channel
dstchannel — Destination channel (agent's channel)
billsec — Billable seconds (actual talk time)
duration — Total duration including ring time
disposition — ANSWERED, NO ANSWER, BUSY, FAILED
calldate — Timestamp
uniqueid — Unique call identifier
3. CEL (Channel Event Logging)
CEL provides the most granular event-level data. It captures every state change in a call's lifecycle, making it possible to calculate exact hold times, transfer chains, and conference durations.
Key CEL events:
CHAN_START — Channel created (call initiated)
ANSWER — Channel answered
BRIDGE_ENTER — Joined a bridge (connected to other party)
BRIDGE_EXIT — Left a bridge
HOLD — Put on hold
UNHOLD — Taken off hold
HANGUP — Channel hung up
4. AMI (Asterisk Manager Interface)
AMI provides real-time data through events. Useful for live dashboards but not for historical analysis.
QueueMemberStatus — Agent state changes
AgentCalled — Queue attempting to reach agent
AgentConnect — Agent answered queued call
AgentComplete — Agent completed queued call
Extracting Operator Metrics with SQL
If you store CDR and queue_log data in a database (recommended), you can extract powerful operator metrics with SQL queries. Below are production-ready queries for PostgreSQL. Adapt column names for MySQL.
Query 1: Operator Daily Performance Summary
SELECT
agent,
COUNT(*) FILTER (WHERE event = 'CONNECT') AS calls_answered,
COUNT(*) FILTER (WHERE event = 'RINGNOANSWER') AS calls_missed,
COUNT(*) FILTER (WHERE event IN ('COMPLETECALLER','COMPLETEAGENT')) AS calls_completed,
COUNT(*) FILTER (WHERE event = 'TRANSFER') AS calls_transferred,
ROUND(AVG(data2::int) FILTER (WHERE event IN ('COMPLETECALLER','COMPLETEAGENT')), 1) AS avg_talk_sec,
ROUND(AVG(data1::int) FILTER (WHERE event = 'CONNECT'), 1) AS avg_hold_sec,
MAX(data2::int) FILTER (WHERE event IN ('COMPLETECALLER','COMPLETEAGENT')) AS max_talk_sec,
MIN(data2::int) FILTER (WHERE event IN ('COMPLETECALLER','COMPLETEAGENT')) AS min_talk_sec
FROM queue_log
WHERE time_id >= CURRENT_DATE
AND agent != 'NONE'
GROUP BY agent
ORDER BY calls_answered DESC;Query 2: Hourly Operator Activity (Heatmap Data)
SELECT
agent,
EXTRACT(HOUR FROM to_timestamp(time_id)) AS hour,
COUNT(*) FILTER (WHERE event = 'CONNECT') AS calls,
ROUND(AVG(data2::int) FILTER (WHERE event IN ('COMPLETECALLER','COMPLETEAGENT')), 0) AS avg_talk
FROM queue_log
WHERE time_id >= EXTRACT(EPOCH FROM CURRENT_DATE)::int
AND agent != 'NONE'
GROUP BY agent, hour
ORDER BY agent, hour;Query 3: Agent Login/Availability Time
WITH sessions AS (
SELECT
agent,
time_id AS event_time,
event,
LEAD(time_id) OVER (PARTITION BY agent ORDER BY time_id) AS next_event_time,
LEAD(event) OVER (PARTITION BY agent ORDER BY time_id) AS next_event
FROM queue_log
WHERE event IN ('ADDMEMBER', 'REMOVEMEMBER', 'PAUSE', 'UNPAUSE')
AND time_id >= EXTRACT(EPOCH FROM CURRENT_DATE)::int
AND agent != 'NONE'
)
SELECT
agent,
SUM(CASE WHEN event = 'ADDMEMBER' THEN next_event_time - event_time ELSE 0 END) AS total_logged_in_sec,
SUM(CASE WHEN event = 'PAUSE' THEN
LEAST(next_event_time - event_time, 7200) ELSE 0 END) AS total_pause_sec,
ROUND(
SUM(CASE WHEN event = 'ADDMEMBER' THEN next_event_time - event_time ELSE 0 END)::numeric / 3600,
2
) AS logged_in_hours
FROM sessions
WHERE next_event_time IS NOT NULL
GROUP BY agent
ORDER BY total_logged_in_sec DESC;Query 4: Operator Leaderboard (Composite Score)
WITH metrics AS (
SELECT
agent,
COUNT(*) FILTER (WHERE event = 'CONNECT') AS answered,
COUNT(*) FILTER (WHERE event = 'RINGNOANSWER') AS missed,
COALESCE(AVG(data2::int) FILTER (WHERE event IN ('COMPLETECALLER','COMPLETEAGENT')), 0) AS avg_talk,
COALESCE(AVG(data1::int) FILTER (WHERE event = 'CONNECT'), 0) AS avg_hold
FROM queue_log
WHERE time_id >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '7 days'))::int
AND agent != 'NONE'
GROUP BY agent
HAVING COUNT(*) FILTER (WHERE event = 'CONNECT') >= 10
)
SELECT
agent,
answered,
missed,
ROUND(avg_talk, 1) AS avg_talk_sec,
ROUND(avg_hold, 1) AS avg_hold_sec,
ROUND(answered::numeric / NULLIF(answered + missed, 0) * 100, 1) AS answer_rate_pct,
ROUND(
(answered::numeric / NULLIF(answered + missed, 0) * 40) +
(LEAST(300, avg_talk) / 300 * 30) +
(GREATEST(0, 30 - avg_hold) / 30 * 30),
1
) AS performance_score
FROM metrics
ORDER BY performance_score DESC;This composite score weighs answer rate (40%), talk efficiency (30%), and speed of answer (30%). Adjust weights based on your priorities.
Query 5: Identify Operators Needing Coaching
SELECT
agent,
COUNT(*) FILTER (WHERE event = 'CONNECT') AS calls_answered,
COUNT(*) FILTER (WHERE event = 'RINGNOANSWER') AS calls_missed,
ROUND(AVG(data2::int) FILTER (WHERE event IN ('COMPLETECALLER','COMPLETEAGENT')), 0) AS avg_talk_sec,
ROUND(AVG(data1::int) FILTER (WHERE event = 'CONNECT'), 0) AS avg_hold_sec,
CASE
WHEN COUNT(*) FILTER (WHERE event = 'RINGNOANSWER') >
COUNT(*) FILTER (WHERE event = 'CONNECT') * 0.2
THEN 'HIGH MISS RATE'
WHEN AVG(data2::int) FILTER (WHERE event IN ('COMPLETECALLER','COMPLETEAGENT')) > 600
THEN 'LONG CALLS'
WHEN AVG(data1::int) FILTER (WHERE event = 'CONNECT') > 30
THEN 'SLOW PICKUP'
ELSE 'OK'
END AS flag
FROM queue_log
WHERE time_id >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '7 days'))::int
AND agent != 'NONE'
GROUP BY agent
HAVING CASE
WHEN COUNT(*) FILTER (WHERE event = 'RINGNOANSWER') >
COUNT(*) FILTER (WHERE event = 'CONNECT') * 0.2 THEN TRUE
WHEN AVG(data2::int) FILTER (WHERE event IN ('COMPLETECALLER','COMPLETEAGENT')) > 600 THEN TRUE
WHEN AVG(data1::int) FILTER (WHERE event = 'CONNECT') > 30 THEN TRUE
ELSE FALSE
END
ORDER BY flag, agent;CLI-Based Monitoring (Quick Checks)
For quick operator status checks without database access, use Asterisk CLI commands:
Current Queue Status
asterisk -rx "queue show"Output includes each agent's status, calls taken, last call time, and penalty:
support has 3 calls (max unlimited) in 'ringall' strategy
Members:
SIP/agent101 (ringinuse disabled) (dynamic) (Not in use) has taken 47 calls (last was 142 secs ago)
SIP/agent102 (ringinuse disabled) (dynamic) (In use) has taken 38 calls (last was 12 secs ago)
SIP/agent103 (ringinuse disabled) (dynamic) (Paused) has taken 22 calls (last was 891 secs ago)
Parse Queue Log with Shell
# Top operators today by calls answered
grep "$(date +%s | cut -c1-6)" /var/log/asterisk/queue_log | \
grep "CONNECT" | \
awk -F'|' '{print $4}' | \
sort | uniq -c | sort -rn | head -10# Average talk time per agent (today)
grep "$(date +%s | cut -c1-6)" /var/log/asterisk/queue_log | \
grep -E "COMPLETECALLER|COMPLETEAGENT" | \
awk -F'|' '{agent=$4; talk=$7; sum[agent]+=talk; count[agent]++}
END {for (a in sum) printf "%s: %.0f sec avg (%d calls)\n", a, sum[a]/count[a], count[a]}' | \
sort -t: -k2 -nBuilding an Operator Performance Dashboard
A proper performance tracking system should provide three levels of visibility:
Level 1: Real-Time Wallboard
Shows live operator status for supervisors on the floor:
- —Agent state: Available, On Call, Paused, Wrap-up, Offline
- —Current call duration: How long current call has been going
- —Queue depth: Callers waiting per queue
- —Calls in last hour: Per-agent activity pulse
- —Longest waiting caller: Urgency indicator
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.
Level 2: Daily Performance View
End-of-shift review for team leads:
- —Calls handled vs. missed (per agent)
- —Average handle time trend (is it improving?)
- —Login time vs. pause time (actual availability)
- —Service level contribution (which agents helped or hurt SLA)
- —Leaderboard with composite score
Level 3: Weekly/Monthly Analytics
Strategic view for managers:
- —Performance trends over time (improving or declining?)
- —Agent comparison heatmaps (who is productive when?)
- —Correlation analysis (does shorter AHT correlate with callbacks?)
- —Training impact measurement (did coaching improve metrics?)
- —Workload distribution fairness
Common Operator Tracking Mistakes
Mistake 1: Tracking Only Call Volume
An operator who handles 100 calls but transfers 40% of them is not a top performer. Always combine volume metrics with quality indicators like transfer rate, hold time, and repeat callers.
Mistake 2: Ignoring Pause and Break Patterns
Some operators game availability by taking frequent short pauses. Track pause frequency, total pause duration, and pause timing (right before shift end is suspicious).
Mistake 3: Using Daily Averages Instead of Per-Call Distributions
An operator with 4-minute average handle time might have 50% of calls at 1 minute (abandoned) and 50% at 7 minutes (actual work). Distribution matters more than averages.
Mistake 4: Not Accounting for Queue Assignment
Comparing operators across different queues is unfair. Technical support calls naturally take longer than billing inquiries. Normalize metrics by queue type.
Mistake 5: Manual Data Collection
If you are pulling queue_log data into spreadsheets weekly, you are already too late. Performance issues need real-time visibility, not retrospective analysis.
Approaches to Operator Performance Tracking
DIY: Parse Queue Log + Custom Scripts
Effort: High — requires scripting, cron jobs, custom dashboards. Pros: Free, fully customizable. Cons: Fragile, no real-time view, maintenance burden.
QueueMetrics
Price: CHF 8/agent/month. Pros: Mature, extensive reporting. Cons: Java-based, complex setup, expensive at scale, legacy UI.
Asternic Call Center Stats
Price: Commercial license required. Pros: Lightweight, queue_log focused. Cons: Limited real-time features, dated interface, minimal agent-level analytics.
Grafana + Custom Queries
Price: Free (OSS). Pros: Beautiful dashboards, flexible. Cons: Requires significant setup, no queue_log parser included, DIY alerting.
Astervis
Price: From $49/month (up to 10 agents). Pros: Purpose-built for Asterisk, 30+ charts out of the box, real-time operator dashboards, leaderboards, KPI tracking, one-command install, CRM integration (Bitrix24, AmoCRM). Cons: Newer product.
Astervis was built specifically to solve the operator tracking problem in Asterisk call centers. Instead of spending weeks building custom queue_log parsers and Grafana dashboards, you get:
- —Operator leaderboards with composite scoring
- —Real-time agent status wallboard
- —Per-agent KPI cards (AHT, calls handled, answer rate, hold time)
- —Performance trend charts over any time range
- —Heatmaps showing each operator's productivity by hour
- —Schedule tracking with login/pause/availability analysis
- —Automatic alerting when operators fall below thresholds
Setup takes under 5 minutes — connect to your Asterisk server and Astervis pulls queue_log and CDR data automatically. No Java, no complex configurations, no maintenance.
Setting Up Performance Tracking in Your Call Center
Follow this checklist to implement operator performance tracking:
Step 1: Enable Queue Logging
Ensure queue_log is active and writing to a database:
; /etc/asterisk/logger.conf
[general]
queue_log = yes
queue_log_to_file = yes
queue_log_name = queue_logFor database storage (recommended for queries):
; /etc/asterisk/extconfig.conf
queue_log => odbc,asterisk,queue_logStep 2: Configure CDR Database Storage
; /etc/asterisk/cdr.conf
[general]
enable = yes
unanswered = yes
congestion = yes
endbeforehexten = yesStep 3: Define Your KPIs
Start with these five core metrics:
- —Answer Rate — target > 95%
- —Average Handle Time — establish baseline, then optimize
- —Calls per Hour — set minimum expectations
- —Occupancy Rate — target 75–85% (above 85% causes burnout)
- —Login Adherence — scheduled vs. actual availability
Step 4: Set Up Reporting
Choose your approach:
- —Quick start: Install Astervis for instant dashboards (14-day free trial)
- —Custom: Build SQL queries (use examples above) + Grafana or Metabase for visualization
- —Manual: Schedule daily queue_log parsing scripts via cron
Step 5: Implement Regular Reviews
- —Daily: Quick check of leaderboard and flagged operators
- —Weekly: Team meeting with performance trends and coaching targets
- —Monthly: Strategic review of KPI targets and process improvements
Key Takeaways
- —Track the right KPIs — volume alone is meaningless without quality metrics
- —Use queue_log as your primary source — it contains the richest operator-level data in Asterisk
- —Automate data collection — manual tracking is always too slow and error-prone
- —Compare fairly — normalize metrics by queue type and shift hours
- —Act on the data — tracking without coaching is wasted effort
- —Start simple — five core KPIs are better than 50 unactioned metrics
Effective operator tracking transforms your Asterisk call center from a cost center into a performance-driven operation. Whether you build custom tooling or use a purpose-built platform like Astervis, the investment in visibility pays for itself through better agent productivity, lower abandonment rates, and happier customers.
Ready to see your operator performance in real time? Try Astervis free for 14 days — no credit card required.
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.
