blob: c11c013248cdb7cd33ccf70acf2cb6221f660713 [file] [log] [blame]
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +01001/*
Harald Weltee08da972017-11-13 01:00:26 +09002 * (C) 2015 by sysmocom - s.f.m.c. GmbH
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +01003 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +01004 * All Rights Reserved
5 *
Harald Weltee08da972017-11-13 01:00:26 +09006 * SPDX-License-Identifier: GPL-2.0+
7 *
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +01008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
Harald Welteeb5b6ce2017-10-15 20:03:24 +020024/*! \addtogroup stats
25 * @{
26 * \file stats_statsd.c */
27
Harald Welte67bdd802017-01-15 17:56:11 +010028#include "config.h"
29#if !defined(EMBEDDED)
30
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +010031#include <osmocom/core/stats.h>
32
33#include <string.h>
34#include <stdint.h>
35#include <errno.h>
36
37#include <osmocom/core/utils.h>
38#include <osmocom/core/logging.h>
39#include <osmocom/core/rate_ctr.h>
40#include <osmocom/core/stat_item.h>
41#include <osmocom/core/msgb.h>
Harald Welte1554f802016-11-11 15:06:06 +010042#include <osmocom/core/stats.h>
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +010043
44static int osmo_stats_reporter_statsd_send_counter(struct osmo_stats_reporter *srep,
45 const struct rate_ctr_group *ctrg,
46 const struct rate_ctr_desc *desc,
47 int64_t value, int64_t delta);
48static int osmo_stats_reporter_statsd_send_item(struct osmo_stats_reporter *srep,
49 const struct osmo_stat_item_group *statg,
Alexander Couzens27a35ed2016-10-04 17:13:58 +020050 const struct osmo_stat_item_desc *desc, int64_t value);
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +010051
Harald Welteeb5b6ce2017-10-15 20:03:24 +020052/*! Create a stats_reporter reporting to statsd. This creates a stats_reporter
53 * instance which reports the related statistics data to statsd.
54 * \param[in] name Name of the to-be-created stats_reporter
55 * \returns stats_reporter on success; NULL on error */
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +010056struct osmo_stats_reporter *osmo_stats_reporter_create_statsd(const char *name)
57{
58 struct osmo_stats_reporter *srep;
59 srep = osmo_stats_reporter_alloc(OSMO_STATS_REPORTER_STATSD, name);
60
61 srep->have_net_config = 1;
62
63 srep->open = osmo_stats_reporter_udp_open;
64 srep->close = osmo_stats_reporter_udp_close;
65 srep->send_counter = osmo_stats_reporter_statsd_send_counter;
66 srep->send_item = osmo_stats_reporter_statsd_send_item;
67
68 return srep;
69}
70
71static int osmo_stats_reporter_statsd_send(struct osmo_stats_reporter *srep,
Alexander Couzens27a35ed2016-10-04 17:13:58 +020072 const char *name1, unsigned int index1, const char *name2, int64_t value,
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +010073 const char *unit)
74{
75 char *buf;
76 int buf_size;
77 int nchars, rc = 0;
78 char *fmt = NULL;
79 char *prefix = srep->name_prefix;
80 int old_len = msgb_length(srep->buffer);
81
82 if (prefix) {
83 if (name1) {
84 if (index1 != 0)
85 fmt = "%1$s.%2$s.%6$u.%3$s:%4$d|%5$s";
86 else
87 fmt = "%1$s.%2$s.%3$s:%4$d|%5$s";
88 } else {
89 fmt = "%1$s.%2$0.0s%3$s:%4$d|%5$s";
90 }
91 } else {
92 prefix = "";
93 if (name1) {
94 if (index1 != 0)
95 fmt = "%1$s%2$s.%6$u.%3$s:%4$d|%5$s";
96 else
97 fmt = "%1$s%2$s.%3$s:%4$d|%5$s";
98 } else {
99 fmt = "%1$s%2$0.0s%3$s:%4$d|%5$s";
100 }
101 }
102
103 if (srep->agg_enabled) {
104 if (msgb_length(srep->buffer) > 0 &&
105 msgb_tailroom(srep->buffer) > 0)
106 {
107 msgb_put_u8(srep->buffer, '\n');
108 }
109 }
110
111 buf = (char *)msgb_put(srep->buffer, 0);
112 buf_size = msgb_tailroom(srep->buffer);
113
114 nchars = snprintf(buf, buf_size, fmt,
115 prefix, name1, name2,
116 value, unit, index1);
117
118 if (nchars >= buf_size) {
119 /* Truncated */
120 /* Restore original buffer (without trailing LF) */
121 msgb_trim(srep->buffer, old_len);
122 /* Send it */
123 rc = osmo_stats_reporter_send_buffer(srep);
124
125 /* Try again */
126 buf = (char *)msgb_put(srep->buffer, 0);
127 buf_size = msgb_tailroom(srep->buffer);
128
129 nchars = snprintf(buf, buf_size, fmt,
130 prefix, name1, name2,
131 value, unit, index1);
132
133 if (nchars >= buf_size)
134 return -EMSGSIZE;
135 }
136
137 if (nchars > 0)
138 msgb_trim(srep->buffer, msgb_length(srep->buffer) + nchars);
139
140 if (!srep->agg_enabled)
141 rc = osmo_stats_reporter_send_buffer(srep);
142
143 return rc;
144}
145
146static int osmo_stats_reporter_statsd_send_counter(struct osmo_stats_reporter *srep,
147 const struct rate_ctr_group *ctrg,
148 const struct rate_ctr_desc *desc,
149 int64_t value, int64_t delta)
150{
151 if (ctrg)
152 return osmo_stats_reporter_statsd_send(srep,
153 ctrg->desc->group_name_prefix,
154 ctrg->idx,
155 desc->name, delta, "c");
156 else
157 return osmo_stats_reporter_statsd_send(srep,
158 NULL, 0,
159 desc->name, delta, "c");
160}
161
162static int osmo_stats_reporter_statsd_send_item(struct osmo_stats_reporter *srep,
163 const struct osmo_stat_item_group *statg,
Alexander Couzens27a35ed2016-10-04 17:13:58 +0200164 const struct osmo_stat_item_desc *desc, int64_t value)
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +0100165{
Holger Hans Peter Freyther5ab8e2c2015-12-17 14:13:22 +0100166 const char *unit = desc->unit;
Jacob Erlbeckaf5bad52015-11-27 18:54:58 +0100167
168 if (unit == OSMO_STAT_ITEM_NO_UNIT) {
169 unit = "g";
170 if (value < 0)
171 osmo_stats_reporter_statsd_send(srep,
172 statg->desc->group_name_prefix,
173 statg->idx,
174 desc->name, 0, unit);
175 }
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +0100176 return osmo_stats_reporter_statsd_send(srep,
177 statg->desc->group_name_prefix,
178 statg->idx,
Jacob Erlbeckaf5bad52015-11-27 18:54:58 +0100179 desc->name, value, unit);
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +0100180}
Harald Welte67bdd802017-01-15 17:56:11 +0100181#endif /* !EMBEDDED */
Harald Welteeb5b6ce2017-10-15 20:03:24 +0200182
183/* @} */