blob: 6e7be735a48ab16d7a2e96042a8ea5601b4e9983 [file] [log] [blame]
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02001/*! \file stats_statsd.c */
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +01002/*
3 * (C) 2015 by Sysmocom s.f.m.c. GmbH
4 *
5 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
6 *
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 *
23 */
24
Harald Welte67bdd802017-01-15 17:56:11 +010025#include "config.h"
26#if !defined(EMBEDDED)
27
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +010028#include <osmocom/core/stats.h>
29
30#include <string.h>
31#include <stdint.h>
32#include <errno.h>
33
34#include <osmocom/core/utils.h>
35#include <osmocom/core/logging.h>
36#include <osmocom/core/rate_ctr.h>
37#include <osmocom/core/stat_item.h>
38#include <osmocom/core/msgb.h>
Harald Welte1554f802016-11-11 15:06:06 +010039#include <osmocom/core/stats.h>
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +010040
41static int osmo_stats_reporter_statsd_send_counter(struct osmo_stats_reporter *srep,
42 const struct rate_ctr_group *ctrg,
43 const struct rate_ctr_desc *desc,
44 int64_t value, int64_t delta);
45static int osmo_stats_reporter_statsd_send_item(struct osmo_stats_reporter *srep,
46 const struct osmo_stat_item_group *statg,
Alexander Couzens27a35ed2016-10-04 17:13:58 +020047 const struct osmo_stat_item_desc *desc, int64_t value);
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +010048
49struct osmo_stats_reporter *osmo_stats_reporter_create_statsd(const char *name)
50{
51 struct osmo_stats_reporter *srep;
52 srep = osmo_stats_reporter_alloc(OSMO_STATS_REPORTER_STATSD, name);
53
54 srep->have_net_config = 1;
55
56 srep->open = osmo_stats_reporter_udp_open;
57 srep->close = osmo_stats_reporter_udp_close;
58 srep->send_counter = osmo_stats_reporter_statsd_send_counter;
59 srep->send_item = osmo_stats_reporter_statsd_send_item;
60
61 return srep;
62}
63
64static int osmo_stats_reporter_statsd_send(struct osmo_stats_reporter *srep,
Alexander Couzens27a35ed2016-10-04 17:13:58 +020065 const char *name1, unsigned int index1, const char *name2, int64_t value,
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +010066 const char *unit)
67{
68 char *buf;
69 int buf_size;
70 int nchars, rc = 0;
71 char *fmt = NULL;
72 char *prefix = srep->name_prefix;
73 int old_len = msgb_length(srep->buffer);
74
75 if (prefix) {
76 if (name1) {
77 if (index1 != 0)
78 fmt = "%1$s.%2$s.%6$u.%3$s:%4$d|%5$s";
79 else
80 fmt = "%1$s.%2$s.%3$s:%4$d|%5$s";
81 } else {
82 fmt = "%1$s.%2$0.0s%3$s:%4$d|%5$s";
83 }
84 } else {
85 prefix = "";
86 if (name1) {
87 if (index1 != 0)
88 fmt = "%1$s%2$s.%6$u.%3$s:%4$d|%5$s";
89 else
90 fmt = "%1$s%2$s.%3$s:%4$d|%5$s";
91 } else {
92 fmt = "%1$s%2$0.0s%3$s:%4$d|%5$s";
93 }
94 }
95
96 if (srep->agg_enabled) {
97 if (msgb_length(srep->buffer) > 0 &&
98 msgb_tailroom(srep->buffer) > 0)
99 {
100 msgb_put_u8(srep->buffer, '\n');
101 }
102 }
103
104 buf = (char *)msgb_put(srep->buffer, 0);
105 buf_size = msgb_tailroom(srep->buffer);
106
107 nchars = snprintf(buf, buf_size, fmt,
108 prefix, name1, name2,
109 value, unit, index1);
110
111 if (nchars >= buf_size) {
112 /* Truncated */
113 /* Restore original buffer (without trailing LF) */
114 msgb_trim(srep->buffer, old_len);
115 /* Send it */
116 rc = osmo_stats_reporter_send_buffer(srep);
117
118 /* Try again */
119 buf = (char *)msgb_put(srep->buffer, 0);
120 buf_size = msgb_tailroom(srep->buffer);
121
122 nchars = snprintf(buf, buf_size, fmt,
123 prefix, name1, name2,
124 value, unit, index1);
125
126 if (nchars >= buf_size)
127 return -EMSGSIZE;
128 }
129
130 if (nchars > 0)
131 msgb_trim(srep->buffer, msgb_length(srep->buffer) + nchars);
132
133 if (!srep->agg_enabled)
134 rc = osmo_stats_reporter_send_buffer(srep);
135
136 return rc;
137}
138
139static int osmo_stats_reporter_statsd_send_counter(struct osmo_stats_reporter *srep,
140 const struct rate_ctr_group *ctrg,
141 const struct rate_ctr_desc *desc,
142 int64_t value, int64_t delta)
143{
144 if (ctrg)
145 return osmo_stats_reporter_statsd_send(srep,
146 ctrg->desc->group_name_prefix,
147 ctrg->idx,
148 desc->name, delta, "c");
149 else
150 return osmo_stats_reporter_statsd_send(srep,
151 NULL, 0,
152 desc->name, delta, "c");
153}
154
155static int osmo_stats_reporter_statsd_send_item(struct osmo_stats_reporter *srep,
156 const struct osmo_stat_item_group *statg,
Alexander Couzens27a35ed2016-10-04 17:13:58 +0200157 const struct osmo_stat_item_desc *desc, int64_t value)
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +0100158{
Holger Hans Peter Freyther5ab8e2c2015-12-17 14:13:22 +0100159 const char *unit = desc->unit;
Jacob Erlbeckaf5bad52015-11-27 18:54:58 +0100160
161 if (unit == OSMO_STAT_ITEM_NO_UNIT) {
162 unit = "g";
163 if (value < 0)
164 osmo_stats_reporter_statsd_send(srep,
165 statg->desc->group_name_prefix,
166 statg->idx,
167 desc->name, 0, unit);
168 }
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +0100169 return osmo_stats_reporter_statsd_send(srep,
170 statg->desc->group_name_prefix,
171 statg->idx,
Jacob Erlbeckaf5bad52015-11-27 18:54:58 +0100172 desc->name, value, unit);
Jacob Erlbeckb6e6bea2015-11-09 15:33:44 +0100173}
Harald Welte67bdd802017-01-15 17:56:11 +0100174#endif /* !EMBEDDED */