36ff3d153d29e5a3c160744eeb86edfd078cc6e8
[lttng-tools.git] / src / common / log-level-rule.cpp
1 /*
2 * Copyright (C) 2020 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 #include <common/dynamic-buffer.hpp>
9 #include <common/error.hpp>
10 #include <common/hashtable/hashtable.hpp>
11 #include <common/hashtable/utils.hpp>
12 #include <common/macros.hpp>
13 #include <common/mi-lttng.hpp>
14
15 #include <lttng/log-level-rule-internal.hpp>
16 #include <lttng/log-level-rule.h>
17
18 #include <stdbool.h>
19 #include <stdlib.h>
20
21 static bool is_log_level_rule_exactly_type(const struct lttng_log_level_rule *rule)
22 {
23 enum lttng_log_level_rule_type type = lttng_log_level_rule_get_type(rule);
24
25 return type == LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY;
26 }
27
28 static bool is_log_level_rule_at_least_as_severe_type(const struct lttng_log_level_rule *rule)
29 {
30 enum lttng_log_level_rule_type type = lttng_log_level_rule_get_type(rule);
31
32 return type == LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS;
33 }
34
35 enum lttng_log_level_rule_type
36 lttng_log_level_rule_get_type(const struct lttng_log_level_rule *rule)
37 {
38 return rule ? rule->type : LTTNG_LOG_LEVEL_RULE_TYPE_UNKNOWN;
39 }
40
41 struct lttng_log_level_rule *lttng_log_level_rule_exactly_create(int level)
42 {
43 struct lttng_log_level_rule *rule = NULL;
44
45 rule = zmalloc<lttng_log_level_rule>();
46 if (!rule) {
47 goto end;
48 }
49
50 rule->type = LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY;
51 rule->level = level;
52
53 end:
54 return rule;
55 }
56
57 enum lttng_log_level_rule_status
58 lttng_log_level_rule_exactly_get_level(const struct lttng_log_level_rule *rule, int *level)
59 {
60 enum lttng_log_level_rule_status status = LTTNG_LOG_LEVEL_RULE_STATUS_OK;
61
62 if (!rule || !level || !is_log_level_rule_exactly_type(rule)) {
63 status = LTTNG_LOG_LEVEL_RULE_STATUS_INVALID;
64 goto end;
65 }
66
67 *level = rule->level;
68 end:
69 return status;
70 }
71
72 struct lttng_log_level_rule *lttng_log_level_rule_at_least_as_severe_as_create(int level)
73 {
74 struct lttng_log_level_rule *rule = NULL;
75
76 rule = zmalloc<lttng_log_level_rule>();
77 if (!rule) {
78 goto end;
79 }
80
81 rule->type = LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS;
82 rule->level = level;
83
84 end:
85 return rule;
86 }
87
88 enum lttng_log_level_rule_status
89 lttng_log_level_rule_at_least_as_severe_as_get_level(const struct lttng_log_level_rule *rule,
90 int *level)
91 {
92 enum lttng_log_level_rule_status status = LTTNG_LOG_LEVEL_RULE_STATUS_OK;
93
94 if (!rule || !level || !is_log_level_rule_at_least_as_severe_type(rule)) {
95 status = LTTNG_LOG_LEVEL_RULE_STATUS_INVALID;
96 goto end;
97 }
98
99 *level = rule->level;
100 end:
101 return status;
102 }
103
104 void lttng_log_level_rule_destroy(struct lttng_log_level_rule *log_level_rule)
105 {
106 free(log_level_rule);
107 }
108
109 ssize_t lttng_log_level_rule_create_from_payload(struct lttng_payload_view *view,
110 struct lttng_log_level_rule **_rule)
111 {
112 ssize_t ret;
113 size_t offset = 0;
114 struct lttng_log_level_rule *rule = NULL;
115 const struct lttng_log_level_rule_comm *comm =
116 (const struct lttng_log_level_rule_comm *) view->buffer.data;
117
118 offset += sizeof(*comm);
119
120 if (!_rule) {
121 ret = -1;
122 goto end;
123 }
124
125 if (view->buffer.size < sizeof(*comm)) {
126 ret = -1;
127 goto end;
128 }
129
130 switch (comm->type) {
131 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
132 rule = lttng_log_level_rule_exactly_create((int) comm->level);
133 break;
134 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
135 rule = lttng_log_level_rule_at_least_as_severe_as_create((int) comm->level);
136 break;
137 default:
138 abort();
139 }
140
141 if (!rule) {
142 ret = -1;
143 goto end;
144 }
145
146 *_rule = rule;
147 ret = offset;
148
149 end:
150 return ret;
151 }
152
153 int lttng_log_level_rule_serialize(const struct lttng_log_level_rule *rule,
154 struct lttng_payload *payload)
155 {
156 int ret;
157 struct lttng_log_level_rule_comm comm;
158
159 if (!rule) {
160 ret = 0;
161 goto end;
162 }
163
164 comm.type = (int8_t) rule->type;
165 comm.level = (int32_t) rule->level;
166
167 DBG("Serializing log level rule of type %d", rule->type);
168 ret = lttng_dynamic_buffer_append(&payload->buffer, &comm, sizeof(comm));
169 if (ret) {
170 goto end;
171 }
172
173 end:
174 return ret;
175 }
176
177 bool lttng_log_level_rule_is_equal(const struct lttng_log_level_rule *a,
178 const struct lttng_log_level_rule *b)
179 {
180 bool is_equal = false;
181
182 if (a == NULL && b == NULL) {
183 /* Both are null. */
184 is_equal = true;
185 goto end;
186 }
187
188 if (a == NULL || b == NULL) {
189 /* One is NULL.*/
190 goto end;
191 }
192
193 if (a == b) {
194 /* Same object.*/
195 is_equal = true;
196 goto end;
197 }
198
199 if (a->type != b->type) {
200 goto end;
201 }
202
203 if (a->level != b->level) {
204 goto end;
205 }
206
207 is_equal = true;
208
209 end:
210 return is_equal;
211 }
212
213 struct lttng_log_level_rule *lttng_log_level_rule_copy(const struct lttng_log_level_rule *source)
214 {
215 struct lttng_log_level_rule *copy = NULL;
216
217 LTTNG_ASSERT(source);
218
219 copy = zmalloc<lttng_log_level_rule>();
220 if (!copy) {
221 goto end;
222 }
223
224 copy->type = source->type;
225 copy->level = source->level;
226 end:
227 return copy;
228 }
229
230 void lttng_log_level_rule_to_loglevel(const struct lttng_log_level_rule *log_level_rule,
231 enum lttng_loglevel_type *loglevel_type,
232 int *loglevel_value)
233 {
234 LTTNG_ASSERT(log_level_rule);
235
236 switch (log_level_rule->type) {
237 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
238 *loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
239 break;
240 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
241 *loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
242 break;
243 default:
244 abort();
245 }
246
247 *loglevel_value = log_level_rule->level;
248 }
249
250 unsigned long lttng_log_level_rule_hash(const struct lttng_log_level_rule *log_level_rule)
251 {
252 unsigned long hash;
253 enum lttng_log_level_rule_status llr_status;
254 int log_level_value;
255 enum lttng_log_level_rule_type type;
256
257 LTTNG_ASSERT(log_level_rule);
258
259 type = lttng_log_level_rule_get_type(log_level_rule);
260
261 switch (type) {
262 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
263 llr_status =
264 lttng_log_level_rule_exactly_get_level(log_level_rule, &log_level_value);
265 break;
266 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
267 llr_status = lttng_log_level_rule_at_least_as_severe_as_get_level(log_level_rule,
268 &log_level_value);
269 break;
270 default:
271 abort();
272 break;
273 }
274
275 LTTNG_ASSERT(llr_status == LTTNG_LOG_LEVEL_RULE_STATUS_OK);
276
277 hash = hash_key_ulong((void *) (unsigned long) type, lttng_ht_seed);
278
279 hash ^= hash_key_ulong((void *) (unsigned long) log_level_value, lttng_ht_seed);
280
281 return hash;
282 }
283
284 enum lttng_error_code lttng_log_level_rule_mi_serialize(const struct lttng_log_level_rule *rule,
285 struct mi_writer *writer)
286 {
287 int ret;
288 enum lttng_error_code ret_code;
289 enum lttng_log_level_rule_status status;
290 const char *element_str = NULL;
291 int level;
292
293 LTTNG_ASSERT(rule);
294 LTTNG_ASSERT(writer);
295
296 switch (lttng_log_level_rule_get_type(rule)) {
297 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
298 status = lttng_log_level_rule_exactly_get_level(rule, &level);
299 element_str = mi_lttng_element_log_level_rule_exactly;
300 break;
301 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
302 element_str = mi_lttng_element_log_level_rule_at_least_as_severe_as;
303 status = lttng_log_level_rule_at_least_as_severe_as_get_level(rule, &level);
304 break;
305 default:
306 abort();
307 break;
308 }
309
310 LTTNG_ASSERT(status == LTTNG_LOG_LEVEL_RULE_STATUS_OK);
311
312 /* Open log level rule element. */
313 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_log_level_rule);
314 if (ret) {
315 goto mi_error;
316 }
317
318 /* Log level rule type element. */
319 ret = mi_lttng_writer_open_element(writer, element_str);
320 if (ret) {
321 goto mi_error;
322 }
323
324 /* Level. */
325 ret = mi_lttng_writer_write_element_signed_int(
326 writer, mi_lttng_element_log_level_rule_level, level);
327 if (ret) {
328 goto mi_error;
329 }
330
331 /* Close log level rule type element. */
332 ret = mi_lttng_writer_close_element(writer);
333 if (ret) {
334 goto mi_error;
335 }
336
337 /* Close log level rule element. */
338 ret = mi_lttng_writer_close_element(writer);
339 if (ret) {
340 goto mi_error;
341 }
342
343 ret_code = LTTNG_OK;
344 goto end;
345
346 mi_error:
347 ret_code = LTTNG_ERR_MI_IO_FAIL;
348 end:
349 return ret_code;
350 }
This page took 0.035465 seconds and 4 git commands to generate.