2 * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
8 #include "loglevel.hpp"
15 struct loglevel_name_value
{
21 static const struct loglevel_name_value loglevel_values
[] = {
22 { .name
= "EMERG", .value
= LTTNG_LOGLEVEL_EMERG
},
23 { .name
= "TRACE_EMERG", .value
= LTTNG_LOGLEVEL_EMERG
},
24 { .name
= "ALERT", .value
= LTTNG_LOGLEVEL_ALERT
},
25 { .name
= "TRACE_ALERT", .value
= LTTNG_LOGLEVEL_ALERT
},
26 { .name
= "CRIT", .value
= LTTNG_LOGLEVEL_CRIT
},
27 { .name
= "TRACE_CRIT", .value
= LTTNG_LOGLEVEL_CRIT
},
28 { .name
= "ERR", .value
= LTTNG_LOGLEVEL_ERR
},
29 { .name
= "TRACE_ERR", .value
= LTTNG_LOGLEVEL_ERR
},
30 { .name
= "WARNING", .value
= LTTNG_LOGLEVEL_WARNING
},
31 { .name
= "TRACE_WARNING", .value
= LTTNG_LOGLEVEL_WARNING
},
32 { .name
= "NOTICE", .value
= LTTNG_LOGLEVEL_NOTICE
},
33 { .name
= "TRACE_NOTICE", .value
= LTTNG_LOGLEVEL_NOTICE
},
34 { .name
= "INFO", .value
= LTTNG_LOGLEVEL_INFO
},
35 { .name
= "TRACE_INFO", .value
= LTTNG_LOGLEVEL_INFO
},
36 { .name
= "DEBUG_SYSTEM", .value
= LTTNG_LOGLEVEL_DEBUG_SYSTEM
},
37 { .name
= "TRACE_DEBUG_SYSTEM", .value
= LTTNG_LOGLEVEL_DEBUG_SYSTEM
},
38 { .name
= "SYSTEM", .value
= LTTNG_LOGLEVEL_DEBUG_SYSTEM
},
39 { .name
= "DEBUG_PROGRAM", .value
= LTTNG_LOGLEVEL_DEBUG_PROGRAM
},
40 { .name
= "TRACE_DEBUG_PROGRAM", .value
= LTTNG_LOGLEVEL_DEBUG_PROGRAM
},
41 { .name
= "PROGRAM", .value
= LTTNG_LOGLEVEL_DEBUG_PROGRAM
},
42 { .name
= "DEBUG_PROCESS", .value
= LTTNG_LOGLEVEL_DEBUG_PROCESS
},
43 { .name
= "TRACE_DEBUG_PROCESS", .value
= LTTNG_LOGLEVEL_DEBUG_PROCESS
},
44 { .name
= "PROCESS", .value
= LTTNG_LOGLEVEL_DEBUG_PROCESS
},
45 { .name
= "DEBUG_MODULE", .value
= LTTNG_LOGLEVEL_DEBUG_MODULE
},
46 { .name
= "TRACE_DEBUG_MODULE", .value
= LTTNG_LOGLEVEL_DEBUG_MODULE
},
47 { .name
= "MODULE", .value
= LTTNG_LOGLEVEL_DEBUG_MODULE
},
48 { .name
= "DEBUG_UNIT", .value
= LTTNG_LOGLEVEL_DEBUG_UNIT
},
49 { .name
= "TRACE_DEBUG_UNIT", .value
= LTTNG_LOGLEVEL_DEBUG_UNIT
},
50 { .name
= "UNIT", .value
= LTTNG_LOGLEVEL_DEBUG_UNIT
},
51 { .name
= "DEBUG_FUNCTION", .value
= LTTNG_LOGLEVEL_DEBUG_FUNCTION
},
52 { .name
= "TRACE_DEBUG_FUNCTION", .value
= LTTNG_LOGLEVEL_DEBUG_FUNCTION
},
53 { .name
= "FUNCTION", .value
= LTTNG_LOGLEVEL_DEBUG_FUNCTION
},
54 { .name
= "DEBUG_LINE", .value
= LTTNG_LOGLEVEL_DEBUG_LINE
},
55 { .name
= "TRACE_DEBUG_LINE", .value
= LTTNG_LOGLEVEL_DEBUG_LINE
},
56 { .name
= "LINE", .value
= LTTNG_LOGLEVEL_DEBUG_LINE
},
57 { .name
= "DEBUG", .value
= LTTNG_LOGLEVEL_DEBUG
},
58 { .name
= "TRACE_DEBUG", .value
= LTTNG_LOGLEVEL_DEBUG
},
61 static const struct loglevel_name_value loglevel_log4j_values
[] = {
62 { .name
= "OFF", .value
= LTTNG_LOGLEVEL_LOG4J_OFF
},
63 { .name
= "LOG4J_OFF", .value
= LTTNG_LOGLEVEL_LOG4J_OFF
},
64 { .name
= "FATAL", .value
= LTTNG_LOGLEVEL_LOG4J_FATAL
},
65 { .name
= "LOG4J_FATAL", .value
= LTTNG_LOGLEVEL_LOG4J_FATAL
},
66 { .name
= "ERROR", .value
= LTTNG_LOGLEVEL_LOG4J_ERROR
},
67 { .name
= "LOG4J_ERROR", .value
= LTTNG_LOGLEVEL_LOG4J_ERROR
},
68 { .name
= "WARN", .value
= LTTNG_LOGLEVEL_LOG4J_WARN
},
69 { .name
= "LOG4J_WARN", .value
= LTTNG_LOGLEVEL_LOG4J_WARN
},
70 { .name
= "INFO", .value
= LTTNG_LOGLEVEL_LOG4J_INFO
},
71 { .name
= "LOG4J_INFO", .value
= LTTNG_LOGLEVEL_LOG4J_INFO
},
72 { .name
= "DEBUG", .value
= LTTNG_LOGLEVEL_LOG4J_DEBUG
},
73 { .name
= "LOG4J_DEBUG", .value
= LTTNG_LOGLEVEL_LOG4J_DEBUG
},
74 { .name
= "TRACE", .value
= LTTNG_LOGLEVEL_LOG4J_TRACE
},
75 { .name
= "LOG4J_TRACE", .value
= LTTNG_LOGLEVEL_LOG4J_TRACE
},
76 { .name
= "ALL", .value
= LTTNG_LOGLEVEL_LOG4J_ALL
},
77 { .name
= "LOG4J_ALL", .value
= LTTNG_LOGLEVEL_LOG4J_ALL
},
80 static const struct loglevel_name_value loglevel_log4j2_values
[] = {
81 { .name
= "OFF", .value
= LTTNG_LOGLEVEL_LOG4J2_OFF
},
82 { .name
= "LOG4J2_OFF", .value
= LTTNG_LOGLEVEL_LOG4J2_OFF
},
83 { .name
= "FATAL", .value
= LTTNG_LOGLEVEL_LOG4J2_FATAL
},
84 { .name
= "LOG4J2_FATAL", .value
= LTTNG_LOGLEVEL_LOG4J2_FATAL
},
85 { .name
= "ERROR", .value
= LTTNG_LOGLEVEL_LOG4J2_ERROR
},
86 { .name
= "LOG4J2_ERROR", .value
= LTTNG_LOGLEVEL_LOG4J2_ERROR
},
87 { .name
= "WARN", .value
= LTTNG_LOGLEVEL_LOG4J2_WARN
},
88 { .name
= "LOG4J2_WARN", .value
= LTTNG_LOGLEVEL_LOG4J2_WARN
},
89 { .name
= "INFO", .value
= LTTNG_LOGLEVEL_LOG4J2_INFO
},
90 { .name
= "LOG4J2_INFO", .value
= LTTNG_LOGLEVEL_LOG4J2_INFO
},
91 { .name
= "DEBUG", .value
= LTTNG_LOGLEVEL_LOG4J2_DEBUG
},
92 { .name
= "LOG4J2_DEBUG", .value
= LTTNG_LOGLEVEL_LOG4J2_DEBUG
},
93 { .name
= "TRACE", .value
= LTTNG_LOGLEVEL_LOG4J2_TRACE
},
94 { .name
= "LOG4J2_TRACE", .value
= LTTNG_LOGLEVEL_LOG4J2_TRACE
},
95 { .name
= "ALL", .value
= LTTNG_LOGLEVEL_LOG4J2_ALL
},
96 { .name
= "LOG4J2_ALL", .value
= LTTNG_LOGLEVEL_LOG4J2_ALL
},
99 static const struct loglevel_name_value loglevel_jul_values
[] = {
100 { .name
= "OFF", .value
= LTTNG_LOGLEVEL_JUL_OFF
},
101 { .name
= "JUL_OFF", .value
= LTTNG_LOGLEVEL_JUL_OFF
},
102 { .name
= "SEVERE", .value
= LTTNG_LOGLEVEL_JUL_SEVERE
},
103 { .name
= "JUL_SEVERE", .value
= LTTNG_LOGLEVEL_JUL_SEVERE
},
104 { .name
= "WARNING", .value
= LTTNG_LOGLEVEL_JUL_WARNING
},
105 { .name
= "JUL_WARNING", .value
= LTTNG_LOGLEVEL_JUL_WARNING
},
106 { .name
= "INFO", .value
= LTTNG_LOGLEVEL_JUL_INFO
},
107 { .name
= "JUL_INFO", .value
= LTTNG_LOGLEVEL_JUL_INFO
},
108 { .name
= "CONFIG", .value
= LTTNG_LOGLEVEL_JUL_CONFIG
},
109 { .name
= "JUL_CONFIG", .value
= LTTNG_LOGLEVEL_JUL_CONFIG
},
110 { .name
= "FINE", .value
= LTTNG_LOGLEVEL_JUL_FINE
},
111 { .name
= "JUL_FINE", .value
= LTTNG_LOGLEVEL_JUL_FINE
},
112 { .name
= "FINER", .value
= LTTNG_LOGLEVEL_JUL_FINER
},
113 { .name
= "JUL_FINER", .value
= LTTNG_LOGLEVEL_JUL_FINER
},
114 { .name
= "FINEST", .value
= LTTNG_LOGLEVEL_JUL_FINEST
},
115 { .name
= "JUL_FINEST", .value
= LTTNG_LOGLEVEL_JUL_FINEST
},
116 { .name
= "ALL", .value
= LTTNG_LOGLEVEL_JUL_ALL
},
117 { .name
= "JUL_ALL", .value
= LTTNG_LOGLEVEL_JUL_ALL
},
120 static const struct loglevel_name_value loglevel_python_values
[] = {
121 { .name
= "CRITICAL", .value
= LTTNG_LOGLEVEL_PYTHON_CRITICAL
},
122 { .name
= "PYTHON_CRITICAL", .value
= LTTNG_LOGLEVEL_PYTHON_CRITICAL
},
123 { .name
= "ERROR", .value
= LTTNG_LOGLEVEL_PYTHON_ERROR
},
124 { .name
= "PYTHON_ERROR", .value
= LTTNG_LOGLEVEL_PYTHON_ERROR
},
125 { .name
= "WARNING", .value
= LTTNG_LOGLEVEL_PYTHON_WARNING
},
126 { .name
= "PYTHON_WARNING", .value
= LTTNG_LOGLEVEL_PYTHON_WARNING
},
127 { .name
= "INFO", .value
= LTTNG_LOGLEVEL_PYTHON_INFO
},
128 { .name
= "PYTHON_INFO", .value
= LTTNG_LOGLEVEL_PYTHON_INFO
},
129 { .name
= "DEBUG", .value
= LTTNG_LOGLEVEL_PYTHON_DEBUG
},
130 { .name
= "PYTNON_DEBUG", .value
= LTTNG_LOGLEVEL_PYTHON_DEBUG
},
131 { .name
= "NOTSET", .value
= LTTNG_LOGLEVEL_PYTHON_NOTSET
},
132 { .name
= "PYTHON_NOTSET", .value
= LTTNG_LOGLEVEL_PYTHON_NOTSET
},
135 static bool string_equal_insensitive(const char *a
, const char *b
)
137 return strcasecmp(a
, b
) == 0;
140 static int lookup_value_from_name(const struct loglevel_name_value values
[],
151 for (i
= 0; i
< values_count
; i
++) {
152 if (string_equal_insensitive(values
[i
].name
, name
)) {
154 ret
= values
[i
].value
;
163 static bool loglevel_parse_range_string_common(const char *str
,
164 const struct loglevel_name_value
*nvs
,
166 int default_most_severe
,
172 const struct loglevel_name_value
*nv
;
175 * Look for a valid loglevel name value at the beginning of 'str'.
177 for (i
= 0; i
< nvs_count
; i
++) {
180 if (strncmp(str
, nv
->name
, strlen(nv
->name
)) == 0) {
186 * Found no valid loglevel name value at the beginning of 'str'.
188 if (i
== nvs_count
) {
193 * Record the least_severe value and skip over the loglevel name found
196 *least_severe
= nv
->value
;
197 str
+= strlen(nv
->name
);
200 * If we are at the end of 'str', only one loglevel name was specified,
201 * it is also the most_severe.
204 *most_severe
= nv
->value
;
210 * Invalid 'str', no loglevel name separator.
212 if (strncmp(str
, "..", strlen("..")) != 0) {
219 * If we are at the end of 'str' after the separator, set the default
220 * most_severe value for the domain as the most_severe.
223 *most_severe
= default_most_severe
;
229 * Look for a valid loglevel name value after the separator in 'str'.
231 for (i
= 0; i
< nvs_count
; i
++) {
234 if (strcmp(str
, nv
->name
) == 0) {
240 * Found no valid loglevel name value after the separator.
242 if (i
== nvs_count
) {
247 * Record the most_severe value for the loglevel found in 'str'.
249 *most_severe
= nv
->value
;
261 int loglevel_name_to_value(const char *name
, enum lttng_loglevel
*loglevel
)
263 int ret
= lookup_value_from_name(loglevel_values
, ARRAY_SIZE(loglevel_values
), name
);
266 *loglevel
= (typeof(*loglevel
)) ret
;
273 bool loglevel_parse_range_string(const char *str
,
274 enum lttng_loglevel
*least_severe
,
275 enum lttng_loglevel
*most_severe
)
277 int least_severe_int
, most_severe_int
;
278 const bool ret
= loglevel_parse_range_string_common(str
,
280 ARRAY_SIZE(loglevel_values
),
281 LTTNG_LOGLEVEL_EMERG
,
285 *least_severe
= (lttng_loglevel
) least_severe_int
;
286 *most_severe
= (lttng_loglevel
) most_severe_int
;
291 int loglevel_log4j_name_to_value(const char *name
, enum lttng_loglevel_log4j
*loglevel
)
293 int ret
= lookup_value_from_name(
294 loglevel_log4j_values
, ARRAY_SIZE(loglevel_log4j_values
), name
);
297 *loglevel
= (typeof(*loglevel
)) ret
;
304 bool loglevel_log4j_parse_range_string(const char *str
,
305 enum lttng_loglevel_log4j
*least_severe
,
306 enum lttng_loglevel_log4j
*most_severe
)
308 int least_severe_int
, most_severe_int
;
309 const bool ret
= loglevel_parse_range_string_common(str
,
310 loglevel_log4j_values
,
311 ARRAY_SIZE(loglevel_log4j_values
),
312 LTTNG_LOGLEVEL_LOG4J_FATAL
,
316 *least_severe
= (lttng_loglevel_log4j
) least_severe_int
;
317 *most_severe
= (lttng_loglevel_log4j
) most_severe_int
;
322 int loglevel_log4j2_name_to_value(const char *name
, enum lttng_loglevel_log4j2
*loglevel
)
324 int ret
= lookup_value_from_name(
325 loglevel_log4j2_values
, ARRAY_SIZE(loglevel_log4j2_values
), name
);
328 *loglevel
= (typeof(*loglevel
)) ret
;
335 bool loglevel_log4j2_parse_range_string(const char *str
,
336 enum lttng_loglevel_log4j2
*least_severe
,
337 enum lttng_loglevel_log4j2
*most_severe
)
339 int least_severe_int
, most_severe_int
;
340 bool ret
= loglevel_parse_range_string_common(str
,
341 loglevel_log4j2_values
,
342 ARRAY_SIZE(loglevel_log4j2_values
),
343 LTTNG_LOGLEVEL_LOG4J2_FATAL
,
347 *least_severe
= (lttng_loglevel_log4j2
) least_severe_int
;
348 *most_severe
= (lttng_loglevel_log4j2
) most_severe_int
;
353 int loglevel_jul_name_to_value(const char *name
, enum lttng_loglevel_jul
*loglevel
)
356 lookup_value_from_name(loglevel_jul_values
, ARRAY_SIZE(loglevel_jul_values
), name
);
359 *loglevel
= (typeof(*loglevel
)) ret
;
366 bool loglevel_jul_parse_range_string(const char *str
,
367 enum lttng_loglevel_jul
*least_severe
,
368 enum lttng_loglevel_jul
*most_severe
)
370 int least_severe_int
, most_severe_int
;
371 const bool ret
= loglevel_parse_range_string_common(str
,
373 ARRAY_SIZE(loglevel_jul_values
),
374 LTTNG_LOGLEVEL_JUL_SEVERE
,
378 *least_severe
= (lttng_loglevel_jul
) least_severe_int
;
379 *most_severe
= (lttng_loglevel_jul
) most_severe_int
;
384 int loglevel_python_name_to_value(const char *name
, enum lttng_loglevel_python
*loglevel
)
386 int ret
= lookup_value_from_name(
387 loglevel_python_values
, ARRAY_SIZE(loglevel_python_values
), name
);
390 *loglevel
= (typeof(*loglevel
)) ret
;
397 bool loglevel_python_parse_range_string(const char *str
,
398 enum lttng_loglevel_python
*least_severe
,
399 enum lttng_loglevel_python
*most_severe
)
401 int least_severe_int
, most_severe_int
;
402 const bool ret
= loglevel_parse_range_string_common(str
,
403 loglevel_python_values
,
404 ARRAY_SIZE(loglevel_python_values
),
405 LTTNG_LOGLEVEL_PYTHON_CRITICAL
,
409 *least_severe
= (lttng_loglevel_python
) least_severe_int
;
410 *most_severe
= (lttng_loglevel_python
) most_severe_int
;
416 lookup_name_from_value(const struct loglevel_name_value values
[], size_t values_count
, int loglevel
)
419 const char *name
= nullptr;
421 for (i
= 0; i
< values_count
; i
++) {
422 if (values
[i
].value
== loglevel
) {
424 name
= values
[i
].name
;
433 const char *loglevel_value_to_name(int loglevel
)
435 return lookup_name_from_value(loglevel_values
, ARRAY_SIZE(loglevel_values
), loglevel
);
438 const char *loglevel_log4j_value_to_name(int loglevel
)
440 return lookup_name_from_value(
441 loglevel_log4j_values
, ARRAY_SIZE(loglevel_log4j_values
), loglevel
);
444 const char *loglevel_log4j2_value_to_name(int loglevel
)
446 return lookup_name_from_value(
447 loglevel_log4j2_values
, ARRAY_SIZE(loglevel_log4j2_values
), loglevel
);
450 const char *loglevel_jul_value_to_name(int loglevel
)
452 return lookup_name_from_value(
453 loglevel_jul_values
, ARRAY_SIZE(loglevel_jul_values
), loglevel
);
456 const char *loglevel_python_value_to_name(int loglevel
)
458 return lookup_name_from_value(
459 loglevel_python_values
, ARRAY_SIZE(loglevel_python_values
), loglevel
);