QueueMetrics reports
QueueMetrics real-time page
Configuring Agents
QueueMetrics installation
MySQL storage and QLoaderd
QueueMetrics configuration
Running outbound campaigns
Common QueueMetrics errors
MySQL-related issues
XML-RPC issues
License-related issues
Advanced configuration
QueueMetrics Add-ons
Can I use multiple time-zones in QueueMetrics?
Unfortunately, it is not possible to use multiple time-zones within the same QueueMetrics instance, for the Reports or Wallboard view.
The QueueMetrics internal date and time depends on the server time, where the software is installed or (in the case of the hosted solution of QueueMetrics) the instance chosen time-zone.
This feature has been deprecated due to the conflicts and confusion that arose from the use of multiple time-zones. For consistent and clear data handling, QueueMetrics now operates under a single time-zone framework.
Permalink - Table of contents
I'm getting error "HTTP Status 400 – Bad Request" when calling APIs
If you use Tomcat 8+ as a servlet container (like modern version of Loway product do), it will return an error code 400 if you do not accurately URL-encode all characters according to RFC 7230 and RFC 3986. This often happens when passing a set of elements that are separated by the pipe symbol - so for example
a|b will not work, but
a%7Cb will. It may also happen if you use other "funny" characters in your requests.
For readability’s sake, the examples on Loway manuals still show the pipe character, but for real
calls, you have to URL-encode each input parameter.
Permalink - Table of contents
Can I remove some agents from reports?
If there are 15 agents in a call center queue, but I want to monitor only 10 agents
becaue I have a 10-agent license, is it possible to see
only those?
That is possible - as long as you run only reports that contain 10 agents. If the queue has 15, that is not possible.
The only thing you can do is to use an alias to "stick together" multiple agents, but at that point you lose the ability
to distinguish between them.
In general, if you have 15 distinct agents (that is, you pay 15 people each month), you should be licensed for all
of them; if not you may find that some queries,
wallbards or real-time reports block because they are over the limit.
Still, if you are okay on losing details, you may use one agent as "catch-all" by setting its aliases
to all the agents you don't want to see. So, for example, if you have a queue that has
agents 101, 102, 103 and 104, and you only want to see 101 and 102, you may create another
agent called "Other" that aliases to "agent/103|agent/104".
This way you will see in the reports agents "101", "102" and "Other", and they will only be counted as
three separate agents. Of course you lose the ability to distinguish between 103 and 104, so YMMV.
See also:
Permalink - Table of contents
Can I run a report for just one hour? Why are there calls marked as "*"?
When you run a report for a specified time frame, say one hour, QueueMetrics only includes events
that belong to that time frame. The shorter it is, the more likely is that you will have a large
percentage of calls that have some but not all events within that hour.
Those calls might appear as "*" as they are partially outside the reporting time. A similar thing happens
to calls that end outside of such time frame: If you run a report from 10:00 to 11:00 and it includes a
call that started at 10:59 and ended at 11:05, the call will only be counted up to 11:00 and will
appear as "incomplete".
Even worse, those calls will appear as incomplete in a report between 10 and 11, will appear
again in a report between 11 and 12 - as they have some events there.
One possible workaround is to use a "time band" filter on top of the report: you run a report from 9:00 to 12:00,
and then band it off using a time filter from 10 to 11. In this case, only calls starting within that period will be included,
but they will appear in their entirety.
Another possible approach is to use reports that are already divided by hour in order to look for the data
you need.
Permalink - Table of contents
I'm seeing incorrect agents and/or lost call counts on my real-time page and wallboards.
Version 23.09 of QueueMetrics ships with a new real-time engine (used to populate wall-boards,
the real-time page and the new agent pages) called Presentialist. Presentialist departs from the
long-running tradition of processing real-time requests at the moment they are needed, and
basically keeps a snapshot of the whole real-time interaction in memory at all times. This means
that on systems with tens or hundreds of agents or open wallboards, it's very likely that the
work required to derive a new real-time picture is way less than it was before, therefore reducing
the system load.
Still - there is a snag: if you have a call reported multiple times on different queues -
for example when using outbound tracking, having a call that is tracked for outbound and also
goes on a queue - then Presentialist, that by definition will build a full picture of
what is happening, will be unable to tell apart the events generated by your queue from the ones generated by
outbound tracking. The result is a dog's breakfast; one of the calls might be reported with an incorrect agent,
and then you might have
a second lost call when both calls close at once.
To see if you are affected by this behavior, just run a normal report for the same
period of time as the real-time page/wallboard was using - if the data you see in the report are correct, then
that's the issue.
This is not an issue for reports, that by definition only process data from queues you specify,
but in order to have a meaningful representation of live data you need to add the following property
to your configuration.properties file:
realtime.ignoredQueues=q-outbound
or if you already have an ignore queue set in Uniloader:
realtime.ignoredQueues=_q-outbound
This will simply hide the queue (or queues) from real-time reports and will let you
run accurate wallboards. You can specify multiple queues by separating them with a
comma. The new properties apply to QueueMetrics 23.09.3 and above.
Permalink - Table of contents
Why are my Excel exports limited to 1000 lines?
You try exporting a report to an Excel file; the first 1000 rows are exported, but by the end there is a row that says (for example)
"...233 rows missing. Please increase maximum XLS rows allowed for exporting."
Since an XLS file can hold up to 65536 lines per sheet, new limitations have been implemented to avoid errors during export.
- The first limitation is that XLS exports cannot export more than 65536 lines per sheet. In case of a document going over that
limit, a line will be added at the end of the document that lets the user know that some data is missing.
- To avoid tables taking up most of the row limit for the sheet, all tables have been limited to 1000 lines by default.
This limit can be changed by editing the following system parameter (you can find it in Explore system parameters):
default.maxRowsXls=1000
Of course changing this property will not override the hard 65536 row limit on the sheet.
If your report exceeds the 65536 rows limit, we recommend dividing the Report Page in multiple pages, that will be exported in separate sheets, so as to avoid the maximum row limit.
Permalink - Table of contents
I can log agents on queues, but they cannot be paused.
The agent seems to log on successfully - on queue_log there will be a record for hotdesking and a ADDMEMBER record, all with the correct extensions; but they do not seem to be able to pause themselves because QueueMetrics is trying to pause an empty extension, e.g. 'SIP/' or ''.
You will notice this behavior when:
- You are using hotdesking (parameter `default.hotdesking` not set to zero)
- You have a fixed SIP extension as an alias for this agent
- When you log the agent on, and look at the Real-time page, the agent appears with a blank extension
This is caused by the fact that the physical extension you are using (e.g. SIP/223) appears in the configuration as an alias for one or more agents. As aliases have priority over hotdesking records, the extension will be translated to the agent that uses it as an alias, therefore "snatching" it from the hotsdesking record.
The problem can be easily fixed by removing the extension as an alias of an agent. In general, if you use hotdesking, specifying SIP aliases for your agents is rather suspicious, as hotdesking is in itself a temporary aliasing mechanism.
Permalink - Table of contents
Installing QueueMetrics on Ubuntu (22.02) server
IMPORTANT: you should install QueueMetrics manually only if you are an expert user. Unfortunately this is a non-standard installation in a non-standard environment and Loway won't be able to support you with system administration problems (tomcat configuration, database permissions and so on), although the support on the QueueMetrics software itself will remain available as always.
Being CentOS the natural habitat for Asterisk and almost all the Asterisk-related world, we always suggest to install QueueMetrics on a CentOS machine (or whatever CentOS flavor like FreePBX or Elastix), and if you ask us CentOS is always the better solution, even in a virtual machine. Using CentOS is not always possible though so your are free to install QueueMetrics in whatever system you prefer.
QueueMetrics is a Java servlet application that runs over a Tomcat server. Potentially you can run QueueMetrics on every Linux distribution and Operating System, Windows as well.
Although the procedure may change amongst the various different systems, conceptually it's ever the same: install all the dependencies and put QueueMetrics on the Tomcat server.
Given that we can't cover every possible Operating System in this tutorial, we'll use a Ubuntu machine to show you the steps to get QueueMetrics working. Your part will be to adapt the steps to your system and situation and remember that filenames and directories may be different.
For this procedure we are going to be using QueueMetrics v22.02.9.186 and Tomcat v8.5.81 on a Ubuntu 22.02 machine.
1) Install the necessary dependencies:
apt-get install openjdk-8-jdk-headless mariadb-server
2) Verify the Java version:
java -version
Example of positive result:
openjdk version "1.8.0_312"
OpenJDK Runtime Environment (build 1.8.0_312-8u312-b07-0ubuntu1-b07)
OpenJDK 64-Bit Server VM (build 25.312-b07, mixed mode)
3) Verify MariaDB is working and running
systemctl status mariadb
Example of positive result:
● mariadb.service - MariaDB database server
Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2020-03-04 08:53:18 CET; 2 days ago
Main PID: 978 (mysqld_safe)
CGroup: /system.slice/mariadb.service
├─ 978 /bin/sh /usr/bin/mysqld_safe --basedir=/usr
└─1250 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --...
4) Download Tomcat:
wget http://archive.apache.org/dist/tomcat/tomcat-8/v8.5.81/bin/apache-tomcat-8.5.81.tar.gz
5) Create the folder:
mkdir -p /opt/tomcat-queuemetrics
6) Unpack Tomcat:
tar xzf apache-tomcat-8.5.81.tar.gz -C /opt/tomcat-queuemetrics
7) Download QueueMetrics:
wget https://downloads.loway.ch/software/queuemetrics/QueueMetrics-22.02.9.186.tar.gz
8) Unpack QueueMetrics:
tar xzf QueueMetrics-22.02.9.186.tar.gz -C /opt/tomcat-queuemetrics/apache-tomcat-8.5.81/webapps/
9) Create a symbolic link:
ln -s /opt/tomcat-queuemetrics/apache-tomcat-8.5.81/webapps/queuemetrics-22.02.9.186 /opt/tomcat-queuemetrics/apache-tomcat-8.5.81/webapps/queuemetrics
10) Update MySQL root password:
mysql -e "set password for 'root'@'localhost' = password('')"
11) Start Tomcat:
/opt/tomcat-queuemetrics/apache-tomcat-8.5.81/bin/startup.sh
Permalink - Table of contents
Why do I get a message "The report exceeds the number of licensed agents"? How many agents do I need?
This error is displayed when QM senses that there are more than the maximum licensed number of agents in the dataset it is processing.
As a general rule, you need an agent for each separate agent entity you want to keep track of - so if you have two shifts of 20 persons each, you need 40 agents total. If your agents change over time and you want to keep track of both present and past ones, using a different code for each, you will have to factor that in as well. So, for most call centers, you will need something more than the number of paychecks you write every month, for people who work with their phones.
QueueMetrics natively tracks only calls on queues, so any entity that is not answering on a queue (or taking part in an outbound campaigns) is not counted. If you use automated outbound tracking, all phones will be tracked and so every one of them will be counted as one agent.
The error above may be caused by three reasons:
- You have more agents than your license is valid for (and in this case you should purchase an enlargement);
- You have less agents than your license is valid for, but agents appear under multiple distinct codes;
- The report covers current and past agents, that in total are more than the licensed number of agents.
Cases #2 and #3 happen if you change your agent codes, or use new agent codes to supplement older ones. From the point of view of QM, each distinct agent code is a unique agent, so it is counted against the license limit.
You can easily check which one is your case by requesting an unlimited demo key and running the same report that displays the error; go to the "Agents on queue" report and count the number of distinct lines that appear there.
What you can do to mitigate this problem:
- Purchase a larger license key
- If you changed your agent numbering plan, avoid running reports that overlap both agent sets
- Try and run reports that do not include more than the licensed agents
- Edit the dataset manually - or create an alias - to merge to the same code in case the same agent appeared under different codes (e.g. sometimes as Agent/101 other times as SIP/101).
See also:
Permalink - Table of contents
Queue_log file missing or empty
The queue_log file (usually found in "/var/log/asterisk/queue_log") contains all the queue information that QueueMetrics uses to create the reports and Live stats.
If you PBX is not writing data in the queue_log file, make sure that your Asterisk is configured to write the information on the file.
It should be enough to add:
queue_log_to_file = yes
To the "/etc/asterisk/logger_general_custom.conf" file, that you find on your Asterisk machine.
Restart Asterisk and make sure that the data is being written.
Permalink - Table of contents
Widget showing no data
With QueueMetrics 19.04 the Wallboard has been updated, it might be needed to reset the queue filters for some widgets.
If some widgets are appearing empty, it might be that they used to have a queue filter set.
Please open the widget configuration and delete all old filters, then set them again.
If the issue persists, recreate the widget.
The issue arises from the fact that now it's possible to filter for more than one queue at the same time, so the queue filter was changed, and old values that were set are no longer compatible.
Permalink - Table of contents
Error: Got error 28 from storage engine
When you encounter the error message
Error: Got error 28 from storage engine usually it means that there is no more free disk space on the server where MySQL is located. QueueMetrics creates temporary tables when it runs, but without free disk space, it cannot work.
You need to:
- clean up the disk;
- make a database dump;
- do a repair of all tables on the database see: Repair MySQL;
- restart your Uniloader/Qloader.
It is possible - though unlikely - that some tables will not be recoverable. In this case you need to go back to a previous back-up.
Permalink - Table of contents
Removing old data from QueueMetrics
Your database got big and you don't mind deleting calls data before a certain date. Here's the procedure to do it:
1) Before doing anything on the database make sure you saved a db dump somewhere:
mysqldump -uqueuemetrics -pjavadude queuemetrics > qmdump.sql
2) Change the partition name to the lines you want to delete, in our example we'll target everything created before 01/01/2016 @ 12:00am (UTC), that's 1451606400 in Unix epoch format.
UPDATE queuemetrics.queue_log
SET 'partition' = 'DEL'
WHERE time_id' < '1451606400';
3)Now log in QueueMetrics as admin and go in "System Diagnostic Tools" -> "RAM caching" and clean the caches: now you can go in the realtime page or run some reports in order to verify everything is ok.
The system might seem slower now, we'll address that in the last step.
4) When you are 100% sure everything is ok you can delete all the rows that are part of the DEL partition:
DELETE FROM queuemetrics.queue_log
WHERE 'partition' = 'DEL';
5) Now optimize the table in order to tune the database performances:
OPTIMIZE TABLE queuemetrics.queue_log
Permalink - Table of contents
My WebRTC softphone registers but when i try calling it I get on Asterisk CLI "Media stream permission denied".
This could be happening for a variety of reasons. Either you're not using an HTTPS connection or your browser does not have permission to use the microphone. It could also be that your computer does not have a microphone in the first place.
Permalink - Table of contents
Why is startup so slow after switching to Java 8 / Tomcat 8?
After upgradig an existing system to Java 8 / Tomcat 8, you notice that the
time it takes from a restart to serving QueueMetrics may run into a few minutes.
While this happens, Java appears to be using almost no CPU and just be idling.
What is going on?
The default settings for Java 8 is to use a strong source of randomness as
a seed to
generate random numbers that are cryptographically secure. Unfortunately, in order to
do this, it has to wait for sufficient entropy to build up, and this may take
a long time (even minutes).
As you will not likely need to use such a high level of randomness in QM, but you
will prefer quick boot times for the application, you can easily edit the file
/etc/sysconfig/qm-tomcat6 and change the line that says:
JAVA_OPTS="-server -Dtomcat.instance=$TOMCAT_INSTANCE $JAVA_MEM $JAVA_RMI"
To:
JAVA_OPTS="-server -Djava.security.egd=file:/dev/./urandom -Dtomcat.instance=$TOMCAT_INSTANCE $JAVA_MEM $JAVA_RMI"
Then restart with service queuemetrics restart. Now it should start up in a few seconds.
This setting is already in place for new installs, so this procedure is only needed
on systems that were originally installed using Java 6.
Permalink - Table of contents
How do I use the new MariaDB JDBC driver?
QueueMetrics 17.x implements a number of changes that are meant to make the system
perform better and use modern architectural components. One of them is the JDBC driver,
that is the piece of software that lets QueueMetrics access the database.
On most systems, if QueueMetrics is installed using the default database
credentials, those changes are implemented automatically. If instead you rely
on custom database credentials, you will need to tell QueueMetrics to access the
database using the new JDBC driver.
In order to do this, you need to edit the file
WEB-INF/tpf.properties
and change the line that says:
JDBC_URL=jdbc:mysql://localhost/queuemetrics?autoReconnect=true&zeroDateTimeBehavior=convertToNull&jdbcCompliantTruncation=false&user=queuemetrics&password=javadude
to something like:
JDBC_URL=jdbc:mariadb://127.0.0.1/queuemetrics?user=queuemetrics&password=javadude&sessionVariables=sql_mode=''&autoReconnect=true
Please note that it is not enough to just change the string "jdbc:mysql" to "jdbc:mariadb"
as the connection parameters accepted by each driver are different.
After the change, restart QueueMetrics.
As an alternative, you may want to install the old MySQL Connector/J driver manually;
in this case, it is enough to dowload it from the official site and add the JAR
to the
WEB-INF/lib folder in QueueMetrics, and then restart (but you
will have to do it manually on every install).
Permalink - Table of contents
How do I upgrade to a modern QueueMetrics system on Elastix 2 / CentOS 5?
The current version of QueueMetrics depends on Java 1.8. This version of Java
is not present in the CentOS 5 upstream repositories and so QueueMetrics will complain
that a required package is not present and a fully automated install is not
possible.
In order to upgrade, you need to:
- Download Java 1.8 from the Oracle repositories. It seems that OpenJDK 8 is not available
for CentOS 5 systems
- Manually install it
- Download the queuemetrics-tomcat package and install it manually
- Upgrade QueueMetrics normally via yum
Downloading and installing Java 1.8
You can download a Java 1.8 SDK (not just the JRE, but the full SDK) for your architecture
from http://www.oracle.com/technetwork/java/javase/downloads/index.html - choose the
right RPM format for your architecture. Use exactly Java 8, not an earlier or later version.
Now run:
yum localinstall jdk-8u121-linux-i586.rpm
If all goes well, by running it you should receive a confirmation message
like the one below:
# java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) Client VM (build 25.121-b13, mixed mode, sharing)
Now we need to create a symlink that lets QueueMetrics find it:
mkdir -p /usr/lib/jvm
cd /usr/lib/jvm
ln -s /usr/java/jdk1.8.0_121/jre/ java
Make sure you change the exact directory (where it says
jdk1.8.0_121) to match your version of Java.
Downloading and installing Tomcat 8
As our Tomcat 8 package has a requirement for Java 1.8, we need to
download and install it manually:
cd /root
wget http://yum.loway.ch/RPMS/noarch/queuemetrics-tomcat-8.5.12-28.noarch.rpm
rpm --nodeps -Uvh queuemetrics-tomcat-8.5.12-28.noarch.rpm
If all goes well, by running the following command you get a confirmation that QueueMetrics will use
the right Java package:
# /usr/local/queuemetrics/java/bin/java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) Client VM (build 25.121-b13, mixed mode, sharing)
Updating QueueMetrics
Now you can upgrade QueueMetrics as usual:
yum update queuemetrics
And then go to home page and follow the update wizard to upgrade your database.
Permalink - Table of contents
How do I install or update a QueueMetrics license?
There a two ways to do that:
-
From the QueueMetrics interface log in as an ADMIN user, then go into the "License page" (key button, at top-right), in there you'll find an "Install new license" link newar your current license's information.
If you don't see the link make sure that your Admin user has the KEYUPDATE security key.
Insert your license, confirm and wait for confirmation, then you are ready to go.
-
You can also change your license manually: open the /path/to/queuemetrics/WEB-INF/tpf.properties file and put your license code into the LICENZA_ARCHITETTURA variable (uncomment the line if necessary).
After that restart QueueMetrics with '/etc/init.d/queuemetrics restart'
Permalink - Table of contents
Is it possible to integrate QueueMetrics with Sugar CRM?
Sugar CRM Integration - Version 1.1
This script integrates the QueueMetrics agent page with SugarCRM. When properly configured, the QueueMetrics
agent call history page opens an external URL for each taken call. This feature could be used to call the provided
PHP script. The script searches between contacts in the SugarCRM, starting from the calling number, and opens the
call detail record, if present on SugarCRM database, or preloads a new contact page with the calling party number.
Permalink - Table of contents
Is there a way to keep track of the number of active agents?
Count Agents - Version 1.0
We provide a Count Agent script: a PHP script that counts how many unique agents are running on a given set of queues during a chosen period of time.
Permalink - Table of contents
Can I manage QueueMetrics Through JSON?
JSON PBX actions - Version 1.0
Yes, QueueMetrics also supports JSON requests. We provide a sample script that contains a set of functions
and a set of examples. This enables an external robot to perform login/logout, pause/unpause, hangup, monitor calls
and other PBX oriented actions by simply calling a set of JSON RPC.
Permalink - Table of contents
Can i manage QueueMetrics Trough XML-RPC?
XML-RPC Test Servlet - Version 1.0
Yes you can. We provide a simple Java Servlet for XML-RPC testing with QueueMetrics. It comes in handy when practicing
with the XML-RPC library becaus it allows you to see the exact output from the various XML-RPC requests sent to
QueueMetrics while writing your custom reports.
Permalink - Table of contents
Is it possible to integrate QueueMetrics with VTiger CRM?
VTiger CRM Integration - Version 1.0
This script integrates the QueueMetrics agent page with VTigerCRM. When properly configured, the QueueMetrics agent call history
page opens an external URL for each taken call. This feature could be used to call the provided PHP script. The script searches
between contacts in the VTigerCRM, starting from the calling number, and opens the call detail record, if present on VTigerCRM
database, or preloads a new contact page with the calling party number.
Permalink - Table of contents
Is there a way to remove all agents from a queue?
Remove all agents - Version 1.0
Yes, This bash script removes all agents from a queue. It comes in handy to run at night to make sure all agents
are logged off at the end of their shift. You may also run it manually to "reset" an Asterisk queue.
Permalink - Table of contents
Can i receive notifications for Qloader errors?
Qloaderd monitor
Yes, we provide a script (that can be run nightly) that will notify the sysadmin of the errors encountered in the Qloader's log file.
This script will monitor the log produced by Qloaderd for disconnection errors and will send an email to the sysadmin
in case any are found. This is useful because if you operate on a WAN, it is possible that you have long-term downtimes
that risk losing data (for example if you do a logrotate while the network is down).
Permalink - Table of contents
Can i Log IVR responses to QA forms in QueueMetrics?
Log Asterisk IVR to a QA form
Yes, we provide a sample script with a trivial example that shows how to log an IVR that
is run at the end of a call to a QA form in QueueMetrics.
Permalink - Table of contents
Where can i find a simple wallboard for QueueMetrics?
The Flantel qmon.php wallboard - Version 1.1
This is the original script, and a QM users' all-time favourite. Now patched to support QueueMetrics 15.02. It provides a simple wallboard to view you QM data in real-time.
Permalink - Table of contents
How to search all calls excluding ones with a specific outcome
Let's say you want to see all calls that aren't marked with outcome 'sales'.
Outcome codes are evaluated as regular expressions so all you have to do is to define a new outcome code ("Edit call outcomes" page):
Status code: ^(?!.*sale).*$
Description: Not sale
In this way, running a custom report filtering the calls by the "Not sale" outcome you will exclude all the calls with "Sale" outcome.
All you have to do now is to set a security key to this new outcome so that it won't be visible to your agents.
Permalink - Table of contents
How to configure outgoing emails with Gmail
In order to use your Gmail account in order to send automated email reports, configure QueueMetrics as follows:
default.smtphost=smtp.gmail.com
default.smtpport=465
default.smtpfrom=username@gmail.com
default.smtpuser=username@gmail.com
default.smtpassword=verysecret
default.smtpssl = true
Permalink - Table of contents
What's the difference between Agents and Users in QueueMetrics?
In QueueMetrics you define agents, every agent represent a person in your call center.
You want to define a new agent:
- Asterisk agent code: agent/321 (this has to follow the pattern: agent/somenumber)
- Agent description: John Doe (this is the human-readable translation; in your report you'll get the real name, not the agent code)
As well you'll need to define a new user:
- Login: agent/321 (the same of the agent)
- Password: password
- Real name: John Doe
Why we created an user and an agent with the same name?
Users and agents are different in QueueMetrics: a user is an access credential to QueueMetrics, it doesn't have to be an agent, it could be just someone that can run reports or an admin user.
An agent, instead, doesn't need to be necessarily an user; if your agents are static in the queues and always use the same phones, you'd want to define the agents in QueueMetrics just to translate phone codes (e.g. SIP/3321) in a readable name in reports.
Permalink - Table of contents
How to make my agents set a new pause without unpausing first
When you send a new Pause event without Unpausing first QueueMetrics doesn't consider that a new pause but always the same pause. It consider as the correct pause code the last one issued.
In order to have two distinct pauses you'll have to unpause, then pause again with the new code.
If you don't like this behaviour (for example, you don't want your agents to be able to change a running pause code) add this line to the QueueMetrics dialplan, at extesion 22, before the "PauseQueueMember" line:
exten => 22,n,System( echo "${EPOCH}|NONE|NONE|Agent/${AGENTCODE}|UNPAUSEALL|" >> /var/log/asterisk/queue_log )
Permalink - Table of contents
How do I make my agents know which queue is ringing their phone?
It's not possible for QueueMetrics to know which queue is ringing your agents' phones, since that depends also on internal Asterisk's decisions based on its configuration.
What you can do is to modify the
caller id of the call, to show the queue's name before the caller's number.
Modify the queue's dialplan adding, before the Answer:
exten => queue-ext,n,Set(CALLERID(name)=queuename - ${CALLERID(num))
Permalink - Table of contents
What happens when a call overlaps the report's time window?
The QueueMetrics database is built around the concept of a stream of events. Every event is bound to its timestamp (time when it happened).
When you run a report fro a specific time period, especially if it is very short because you are polling data via XML-RPC, QueueMetrics includes all the information that comes from events in the specified time-frame, and nothing more. So there are four scenarios:
- Calls which its events are all in the time period: no problems; they are correctly reported.
- Calls which started in the time period, but ended after it. You'll know when it started but not when it ended.
- Calls which started before the time period but ended in it. Some information (notably the Caller-ID) is missing.
- Calls which started before the time period and terminated after the time period without any event in-between. These calls didn't generate any event in that time period. So such calls might be skipped altogether.
The reason why QueueMetrics uses a bounded window is that when running a report for a specific period, a deeper problem looms: when is a call to be counted? when it started in the given period, or when it connected, or when it ended, or when it is completely within? this commonly happens when you make multiple consecutive short-time analyses - if a call starts in period A and ends in period B, where is it to be counted? the correct answer depends on what you need the data for, so our approach is to be agnostic on this and look at plain events.
A good real-life solution to the problem is to take your time period and add a margin before and after. How much is a good margin? it depends. We suggest at least twice the average duration of the calls in your call center. Then your script will examine those calls timings (answer, hang-up) and decide which ones to count and which are to be skipped.
Permalink - Table of contents
Why do I get a JSP compilation error (missing method)?
Sometimes, after an update, it could happen that you get an error in the JSP files compilation.
In that case you'll need to clean the Tomcat's cache:
/etc/init.d/queuemetrics stop
/etc/init.d/qm-tomcat6 cleancache
/etc/init.d/queuemetrics start
Permalink - Table of contents
Why do I see agents logged in twice - under their own name and as Agent/name?
If you see agent logged in twice, once under their correct name and a second one
under the name
"Agent/agent name", often with a difference of a few seconds.
Sometimes you will see that the correct name will log off at the end of the
agent session, while the
"Agent/agent name" will linger on for a while.
This is caused by not having "Friendly names" set -
see
Why do agents on a call show up with a different name?
to fix this.
Permalink - Table of contents
I use FreePBX - why do agents on a call show up with a different name?
When setting up FreePBX, you can tell it to either use the default Extension mode
or use the
"User & Device" mode. While in Extension mode the user (agent)
code and thir extension match, in U&D mode they are independent.
When running in this mode, agents are logged in one way when they join
a queue (usually with their extension code) and in a different way (using their
user name) when they receive a call. So QueueMetrics sees the equivalent of
"Extension 203 logged on at 9:30 and John received a call at 9:31" and
cannot natively make sense of it, as it is never logged that extension
203
goes under the name
John. That's why you see agents logged under one name and
handling calls under a different one.
In order to handle this, QueueMetrics has the concept of "Friendly name", that
is a name that you configure on the agent configuration page that will be mapped to the
same agent code. So, if you set up a friendly name of "John" for Agent/203,
whenever QueueMetrics finds a "John" it will silently rewrite it as Agent/203.
This way, calls are attribuited correctly and agent sessions are counted correctly.
You can have multiple friendly names for the same extensions. Just enter them
separated by a pipe character. This is needed in case you changed the User name
during the period under analysis.
Please note that agent session statistics will be incorrect if you do
not set Friendly Names when they are needed. In general, anyway, if you need to
keep track of multipl epeople working from the same extension, QueueMetrics
Hotdesking mode will be a better approach.
See also:
Permalink - Table of contents
How do I enable actions (login, logoff, transfer....) on the Realtime page?
Since QueueMetrics 12.10, the Realtime page lets you perform a set of actions that
are sent to Asterisk for processing. These include:
- Logging agents on and off
- Pausing and unpausing agents
- Transferring calls
- Sending SMS
- Listening to live calls
If you upgrade from an earlier system, these actions will not usually appear
in your RT page - this is because they need three distinct elements:
- A security key: each action is enabled by giving your users a specific security
key. You should esit the user or class profile and add the required key
- A configuration item: the action is possible only if we tell QM
that the action is allowed and how to perform it (that is, where is the Asterisk
dialplan it should go in order to have the action performed). If you upgrade
from an earlier version, you should manually add the configuration items
in your configuration.properties. All such properties start with "callfile.*"
- A dialplan item: the Asterisk dialplan should include an extension (generally
in the supplied context named queuemetrics) that actually performs the
requested action
Let's see an example: imagine we want to turn on call transfers on an older system.
- First we add the key RT_TRANSFERCALL to the Admin class. A list of keys for each
feature can be found in the Qm user manual, appendix B: Security keys
- Then we add the following configuration item:
callfile.transfercall.enabled=true
callfile.transfercall.channel=Local/10@queuemetrics/n
callfile.transfercall.extension=31
callfile.transfercall.context=queuemetrics
This stanza tells QM that the feature is enabled and that in order to process it is
must invoke extension 31@queuemetrics in Asterisk.
A list of properties for each feature
can be found in the Qm user manual, appendix D. System preferences
- The Asterisk dialplan should include a stanza like:
exten => 31,1,NoOp( " QM: Call redirect ,ade by ${QM_LOGIN} for callID: ${CALLID} to extension ${REDIR_EXT}")
exten => 31,n,ChannelRedirect(${CALLID},from-internal,${REDIR_EXT},1)
exten => 31,n,Hangup
Samples for each possible stanza are found in the extensions_queuemetrics.conf that ships with each
version of QM and must be adapted to your local system.
More details can be found in the Qm user manual, appendix C. The [queuemetrics] context
Permalink - Table of contents
Completion of any call in the queue appears as Caller Completed.
All calls processed by QueueMetrics are reported as if the caller hung up, even when it
was the agent hanging up.
This is a known issue with FreePBX 2.10 and you can easily fix it by
editing the dialplan as explained in
the Asterisk Forums.
Permalink - Table of contents
Printing and mailing out a report automatically
Since QueueMetrics 13.04, it is possible to have QueueMetrics
generate a report in PDF or XLS format, and download it or sent it automatically
to a group of recipients by e-mail.
The following notes only apply to earlier versions of QueueMetrics.
It is possible to print a full report to PDF automatically and have it emailed
periodically with no human intervention.
In order to run the following script, you need to install the following
packages on your server:
yum install htmldoc
yum install nail
(you need to enable the DAG repository to have
nail).
The script is as follows:
#! /bin/bash
QM_SERVER=http://127.0.0.1:8080
QM_WEBAPP=DAILY
QM_QUEUE=q1
QM_PERIOD=d90
QM_USER=robot
QM_PASS=robot
EMAIL=mu@email
# cleanup images
rm -rf $QM_WEBAPP/
rm -rf img/
# download images
wget -nH -k -K -p "$QM_SERVER/$QM_WEBAPP/qm_rep.do?user=$QM_USER&pass=$QM_ASS&queues=none&period=t1"
mv $QM_WEBAPP/img/ .
wget -o img/shade-histo.gif "$QM_SERVER/$QM_WEBAPP/img/shade-histo.gif"
# download report
wget -nH -k -K -p -l 1 -O report.html "$QM_SERVER/$QM_WEBAPP/qm_rep.do?user=$QM_USER&pass=$QM_PASS&queues=$QM_QUEUE&period=$QM_PERIOD"
# convert to PDF
htmldoc --webpage --size 11x8.5in -f myreport.pdf myreport.html
# mail out
echo "Your daily report is attached as a PDF" | env MAILRC=/dev/null from=qm-server@example.com smtp=mail.example.com nail -n -s
"Daily Report" -a myreport.pdf $EMAIL
This can be run automatically. For valid queue and time period parameters, see
the chapter "Automating statistics download: the ROBOT profile" in the QM user
manual.
In order to run the script, make sure that the ROBOT user is enabled in your QueueMetrics
installation (it is disabled by default).
Permalink - Table of contents
QueueMetrics logs are filling up all of my disk
QueueMetrics produces a detailed activity at the container level that lets us diagnose
performance issues and technical errors.
These logs are NOT automatically deleted in any way so they may end up filling all of the disk space
if they are never purged.
As disk space is very cheap these days, we advise in any case to make a backup before
removing files and data - what is removed cannot be restored.
The system log
The system log is where QM keeps information about actions performed and failed and successful log-ons.
You can purge it manually by running the following queries:
mysql> delete from arch_syslog where sys_dt_creazione < DATE_SUB( NOW(), INTERVAL 90 DAY );
Query OK, 756 rows affected (0.04 sec)
mysql> optimize table arch_syslog;
Optimizing is very important as it reclaims disk space. The query above deletes all records older than 90 days.
Tomcat log files
Tomcat keeps a running log of all activity and errors. In a standard QM installation,
it should be located in
/usr/local/queuemetrics/tomcat/logs.
[root@qm ~]# du --human-readable /usr/local/queuemetrics/tomcat/logs/
6.1G /usr/local/queuemetrics/tomcat/logs/
[root@qm ~]# cd /usr/local/queuemetrics/tomcat/logs/
[root@qm logs]# /etc/init.d/queuemetrics stop
[root@qm logs]# rm -f catalina.out
[root@qm logs]# rm -f localhost*.txt
[root@qm logs]# /etc/init.d/queuemetrics start
[root@qm logs]# du --human-readable /usr/local/queuemetrics/tomcat/logs/
20M /usr/local/queuemetrics/tomcat/logs/
As you can see, it is necessary to stop Tomcat in order to do this.
If you want, it is possible to control the logging made by Tomcat or turn it off altogether -
see section "Logs and Logging" of the WombatDialer User Manual
at
http://wombatdialer.com/manuals/WD_UserManual-chunked/ar01s07.html#_logs_and_logging.
Permalink - Table of contents
"Agent status cannot be determined" after logging on
After logging on or off from the agent's page, you still see the agent status as
"Agent status cannot be determined".
When QueueMetrics performs an action, what it actually does is to send a command
to Asterisk over AMI as an Originate request, waits a few seconds and and then
reads back the results from the queue_log.
There may be two issues here:
- if Asterisk is receiving isn't processing the request, then we have no way of knowing
that it hasn't been implemented;
- if Asterisk is very slow in processing this request because (for example)
it is quite busy, then it is possible that it will take a while for the
request to be processed, so when the page reloads, the request may not have
been loaded yet.
What we suggest in this case is:
- Check on the AMI tester from the DBTEST page whether it is possible for
QM to send commands to Asterisk and whether the relevant piece of
dialplan is present in Asterisk;
- if all is well, you should monitor what Asterisk is doing at the CLI level
when you receive a failed log-in/off attempt; whether the agent is actually added to
the queue or not and whether the queue_log is updated.
Permalink - Table of contents
Moving a QueueMetrics instance to a new server
If you need to move your existing QueueMetrics server to a different host and do not want to lose your current data and configuration, you can do that easily using yum. As a side effect, your system will be updated to the latest version. In this tutorial we expect that the MySQL server was on the old QM server and you want to use a new one on your new server, so you will have to move the database as well. Asterisk may be local on the old server or on a separate server altogether.
- Stop any qloaderd running, so the current database is in a stable state
- Make a complete backup of your existing system (configuration and database - see below)
- Stop the old QueueMetrics instance
- Install QueueMetrics using yum on your new server
- When it's working (you are able to log in), turn it off
- Edit the memory settings for your new system
- Overwrite the QueueMetrics database on the new server with the database dump from the old server
- Copy
web.xml
and the various properties files from the WEB-INF/
folder of the old system to the new system
- Make sure the access parameters for the database are correct (they usually already are, as the database is searched for on 'localhost')
- Start the new QueueMetrics instance
- When you connect to the new QueueMetrics, it will sense that the database comes from an older version and will automatically update it, if needed
- Edit your qloaderd properties (usually stored in
/etc/sysconfig/qloaderd
on the Asterisk server) so that it can upload data to the new database
- Restart qloaderd
- Check that it is able to upload data to the new database (you may need to create a MySQL grant so that qloaderd can connect to the new server)
- The new system should be working now!
It is of paramount importance that the new system and the old system are never running at the same time, as this could lead to license deactivation.
See also:
- Installing QueueMetrics using yum
- Backing up a QueueMetrics system and Backing up and restoring a QueueMetrics system
- Tuning Java memory
- Access Denied MySQL errors
Permalink - Table of contents
Understanding QueueMetrics agent name rewriting
QueueMetrics was built to handle agent names as separate entities from extensions.
This raises a few issues with newer versions of Asterisk, as the canonical form
Agent/1234 may not be used.
In order to do this, it is better if you start by taking an activity trace as described in a separate FAQ
here.
The first thing that we have to implement is that if see channels appearing on the log as
Local/1234@from-internal, then you have to set:
default.rewriteLocalChannels=true
so that when QM reads them back, it reads them as Agent/1234. This is used as the channel string is used as the agent's name,
as configured in the
Edit Agents page of QueueMetrics.
The second issue you may have is that if you use a GUI, it is possible that you see the agent names logged in "friendly"
format, as e.g
mike boo instead of
Local/1234@from-internal.
The big problem here is that this only applies to calls and not to agents logging on and off.
This typically leads to a situation where, on the real-time page, you see the agent logging on as e.g. "Mike Boo (1234)" (that's the name you gave the agent in QM) and then when he first receives a call, a new entry "agent/mike boo" appears as well.
In order to solve this, we have to tell QM that when it finds
mike boo it needs to read it as
Agent/1234.
We do this by setting a "fiendly name" for the agent, that must be the exact string that the agent appears
on the
queue_log as, for our agent in the
Edit Agents page of QueueMetrics.
Permalink - Table of contents
Taking an activity trace
In order to debug a set of issues with agents not logging in correctly, we often ask users to provide an activity trace. Here is how you should do it.
First and foremost, you should take an activity trace only when the PBX is idle; otherwise a number of unrelated log lines are inserted and it is hard to understand the result.
You should open the
queue_log file on the PBX that is located in
/var/log/asterisk/queue_log - you could e.g. issue the command:
tail -f /var/log/asterisk/queue_log
that will display the new lines being appended.
What you do now is:
- You log the agent on (from either the QM agent's page or your own login scripts)
- You send a call to the agent; have the agent answer it and hang up
- You set a status code for the call
- You pause the agent (from either the QM agent's page or your own scripts). If you do it from the QM web interface, do set a pause code.
- After a few seconds, you unpause the agent
- You log the agent off
You can now send Loway the resulting logs, from which it is possible to understand what is going wrong.
Permalink - Table of contents
I don't see agent sessions without calls
It is possible that when running a custom report, selecting the agents name, the queue and the date and navigating to the "Agents" tab, QueueMetrics shows no information.
This happens because QueueMetrics considers an agent session without activity a logging anomaly as it is very unusual for an agent not to take at least one call throughout a shift.
However, QueueMetrics can be configured in order display these agent sessions where no calls were taken by the agent, by setting the following property to TRUE:
default.useRawAgentSessions=true
If true, shows all agent sessions. If false, shows only agent sessions with at least one call handled. (The property defaults to false).
Permalink - Table of contents
Backing up and restoring QueueMetrics
To make a backup of a working QueueMetrics system, you should backup the following items:
- The QM database by typing:
mysqldump -uqueuemetrics -pjavadude queuemetrics > database.sql
File will be located at /root/database.sql
- The web.xml and configuration.properties files being used (You can
find them under the QM webapp under WEB-INF; if you run a recent version of
QM, just look for the System path entry on the Licence page)
Files will be located (e.g.) at /usr/local/queuemetrics/webapps/queuemetrics-1.7.0.2/WEB-INF/
- The queue_log data used for input (it is advisable to this in any
case, even if you use MySQL storage, just to be on the safe side).
Files will be located: /var/log/asterisk
Restoring:
- Create an appropriately named database on the target machine and make it accessible to user 'queuemetrics' password 'javadude'
- Load the file using the mysql command:
mysql -uqueuemetrics -pjavadude queuemetrics < database.sql
- Restore web.xml, tpf.properties and configuration.properties under the WEB-INF directory of
the new QM instance
- Then open up GUI window where QueueMetrics is located (e.g. http://127.0.0.1:8080/queuemetrics ) and
run the DB updater wizard to repair.
Permalink - Table of contents
IE8 error: "The following error occurred in the Transaction handler: Il verbo '...' non e' stato trovato tra quelli caricati."
This basically means that the controller (the servlet /tpf ) received an empty HTTP request, so it does not know what to do with it.
To resolve the issue make sure that cookies are set to ON in IE8 Enhanced Security Mode.
Permalink - Table of contents
How do I remove duplicate rows from the queue_log table?
If more than one instance of qloaderd are running concurrently,
this will lead to duplicate entries within the queue_log table.
These entries must be removed by using the following procedure
(requires MySQL 5):
1. Stop all qloaderd's - you should see no data being appended
2. Create a new table called queue_log_b that has the same definition as your current queue_log table:
CREATE TABLE `queue_log_b` (
`partition` varchar( 20 ) NOT NULL default '',
`time_id` int( 11 ) unsigned NOT NULL default '0',
`call_id` varchar( 30 ) NOT NULL default '',
`queue` varchar( 30 ) NOT NULL default '',
`agent` varchar( 30 ) NOT NULL default '',
`verb` varchar( 30 ) NOT NULL default '',
`data1` varchar( 200 ) NOT NULL default '',
`data2` varchar( 200 ) NOT NULL default '',
`data3` varchar( 200 ) NOT NULL default '',
`data4` varchar( 200 ) NOT NULL default '',
`data5` varchar( 200 ) NOT NULL default '',
`serverid` varchar( 10 ) NOT NULL default '',
`unique_row_count` int( 10 ) unsigned NOT NULL AUTO_INCREMENT ,
KEY `idx_sel` ( `partition` , `time_id` , `queue` ( 2 ) ) ,
KEY `partizione_b` ( `partition` , `time_id` , `unique_row_count` ) ,
KEY `by_hotdesk` ( `partition` ( 5 ) , `verb` ( 5 ) , `time_id` )
) ENGINE = MYISAM DEFAULT CHARSET = latin1;
3. Copy all data from queue_log to queue_log_b
INSERT INTO queue_log_b
SELECT *
FROM queue_log
4. Delete the queue_log table
TRUNCATE TABLE queue_log
5. Copy all unique rows back to queue_log
INSERT INTO queue_log (
SELECT `partition`, `time_id`, `call_id`, `queue`, `agent`,
`verb`, `data1`, `data2`, `data3`, `data4`, `data5`,
`serverid`, MIN(`unique_row_count`)
FROM queue_log_b
GROUP BY `partition`, `time_id`, `call_id`, `queue`,
`agent`, `verb`, `data1`, `data2`, `data3`,
`data4`, `data5`, `serverid`
ORDER BY time_id, MIN(unique_row_count)
)
this may take a while.
6. Restart ONE instance of qloaderd.
7. Do not forget to CLEANUP the temporary table:
DROP table queue_log_b;
Permalink - Table of contents
Can I use logrotate for the queue_log file?
On a QueueMetrics system, it is often not necessary to rotate the queue_log file.
If you really need to rotate the queue_log file, you can do this provided that
you are using SQL data storage and have
qloaderd installed. The
qloaderd
process must be notified as soon as the file are rotated.
The following logrotate directive can be used:
/var/log/asterisk/queue_log {
weekly
missingok
rotate 10
notifempty
sharedscripts
create 0640 asterisk asterisk
postrotate
/etc/rc.d/init.d/qloaderd restart > /dev/null 2> /dev/null
endscript
}
This code will perform weekly rotations and will keep an archive of 10
weeks of data. We suggest in any case to keep a complete backup of
all
queue_log data that gets written, in order to allow for future analysis.
For further details about log file rotation, refer to the following link:
log file rotation
Permalink - Table of contents
After installing the license key, QM does not even start!
You just installed a new QueueMetrics key that you were sent by Loway; after the
installation, the whole QueueMetrics webapp seems to be unavailable and
displaying an error like the following one:
HTTP Status 404 - /queuemetrics/
-----
type: Status report
message: /queuemetrics/
description: The requested resource (/queuemetrics/) is not available.
-----
Apache Tomcat/5.0.28
This is caused by an invalid or corrupted
web.xml file; it prevents
the whole webapp from being loaded by the Tomcat container and therefore
the webapp is reported as being unavailable.
When you edit the
web.xml file, you should make sure that it remains
a valid XML document; in order to spot any mistakes, you can check the
validity by issuing the following command after every upgrade:
xmllint web.xml
If everything goes well, it should return no errors.
(In case you do not find it on your server, you can install it easily by
issuing the command
yum install libxml2-devel
on Red-Hat based
Linux distributions).
If that don't work try deleting the following file
/usr/local/queuemetrics/tomcat/conf/Catalina/localhost/queuemetrics.xml
and restarting the
queuemetrics service.
Permalink - Table of contents
Can I move the license key when installing a new server?
QueueMetrics licenses are not tied to a specific server; so you can
copy yor existing license from one server to another one. Of course you cannot
have multiple copies of the same license active at the same time, even on the
same server; this goes against the EULA and the licensing terms.
The license manager tries to avoid multiple instances of the same license
being active at the same time; they maystop working, block each other and
even invalidate the key. This is by design a random behavior, so it is hard to
tell in advance what exactly will happen.
In case you need to install and test a different server, what we usually do is
that we send you a demo key to do complete the installation; then you turn off
the old server, copy the key to the new one and start it. It would be better
to remove the key from the old server at all, so you do not risk to turn it
on accidentally.
Permalink - Table of contents
Why agents that do not logon are not a good idea
Many call-centers prefer to have agents always logged on, that is, the queue
always rings the same set of phones 24/7. This is apparently easier to
set up, as agents do not have to log on when they start working and
off when they stop.
We advise against this method of managing agents, because:
- Even if your phones are members of the queue 24/7, it is possible that
some of them occasionally go unmanned. As Asterisk has no way of
knowing which phones are to be used and which are not, it will simply
try and ring them in sequence; if nobody answers, it will try a
different one. This raises the wait-time for the callers without giving
you any benefit. You may also have callers struck for long periods on
queues where nobody answers, because there is nobody to answer but Asterisk
is not aware of this!
- As you have extensions and not people as end-points for your queue,
it is very hard to tell who did what, whose performance was good and
who answered the phone versus those who did a poor job. They all
end up in the same statistics. By having people log on, it is easy
to distinguish who did what. It is also easy to tell who is available
at a given moment, even remotely.
- As a result of both bullets above, agents know they are reponsible
for what they do and know their behavior is monitored; so they have
all the right incentives to do their best.
- Agents that do not logon at every shift do not appear reliably on the
RealTime monitoring in QM - see below.
If you still do not want to use agent logons, QueueMetrics will nevertheless
monitor reliably your traffic; the Agents page and statitics that depend on agent
sessions will be blank or may yeld meaningless results.
See also:
Permalink - Table of contents
What is the time period considered for real-time?
When QueueMetrics has to compute the Real-Time report, it tries to build the current
situation based on what happened recently - normally since the last midnight. This
usually works fine in the common case where all agents stop working at night and start working
by logging on in the morning. On the other side, this produces incorrect results
if your call-center works over the 24 hours, because at midnight by default all agents
appear to be logged off.
This choice was made in order to minimize database searching for QueueMetrics, and it
works just fine in the majority of call centers. There are a few cases where this choice
may have to be changed:
- If your call center stops daily, but not at midnight, you should tell QM the time
when you expect all agents to be logged off. If e.g. at 4 AM you are sure all agents
are logged off, you should set:
realtime.startHour=4
- If your call-center never stops, but agents work in shift of 6 hours, you should use a
"sliding window" instead; this determines the maximum lookback based on a number of hours
before now (make it 1.5x to 2x the length of the shift).
realtime.startHour=s8
Of course, the larger the sliding window, the more data QM has to evaluate every time it
produces a realtime report, so it will use more RAM and CPU.
- If your agents are always logged on, you should ignore the statuses as reported by QM,
as QM has no way to reliably know if they are available or not. QM will generally log
them on as they take calls within the given time window. See below
for a detailed explanation of why it is not a good idea to have permanent agents.
See also:
Permalink - Table of contents
Why aren't all reports showing up in my copy of QM?
If you updtate to a new version of QueueMetrics that includes new reports, or have new reports
custom-developed for you and update your system, you will notice that they will
NOT appear after upgrading QM with the old database. This is because the definitions for your
existing reports do not include the new blocks that were just created.
In order to add the new blocks, do the following:
- With an admin user, select Edit QueueMetrics settings -> Edit reports
- Click on a report, e.g. "All Reports"
- Choose a screen to ad dyour new report to
- When the list of times for the screen is visible, click on "Create new"
On the "add record page" enter:
- A title and (optionally) a subtitle for the new report
- From "Data Blocks", select the new report block - you should have been given a short code
like e.g. UN18 so it is easy to select in from the drop-down box
- Decide whether the new report should be visible in the "All reports" page
After saving, if you try running the report and select the chosen page, the new block will appear.
Permalink - Table of contents
Detecting realtime timing issues
If you run MySQL storage, it is easy to check whether the time zone on
the Asterisk server is correct:
- Go to Home -> Edit QueueMetrics settings -> Mysql storage information
- Look at the partition that contains your Asterisk data
- Look at the "To" and "Last heartbeat" values; write them down somewhere
- Send a call to the any queue on the system and look at your watch
- Go again to Home -> Edit QueueMetrics settings -> Mysql
storage information so that the page is reloaded
- You should see that the "To" and "last heartbeat" values have changed and
show the time the call was placed, answered or closed (whetever happened last)
- If the values have not changed, this means your qloaderd is not running.
Try and restart it
- If the values are off from what you looked up on your watch, this means
that Asterisk is using a wrong time or - worse - a wrong time zone.
See also:
Permalink - Table of contents
Error: Out of memory error - Tuning Java Memory
This error can manifest itself in a multitude of ways, the most common being an error stating:
Servlet.service() for servlet LowayTransactionController threw exception java.lang.OutOfMemoryError
The problem with Java memory is that it is fixed, i.e. Java will not automatically use free memory unless
explicityly told to do so. The default maximum memory size for most JVMs is 64 megabytes maxiumum, and it
is not much if multiple users are running multi-megabyte analyses in QueueMetrics.
To tell Tomcat to use more memory than the standard pool, you have to set an environment variable
before starting it up:
JAVA_OPTS="-Xms256M -Xmx512M"
export JAVA_OPTS
This tells Java to start by using 256 megabytes and expand the memory pool as needed up to 512 megabytes.
Please note that Java will not return memory back to the system memory pool, so the only way to reclaim memory is by
restarting Tomcat (you could restart it nightly with a script). You should also set this in the
/etc/init.d/queuemetrics startup file, so that it's set system-wide when QueueMetrics starts.
A real-life example for a larger call-center using Sun JDK 1.6 may be the following set:
JAVA_OPTS="-server -Xms3072M -Xmx3072M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+CMSIncrementalPacing"
export JAVA_OPTS
In any case, if you experience this problem, you should be reading the "Tuning QueueMetrics memory settings" section of QueueMetrics
Advanced Configuration manual, that details
how to tune and - most important - monitor a running JVM instance.
See
http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html
for more information on Java memory setting and monitoring.
See also:
- If the error you get is actually "OutOfMemory: Unable to create new native thread", see this
FAQ entry.
- If the error you get is actually "java.lang.OutOfMemoryError: PermGen space", then you have to set the maximum PermGen size
as detailed in the Advanced Configuration manual.
Permalink - Table of contents
Why do I get wrong agent names displayed?
In order for QM to work correctly, you should not have an agent name associated
with an agent at the Asterisk level; in any case, that name should not contain
spaces.
If in Asterisk you have a configuration like:
myvoip*CLI> agent show
123 (John Doe) available at '1234@from-internal' (musiconhold is 'default')
You should remove the agent name from agents.conf or from the realtime table
where it is defined; you should make sure that the logging happens as
Agent/123 for calls; the in QM you can configure a mnemonic name
for the agent so that it apperas in the reports.
Permalink - Table of contents
Using UTF-8 encoding
QueueMetrics is a fully internationalized application: that is, it handles all
user transaction with UTF-8 encodig, and therefore can display and accept any
character for any language.
Unfortunately, MySQL does not natively use UTF-8 encoding for its tables and
will try to use the "current encoding" whenever possible. So you may notice
that if you e.g. enter an agent's name using not-Latin characters, when you
read it back from disk it appears all garbled or a series of ??? signs.
To make QM fully able to process UTF-8 strings, you should follow the steps
detailed here:
1. Run the following commands on all tables of the database but the queue_log table:
ALTER TABLE `agaw_alarms` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `agaw_dati` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `agaw_logs` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `agaw_runs` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `agenti_noti` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `arch_classes` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `arch_syslog` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `arch_users` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `broadcast_msg` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `call_status` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `code_possibili` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `dbversion` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `locations` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `oq_calls` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `oq_notes` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `oq_queues` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `pause_codes` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `qa_data` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `qa_forms` CONVERT TO CHARACTER SET utf8;
ALTER TABLE `qa_forms_items` CONVERT TO CHARACTER SET utf8;
If your system has other tables, please do the conversion on ALL tables.
2. Open the QueueMetrics
web.xml and modify the connection string adding, before
the
</param-value> tag, the string:
&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
After this modification you should have something that looks like:
<param-value>jdbc:mysql://127.0.0.1/queuemetrics?zeroDateTimeBehavior=convertToNull
&jdbcCompliantTruncation=false&user=queuemetrics&password=javadude
&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8</param-value>
It must all be written on a single line.
3. Then download the latest MySQL java connector binary package you can find at the link:
http://dev.mysql.com/downloads/connector/j/5.1.html
Extract the
mysql-connector-java-5.1.7-bin.jar file and copy it on your
QueueMetrics box, placing in the folder
/usr/share/java.
Replace the symbolic link you can find in
/usr/local/queuemetrics/webapps/queuemetrics-1.x.x/WEB-INF/lib in order
to have it pointing to new connector.
4. Restart the QueueMetrics service issuing a
/etc/init.d/queuemetrics restart
This will enable UTF8 support.
Permalink - Table of contents
Updating QueueMetrics and keeping the key and configuration
When updating QueueMetrics, whether you do that manually or using yum, you need
to copy
web.xml and
configuration.properties from the old
installetion to the new one.
This is easy to do, as distinct QM applications are stored as:
/usr/local/queuemetrics/webapps/queuemetrics-1.5.0/
/usr/local/queuemetrics/webapps/queuemetrics-1.5.1/
/usr/local/queuemetrics/webapps/queuemetrics-1.5.3/
So they are never deleted.
Before the upgrade, make a backup of the QM database; it may be updated by the
QM updater on the first run, so it is better to have a copy - just in case.
After the upgrade, have a look at the WEB-INF/README/Updating.txt file - it
shows the new parameters and the new security keys that you m,ay have to enable
on an existing install in order to unlock the new functionalities.
See also:
Permalink - Table of contents
Mixed-up pages after an upgrade
After an upgrade, you notice that pages are "mixed up" - that is, not all pages
show the new version on their title bar. This may lead to many different errors
and malfunctions.
This may be caused by two things:
- You have the page in the clients cache. Clean up the browser cache and
retry.
- The Tomcat system caches are not updated. Do this to clean them up:
/etc/init.d/queuemetrics stop
rm -rf /usr/local/queuemetrics/tomcat/work/Catalina/*
/etc/init.d/queuemetrics start
This should fix all issues.
Permalink - Table of contents
Updating the Java SDK
If you want to update the Java SDK you use to run QueueMetrics, it is very easy
to do it.
Download and install a new version of Java SDK (from SUN, it's better - do not
use GCJ).
You can install it anywhere on your system - like imagine you install it as
/opt/java/jdk1.6.0b7.
As QueueMetrics accesses its own Java SDK under a symbolic link placed at
/usr/local/queuemetrics/java, it is trivial to change that to use a
different SDK.
cd /usr/local/queuemetrics
rm -f java
ln -s /opt/java/jdk1.6.0b7 java
then restart QueueMetrics.
To check that the new Java is working, go to the License page and check the Java
version that it is using.
Permalink - Table of contents
Removing Tomcat logging
QueueMetrics keeps a detailed log of all transactions performed, in order to
be able to find which transactions are slow and for forensic analysis (you
can never know...). They may end up taking substantial disk space.
First, you may want to rotate Tomcat logs using a logrotate job like the following one:
/usr/local/queuemetrics/tomcat/logs/*.* {
missingok
rotate 5
daily
compress
create 0640 root root
postrotate
/etc/init.d/queuemetrics restart > /dev/null 2> /dev/null
endscript
}
If you want to turn off logging entirely, edit the server.xml file and remove sections:
<Logger className="org.apache.catalina.logger.FileLogger"
prefix="catalina_log." suffix=".txt"
timestamp="true"/>
and:
<Logger className="org.apache.catalina.logger.FileLogger"
directory="logs" prefix="localhost_log." suffix=".txt"
timestamp="true"/>
Then edit catalina.sh and remove all logging to
"$CATALINA_BASE"/logs/catalina.out 2>&1
by entering:
/dev/null 2>&1
For more information on Tomcat logging, see
http://wiki.apache.org/tomcat/FAQ/Logging
Thanks to PSN for input!
Permalink - Table of contents
Repairing a MySQL database
It sometimes happens that if your database server crashes, you may find that:
- QM is not working because it cannot access the database
- Qloaderd is not working because it cannot write to the queue_log table
- You get weird errors when updating from an older version of QM
This sometimes happens even on systems that seemed to work fine for a long time.
In order to fix these issues, you should:
- stop MySQL - THIS IS EXTREMELY IMPORTANT
/etc/init.d/mysqld stop
- check tables using myisamchk (use the same case as written here):
myisamchk -c /var/lib/mysql/queuemetrics/*.MYI
- if any error is shown, repair tables:
myisamchk -r /var/lib/mysql/queuemetrics/*.MYI
- after that, restart Mysql:
/etc/init.d/mysqld start
Permalink - Table of contents
AMI connection not working in Asterisk 1.6
In order to perform a set of actions in Asterisk (eg. getting Live statistics,
starting channel monitoring, logging agents on and off, setting call statuses)
QueueMetrics needs to connect to Asterisk over the AMI interface.
In Asterisk 1.6 (AMI 1.1), in order to set up its calls, you have to make sure
that the account that QM uses has ORIGINATE privileges as well as WRITE.
Permalink - Table of contents
Figures do not match when running hourly versus daily reports
Imagine you run a report for Aug 25th, queue A, between 7 and 8 - it says there
are 150 answered calls.
You run it again, between 7 and 13 and look at the hourly statistics - now it
says there are 154 answered calls between 7 and 8.
What happened? that's simple - between 7 and 8, some calls were queued but not
yet answered - so you are going to find them, but on the "Lost" page and with
status "Ongoing".
You run the report again between 7 and 9, and now you see that the call was
answered - because it was answered after 8 am.
If you run a report between 7 and 8, QM only sees data that cam between 7 and 8
- not what happened before of afterwards. It's like being at 8am and asking for
future data. If you want to see what happened when you have a full day of data,
run a report for a full day and look at the hourly breakdowns.
Permalink - Table of contents
Help! The Real-time page is showing no data!
If the Real-time page will show no data at all - no agents logged on, no calls
being processe, you should check the following items:
- Make sure that reports are showing data
If they show no data, see this FAQ entry.
- The time on the Asterisk server is far off from the time on the QM server
In order for the real-time page to work correctly, the clocks on the Asterisk
server, the one on the QM server and the one on the MySQL server must be aligned
with a sub-second difference. If this is not so, QM has no way of knowing
which calls are in transit and which are terminated.
In order to check this, there is a label on the Licence page that will
show if there are differences between QM and its MySQL server. To assess
timing differences from the Asterisk box, try and process a call and then run
a report where that call appears and check if the time is correct.
Luckily, it is trivial
to keep the clocks aligned - see this FAQ entry.
See also:
Permalink - Table of contents
How do I modify or turn off the sounds on the Real-time page?
The default Real-time page that ships with QueueMetrics will play sounds
when yellow or red alarms are triggered. The sounds played, or whether to play
any, are controlled by a couple of system properties in the
configuration.properties file:
sound.yellowAlarm=http://myserver/audioYellow.wav
sound.redAlarm=http://myserver/audioRed.wav
If you want to turn them off completely, just set them to blank.
Of course, alarm thresholds are user configurable from the Queue editor page.
Permalink - Table of contents
Why do I see duplicate calls in the reports with a Caller-ID set to '*'?
If you see all (or many) calls in the
Processed Calls or the
Lost
Calls reports as being present twice with the
same start hour, the first time having a correct Caller-ID and the second time
displaying '*' in the Caller-ID field, this means that you have duplicate data
in your database.
This is usually caused by having mutiple instances of the
qloaderd running
at the same time - maybe you run them manually, or one instance was not stopped
correctly during a restart. Stop them all manually and restart just one.
In order to "clean up" the database, use the
queuePartialUpdater tool that
ships with the
qloaderd - it will basically unload a queue_log file and
will reload it.
Permalink - Table of contents
Exception: java.nio.BufferOverflowException - Encoding problems when reading files
If QueueMetrics crashes with an exception like:
[ERR] -- Inner Exception --
Exception: java.nio.BufferOverflowException
Stack trace:
java.nio.BufferOverflowException
at java.nio.charset.CoderResult.throwException(CoderResult.java:259)
at java.lang.StringCoding$CharsetSE.encode(StringCoding.java:344)
at java.lang.StringCoding.encode(StringCoding.java:378)
at java.lang.String.getBytes(String.java:812)
at java.io.UnixFileSystem.getBooleanAttributes0(Native Method)
at java.io.UnixFileSystem.getBooleanAttributes(UnixFileSystem.java:228)
this means that it is trying to read a file using the current Locale that is
set for your server but this is not correct for QueueMetrics. You can check
what is the encoding of the file names in your local server
by typing "locale".
You can anyway force it to UTF-8 by changing
JAVA_OPTS in the file
/etc/init.d/queuemetrics:
JAVA_OPTS="-Xms512M -Xmx512M -Dfile.encoding=UTF-8"
Or, if it still does not work:
JAVA_OPTS="-Xms512M -Xmx512M -Dfile.encoding=ISO-8859-1"
Make sure that you kill the current Java process and restart it before logging
on again in QM.
This error might also be triggered when reading a directory that has too many
files, e.g. the place where you store audio recordings. You can override this
behaviour by using the LocalFilesByDay storage model - it will also be way faster when retrieving recordings.
See e.g.:
http://astrecipes.net/index.php?n=387
and
http://astrecipes.net/index.php?n=388
Permalink - Table of contents
Help! QueueMetrics reports shows no data at all!
If you have activity in Asterisk but your QueueMetrics reports show no data
at all - no calls processed, no agent sessions, you should check the
following possible causes:
- The qloaderd is not working
If you have set up QueueMetrics to use the SQL storage model, you need
to make sure that the loader process on the Asterisk box is actually sending
data to the QueueMetrics database. This can be easily checked by looking
at the Licence page (where the storage model will be displayed) and if
it is correct, by clicking on the Mysql storage information where
you will see a growing number of lines in the selected partition if there
is Asterisk activity and the loader is actually working.
- You are reporting from the wrong partition
Check on the licence page for the storage model and the partition being
currently in use. If the partition code is different, no data will be found.
- You are asking for the wrong queue
The queue identifier that appears in QueueMetrics must match exactly,
letter by letter, the one that appears as the queue name in Asterisk. If
this is not so, the queue will not be displayed.
Permalink - Table of contents
How do I secure access from a given subnet only?
Very often, you will want to make sure that the QueueMetrics application is accessible only
from a given subnet. Even if QueueMetrics has its own security mechanism built-in, denying
access to all clients that have no right to access QM will surely improve security.
In order to do so, you just edit the file:
/usr/local/queuemetrics/tomcat/conf/Catalina/localhost/queuemetrics.xml
so that it looks like the following one.
<Context docBase="/usr/local/queuemetrics/webapps/queuemetrics-1.5.1"
path="/queuemetrics">
<Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127.0.0.1"/>
</Context>
You could use the following format for the address instead of 127.0.0.1:
- allow="1.2.3.4, 1.2.3.5, 1.2.3.7" to specify multiple IP addresses, or
- allow="128.117.140.*" to specify a full class.
If all goes well, when you restart QueueMetrics and try to access it from a forbidden IP address,
you get the message "Access to the specified resource has been forbidden."
Please note that the
queuemetrics.xml file is rebuilt upon automatic update, so you will have to
edit it after running "yum update".
Permalink - Table of contents
How to upload an older queue_log file
Imagine you have a queue_log file that uploads to partition P003, and is
missing from timestamp 100 to 150; and imagine that old data is
available in a file called
queue_log.old
- Make sure there is no data in the table for partition P003 between
timestamps 100 and 150.
e.g SELECT * FROM queue_log WHERE partition='P003' AND time_id BETWEEN 100 and 150
- Stop importing on partition P003
- Move queue_log data newer than timestamp 150 to a new partition (eg P003B)
e.g. UPDATE queue_log SET partition = 'P003B' WHERE partition='P003' AND time_id > 150
- Run the qloaderd on your queue_log.old file, so that it will load all data.
You will have to watch its log file to se when it ends adding lines.
- Check that all data has been loaded
e.g. SELECT count(*) FROM queue_log WHERE partition='P003' AND time_id BETWEEN 100 and 150
- Stop the qloader process
- Move back newer data from P003B to P003
e.g UPDATE queue_log SET partition='P003' WHERE partition='P003B'
- Point qloaderd to your normal queue_log file, and restart normal importing
After you are done, try running a report to see if old data is actually seen by QueueMetrics.
Permalink - Table of contents
Tracking timing and time-zone problems in QueueMetrics
It sometimes happens that a new QueueMetrics install has time-zone problems on a specified box.
Generally speaking, the local time for the QueueMetrics instance should be the same as your own
local time, and so should be for the MySQL server and the Asterisk server it relies on.
Small timing discrepancies can cause
many problems, like calls not shown, wrong call duration and wait times on the realtime page, or
even calls not showing at all on the realtime page.
Generally speaking, the first thing you should do if you suspect a timing problem is run a command
that will sync the system clock with an high-precision atomic clock on all involved machines, for example:
ntpdate ntp.ien.it
As harware clocks tend to "drift" in the long period, it is a good idea to add this command to a
nightly cron job that will keep the clocks of all involved systems below a one-second difference.
If you want to see the current clock and time zone for the QueueMetrics server and its MySQL instance,
just click on the
Licence page and those values will be shown. It's important that there is no difference between those values.
If one of the clocks is very different from the current time, it is usually a time zone problem on your box.
This can usually be solved/detected running the following commands:
[root@asterisk1 ~]# hwclock --show
[root@asterisk1 ~]# date -R
[root@asterisk1 ~]# date
[root@asterisk1 ~]# more /etc/sysconfig/clock
If everything seems correct and still the QueueMetrics server will insist on using the wrong time zone,
you should try the following options:
- Set the TZ environment variable, like export TZ="US/Eastern" in the startup script you
use for the QueueMetrics server
- Add the following option to the JAVA_OPTS environment variable: -Duser.timezone=US/Eastern
in the startup script you use for the QueueMetrics server.
For example, if you live in a place that is
GMT+5, you could change the /etc/init.d/queuemetrics init script so that it has an options line like:
export JAVA_OPTS="-Xms128M -Xmx128M -server -Duser.timezone=GMT+05:00"
After saving and restarting QM, if you go to the Realtime page, you should see that the time
is now correct.
See also:
http://minaret.biz/tips/timezone.html.
Permalink - Table of contents
Transfers from the queue are not reported in QM
If your agents on a queue use to transfer calls out to other callers or to
other queues, you may notice that this is not reported correctly by QueueMetrics.
You may also notice that if you use agent channels, an agent stays idle after the
transfer until the transferred call is over.
Unfortunately this is "by design"; this is because when you use
the Attended transfer button on the agent's phone, the main PBX is not notified that
the call is "handed-over", so it still thinks it's connected to the original agent.
The official documentation says that
"transfers performed by SIP UA's by way
of a reinvite may not always be caught by Asterisk [...] The only way to be 100% sure that you will get this event when
a transfer is performed by a queue member is to use the built-in transfer
functionality of Asterisk".
So the only way there is to handle this case is then to use so-called "Unattended transfer", that
is, setting the
t option in the queue and then having your agent press
# to
start a transfer to a different extension. Unfortunately, this does not give you Attended transfer, that is,
speaking to the receiver before handing over the call.
Our real-life workaround is to use the "#" unattended transfers of Asterisk to transfer calls only
after having opened up a parallel conversation to
negotiate with the receiver. We know it's sub-optimal, but this has been shown to work.
Permalink - Table of contents
Using multi-stint mode in reports
When QueueMetrics run an activity report, its basic "unit of measurement" is the queue;
that is the activity that your call made on a specific queue. This may lead to
a situation that is harder to understand if you have spill-over queues in place,
that is, if a call is not handled in one queue it is moved to a different one.
In order to address this problem, queueMetrics implements a
multi-stint analysis
mode, where mutiple passages on different queues are "joined together",
like in the following example. Imagine this call:
h 10.00.00 enters queue 1
h 10.00.59 exits queue 1
h 10.01.00 enters queue 2
h 10.01.59 exits queue 2
h 10.02.00 enters queue 3
h 10.02.30 answered on queue 3
h 10.03.00 caller hangs up
With single stint mode you would see:
h 10.00.00 lost call on "queue 1", waited for 59 seconds
h 10.01.00 lost call on "queue 2", waited for 59 seconds
h 10.02.00 answered call on "queue 3", waited for 30 seconds, duration 30 seconds
With multi-stint mode you would see:
h 10.00.00 call enters on queue 3, waits for 2:30, duration 30 seconds
and by clicking on the call detail, you get the whole history.
In order to have multi-stint work correctly, you should include ALL the queues
that the call was handled upon in the same report - otherwise it will not find
out where the call passed.
Of course, in real-life you can run both multi-stint and single-stint analyses
when querying the performance of your call-center; you use multi-stint to see the
performance from the point of view of the caller, and single-stint to see
what happended from the point of view of the providers, e.g. service groups.
Permalink - Table of contents
XML-RPC not working: Could not instantiate XMLReader parser
If the XML-RPC interface of QueueMetrics is not working, i.e you get no
meaningful response, you have to look up on the
catalina.out file in
order to detect possible problems.
Xerces not installed
With Java 1.5 and Tomcat 5.5, you may encounter the problem as an error string
stating
redstone.xmlrpc.XmlRpcException: Could not instantiate XMLReader
parser. This means the Xerces XML parser cannot be found.
If this happens, download Xerces from
http://xerces.apache.org/xerces-j/ and put the file called
xercesImpl.jar in your
queuemetrics/WEB-INF/lib.
This should solve your problems.
Permalink - Table of contents
How to let Agents access the Realtime page
It is possible to let your QueueMetrics agents access the full RealTime page
and not just the Agent's page:
- Create a new class for agents. You may call it RTAGENTS (Realtime Agents)
- Give your agents the following keys: USER AGENT CHPASSWD REALTIME. For the
exact meaning of each key, see Appendix II of the User Manual.
- Create (or select) some agents and assign them to class RTAGENTS.
Those users will be able to login, access the realtime page, access the agent's
page and change password.
If you want your agents to be able to see only a subset of all possible queues
through the Realtime page, you should see also:
How do I make some queues visible by some
users only?.
Please consider that running the realtime page instead of the Agent's page is
extremely expensive, computationally speaking, so run a few test before deploying
this in a 1000-agent setting.
Permalink - Table of contents
Missing records on KeyPress
Sometimes calls in Qm seem to go on forever... even if they have been terminated.
This is often the case when your users exit the key by pressing a numeric key;
some versions of Asterisk don't log this event correctly, so the call appears
to be going on and on.
In order to check if this is the case, you should monitor your
queue_log
file when you exit a call by pressing a key; you should expect a line that looks like:
1106553723|1106553678.2598|queue-f|NONE|EXITWITHKEY|3|1
If such a line is not present, you may detect the event via the ${QUEUESTATUS}
variable when the queue() app terminates, and produce a record like the following
one:
exten => s,1,System( echo
"${EPOCH}|${UNIQUEID}|myqueue|NONE|EXITWITHKEY|key|1|" >>
/var/log/asterisk/queue_log )
Where "myqueue" is the queue name and "key" is the key pressed (if you need to
track it, otherwise set it to 1).
See also
Handling ghost calls.
Permalink - Table of contents
Handling 'Ghost Calls'
Sometimes calls in Qm seem to go on forever... even if they have been terminated.
This may be caused by two reasons:
- In some versions of Asterisk, some ways of exiting a queue trace no log
Mostly on older (1.0 and 1.2) versions of Asterisk, sometimes you discover that
exiting a queue in a certain manner (eg a timeout, a transfer) consistently
provides no end-of-call log. This makes it impossible for QM to know that the
call is over.
- Asterisk sometimes randomly "forgets" to trace some end of call.
This is a problem that happens on most large systems. If this is below 1% of
all calls, it should be considered normal. Some installations are almost
completely unaffected while others are heavily affected.
While case #1 can be fixed adding some dialplan logic to test the exit status
and output a call closure log, case #2 still lingers.
QM handles this problem in two ways:
- The realtime page can be instructed about "anomalous" calls that will not
be displayed if the wait or talk times are too long. This is what
default.maxOngoingWaitTime and default.maxOngoingTalkTime are for (as the
definition of "too long" varies from call center to call center).
- Since QM 1.4.5 and when running with a MySQL database, it is possible for
certain administrative users to "close" ongoing ghost calls by finding them on the real-time
or the historical call list (requires security key CLOSECALLS)
See also
Missing records on KeyPress.
Permalink - Table of contents
How do I run QueueMetrics with Java Security?
Java Security is a way to fine-tune the grants that a web-application has. This can be
quite complex if you do not exactly know what a webapp is doing internally. You can set this
by updating a policy file and running Tomcat in secure mode.
To make sure you are running under Java Security, you can check the value of the property
java.security.policy under the Licence page - if it is set to something like
=/usr/local/queuemetrics/tomcat/conf/catalina.policy, then security is enabled.
The following permissions apply to QM 1.4.5 - just add them to your
catalina.policy file:
grant codeBase "file:/usr/local/queuemetrics/tomcat/webapps/queuemetrics/-" {
permission java.net.SocketPermission "localhost:3306", "connect,resolve";
permission java.io.FilePermission "/var/log/asterisk/queue_log", "read";
permission java.util.PropertyPermission "*", "read,write";
permission java.lang.RuntimePermission "createClassLoader";
permission java.io.FilePermission "${java.io.tmpdir}/-", "read,write,delete";
// if you use LIVE connection to Asterisk instances:
permission java.net.SocketPermission "127.0.0.1:5038", "connect,resolve";
};
Of course you have edit them to:
- set the correct path for your QM webapp in the grant codeBase line
- set the correct path to your database
- set the cortrect path to the manager port of your Asterisk server
- if you use external XML-RPC services, you should add "connect, resolve" grants for those as well.
Permalink - Table of contents
Configuring ViciDial for QueueMetrics
ViciDial, a widely-used outbound dialer and campaign manager, can be configured to write its call activity logs
directly to the QueueMetrics call database.
In ViciDial, this can be enabled as follows (Go to "System Settings"):
- Enable QueueMetrics logging: 1
- QueueMetrics server IP / DB name / DB login / DB password: These values are for the MySQL server that holds the QM database
- QueueMetrics URL: enter a fully qualified URL of your QM system, e.g. http://qmserver:8080/queuemetrics
- QueueMetrics LogID: this is the name of the QM partition ViciDial will write to. E.g. P001, or VIC.
- QueueMetrics EnterQueue Prepend: you can use this switch to prepend the campaign-id to
the caller-id so you can run a breakndown using QM's are analysis. In most cases just leave that to NONE.
This should be it. Now create the campaigns in QM and make sure you're using the chosen LogID as the partition (e.g. if your log-id is VIC, you should enter sql:VIC as the file name).
Permalink - Table of contents
Backing-up a QueueMetrics system
To make a backup of a working QueueMetrics system, you should backup the following items:
- The QM database
- The web.xml and configuration.properties files being used
(You can find them under the QM webapp under WEB-INF; if
you run a recent version of QM, just look for the System path
entry on the Licence page)
- The queue_log data used for input (it is advisable to this in any case,
even if you use MySQL storage, just to be on the safe side).
Nothing else is needed.
See also:
Permalink - Table of contents
How is the field "N.Agents" computed?
The first cell of the top realtime panel ("N Agents") is computed as follows:
- for each queue, QM looks for all agents that are KNOWN MEMBERS of that queue
(that is, they have an association through QM's editor) plus all agents that
are logged on dynamically to that queue
- for the grand total (first line) QM looks for all agents that appear in the
report - they should match the number of lines of the lowest table
Therefore it is very well possible that the first number does not match the
following ones, because on one side an agent can be a known member of more than
one queue, and on the other side an agent may not be a known member on any
queue (in this case, it will be counted on the grand total but not on a
queue-per-queue basis).
Permalink - Table of contents
How do I make some queues visible by some users only?
In order to make sure that some users (e.g. supervisors) can only see their queues, you
should use QM's security model. When you protect something with a key, this
means that you protect it (physically speaking) with a lock that opens if the
user holds that key in his keyring. You know that eash user has a keyring, that
is the sum of the keys that belong to his current class plus the keys that he
individually has.
So, if you have a number of supervisors and a number of queues, you could
protect each queue individually with a different key, and then give each
supervisor individually the required key.
For example, you can do this:
- queueA -> key KA
- queueB -> key KB
- queueC -> no key
- queueD -> key KD
- queueE -> key KE
- supervisor Alice -> keys KA and KD
- supervisor Bob -> keys KB and KE
When they log on, Alice sees queue A, queue C and queue D. Bob instead will see
queue B, queue C and queue E.
Please note that if you have an aggregate queue, only the key protecting the
aggregate queue will be ckecked, i.e. the checks on the members will NOT be
performed (so you can have an aggregate queue that behaves differently in security terms from
the set of its members, if you need it).
Permalink - Table of contents
Error: "You do not have the rights to perform the requested action."
While working on the "Agent's page" and trying to log-on, log-off or pause an agent,
the following error is displayed in the pop-up window after entering the Agent's code
and Extension: "You do not have the rights to perform the requested action."
This means that QM is trying to connect to Asterisk to run that action, but
Asterisk refuses the connection. In order to make it work, the following steps
should be hand-checked:
- Are the connect credentials correct?
The credentials supplied in the configuration.properties file should look like:
callfile.dir=tcp:dial:bingo@1.2.3.4
Check that they match the ones in Asterisk's own /etc/asterisk/manager.conf
- Is the dialplan context [queuemetrics] included?
You can check that by typing the following command in Asterisk:
asterisk*CLI> show dialplan queuemetrics
[ Context 'queuemetrics' created by 'pbx_config' ]
'10' => 1. Answer() [pbx_config]
2. Wait(10) [pbx_config]
..and a lot more stuff here....
If it's not included, you can find the example file extensions_queuemetrics.conf
under QueueMetrics' own README directory - just copy that to /etc/asterisk and
#include it in the main dialplan (note: you should review that file before inclusion
as it should be customized to fit your environment).
- Are you seeing connection attempts?
If you open the Asterisk CLI, you should see a message when QM connects and
disconnects. If you see nothing, there is some setup error (e.g. a firewall)
that prevents QM to connect to Asterisk.
Permalink - Table of contents
Using a different Asterisk manager port
It is possible to switch the port QueueMetrics uses to connect to the
Asterisk manager interface fom the default port 5038 to any other port -
use something like:
callfile.dir=tcp:dial:bingo@10.10.3.27:1234
This will set the Manager to port 1234 on server 10.10.3.27.
Permalink - Table of contents
Using fully dynamic members with QM 1.4 and Asterisk 1.2
If you run QueueMetrics 1.4.1 or newer, you can fully use the new ADDMEMBER / REMOVEMEMBER to
track agents logging on on a queue-by-queue basis. Unfortunately, Asterisk 1.2 does not automatically log them,
so we must resort to something like the following example.
In this example, we assume that:
- All agents are entered as Local/NUM@agents - feel free to use Local/XX@from-internal or whatever matches your system configuration
- The example queue you join here is called my-queue
- You will call the following pieces of dialplan:
- 422XX to log on Agent/XX to the queue my-queue
- 423XX to log off Agent/XX from the queue my-queue
- 416XX to pause Agent/XX (on all queues she's working on)
- 417XX to unpause Agent/XX
This is the relevant piece of dial plan:
; addqueuemember - 422
exten => _422XX,1,Answer
exten => _422XX,2,AddQueueMember(my-queue,Local/${EXTEN:3}@agents)
exten => _422XX,3,System( echo "${EPOCH}|${UNIQUEID}|my-queue|Agent/${EXTEN:3}|ADDMEMBER|-" >> /var/log/asterisk/queue_log )
exten => _422XX,4,DBput(dynlogin/log_Agent-${EXTEN:3}=${EPOCH})
exten => _422XX,5,Hangup
; removequeuemember - 423
exten => _423XX,1,Answer
exten => _423XX,2,RemoveQueueMember(my-queue,Local/${EXTEN:3}@agents)
exten => _423XX,3,DBget(ORGEPOCH=dynlogin/log_Agent-${EXTEN:3})
exten => _423XX,4,Set(RV=$[${EPOCH} - ${ORGEPOCH}])
exten => _423XX,5,GotoIf($["${RV}" = "0"]?8:6)
exten => _423XX,6,System( echo "${EPOCH}|${UNIQUEID}|my-queue|Agent/${EXTEN:3}|REMOVEMEMBER|-|${RV}" >> /var/log/asterisk/queue_log )
exten => _423XX,7,DBdel(dynlogin/log_Agent-${EXTEN:3})
exten => _423XX,8,Hangup
; agent pause
exten => _416XX,1,PauseQueueMember(|Agent/${EXTEN:3})
exten => _416XX,n,Hangup()
; agent unpause
exten => _417XX,1,UnpauseQueueMember(|Agent/${EXTEN:3})
exten => _417XX,n,Hangup()
Do not forget to also change the value:
default.rewriteLocalChannels=false
in QueueMetrics'
WEB-INF/configuration.properties file.
Permalink - Table of contents
Tracking agent extensions for outbound dialing
When you do outbound calling, it's easy to track the extension that is doing
outbound calling. It would be nice to match the agent that is logged on to that
extension.
To do this, we must store the current agent's estension in a global variable:
exten => 2000,1,Answer
exten => 2000,2,NoOp( "QM: Logging on Agent/${AGENTCODE} to extension ${AGENT_EXT}@from-internal" )
exten => 2000,3,AgentCallBackLogin(${AGENTCODE}||${AGENT_EXT}@from-internal)
exten => 2000,4,Set(AGENTE_${AGENT_EXT}=${AGENTCODE}|g)
exten => 2000,5,Hangup
When you need to dial out you do:
[queuedial]
exten => _7.,1,Set(MY_QUE=300)
exten => _7.,n,Set(MY_NUM=${EXTEN:1})
exten => _7.,n,Set(MY_AGENT=${AGENTE_${CALLERID(num)}})
exten => _7.,n,NoOp,Ag: ${MY_AGENT} N: ${MY_NUM} Q: ${MY_QUE}
......
This way it works easily.
Permalink - Table of contents
Using fully dynamic members with QM 1.4 and Asterisk 1.4
If you run QueueMetrics 1.4.1 or newer, you can fully use the new ADDMEMBER / REMOVEMEMBER to
track agents logging on on a queue-by-queue basis. If you run Asterisk 1.4, most of the logging
is already done correctly by Asterisk itself.
In this example, we assume that:
- All agents are entered as Local/NUM@agents - feel free to use Local/XX@from-internal or whatever matches your system configuration
- The example queue you join here is called my-queue
- You will call the following pieces of dialplan:
- 422XX to log on Agent/XX to the queue my-queue
- 423XX to log off Agent/XX from the queue my-queue
- 416XX to pause Agent/XX (on all queues she's working on)
- 417XX to unpause Agent/XX
This is the relevant piece of dial plan:
; addqueuemember - 422
exten => _422XX,1,Answer
exten => _422XX,2,AddQueueMember(my-queue,Local/${EXTEN:3}@agents)
exten => _422XX,3,Hangup
; removequeuemember - 423
exten => _423XX,1,Answer
exten => _423XX,2,RemoveQueueMember(my-queue,Local/${EXTEN:3}@agents)
exten => _423XX,3,Hangup
; agent pause
exten => _416XX,1,PauseQueueMember(|Agent/${EXTEN:3})
exten => _416XX,n,Hangup()
; agent unpause
exten => _417XX,1,UnpauseQueueMember(|Agent/${EXTEN:3})
exten => _417XX,n,Hangup()
Do not forget to also change the value:
default.rewriteLocalChannels=false
in QueueMetrics'
WEB-INF/configuration.properties file.
Permalink - Table of contents
How to write internationalized data to the database
If you use an internationalized version of QueueMetrics for a language based on a non-Latin
character set, you may find yourself unable to write strings in your own language (e.g. the name of
a queue) into QueueMetrics. This is usually not caused by QueueMetrics itself (that is completely
UTF-8 compliant) but by the underlying MySQL instance.
In order to make sure that your charset is accepted by your database:
- Make sure that MySQL is installed in/for your language.
- Run the following commands on all tables of the database but the queue_log table:
ALTER TABLE `call_status` CHARACTER SET utf8;
ALTER TABLE `pause_codes` CHARACTER SET utf8;
....
This tells the database engine to accept UTF-8 on all storage tables.
- Modify the connection string in web.xml so that it ends with:
....&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
This tells the MySQL connector to force UTF-8 encoding when talking to the datbase server.
In our experience this is usually all that is needed to run an Unicode datbase instance.
Permalink - Table of contents
How to use subqueues
If you work in an environment where a single queue is used to service a number of different
calling clients, it might be of interest to you to enable
subqueues; i.e. to have the queue name
rewritten appending a client code at the end, so that you can query them from QueueMetrics
as if each client was serviced by a dedicated queue.
You can also use this technique in order to have very few actual queues in your call center
but you still want to differentiate callers based on their incoming DID, or the group they belong to.
To set up this feature you should:
- Be running qloaderd and being successful in using the MySQL storage in QueueMetrics
- Create the new table qlog_opencalls as described in the qloaderd documentation
- Enable subqueues changing the qloader.pl file and setting:
my $use_subqueue = 1;
- when you call a queue, you pass the DID code in its URL parameter, e.g.
exten => s,8,Queue(queue-service|t|1234||180)
- When qloaderd picks up the call, it will import it as queuename.code; in the example
above, it would import the call as queue-service.1234.
Please note that you should mantain the qlog_opencalls table yourselves, deleting periodically
rows with a 'lastUpd' timestamp over one day old and optimizing it as needed.
Permalink - Table of contents
Error: OutOfMemory: Unable to create new native thread
After running QueueMetrics for a while, the JVM stops with the exception "OutOfMemoryError:
unable to create new native thread". This is usually caused by using the wrong JVM / Tomcat / Linux Kernel
set, and is usually solved by:
- Installing a newer (or older) JDK, or one that is designed right for your hardware
- Installing a newer (or older) Tomcat version
QM will run just fine with any JDK >= 1.4.2 and Tomcat >= 4.0, so there is usually no great benefit in
running the very latest version of them.
See also:
Java thread tuning.
Permalink - Table of contents
Metadata file does not match checksum in Yum
When trying to install or update via Yum, you get an error like:
Reading repository metadata in from local files
primary.xml.gz 100% |=========================| 3.7 kB 00:00
http://yum.loway.ch/RPMS/repodata/primary.xml.gz: [Errno -1] Metadata file does not match checksum
Trying other mirror.
Error: failure: repodata/primary.xml.gz from LowayResearch: [Errno 256] No more mirrors to try.
This might be caused by having corrupted metadata information, and it sometimes cannot be fixed even if you run
yum clean all. If this is your case, try the following:
yum clean all
cd /var/cache/yum/LowayResearch/
wget --cache=off http://yum.loway.ch/RPMS/repodata/filelists.xml.gz
wget --cache=off http://yum.loway.ch/RPMS/repodata/primary.xml.gz
wget --cache=off http://yum.loway.ch/RPMS/repodata/repomd.xml
And will then run the
yum update queuemetrics command.
Permalink - Table of contents
Some pages won't compile and show JasperException
It sometimes happens that some pages of QueueMetrics cannot be opened; they crash during the JSP
compilation stage with a "JasperException" showing that the page cannot be compiled.
This is often caused by having the wrong system-wide charset encoding, so that the source files
cannot be read correctly from the disk.
To check if this is your case, you should go to the Licence Page, click on the [...] link to see all
Java properties and check the value of
file.encoding that should be
ISO-8859-1.
If it's anything else,
it is a good idea to tell the Java subsystem to use this as a default encoding. To do this, you have to set an
environment variable before starting Tomcat:
JAVA_OPTS="-Dfile.encoding=ISO-8859-1 -Xms256M -Xmx512M"
export JAVA_OPTS
This tells Java to start by using ISO-8859-1 as the default file encoding and use a minimum of 256
megabytes and expand the memory pool as needed up to 512 megabytes. You should also set this in the
/etc/init.d/queuemetrics startup file, so that it's set system-wide when QueueMetrics starts.
See also
FAQ: Out of memory error for more information on Java setup variables.
Permalink - Table of contents
Tracking hourly call distribution for multiple incoming DIDs
If you have multiple incoming DIDs pointing to the same queue, and you would like to track
the hourly distribution of calls on each DID for planning, there is a simple thing you can do.
You create a "virtual queue" for each DID, then when a call comes in into that DID, and before
passing it to the actual queue that's servicing it, you write two log lines as if it was a lost call.
Then you can define each "virtual queue" in QueueMetrics and run reports on it like you currently do;
you will find all calls as "lost" but you do get call count, incoming caller id and hourly/daily/weekly
call distribution.
In practice what you do is modify the dialplan so that:
exten => s,n, .....
exten => s,n,Macro(qm-lostcall,did-11,${CALLERID(name)})
exten => s,n,Queue(service-q,,30)
exten => s,n, .....
[macro-qm-lostcall]
; ${ARG1} - the name for the fake queue
; ${ARG2} - the caller id to be logged
exten => s,1,System( echo "${EPOCH}|${UNIQUEID}.1|${ARG1}|NONE|ENTERQUEUE||${ARG2}" >> /var/log/asterisk/queue_log )
exten => s,2,System( echo "${EPOCH}|${UNIQUEID}.1|${ARG1}|NONE|ABANDON|0|0|0" >> /var/log/asterisk/queue_log )
Now if you want to know what happended through the usual statistics, you run a report for queue
service-q, while if you
want to know about the incoming DID #11 you run a report for
did-11.
See also
Tracking the incoming DID on a queue.
Permalink - Table of contents
Why do some calls disappear from the Realtime page?
You know that most call centers have a 80/20 rule (80% of the calls taken withing 20 seconds), so it is very
abnormal for them to have calls answered after tens of minutes. In order to avoid showing calls
that are actually logging anomalies, QueueMetrics considers calls that have been waiting too long
or have conversation times too long on the realtime page as errors and does not show them anymore.
The basic wait duration is 1000 seconds, but if your call center shows such calls routinely,
you can change this feature or turn it off altogether through the following
configuration.properties
settings:
#If an ongoing call has a wait time that exceeds this value, drop it. 0: ignore
default.maxOngoingWaitTime=1000
#If an ongoing call has a talk time that exceeds this value, drop it. 0: ignore
default.maxOngoingTalkTime=2000
Permalink - Table of contents
Why does the Agent report show all Agent levels as "Undefined"?
The reason is usually pretty simple - because they are undefined. Whenever QueueMetrics runs a report on a queue,
it loads the "agent level" information from that very queue definition that is being run - this means that
if you use the same queue multiple times, e.g. once by itself, once as a member of an aggregate queue, you'll
have to set the agent priority for all cases.
In order to assign agents to a queue, you follow the following procedure:
- Go to the queue editor and select the queue you're reporting upon (from the main page, click on "Edit queue")
- Click on the agents icon for the queue you intend to work on (that's the middle icon on the right with
little people showing) - you should be driven to a page with "Main", "Wrap" and "Spill" columns
- Click who is who for each level - "Main" is the first line level, "Wrap" is a backup for Main, and "Spill"
is the backup for Wrap.
Of course, in order for this to produce meaningful results, you should set up penalities accordingly in the
queue definition for Asterisk.
Permalink - Table of contents
Page encoding problems (Getting "JasperException: Exception parsing file" or "JasperException Error: Cannot read file" errors)
Some JVM's, particularly IBM's, seem to be a bit more picky on page encoding that Sun's. The result is that some pages
of QueueMetrics do not get compiled at all, resulting in one of the exceptions above.
If this happens to you, please notify Loway of the pages you are having problems with, so that we can fix them for the
next version. There is also a simple workaround that will make the page readable in most cases:
- Stop QueueMetrics
- Make a copy of your broken page (in this example we assume it's licence.jsp - copy licence.jsp and call it licence_OLD.jsp)
- Run the command:
iconv --from-code=ISO_8859-1 --to-code=UTF-8 --output licence.jsp licence_OLD.jsp
- Restart QM
- See if the culprit page loads
Permalink - Table of contents
Tracking the incoming DID on a queue
If you have a scenario where you have multiple incoming DIDs pointing to the same queue, and want
to track how many calls
you received on the queue from each of those DIDs, the easiest thing to do is use the Area Analysis
function of QueueMetrics to take care of this automatically.
When a call comes in, you add the DID code to the incoming Caller ID, so that
you get incoming numbers like "D7-0123456" where D7 means the call was received on DID 7 and
0123456 is the original Caller-ID. Then if you go to the Area
Analysis in QueueMetrics, you can ask for a call report based on a number of Caller-ID digits
(like 2 in this case, to extract the first two characters of the caller), and it
will break down all calls by DID code.
You may also use this same function to track other information associated with the
same calls, like multiple IVR choices pointing to the same queue.
For more information on Caller-ID rewriting, see the FAQ entry
"How to set the Caller-ID".
If you need a break down of calls by calling DID and time, see
Tracking hourly call distribution for multiple incoming DIDs.
Permalink - Table of contents
Deploying QueueMetrics with JBoss
It is possible to deploy QueueMetrics into a JBoss application server:
- Frst, unpack QM and set the necessary config changes (like the JDBC URL in WEB-INF/web.xml)
- Create a WAR file out of the unpacked directory (see this tutorial)
- Drop the war file in the JBoss deploy directory and restart Jboss
Permalink - Table of contents
The Qloaderd process will stop working at night
The Qloaderd process will send data from a machine's queue_log to a MySQL server. It was
designed for maximum safety, so that in case there are connection errors it will try
resubmitting the same query over and over, but we noticed that with some versions of the DBI
it will not be able to reconnect successfully if the MySQL connection was terminated because
of inactivity.
In order to avoid this, you may want to set the inactivity timeout to a very high value, by
editing or adding the following variables in the
[server]
section of your /etc/my.ini file:
interactive_timeout = 2764800
wait_timeout = 2764800
This will avoid MySQL marking the connection as dead when the CC is inactive for may hours.
Starting from version 1.3, Qloaderd will also issue periodical queries every 15 minutes even when
there is no activity to avoid this problem.
Permalink - Table of contents
How to set the Caller-ID
If you need to rewrite the caller-ID of the incoming call and want the rewritten
number to apperar in QueueMetrics, you should set the following Asterisk
dialplan variable: CALLERID(num). This variable gets written to the queue_log, so that
the information can be picked up by QueueMetrics.
The popular TrixBox distro sets the authenticated caller-ID name in the CALLERID(name) variable but not
in CALLERID(num); the following piece of diaplan will do the trick:
[from-trunk-custom]
exten => _X.,1,Set(CALLERID(num)=${CALLERID(name)})
exten => _X.,n,Set(CALLERID(name)=${CALLERID(name)})
exten => _X.,n,Goto(from-trunk,${EXTEN},1)
(thanks to Barry for pointing this out).
Permalink - Table of contents
How to fix timing problems in the realtime page when using MySQL storage
If you run QueueMetrics with MySQL storage mode, you will likely have QueueMetrics reside on a
server that will be different from the one Asterisk is, and might as
well be different from the one MySQL is.
If the clocks of all or some of those those machines
have small discrepancies, this can lead to minor problems with the realtime page,
showing calls with negative or positive length offsets and sometimes completely ignoring
the shortest of calls.
Those problems will be experienced only with the realtime page, while the standard
reports are unaffected (as they compute durations from actual data and not by inferring them
from the local time).
To fix those problems, we strongly suggest you use a high-precision time syncing utility
like the NTP package found in most Linux distros, and that you run it on all servers involved
(Asterisk, QueueMetrics and MySQL) in order to have highly coherent timing and logging data.
To do this, simply run the following command as root to fix your system clock:
ntpdate ntp.ien.it
We strongly suggest running it daily using a cron job so that you make sure the servers are
consistently time-aligned in the future.
Permalink - Table of contents
How to monitor multiple queues at once
To monitor multiple queues at just create a composite queue, that is a queue which definition is a set of
other queues; they can be inbound, outbound or mixed. To do this, log on as an administration, click on
"Edit queues", then fill in the form on the bottom of the page called "Add new queue".
Fill-in the following form fields:
- Alias is the name you want your composite queue to be shown as in QueueMetrics
- Queue(s) must be filled with a set of Asterisk queue names separated by the pipe symbol (like A|B|C
to monitor queues A, B and C at once)
Save and go back to the home page. Now you are ready to test your composite queue on both historical
and real-time reports.
In this
way you can run a report for a composite queue and see the details of a number of queues at once
(this is very useful e.g. for real-time monitoring).
We also suggest creating a queue named
"00 All" that will always appear as the first in
the drop-down queue selection box and will allow easy access to the overall monitoring.
Permalink - Table of contents
How to change the realtime page refresh time
You can modify the realtime page refresh rate from the basic 20-second period to any value
you choose. Just set the following property:
#In how many seconds is the realtime page to refresh?
realtime.refresh_time=18
We do not suggest using a value less than 10 seconds, or the browser will flicker a bit.
Time ranges in the 15-30 seconds usually work best. Please consider that decrementing the
refresh timeout will add more load on the server.
Permalink - Table of contents
Logged-on agents disappear at midnight
If your agents work in shifts around midnight, with a plain QueueMetrics installation you will see
that they will "disappear" at midnight from the Realtime screen, as if they logged off, though they
will continue receiving calls (and calls they receive will be reported correctly).
Calls handled over the midnight (i.e. started before the midnight and ending after the midnight) may
seem to have been dropped as well from the realtime screen.
This is because QueueMetrics will consider agent logon information starting from the last midnight, and this arrangement works great for
call centers working during the classical 9-to-5 office hours. If you need a different arrangement, you
can use a "sliding window" model, where QM will look for information during a time period you define.
For example, to set a sliding window of 12 hours, you would set the following property:
#The hour of the day to start real-time monitoring or sXX: sliding window of XX hours
realtime.startHour=s12
You could also set it to "s18" or "s24" to look back 18 or 24 hours respectively - of course,
the longest this period, the more data QM has to process each time.
Permalink - Table of contents
Non existent calls taken when no agents were available seem to be lagging in the queue
If you enable the
maxlen,
joinempty,
leavewhenempty options in a queue, it
is well possible that if a call enters a queue with too many waiters, or no available agents,
the call is not queued but terminated immediately. Unfortunately such ghost calls seem to be
present in QueueMetrics and never being taken by any agent. This is because Asterisk is not logging the
piece of information that tells us that the call was rejected from the queue, so QueueMetrics has
no way to know the call is not there anymore.
What we do to fix this case is that whenever the queue() command terminates and goes on with the dialplan,
we make sure that we output the missing information - and this is in fact pretty easy..
We configure a queue like this:
[myqueue]
exten => s,1,Queue(queuename||)
exten => s,2,System( echo "${EPOCH}|${UNIQUEID}|queuename|NONE|EXITWITHTIMEOUT|1" >> /var/log/asterisk/queue_log )
Of course this is a very simplified case, but you should get the idea of how to do it.
Permalink - Table of contents
Fully dynamic agents and QueueMetrics
NOTE: If you run QueueMetrics 1.4.x and would like to enable queue-by-queue logons
and logoffs with fully dynamic agents, see here for Asterisk 1.2 or
here for Asterisk 1.4.
QueueMetrics requires a little tweaking to work with fully dynamic agents. This is because
the AddQueueMember() command will not log data correctly to queue_log, so we have to do this manually.
The best way to do this is to log on your agents to all the queues you need and do an AGENTLOGIN,
and then log them off when you do an AGENTLOGOFF. Calls will be reported correctly to the correct queue
anyway.
For example, if your operator works on queue q1 and q2 and q3, you would do like this:
; Add Member - 422
exten => _422XX,1,Answer
exten => _422XX,2,AddQueueMember(q1,SIP/${EXTEN:3})
exten => _422XX,3,AddQueueMember(q2,SIP/${EXTEN:3})
exten => _422XX,4,AddQueueMember(q3,SIP/${EXTEN:3})
exten => _422XX,5,System( echo "${EPOCH}|${UNIQUEID}|NONE|SIP/${EXTEN:3}|AGENTLOGIN|-" >> /var/log/asterisk/queue_log )
exten => _422XX,6,DBput(dynlogin/log_Agent-${EXTEN:3}=${EPOCH})
exten => _422XX,7,Hangup
; Remove Member - 423
exten => _423XX,1,Answer
exten => _423XX,2,RemoveQueueMember(q1,SIP/${EXTEN:3})
exten => _423XX,3,RemoveQueueMember(q2,SIP/${EXTEN:3})
exten => _423XX,4,RemoveQueueMember(q3,SIP/${EXTEN:3})
exten => _423XX,5,DBget(ORGEPOCH=dynlogin/log_Agent-${EXTEN:3})
exten => _423XX,6,Set(RV=$[${EPOCH} - ${ORGEPOCH}])
exten => _423XX,7,GotoIf($["${RV}" = "0"]?10:8)
exten => _423XX,8,System( echo "${EPOCH}|${UNIQUEID}|NONE|SIP/${EXTEN:3}|AGENTLOGOFF|-|${RV}" >> /var/log/asterisk/queue_log )
exten => _423XX,9,DBdel(dynlogin/log_Agent-${EXTEN:3})
exten => _423XX,10,Hangup
If you use Local/XX@ext channel rewriting to Agent/XX, make sure to log 'Agent/${EXTEN:3}' instead of 'SIP/${EXTEN:3}'
As a further alternative, you could have your agents login in the morning to a "fake" extension producing the log line, then join each single queue without producing a log line, and then logging off in the evening to another "fake" extension producing the log line.
As a last alternative, if you need to track the actual logon-logoff times for each queue, what you have to do is to log on each queue by logging to a different agent, like:
- Operator 20 on queue q1 is Agent/q1-20
- Operator 21 on queue q2 is Agent/q2-21
And so on. This way you can track precisely the queue logon and logoff times for each agent on each queue. In order for this to work, you must set the following configurtation properties:
default.rewriteLocalChannels=true
default.rewriteLocalWithQueue=true
The login-logoff code in this case is as follows (for queue 'q1'):
; Add Member - 422
exten => _422XX,1,Answer
exten => _422XX,2,AddQueueMember(q1,SIP/${EXTEN:3})
exten => _422XX,3,System( echo "${EPOCH}|${UNIQUEID}|NONE|Agent/q1-${EXTEN:3}|AGENTLOGIN|-" >> /var/log/asterisk/queue_log )
exten => _422XX,4,DBput(dynlogin/log_Agent-q1-${EXTEN:3}=${EPOCH})
exten => _422XX,5,Hangup
; Remove Member - 423
exten => _423XX,1,Answer
exten => _423XX,2,RemoveQueueMember(q1,SIP/${EXTEN:3})
exten => _423XX,3,DBget(ORGEPOCH=dynlogin/log_Agent-q1-${EXTEN:3})
exten => _423XX,4,Set(RV=$[${EPOCH} - ${ORGEPOCH}])
exten => _423XX,5,GotoIf($["${RV}" = "0"]?8:6)
exten => _423XX,6,System( echo "${EPOCH}|${UNIQUEID}|NONE|Agent/q1-${EXTEN:3}|AGENTLOGOFF|-|${RV}" >> /var/log/asterisk/queue_log )
exten => _423XX,7,DBdel(dynlogin/log_Agent-q1-${EXTEN:3})
exten => _423XX,8,Hangup
Permalink - Table of contents
How to install and update QueueMetrics using yum
Yum is a package manager that is used on a number of Linux systems, notably Red Hat / CentOS
and derivatives like Asterisk At Home / TrixBox,
in order to ease the installation and update of software packages.
If your systems uses yum, you can install QueueMetrics from scratch using the following
commands:
wget https://yum.loway.ch/loway.repo -O /etc/yum.repos.d/loway.repo
yum install queuemetrics
And then following the on-screen instructions in order to create the database.
The first line is needed in order to add Loway Research as one of the authorized repositories
into which yum can search for packages.
To update QueueMetrics to the latest version, just use:
yum update queuemetrics
And then have a look at the Updating.txt file in order to modify the database
and/or the configuration.properties file if so is needed.
As an alternative, you may want to delete it and reinstall it from scratch, as:
yum erase queuemetrics
yum install queuemetrics
Permalink - Table of contents
Why do I get the error 'Bad interpreter' trying to run a shell file or an AGI?
If you run a command file that is written in Perl, and the file does not seem to
run at all unless it is launched manually with "perl filename.pl" it is very
likely that you forgot to convert it from DOS format to UNIX. You usually
get the error "bad interpreter" when running it manually.
To solve this problem, type
dos2unix commandname - the file will be changed
from DOS format to UNIX and will be immediately runnable by typing
./commandname
If this is not enough, make sure that the file is executable (
chmod a+x commandname)
and that the path of the Perl interpreter as specified in the first line is correct
for your environment.
Permalink - Table of contents
What do the fields named UNK and BSY mean?
In the realtime view, there are two fields that may look puzzling: BSY and UNK.
- BSY is the number of agents that are currently busy on a different queue.
Like, if you have an agent that is active on queue A and queue B, when he is on
conversation in queue A will be counted as BSY on queue B, as he is not actually ready
to take calls in queue B.
- UNK are unknown agents that are speaking on the queue.
When QueueMetrics tries to determine how many agents are ready for a queue, it takes the
total number of known agents and subtracts those who are speaking, those who are on pause and those who are BSY.
If an agent shows up in a queue and QM does not know that the agent is working on that queue,
the agent is counted in the UNK field.
If you want to avoid having UNK agents, make sure that your QM agents-on-queue configuration actually matches
the underlying Asterisk configuration.
Permalink - Table of contents
Why doesn't my AGI file seem to work
When installing a new AGI script, sometimes Asterisk seems to reporting that the file gets executed with result 0
while the file it is not in fact being executed at all.
If it does not, there are a few possible reasons:
- the script does not exist at the given agi-bin location or it is not "visible" to the user running Asterisk (solution: update unix file permisions)
- the script is not executable - try running it manually (do a "chmod a+x queueDial.agi")
- the script is in DOS mode - i.e. uses CR/LF as the line endings - and won't start from the shell (do a "dos2unix queueDial.agi" to fix it)
- check if the file /var/log/asterisk/agi-log.txt is read/writeable by Asterisk
Permalink - Table of contents
How to implement a dial-out queue
Note: this FAQ applies to an outdated approach. See the document "Tracing outbound calls through QueueMetrics in TrixBox" version 2.0, available form the Downloads page.
The following is is a piece of real-world dialplan one of our
clients is using:
exten => _9XXX.,1,Set(MY_QUE=${EXTEN:1:3})
exten => _9XXX.,2,Set(MY_NUM=${EXTEN:4})
exten => _9XXX.,3,Set(MY_AGENT=${CALLERID(num)})
exten => _9XXX.,4,NoOp,Ag: ${MY_AGENT} N: ${MY_NUM} Q: ${MY_QUE}
exten => _9XXX.,5,MixMonitor(Q-${MY_QUE}-${UNIQUEID}.wav|b|)
exten => _9XXX.,6,DeadAGI(queueDial.agi|${MY_NUM}|Zap/g0/${MY_NUM}|q-${MY_QUE}|Agent/${MY_AGENT})
exten => _9XXX.,7,Congestion
This example needs a three digit campaign number, like '301'. If you have to dial the number 01234567 for
campaign #301, you actually dial 9 301 01234567 so that the system knows on which outbound queue the call is being
handled. The agent code is inferred from the current terminal it is being used and all calls are
saved to disk for future reference with a name that QueueMetrics can understand (so you can listen to them
with a click from the mouse).
As this feature requires making a number of changes to the Asterisk configuration, we suggest you
proceed one step at a time during its implementation:
- First change the dialplan in order to have a NoOp() console output - like the example above steps 1-4 - so you can
see that your changes to the dialplan are correct and do indeed work
- Then try adding the queueDial.agi in that point in the dialplan so that you are sure it is called through
the diaplan (you can see it being called through the Asterisk command line interface, though it might not work yet)
- Once you are sure it is called, check if all file permissions are OK and the queueDial.agi does actually
what it is supposed to do - places a call and adds lines to the queue_log. If it does not, chances are it
is not being executed at all - see "Why doesn't my AGI file seem to work?"
- When everything is ready, configure QM to pick up the new queue you created.
Note: if you run some of the latest Asterisk 1.4s, it is possible that some of the calls terminated using the queueDial.agi script fail and remain "hung" in QueueMetrics - to fix this, see
Quemeterics not recognising remote caller hangup on the forums.
Permalink - Table of contents
Java Security errors
On some systems, notably Debian, the Tomcat package is installed by default with Java security policies active;
such policies are very restrictive and may block Tomcat when trying to access the database or read files from the
local file system.
See the entry
Running with Java security
for an example ruleset that applies to QM 1.4.5.
If this is not possible, you'd better install Tomcat fresh from the tar file as described in the User Manual.
See also the Tomcat Security Manager HOW-TO for a better undertanding of the security manager.
Permalink - Table of contents
Error: java.lang.NoSuchMethodError
This error manifests itself usually after upgrading the webapp and has no apparent meaning, as the required class
seems to be present in the compiled jar files. It is usually due to one of the two following causes:
- An old version of the compiled classes is being cached by Tomcat, or
- Tomcat is not being restarted, i.e. Tomcat receives the shutdown command but for some reason cannot terminate
To solve this problem:
- Shut down Tomcat (check with the Unix command ps fax that no instances of java keep running after the
required shutdown and - in case they do - kill them manuall with killall -9 java).
- Clean up the Tomcat class cache - delete the entire content of the directory work that is usually
located within the main Tomcat directory
- Make sure that there is one and only one QueueMetrics webapp in the entire Tomcat system (look below the
webapps directory and delete accordingly)
- Restart Tomcat
This should fix your problem. If you fear that you have too few RAM for QueueMetrics, an ongoing "deep" garbage collection
can slow down the JAva VM to a crawl and prevent it from stopping when requested to do so. In this case,
see also "Out of memory error".
Permalink - Table of contents
QueueMetrics does not seem to work with GCJ
QueueMetrics does not currently work with GCJ 3 and seems to use a lot of CPU and memory on GCJ 4.
GCJ is a free Java compiler/interpreter usually found on most Linux distributions but is not currently
100% compatible yet with the standard Java bundle - see
http://gcc.gnu.org/java/.
You should use an industrial-strength Java SDK instead, like the ones from Sun or IBM. Our suggestion is to go for the latest Sun SDK available.
Permalink - Table of contents
Error: java.sql.SQLException: Data source rejected establishment of connection, message from server: 'Host 'localhost.localdomain' is not allowed to connect to this MySQL server'
You always think that your machine is
localhost when connecting from the same host, but MySQL sometimes thinks that it's
localhost.localdomain and so your credentials will not match.
On MySQL, try the following line:
grant all privileges on queuemetrics.* to 'queuemetrics'@'localhost.localdomain' identified by 'password';
Permalink - Table of contents
Error: "Il verbo '.....' richiede una chiave non disponibile all'utente corrente"
You need a key you do not currently have to run the required transaction. Likely, your session timed out for inactivity, so you have no key at all associated with your profile; when you then click on a link, the system tells you that you have to log on again.
Permalink - Table of contents
Error: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
The Java MySQL driver was not found. Try downloading it again, putting the appropriate JAR file in WEB-INF/lib and restarting the servlet container.
Permalink - Table of contents
Error: "Problema update DB: com.mysql.jdbc.MysqlDataTruncation ..."
To fix this problem, that comes with the newer versions of MySQL and Connector/J, add the parameter
jdbcCompliantTruncation=false to your JDBC URI in WEB-INF/web.xml.
Permalink - Table of contents
Error: java.sql.SQLException: Cannot convert value '0000-00-00 00:00:00' from column 14 to TIMESTAMP
You are using a version of the MySQL connector that is >= 3.1. To solve this problem add the parameter
zeroDateTimeBehavior=convertToNull to your JDBC connection string located in WEB-INF/web.xml, like in the following example:
jdbc:mysql://localhost/queuemetrics?zeroDateTimeBehavior=convertToNull&user=queuemetrics&password=javadude
Permalink - Table of contents
Error: "Il verbo '.....' non consente la creazione di una nuova sessione"
Your session timed out for inactivity; when you then click on a link, the system tells you that you have to log on again.
Permalink - Table of contents
Error: java.sql.SQLException: Invalid authorization specification message from server: 'Access denied for user: 'queuemetrics@localhost.localdomain' (Using password: YES)'
You always think that your machine is
localhost when connecting from the same host, but MySQL sometimes thinks that it's
localhost.localdomain and so your credentials will not match.
On MySQL, try the following line:
grant all privileges on queuemetrics.* to 'queuemetrics'@'localhost.localdomain' identified by 'password';
Permalink - Table of contents
Error: java.sql.SQLException: Access denied for user 'queuemetrics'@'mydb' (using password: YES)
The error means that the user and/or password given in WEB-INF/web.xml do not match credentials supplied with MySQL. On MySQL, try the following line:
grant all privileges on queuemetrics.* to 'queuemetrics'@'mydb' identified by 'password';
Permalink - Table of contents