mirror of https://gerrit.osmocom.org/libosmocore
175 lines
4.5 KiB
C
175 lines
4.5 KiB
C
/*! \file stats_statsd.c */
|
|
/*
|
|
* (C) 2015 by Sysmocom s.f.m.c. GmbH
|
|
*
|
|
* Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
|
|
*
|
|
* All Rights Reserved
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
*/
|
|
|
|
#include "config.h"
|
|
#if !defined(EMBEDDED)
|
|
|
|
#include <osmocom/core/stats.h>
|
|
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
#include <errno.h>
|
|
|
|
#include <osmocom/core/utils.h>
|
|
#include <osmocom/core/logging.h>
|
|
#include <osmocom/core/rate_ctr.h>
|
|
#include <osmocom/core/stat_item.h>
|
|
#include <osmocom/core/msgb.h>
|
|
#include <osmocom/core/stats.h>
|
|
|
|
static int osmo_stats_reporter_statsd_send_counter(struct osmo_stats_reporter *srep,
|
|
const struct rate_ctr_group *ctrg,
|
|
const struct rate_ctr_desc *desc,
|
|
int64_t value, int64_t delta);
|
|
static int osmo_stats_reporter_statsd_send_item(struct osmo_stats_reporter *srep,
|
|
const struct osmo_stat_item_group *statg,
|
|
const struct osmo_stat_item_desc *desc, int64_t value);
|
|
|
|
struct osmo_stats_reporter *osmo_stats_reporter_create_statsd(const char *name)
|
|
{
|
|
struct osmo_stats_reporter *srep;
|
|
srep = osmo_stats_reporter_alloc(OSMO_STATS_REPORTER_STATSD, name);
|
|
|
|
srep->have_net_config = 1;
|
|
|
|
srep->open = osmo_stats_reporter_udp_open;
|
|
srep->close = osmo_stats_reporter_udp_close;
|
|
srep->send_counter = osmo_stats_reporter_statsd_send_counter;
|
|
srep->send_item = osmo_stats_reporter_statsd_send_item;
|
|
|
|
return srep;
|
|
}
|
|
|
|
static int osmo_stats_reporter_statsd_send(struct osmo_stats_reporter *srep,
|
|
const char *name1, unsigned int index1, const char *name2, int64_t value,
|
|
const char *unit)
|
|
{
|
|
char *buf;
|
|
int buf_size;
|
|
int nchars, rc = 0;
|
|
char *fmt = NULL;
|
|
char *prefix = srep->name_prefix;
|
|
int old_len = msgb_length(srep->buffer);
|
|
|
|
if (prefix) {
|
|
if (name1) {
|
|
if (index1 != 0)
|
|
fmt = "%1$s.%2$s.%6$u.%3$s:%4$d|%5$s";
|
|
else
|
|
fmt = "%1$s.%2$s.%3$s:%4$d|%5$s";
|
|
} else {
|
|
fmt = "%1$s.%2$0.0s%3$s:%4$d|%5$s";
|
|
}
|
|
} else {
|
|
prefix = "";
|
|
if (name1) {
|
|
if (index1 != 0)
|
|
fmt = "%1$s%2$s.%6$u.%3$s:%4$d|%5$s";
|
|
else
|
|
fmt = "%1$s%2$s.%3$s:%4$d|%5$s";
|
|
} else {
|
|
fmt = "%1$s%2$0.0s%3$s:%4$d|%5$s";
|
|
}
|
|
}
|
|
|
|
if (srep->agg_enabled) {
|
|
if (msgb_length(srep->buffer) > 0 &&
|
|
msgb_tailroom(srep->buffer) > 0)
|
|
{
|
|
msgb_put_u8(srep->buffer, '\n');
|
|
}
|
|
}
|
|
|
|
buf = (char *)msgb_put(srep->buffer, 0);
|
|
buf_size = msgb_tailroom(srep->buffer);
|
|
|
|
nchars = snprintf(buf, buf_size, fmt,
|
|
prefix, name1, name2,
|
|
value, unit, index1);
|
|
|
|
if (nchars >= buf_size) {
|
|
/* Truncated */
|
|
/* Restore original buffer (without trailing LF) */
|
|
msgb_trim(srep->buffer, old_len);
|
|
/* Send it */
|
|
rc = osmo_stats_reporter_send_buffer(srep);
|
|
|
|
/* Try again */
|
|
buf = (char *)msgb_put(srep->buffer, 0);
|
|
buf_size = msgb_tailroom(srep->buffer);
|
|
|
|
nchars = snprintf(buf, buf_size, fmt,
|
|
prefix, name1, name2,
|
|
value, unit, index1);
|
|
|
|
if (nchars >= buf_size)
|
|
return -EMSGSIZE;
|
|
}
|
|
|
|
if (nchars > 0)
|
|
msgb_trim(srep->buffer, msgb_length(srep->buffer) + nchars);
|
|
|
|
if (!srep->agg_enabled)
|
|
rc = osmo_stats_reporter_send_buffer(srep);
|
|
|
|
return rc;
|
|
}
|
|
|
|
static int osmo_stats_reporter_statsd_send_counter(struct osmo_stats_reporter *srep,
|
|
const struct rate_ctr_group *ctrg,
|
|
const struct rate_ctr_desc *desc,
|
|
int64_t value, int64_t delta)
|
|
{
|
|
if (ctrg)
|
|
return osmo_stats_reporter_statsd_send(srep,
|
|
ctrg->desc->group_name_prefix,
|
|
ctrg->idx,
|
|
desc->name, delta, "c");
|
|
else
|
|
return osmo_stats_reporter_statsd_send(srep,
|
|
NULL, 0,
|
|
desc->name, delta, "c");
|
|
}
|
|
|
|
static int osmo_stats_reporter_statsd_send_item(struct osmo_stats_reporter *srep,
|
|
const struct osmo_stat_item_group *statg,
|
|
const struct osmo_stat_item_desc *desc, int64_t value)
|
|
{
|
|
const char *unit = desc->unit;
|
|
|
|
if (unit == OSMO_STAT_ITEM_NO_UNIT) {
|
|
unit = "g";
|
|
if (value < 0)
|
|
osmo_stats_reporter_statsd_send(srep,
|
|
statg->desc->group_name_prefix,
|
|
statg->idx,
|
|
desc->name, 0, unit);
|
|
}
|
|
return osmo_stats_reporter_statsd_send(srep,
|
|
statg->desc->group_name_prefix,
|
|
statg->idx,
|
|
desc->name, value, unit);
|
|
}
|
|
#endif /* !EMBEDDED */
|