blob: 342bb88e29c0a34448d705024478842ea1c08c63 [file] [log] [blame]
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +01001/*
2 * (C) 2015 by Sysmocom s.f.m.c. GmbH
3 *
4 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
5 *
6 * All Rights Reserved
7 *
8 * 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 Welte67bdd802017-01-15 17:56:11 +010024#include "config.h"
25#if !defined(EMBEDDED)
26
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +010027#include <osmocom/core/stats.h>
28
29#include <string.h>
30#include <stdint.h>
31#include <errno.h>
32
33#include <osmocom/core/utils.h>
34#include <osmocom/core/logging.h>
35#include <osmocom/core/rate_ctr.h>
36#include <osmocom/core/stat_item.h>
37#include <osmocom/core/msgb.h>
Harald Welte1554f802016-11-11 15:06:06 +010038#include <osmocom/core/stats.h>
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +010039
40static int osmo_stats_reporter_statsd_send_counter(struct osmo_stats_reporter *srep,
41 const struct rate_ctr_group *ctrg,
42 const struct rate_ctr_desc *desc,
43 int64_t value, int64_t delta);
44static int osmo_stats_reporter_statsd_send_item(struct osmo_stats_reporter *srep,
45 const struct osmo_stat_item_group *statg,
Alexander Couzens27a35ed2016-10-04 17:13:58 +020046 const struct osmo_stat_item_desc *desc, int64_t value);
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +010047
48struct osmo_stats_reporter *osmo_stats_reporter_create_statsd(const char *name)
49{
50 struct osmo_stats_reporter *srep;
51 srep = osmo_stats_reporter_alloc(OSMO_STATS_REPORTER_STATSD, name);
52
53 srep->have_net_config = 1;
54
55 srep->open = osmo_stats_reporter_udp_open;
56 srep->close = osmo_stats_reporter_udp_close;
57 srep->send_counter = osmo_stats_reporter_statsd_send_counter;
58 srep->send_item = osmo_stats_reporter_statsd_send_item;
59
60 return srep;
61}
62
63static int osmo_stats_reporter_statsd_send(struct osmo_stats_reporter *srep,
Alexander Couzens27a35ed2016-10-04 17:13:58 +020064 const char *name1, unsigned int index1, const char *name2, int64_t value,
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +010065 const char *unit)
66{
67 char *buf;
68 int buf_size;
69 int nchars, rc = 0;
70 char *fmt = NULL;
71 char *prefix = srep->name_prefix;
72 int old_len = msgb_length(srep->buffer);
73
74 if (prefix) {
75 if (name1) {
76 if (index1 != 0)
77 fmt = "%1$s.%2$s.%6$u.%3$s:%4$d|%5$s";
78 else
79 fmt = "%1$s.%2$s.%3$s:%4$d|%5$s";
80 } else {
81 fmt = "%1$s.%2$0.0s%3$s:%4$d|%5$s";
82 }
83 } else {
84 prefix = "";
85 if (name1) {
86 if (index1 != 0)
87 fmt = "%1$s%2$s.%6$u.%3$s:%4$d|%5$s";
88 else
89 fmt = "%1$s%2$s.%3$s:%4$d|%5$s";
90 } else {
91 fmt = "%1$s%2$0.0s%3$s:%4$d|%5$s";
92 }
93 }
94
95 if (srep->agg_enabled) {
96 if (msgb_length(srep->buffer) > 0 &&
97 msgb_tailroom(srep->buffer) > 0)
98 {
99 msgb_put_u8(srep->buffer, '\n');
100 }
101 }
102
103 buf = (char *)msgb_put(srep->buffer, 0);
104 buf_size = msgb_tailroom(srep->buffer);
105
106 nchars = snprintf(buf, buf_size, fmt,
107 prefix, name1, name2,
108 value, unit, index1);
109
110 if (nchars >= buf_size) {
111 /* Truncated */
112 /* Restore original buffer (without trailing LF) */
113 msgb_trim(srep->buffer, old_len);
114 /* Send it */
115 rc = osmo_stats_reporter_send_buffer(srep);
116
117 /* Try again */
118 buf = (char *)msgb_put(srep->buffer, 0);
119 buf_size = msgb_tailroom(srep->buffer);
120
121 nchars = snprintf(buf, buf_size, fmt,
122 prefix, name1, name2,
123 value, unit, index1);
124
125 if (nchars >= buf_size)
126 return -EMSGSIZE;
127 }
128
129 if (nchars > 0)
130 msgb_trim(srep->buffer, msgb_length(srep->buffer) + nchars);
131
132 if (!srep->agg_enabled)
133 rc = osmo_stats_reporter_send_buffer(srep);
134
135 return rc;
136}
137
138static int osmo_stats_reporter_statsd_send_counter(struct osmo_stats_reporter *srep,
139 const struct rate_ctr_group *ctrg,
140 const struct rate_ctr_desc *desc,
141 int64_t value, int64_t delta)
142{
143 if (ctrg)
144 return osmo_stats_reporter_statsd_send(srep,
145 ctrg->desc->group_name_prefix,
146 ctrg->idx,
147 desc->name, delta, "c");
148 else
149 return osmo_stats_reporter_statsd_send(srep,
150 NULL, 0,
151 desc->name, delta, "c");
152}
153
154static int osmo_stats_reporter_statsd_send_item(struct osmo_stats_reporter *srep,
155 const struct osmo_stat_item_group *statg,
Alexander Couzens27a35ed2016-10-04 17:13:58 +0200156 const struct osmo_stat_item_desc *desc, int64_t value)
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +0100157{
Holger Hans Peter Freyther5ab8e2c2015-12-17 14:13:22 +0100158 const char *unit = desc->unit;
Jacob Erlbeckaf5bad52015-11-27 18:54:58 +0100159
160 if (unit == OSMO_STAT_ITEM_NO_UNIT) {
161 unit = "g";
162 if (value < 0)
163 osmo_stats_reporter_statsd_send(srep,
164 statg->desc->group_name_prefix,
165 statg->idx,
166 desc->name, 0, unit);
167 }
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +0100168 return osmo_stats_reporter_statsd_send(srep,
169 statg->desc->group_name_prefix,
170 statg->idx,
Jacob Erlbeckaf5bad52015-11-27 18:54:58 +0100171 desc->name, value, unit);
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +0100172}
Harald Welte67bdd802017-01-15 17:56:11 +0100173#endif /* !EMBEDDED */