Hi Joel,
thank you very much for the hints and the input.
I am not sure if i should run that in the REQUEST, but it works for me.
Only headache with that is, that i also use Websockets in my event_route.
And AFAIK there is "only one" event_route[xhttp:request].
Would be nice to separate the /stats to an local bound listener without
break the WS stuff.
An working one is this config snipped for me:
[...]
event_route[xhttp:request] {
set_reply_close();
set_reply_no_connect();
if ($Rp != MY_WS_PORT
#!ifdef WITH_TLS
&& $Rp != MY_WSS_PORT
#!endif
) {
xlog("L_WARN", "HTTP request received on $Rp\n");
if ($sel(cfg_get.mylog.logint) > 1) {
xhttp_reply("200", "OK",
"text/html","<html><body>Received HTTP request to $hu from
[$si:$sp] with
protocol $proto</body></html>");
} else {
xhttp_reply("403", "Forbidden", "",
"");
}
exit;
}
xlog("L_DBG", "HTTP Request Received\n");
xlog("L_INFO", "HTTP Request Received hu:($hu)
src_ip:($src_ip)\n");
#!ifdef WITH_JSONSTATS
# Metrics endpoint
if ( ($src_ip == "127.0.0.1") && ($hu =~ "^/stats") )
{
jsonrpc_exec('{"jsonrpc":
"2.0","method":
"stats.get_statistics","params": ["all"],"id":
1}');
$var(metrics_count) = 0;
jansson_array_size("result", $jsonrpl(body),
"$var(total_metrics)");
while($var(metrics_count) < $var(total_metrics)) {
jansson_get("result[$var(metrics_count)]",
$jsonrpl(body), "$var(v)");
$var(metric_key) =
$(var(v){s.select,0,=}{s.trim}{s.replace,:,-});
$var(metric_value) = $(var(v){s.select,1,=}{s.trim});
jansson_set("integer", "$var(metric_key)",
"$var(metric_value)", "$var(metrics_json)");
$var(metrics_count) = $var(metrics_count) + 1;
}
xhttp_reply("200", "OK",
"application/json",
"$var(metrics_json)");
exit;
}
#!endif
if ($hdr(Upgrade)=~"websocket"
&& $hdr(Connection)=~"Upgrade"
&& $rm=~"GET") {
[...]
curl -s --interface lo -k
https://MY-WEBRTC-IP:MY-WEBRTC-PORT/stats | jq '.'
{
"core-bad_URIs_rcvd": 0,
"core-bad_msg_hdr": 0,
"core-drop_replies": 0,
"core-drop_requests": 3,
"core-err_replies": 0,
"core-err_requests": 0,
"core-fwd_replies": 0,
"core-fwd_requests": 3,
"core-rcv_replies": 16,
"core-rcv_replies_18x": 0,
"core-rcv_replies_1xx": 3,
"core-rcv_replies_2xx": 13,
"core-rcv_replies_3xx": 0,
"core-rcv_replies_401": 0,
"core-rcv_replies_404": 0,
"core-rcv_replies_407": 0,
"core-rcv_replies_480": 0,
"core-rcv_replies_486": 0,
"core-rcv_replies_4xx": 0,
"core-rcv_replies_5xx": 0,
"core-rcv_replies_6xx": 0,
"core-rcv_requests": 30,
"core-rcv_requests_ack": 3,
"core-rcv_requests_bye": 3,
"core-rcv_requests_cancel": 0,
"core-rcv_requests_info": 0,
"core-rcv_requests_invite": 6,
"core-rcv_requests_message": 0,
"core-rcv_requests_notify": 0,
"core-rcv_requests_options": 8,
"core-rcv_requests_prack": 0,
"core-rcv_requests_publish": 0,
"core-rcv_requests_refer": 0,
"core-rcv_requests_register": 0,
"core-rcv_requests_subscribe": 0,
"core-rcv_requests_update": 0,
"core-unsupported_methods": 0,
"dns-failed_dns_request": 0,
"mysql-driver_errors": 0,
"registrar-accepted_regs": 0,
"registrar-default_expire": 3600,
"registrar-default_expires_range": 0,
"registrar-expires_range": 0,
"registrar-max_contacts": 0,
"registrar-max_expires": 3600,
"registrar-rejected_regs": 0,
"shmem-fragments": 62,
"shmem-free_size": 1064748608,
"shmem-max_used_size": 9040400,
"shmem-real_used_size": 8993216,
"shmem-total_size": 1073741824,
"shmem-used_size": 5363816,
"sl-1xx_replies": 0,
"sl-200_replies": 17,
"sl-202_replies": 0,
"sl-2xx_replies": 0,
"sl-300_replies": 0,
"sl-301_replies": 0,
"sl-302_replies": 0,
"sl-3xx_replies": 0,
"sl-400_replies": 0,
"sl-401_replies": 0,
"sl-403_replies": 0,
"sl-404_replies": 0,
"sl-407_replies": 3,
"sl-408_replies": 0,
"sl-483_replies": 0,
"sl-4xx_replies": 0,
"sl-500_replies": 0,
"sl-5xx_replies": 0,
"sl-6xx_replies": 0,
"sl-failures": 0,
"sl-received_ACKs": 3,
"sl-sent_err_replies": 0,
"sl-sent_replies": 20,
"sl-xxx_replies": 0,
"tcp-con_reset": 0,
"tcp-con_timeout": 0,
"tcp-connect_failed": 0,
"tcp-connect_success": 0,
"tcp-current_opened_connections": 1,
"tcp-current_write_queue_size": 0,
"tcp-established": 10,
"tcp-local_reject": 0,
"tcp-passive_open": 10,
"tcp-send_timeout": 0,
"tcp-sendq_full": 0,
"tmx-2xx_transactions": 6,
"tmx-3xx_transactions": 0,
"tmx-4xx_transactions": 0,
"tmx-5xx_transactions": 0,
"tmx-6xx_transactions": 0,
"tmx-UAC_transactions": 0,
"tmx-UAS_transactions": 6,
"tmx-active_transactions": 0,
"tmx-inuse_transactions": 0,
"tmx-rpl_absorbed": 3,
"tmx-rpl_generated": 3,
"tmx-rpl_received": 9,
"tmx-rpl_relayed": 6
}
2018-03-15 22:21 GMT+01:00 Joel Serrano <joel(a)gogii.net>et>:
Hi Karsten,
In my specific case, I had a requirement that it had to be compatible with
the telegraf httpjson input plugin.
Kamailio by default returns all the metrics in an array, and has a ':' in
the metric name.
Example:
{
"jsonrpc": "2.0",
"result": [
"core:bad_URIs_rcvd = 26",
"core:bad_msg_hdr = 354",
"core:drop_replies = 0",
"core:drop_requests = 1634",
"core:err_replies = 0",
"core:err_requests = 0",
"core:fwd_replies = 222",
"core:fwd_requests = 140221",
"core:rcv_replies = 3633129",
"core:rcv_replies_18x = 153980",
"core:rcv_replies_1xx = 388669",
"core:rcv_replies_2xx = 2844680",
"core:rcv_replies_3xx = 0",
"core:rcv_replies_401 = 335571",
"core:rcv_replies_404 = 1882",
"core:rcv_replies_407 = 3960",
"core:rcv_replies_480 = 4818",
"core:rcv_replies_486 = 6734",
"core:rcv_replies_4xx = 388874",
"core:rcv_replies_5xx = 10410",
"core:rcv_replies_6xx = 496",
"core:rcv_requests = 1406155",
"core:rcv_requests_ack = 200019",
"core:rcv_requests_bye = 141683",
"core:rcv_requests_cancel = 32887",
"core:rcv_requests_info = 332",
"core:rcv_requests_invite = 200125",
"core:rcv_requests_message = 0",
"core:rcv_requests_notify = 0",
"core:rcv_requests_options = 500785",
"core:rcv_requests_prack = 0",
"core:rcv_requests_publish = 0",
"core:rcv_requests_refer = 0",
"core:rcv_requests_register = 42",
"core:rcv_requests_subscribe = 0",
"core:rcv_requests_update = 0",
"core:unsupported_methods = 19",
"dialog:active_dialogs = 27",
"dialog:early_dialogs = 2",
"dialog:expired_dialogs = 14",
"dialog:failed_dialogs = 59781",
"dialog:processed_dialogs = 197375",
"dns:failed_dns_request = 5762",
"httpclient:connections = 0",
"httpclient:connfail = 55",
"httpclient:connok = 101123",
"pike:blocked_ips = 0",
"shmem:fragments = 61",
"shmem:free_size = 532084488",
"shmem:max_used_size = 5328880",
"shmem:real_used_size = 4786424",
"shmem:total_size = 536870912",
"shmem:used_size = 4454760",
"siptrace:traced_replies = 0",
"siptrace:traced_requests = 0",
"sl:1xx_replies = 0",
"sl:200_replies = 827319",
"sl:202_replies = 0",
"sl:2xx_replies = 0",
"sl:300_replies = 0",
"sl:301_replies = 0",
"sl:302_replies = 0",
"sl:3xx_replies = 0",
"sl:400_replies = 83",
"sl:401_replies = 0",
"sl:403_replies = 1847",
"sl:404_replies = 4",
"sl:407_replies = 0",
"sl:408_replies = 0",
"sl:483_replies = 0",
"sl:4xx_replies = 883",
"sl:500_replies = 4",
"sl:5xx_replies = 976",
"sl:6xx_replies = 0",
"sl:failures = 0",
"sl:received_ACKs = 1634",
"sl:sent_err_replies = 0",
"sl:sent_replies = 831116",
"sl:xxx_replies = 0",
"tcp:con_reset = 0",
"tcp:con_timeout = 0",
"tcp:connect_failed = 0",
"tcp:connect_success = 0",
"tcp:current_opened_connections = 1",
"tcp:current_write_queue_size = 0",
"tcp:established = 2",
"tcp:local_reject = 0",
"tcp:passive_open = 2",
"tcp:send_timeout = 0",
"tcp:sendq_full = 0",
"tmx:2xx_transactions = 2844324",
"tmx:3xx_transactions = 0",
"tmx:4xx_transactions = 709680",
"tmx:5xx_transactions = 10733",
"tmx:6xx_transactions = 495",
"tmx:UAC_transactions = 3196487",
"tmx:UAS_transactions = 3561209",
"tmx:active_transactions = 6",
"tmx:inuse_transactions = 7",
"tmx:rpl_absorbed = 287838",
"tmx:rpl_generated = 571117",
"tmx:rpl_received = 3632903",
"tmx:rpl_relayed = 3345065",
"tmx:rpl_sent = 3916182",
"usrloc:registered_users = 0"
],
"id": 8362
}
That format (although correct) isn't compatible with what the httpjson
telegraf plugin expects:
https://github.com/influxdata/
telegraf/tree/master/plugins/inputs/httpjson
I had to build my own JSON in a way that telegraf liked it:
jsonrpc_exec('{"jsonrpc": "2.0","method":
"stats.get_statistics","params":
["all"],"id": 1}');
$var(metrics_count) = 0;
jansson_array_size("result", $jsonrpl(body),
"$var(total_metrics)");
while($var(metrics_count) < $var(total_metrics)) {
jansson_get("result[$var(metrics_count)]", $jsonrpl(body),
"$var(v)");
$var(metric_key) = $(var(v){s.select,0,=}{s.trim}
{s.replace,:,-});
$var(metric_value) = $(var(v){s.select,1,=}{s.trim});
jansson_set("integer", "$var(metric_key)",
"$var(metric_value)", "$var(metrics_json)");
$var(metrics_count) = $var(metrics_count) + 1;
}
And this is an example if the resulting JSON:
{
"core-bad_URIs_rcvd":26,
"core-bad_msg_hdr":354,
"core-drop_replies":0,
"core-drop_requests":1634,
"core-err_replies":0,
"core-err_requests":0,
"core-fwd_replies":222,
"core-fwd_requests":140287,
"core-rcv_replies":3633735,
"core-rcv_replies_18x":154043,
"core-rcv_replies_1xx":388838,
"core-rcv_replies_2xx":2845062,
"core-rcv_replies_3xx":0,
"core-rcv_replies_401":335604,
"core-rcv_replies_404":1882,
"core-rcv_replies_407":3960,
"core-rcv_replies_480":4820,
"core-rcv_replies_486":6740,
"core-rcv_replies_4xx":388925,
"core-rcv_replies_5xx":10412,
"core-rcv_replies_6xx":498,
"core-rcv_requests":1406490,
"core-rcv_requests_ack":200107,
"core-rcv_requests_bye":141753,
"core-rcv_requests_cancel":32896,
"core-rcv_requests_info":332,
"core-rcv_requests_invite":200211,
"core-rcv_requests_message":0,
"core-rcv_requests_notify":0,
"core-rcv_requests_options":500835,
"core-rcv_requests_prack":0,
"core-rcv_requests_publish":0,
"core-rcv_requests_refer":0,
"core-rcv_requests_register":42,
"core-rcv_requests_subscribe":0,
"core-rcv_requests_update":0,
"core-unsupported_methods":19,
"dialog-active_dialogs":24,
"dialog-early_dialogs":2,
"dialog-expired_dialogs":14,
"dialog-failed_dialogs":59803,
"dialog-processed_dialogs":197460,
"dns-failed_dns_request":5762,
"httpclient-connections":0,
"httpclient-connfail":55,
"httpclient-connok":101174,
"pike-blocked_ips":0,
"shmem-fragments":81,
"shmem-free_size":532089200,
"shmem-max_used_size":5328880,
"shmem-real_used_size":4781712,
"shmem-total_size":536870912,
"shmem-used_size":4454520,
"siptrace-traced_replies":0,
"siptrace-traced_requests":0,
"sl-1xx_replies":0,
"sl-200_replies":827400,
"sl-202_replies":0,
"sl-2xx_replies":0,
"sl-300_replies":0,
"sl-301_replies":0,
"sl-302_replies":0,
"sl-3xx_replies":0,
"sl-400_replies":83,
"sl-401_replies":0,
"sl-403_replies":1847,
"sl-404_replies":4,
"sl-407_replies":0,
"sl-408_replies":0,
"sl-483_replies":0,
"sl-4xx_replies":883,
"sl-500_replies":4,
"sl-5xx_replies":976,
"sl-6xx_replies":0,
"sl-failures":0,
"sl-received_ACKs":1634,
"sl-sent_err_replies":0,
"sl-sent_replies":831197,
"sl-xxx_replies":0,
"tcp-con_reset":0,
"tcp-con_timeout":0,
"tcp-connect_failed":0,
"tcp-connect_success":0,
"tcp-current_opened_connections":2,
"tcp-current_write_queue_size":0,
"tcp-established":3,
"tcp-local_reject":0,
"tcp-passive_open":3,
"tcp-send_timeout":0,
"tcp-sendq_full":0,
"tmx-2xx_transactions":2844706,
"tmx-3xx_transactions":0,
"tmx-4xx_transactions":709758,
"tmx-5xx_transactions":10735,
"tmx-6xx_transactions":497,
"tmx-UAC_transactions":3196787,
"tmx-UAS_transactions":3561671,
"tmx-active_transactions":5,
"tmx-inuse_transactions":6,
"tmx-rpl_absorbed":287958,
"tmx-rpl_generated":571244,
"tmx-rpl_received":3633509,
"tmx-rpl_relayed":3345551,
"tmx-rpl_sent":3916795,
"usrloc-registered_users":0
}
That JSON was correctly parsed by Telegraf and the metrics were inserted
into InfluxDB correctly.
NOTE: In our case we needed all the metrics so we also had to increase the
*max_while_loops* param:
https://www.kamailio.
org/wiki/cookbooks/devel/core#max_while_loops
I'm sure there are better ways for this, but this one I can tell you is
working.
Let me know how it goes!
Cheers,
Joel.
On Thu, Mar 15, 2018 at 9:22 AM, Karsten Horsmann <khorsmann(a)gmail.com>
wrote:
Hello List,
Hello Joel,
i have now the time to implement this idea.
How you got $var(metrics_json) filed with the kamailio stats /
whatever internal informations?
btw i use kamailio 5.0.6 at this moment.
Thanks!
2017-12-06 18:11 GMT+01:00 Joel Serrano <joel(a)gogii.net>et>:
I use a mix of the above...
With kamailio I export that stats I want via http:
event_route[xhttp:request] {
# Verify request come from localhost
if(src_ip!=127.0.0.1) {
xhttp_reply("403", "Forbidden", "text/html",
"<html><body>Forbidden</body></html>");
xlog("L_WARN", "[HTTP] Unauthorized access from: $si\n");
exit;
}
# Metrics endpoint
if ($hu =~ "^/statistics") {
... build a $var(metrics_json) with the metrics you want, must
be JSON format ...
}
xhttp_reply("200", "OK", "application/json",
"$var(metrics_json)");
}
return;
}
Then in telegraf I use the httpjson module to gather the metrics:
...
[[inputs.httpjson]]
name_override = "kamailio"
servers = [ "http://127.0.0.1/statistics" ]
method = "GET"
...
This is an example:
joel@sbc-dev:~$ curl -q
http://127.0.0.1/statistics 2> /dev/null |
python -m json.tool
{
"core-bad_URIs_rcvd": 0,
[cut some output
"tmx-rpl_received": 436444,
"tmx-rpl_relayed": 379358,
"tmx-rpl_sent": 489589,
"usrloc-registered_users": 0
}
joel@sbc-dev:~$
We have all those metrics available now in influxdb, then, as others
have stated, Grafana is your best friend to make those metrics look nice.
Hope these little snippets help you and anyone else getting started with
Kamailio metrics.
Cheers,
Joel.
On Wed, Dec 6, 2017 at 1:20 AM, Daniel-Constantin Mierla <
miconda(a)gmail.com> wrote:
Hello,
have you seen the article posted at:
-
https://www.kamailio.org/w/2015/03/kamailio-statsd-best-practices/
Eloy had a blog about it linked from above page.
Cheers,
Daniel
On 06.12.17 08:54, Karsten Horsmann wrote:
Hello List,
I thought about some kind of Kamailio stats source (like registered
users, calls active and some other things) to collect them into influx dB
and draw them with grafana.
How do you solved that?
Timer based routes or statsd or whatever?
Kind regards
Karsten Horsmann
_______________________________________________
Kamailio (SER) - Users Mailing
Listsr-users@lists.kamailio.orghttps://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
--
Daniel-Constantin
Mierlawww.twitter.com/miconda --
www.linkedin.com/in/miconda
Kamailio Advanced Training -
www.asipto.com
Kamailio World Conference - May 14-16, 2018 -
www.kamailioworld.com
_______________________________________________
Kamailio (SER) - Users Mailing List
sr-users(a)lists.kamailio.org
https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
--
Kind Regards
*Karsten Horsmann*
--
Mit freundlichen Grüßen
*Karsten Horsmann*