docs: Add supported versions and fix-backport policy
[lttng-tools.git] / src / bin / lttng / loglevel.cpp
CommitLineData
7e8f2e9c
JG
1/*
2 * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
c9e313bc 8#include "loglevel.hpp"
28ab034a
JG
9
10#include <ctype.h>
7e8f2e9c 11#include <string.h>
f41294ed 12#include <strings.h>
7e8f2e9c 13
f1494934 14namespace {
7e8f2e9c
JG
15struct loglevel_name_value {
16 const char *name;
17 int value;
18};
f1494934 19} /* namespace */
7e8f2e9c 20
28ab034a 21static const struct loglevel_name_value loglevel_values[] = {
7e8f2e9c 22 { .name = "EMERG", .value = LTTNG_LOGLEVEL_EMERG },
85b05318 23 { .name = "TRACE_EMERG", .value = LTTNG_LOGLEVEL_EMERG },
7e8f2e9c 24 { .name = "ALERT", .value = LTTNG_LOGLEVEL_ALERT },
85b05318 25 { .name = "TRACE_ALERT", .value = LTTNG_LOGLEVEL_ALERT },
7e8f2e9c 26 { .name = "CRIT", .value = LTTNG_LOGLEVEL_CRIT },
85b05318 27 { .name = "TRACE_CRIT", .value = LTTNG_LOGLEVEL_CRIT },
7e8f2e9c 28 { .name = "ERR", .value = LTTNG_LOGLEVEL_ERR },
85b05318 29 { .name = "TRACE_ERR", .value = LTTNG_LOGLEVEL_ERR },
7e8f2e9c 30 { .name = "WARNING", .value = LTTNG_LOGLEVEL_WARNING },
85b05318 31 { .name = "TRACE_WARNING", .value = LTTNG_LOGLEVEL_WARNING },
7e8f2e9c 32 { .name = "NOTICE", .value = LTTNG_LOGLEVEL_NOTICE },
85b05318 33 { .name = "TRACE_NOTICE", .value = LTTNG_LOGLEVEL_NOTICE },
7e8f2e9c 34 { .name = "INFO", .value = LTTNG_LOGLEVEL_INFO },
85b05318 35 { .name = "TRACE_INFO", .value = LTTNG_LOGLEVEL_INFO },
7e8f2e9c 36 { .name = "DEBUG_SYSTEM", .value = LTTNG_LOGLEVEL_DEBUG_SYSTEM },
85b05318 37 { .name = "TRACE_DEBUG_SYSTEM", .value = LTTNG_LOGLEVEL_DEBUG_SYSTEM },
7e8f2e9c 38 { .name = "SYSTEM", .value = LTTNG_LOGLEVEL_DEBUG_SYSTEM },
7e8f2e9c 39 { .name = "DEBUG_PROGRAM", .value = LTTNG_LOGLEVEL_DEBUG_PROGRAM },
85b05318 40 { .name = "TRACE_DEBUG_PROGRAM", .value = LTTNG_LOGLEVEL_DEBUG_PROGRAM },
7e8f2e9c 41 { .name = "PROGRAM", .value = LTTNG_LOGLEVEL_DEBUG_PROGRAM },
7e8f2e9c 42 { .name = "DEBUG_PROCESS", .value = LTTNG_LOGLEVEL_DEBUG_PROCESS },
85b05318 43 { .name = "TRACE_DEBUG_PROCESS", .value = LTTNG_LOGLEVEL_DEBUG_PROCESS },
7e8f2e9c 44 { .name = "PROCESS", .value = LTTNG_LOGLEVEL_DEBUG_PROCESS },
7e8f2e9c 45 { .name = "DEBUG_MODULE", .value = LTTNG_LOGLEVEL_DEBUG_MODULE },
85b05318 46 { .name = "TRACE_DEBUG_MODULE", .value = LTTNG_LOGLEVEL_DEBUG_MODULE },
7e8f2e9c 47 { .name = "MODULE", .value = LTTNG_LOGLEVEL_DEBUG_MODULE },
7e8f2e9c 48 { .name = "DEBUG_UNIT", .value = LTTNG_LOGLEVEL_DEBUG_UNIT },
85b05318 49 { .name = "TRACE_DEBUG_UNIT", .value = LTTNG_LOGLEVEL_DEBUG_UNIT },
7e8f2e9c 50 { .name = "UNIT", .value = LTTNG_LOGLEVEL_DEBUG_UNIT },
7e8f2e9c 51 { .name = "DEBUG_FUNCTION", .value = LTTNG_LOGLEVEL_DEBUG_FUNCTION },
85b05318 52 { .name = "TRACE_DEBUG_FUNCTION", .value = LTTNG_LOGLEVEL_DEBUG_FUNCTION },
7e8f2e9c 53 { .name = "FUNCTION", .value = LTTNG_LOGLEVEL_DEBUG_FUNCTION },
7e8f2e9c 54 { .name = "DEBUG_LINE", .value = LTTNG_LOGLEVEL_DEBUG_LINE },
85b05318 55 { .name = "TRACE_DEBUG_LINE", .value = LTTNG_LOGLEVEL_DEBUG_LINE },
7e8f2e9c 56 { .name = "LINE", .value = LTTNG_LOGLEVEL_DEBUG_LINE },
7e8f2e9c 57 { .name = "DEBUG", .value = LTTNG_LOGLEVEL_DEBUG },
85b05318 58 { .name = "TRACE_DEBUG", .value = LTTNG_LOGLEVEL_DEBUG },
7e8f2e9c
JG
59};
60
28ab034a 61static const struct loglevel_name_value loglevel_log4j_values[] = {
7e8f2e9c 62 { .name = "OFF", .value = LTTNG_LOGLEVEL_LOG4J_OFF },
85b05318 63 { .name = "LOG4J_OFF", .value = LTTNG_LOGLEVEL_LOG4J_OFF },
7e8f2e9c 64 { .name = "FATAL", .value = LTTNG_LOGLEVEL_LOG4J_FATAL },
85b05318 65 { .name = "LOG4J_FATAL", .value = LTTNG_LOGLEVEL_LOG4J_FATAL },
7e8f2e9c 66 { .name = "ERROR", .value = LTTNG_LOGLEVEL_LOG4J_ERROR },
85b05318 67 { .name = "LOG4J_ERROR", .value = LTTNG_LOGLEVEL_LOG4J_ERROR },
7e8f2e9c 68 { .name = "WARN", .value = LTTNG_LOGLEVEL_LOG4J_WARN },
85b05318 69 { .name = "LOG4J_WARN", .value = LTTNG_LOGLEVEL_LOG4J_WARN },
7e8f2e9c 70 { .name = "INFO", .value = LTTNG_LOGLEVEL_LOG4J_INFO },
85b05318 71 { .name = "LOG4J_INFO", .value = LTTNG_LOGLEVEL_LOG4J_INFO },
7e8f2e9c 72 { .name = "DEBUG", .value = LTTNG_LOGLEVEL_LOG4J_DEBUG },
85b05318 73 { .name = "LOG4J_DEBUG", .value = LTTNG_LOGLEVEL_LOG4J_DEBUG },
7e8f2e9c 74 { .name = "TRACE", .value = LTTNG_LOGLEVEL_LOG4J_TRACE },
85b05318 75 { .name = "LOG4J_TRACE", .value = LTTNG_LOGLEVEL_LOG4J_TRACE },
7e8f2e9c 76 { .name = "ALL", .value = LTTNG_LOGLEVEL_LOG4J_ALL },
85b05318 77 { .name = "LOG4J_ALL", .value = LTTNG_LOGLEVEL_LOG4J_ALL },
7e8f2e9c
JG
78};
79
28ab034a 80static const struct loglevel_name_value loglevel_jul_values[] = {
7e8f2e9c 81 { .name = "OFF", .value = LTTNG_LOGLEVEL_JUL_OFF },
85b05318 82 { .name = "JUL_OFF", .value = LTTNG_LOGLEVEL_JUL_OFF },
7e8f2e9c 83 { .name = "SEVERE", .value = LTTNG_LOGLEVEL_JUL_SEVERE },
85b05318 84 { .name = "JUL_SEVERE", .value = LTTNG_LOGLEVEL_JUL_SEVERE },
7e8f2e9c 85 { .name = "WARNING", .value = LTTNG_LOGLEVEL_JUL_WARNING },
85b05318 86 { .name = "JUL_WARNING", .value = LTTNG_LOGLEVEL_JUL_WARNING },
7e8f2e9c 87 { .name = "INFO", .value = LTTNG_LOGLEVEL_JUL_INFO },
85b05318 88 { .name = "JUL_INFO", .value = LTTNG_LOGLEVEL_JUL_INFO },
7e8f2e9c 89 { .name = "CONFIG", .value = LTTNG_LOGLEVEL_JUL_CONFIG },
85b05318 90 { .name = "JUL_CONFIG", .value = LTTNG_LOGLEVEL_JUL_CONFIG },
7e8f2e9c 91 { .name = "FINE", .value = LTTNG_LOGLEVEL_JUL_FINE },
85b05318 92 { .name = "JUL_FINE", .value = LTTNG_LOGLEVEL_JUL_FINE },
7e8f2e9c 93 { .name = "FINER", .value = LTTNG_LOGLEVEL_JUL_FINER },
85b05318 94 { .name = "JUL_FINER", .value = LTTNG_LOGLEVEL_JUL_FINER },
7e8f2e9c 95 { .name = "FINEST", .value = LTTNG_LOGLEVEL_JUL_FINEST },
85b05318 96 { .name = "JUL_FINEST", .value = LTTNG_LOGLEVEL_JUL_FINEST },
7e8f2e9c 97 { .name = "ALL", .value = LTTNG_LOGLEVEL_JUL_ALL },
85b05318 98 { .name = "JUL_ALL", .value = LTTNG_LOGLEVEL_JUL_ALL },
7e8f2e9c
JG
99};
100
28ab034a 101static const struct loglevel_name_value loglevel_python_values[] = {
7e8f2e9c 102 { .name = "CRITICAL", .value = LTTNG_LOGLEVEL_PYTHON_CRITICAL },
85b05318 103 { .name = "PYTHON_CRITICAL", .value = LTTNG_LOGLEVEL_PYTHON_CRITICAL },
7e8f2e9c 104 { .name = "ERROR", .value = LTTNG_LOGLEVEL_PYTHON_ERROR },
85b05318 105 { .name = "PYTHON_ERROR", .value = LTTNG_LOGLEVEL_PYTHON_ERROR },
7e8f2e9c 106 { .name = "WARNING", .value = LTTNG_LOGLEVEL_PYTHON_WARNING },
85b05318 107 { .name = "PYTHON_WARNING", .value = LTTNG_LOGLEVEL_PYTHON_WARNING },
7e8f2e9c 108 { .name = "INFO", .value = LTTNG_LOGLEVEL_PYTHON_INFO },
85b05318 109 { .name = "PYTHON_INFO", .value = LTTNG_LOGLEVEL_PYTHON_INFO },
7e8f2e9c 110 { .name = "DEBUG", .value = LTTNG_LOGLEVEL_PYTHON_DEBUG },
85b05318 111 { .name = "PYTNON_DEBUG", .value = LTTNG_LOGLEVEL_PYTHON_DEBUG },
7e8f2e9c 112 { .name = "NOTSET", .value = LTTNG_LOGLEVEL_PYTHON_NOTSET },
85b05318 113 { .name = "PYTHON_NOTSET", .value = LTTNG_LOGLEVEL_PYTHON_NOTSET },
7e8f2e9c
JG
114};
115
28ab034a 116static bool string_equal_insensitive(const char *a, const char *b)
7e8f2e9c 117{
f41294ed 118 return strcasecmp(a, b) == 0;
7e8f2e9c
JG
119}
120
28ab034a
JG
121static int lookup_value_from_name(const struct loglevel_name_value values[],
122 size_t values_count,
123 const char *name)
7e8f2e9c
JG
124{
125 size_t i;
126 int ret = -1;
127
128 if (!name) {
129 goto end;
130 }
131
132 for (i = 0; i < values_count; i++) {
133 if (string_equal_insensitive(values[i].name, name)) {
134 /* Match found. */
135 ret = values[i].value;
136 goto end;
137 }
138 }
139
140end:
141 return ret;
142}
143
949f049b 144static bool loglevel_parse_range_string_common(const char *str,
28ab034a
JG
145 const struct loglevel_name_value *nvs,
146 size_t nvs_count,
147 int *min,
148 int *max)
949f049b
SM
149{
150 bool ret;
151 int i;
152 const struct loglevel_name_value *nv;
153
154 for (i = 0; i < nvs_count; i++) {
155 nv = &nvs[i];
156
157 if (strncmp(str, nv->name, strlen(nv->name)) == 0) {
158 break;
159 }
160 }
161
162 if (i == nvs_count) {
163 goto error;
164 }
165
166 *min = nv->value;
167 str += strlen(nv->name);
168
169 if (*str == '\0') {
170 *max = nv->value;
171 ret = true;
172 goto end;
173 }
174
175 if (strncmp(str, "..", strlen("..")) != 0) {
176 goto error;
177 }
178
179 str += strlen("..");
180
181 if (*str == '\0') {
182 *max = LTTNG_LOGLEVEL_EMERG;
183 ret = true;
184 goto end;
185 }
186
187 for (i = 0; i < nvs_count; i++) {
188 nv = &nvs[i];
189
190 if (strcmp(str, nv->name) == 0) {
191 break;
192 }
193 }
194
195 if (i == nvs_count) {
196 goto error;
197 }
198
199 *max = nv->value;
200
201 ret = true;
202 goto end;
203
204error:
205 ret = false;
206
207end:
208 return ret;
209}
210
7e8f2e9c
JG
211int loglevel_name_to_value(const char *name, enum lttng_loglevel *loglevel)
212{
28ab034a 213 int ret = lookup_value_from_name(loglevel_values, ARRAY_SIZE(loglevel_values), name);
7e8f2e9c
JG
214
215 if (ret >= 0) {
216 *loglevel = (typeof(*loglevel)) ret;
217 ret = 0;
218 }
219
220 return ret;
221}
222
949f049b 223bool loglevel_parse_range_string(const char *str,
28ab034a
JG
224 enum lttng_loglevel *min,
225 enum lttng_loglevel *max)
949f049b
SM
226{
227 int min_int, max_int;
28ab034a
JG
228 bool ret = loglevel_parse_range_string_common(
229 str, loglevel_values, ARRAY_SIZE(loglevel_values), &min_int, &max_int);
949f049b 230
48a40005
SM
231 *min = (lttng_loglevel) min_int;
232 *max = (lttng_loglevel) max_int;
949f049b
SM
233
234 return ret;
235}
236
28ab034a 237int loglevel_log4j_name_to_value(const char *name, enum lttng_loglevel_log4j *loglevel)
7e8f2e9c 238{
28ab034a
JG
239 int ret = lookup_value_from_name(
240 loglevel_log4j_values, ARRAY_SIZE(loglevel_log4j_values), name);
7e8f2e9c
JG
241
242 if (ret >= 0) {
243 *loglevel = (typeof(*loglevel)) ret;
244 ret = 0;
245 }
246
247 return ret;
248}
249
949f049b 250bool loglevel_log4j_parse_range_string(const char *str,
28ab034a
JG
251 enum lttng_loglevel_log4j *min,
252 enum lttng_loglevel_log4j *max)
949f049b
SM
253{
254 int min_int, max_int;
28ab034a
JG
255 bool ret = loglevel_parse_range_string_common(
256 str, loglevel_log4j_values, ARRAY_SIZE(loglevel_log4j_values), &min_int, &max_int);
949f049b 257
48a40005
SM
258 *min = (lttng_loglevel_log4j) min_int;
259 *max = (lttng_loglevel_log4j) max_int;
949f049b
SM
260
261 return ret;
262}
263
28ab034a 264int loglevel_jul_name_to_value(const char *name, enum lttng_loglevel_jul *loglevel)
7e8f2e9c 265{
28ab034a
JG
266 int ret =
267 lookup_value_from_name(loglevel_jul_values, ARRAY_SIZE(loglevel_jul_values), name);
7e8f2e9c
JG
268
269 if (ret >= 0) {
270 *loglevel = (typeof(*loglevel)) ret;
271 ret = 0;
272 }
273
274 return ret;
275}
276
949f049b 277bool loglevel_jul_parse_range_string(const char *str,
28ab034a
JG
278 enum lttng_loglevel_jul *min,
279 enum lttng_loglevel_jul *max)
949f049b
SM
280{
281 int min_int, max_int;
28ab034a
JG
282 bool ret = loglevel_parse_range_string_common(
283 str, loglevel_jul_values, ARRAY_SIZE(loglevel_jul_values), &min_int, &max_int);
949f049b 284
48a40005
SM
285 *min = (lttng_loglevel_jul) min_int;
286 *max = (lttng_loglevel_jul) max_int;
949f049b
SM
287
288 return ret;
289}
290
28ab034a 291int loglevel_python_name_to_value(const char *name, enum lttng_loglevel_python *loglevel)
7e8f2e9c 292{
28ab034a
JG
293 int ret = lookup_value_from_name(
294 loglevel_python_values, ARRAY_SIZE(loglevel_python_values), name);
7e8f2e9c
JG
295
296 if (ret >= 0) {
297 *loglevel = (typeof(*loglevel)) ret;
298 ret = 0;
299 }
300
949f049b
SM
301 return ret;
302}
303
949f049b 304bool loglevel_python_parse_range_string(const char *str,
28ab034a
JG
305 enum lttng_loglevel_python *min,
306 enum lttng_loglevel_python *max)
949f049b
SM
307{
308 int min_int, max_int;
309 bool ret = loglevel_parse_range_string_common(str,
28ab034a
JG
310 loglevel_python_values,
311 ARRAY_SIZE(loglevel_python_values),
312 &min_int,
313 &max_int);
949f049b 314
48a40005
SM
315 *min = (lttng_loglevel_python) min_int;
316 *max = (lttng_loglevel_python) max_int;
949f049b 317
7e8f2e9c 318 return ret;
00608d5a 319}
85b05318 320
28ab034a
JG
321static const char *
322lookup_name_from_value(const struct loglevel_name_value values[], size_t values_count, int loglevel)
85b05318
JR
323{
324 size_t i;
cd9adb8b 325 const char *name = nullptr;
85b05318
JR
326
327 for (i = 0; i < values_count; i++) {
328 if (values[i].value == loglevel) {
329 /* Match found. */
330 name = values[i].name;
331 goto end;
332 }
333 }
334
335end:
336 return name;
337}
338
85b05318
JR
339const char *loglevel_value_to_name(int loglevel)
340{
28ab034a 341 return lookup_name_from_value(loglevel_values, ARRAY_SIZE(loglevel_values), loglevel);
85b05318
JR
342}
343
85b05318
JR
344const char *loglevel_log4j_value_to_name(int loglevel)
345{
28ab034a
JG
346 return lookup_name_from_value(
347 loglevel_log4j_values, ARRAY_SIZE(loglevel_log4j_values), loglevel);
85b05318
JR
348}
349
85b05318
JR
350const char *loglevel_jul_value_to_name(int loglevel)
351{
28ab034a
JG
352 return lookup_name_from_value(
353 loglevel_jul_values, ARRAY_SIZE(loglevel_jul_values), loglevel);
85b05318
JR
354}
355
85b05318
JR
356const char *loglevel_python_value_to_name(int loglevel)
357{
28ab034a
JG
358 return lookup_name_from_value(
359 loglevel_python_values, ARRAY_SIZE(loglevel_python_values), loglevel);
85b05318 360}
This page took 0.062811 seconds and 4 git commands to generate.