SoW-2020-0003: Trace Hit Counters
[lttng-tools.git] / src / common / log-level-rule.c
diff --git a/src/common/log-level-rule.c b/src/common/log-level-rule.c
new file mode 100644 (file)
index 0000000..b5d0e9d
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2020 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#include <assert.h>
+#include <common/dynamic-buffer.h>
+#include <common/error.h>
+#include <common/macros.h>
+#include <common/hashtable/hashtable.h>
+#include <common/hashtable/utils.h>
+#include <lttng/log-level-rule-internal.h>
+#include <lttng/log-level-rule.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+static bool is_log_level_rule_exactly_type(const struct lttng_log_level_rule *rule)
+{
+       enum lttng_log_level_rule_type type =
+                       lttng_log_level_rule_get_type(rule);
+
+       return type == LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY;
+}
+
+static bool is_log_level_rule_at_least_as_severe_type(const struct lttng_log_level_rule *rule)
+{
+
+       enum lttng_log_level_rule_type type =
+                       lttng_log_level_rule_get_type(rule);
+
+       return type == LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS;
+}
+
+enum lttng_log_level_rule_type lttng_log_level_rule_get_type(
+               const struct lttng_log_level_rule *rule)
+{
+       return rule ? rule->type : LTTNG_LOG_LEVEL_RULE_TYPE_UNKNOWN;
+}
+
+struct lttng_log_level_rule *lttng_log_level_rule_exactly_create(
+               int level)
+{
+       struct lttng_log_level_rule *rule = NULL;
+
+       rule = zmalloc(sizeof(struct lttng_log_level_rule));
+       if (!rule) {
+               goto end;
+       }
+
+       rule->type = LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY;
+       rule->level = level;
+
+end:
+       return rule;
+}
+
+enum lttng_log_level_rule_status lttng_log_level_rule_exactly_get_level(
+               const struct lttng_log_level_rule *rule, int *level)
+{
+       enum lttng_log_level_rule_status status = LTTNG_LOG_LEVEL_RULE_STATUS_OK;
+       if (!rule || !level || !is_log_level_rule_exactly_type(rule)) {
+               status = LTTNG_LOG_LEVEL_RULE_STATUS_INVALID;
+               goto end;
+       }
+
+       *level = rule->level;
+end:
+       return status;
+}
+
+struct lttng_log_level_rule *
+lttng_log_level_rule_at_least_as_severe_as_create(int level)
+{
+       struct lttng_log_level_rule *rule = NULL;
+
+       rule = zmalloc(sizeof(struct lttng_log_level_rule));
+       if (!rule) {
+               goto end;
+       }
+
+       rule->type = LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS;
+       rule->level = level;
+
+end:
+       return rule;
+}
+
+enum lttng_log_level_rule_status
+lttng_log_level_rule_at_least_as_severe_as_get_level(
+               const struct lttng_log_level_rule *rule, int *level)
+{
+       enum lttng_log_level_rule_status status = LTTNG_LOG_LEVEL_RULE_STATUS_OK;
+       if (!rule || !level || !is_log_level_rule_at_least_as_severe_type(rule)) {
+               status = LTTNG_LOG_LEVEL_RULE_STATUS_INVALID;
+               goto end;
+       }
+
+       *level = rule->level;
+end:
+       return status;
+}
+
+void lttng_log_level_rule_destroy(struct lttng_log_level_rule *log_level_rule)
+{
+       free(log_level_rule);
+}
+
+LTTNG_HIDDEN
+ssize_t lttng_log_level_rule_create_from_payload(
+               struct lttng_payload_view *view,
+               struct lttng_log_level_rule **_rule)
+{
+       ssize_t ret;
+       size_t offset = 0;
+       struct lttng_log_level_rule *rule = NULL;
+       const struct lttng_log_level_rule_comm *comm =
+                       (const struct lttng_log_level_rule_comm *)
+                                       view->buffer.data;
+
+       offset += sizeof(*comm);
+
+       if (!_rule) {
+               ret = -1;
+               goto end;
+       }
+
+       if (view->buffer.size < sizeof(*comm)) {
+               ret = -1;
+               goto end;
+       }
+
+       switch (comm->type) {
+       case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
+               rule = lttng_log_level_rule_exactly_create((int) comm->level);
+               break;
+       case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
+               rule = lttng_log_level_rule_at_least_as_severe_as_create(
+                               (int) comm->level);
+               break;
+       default:
+               abort();
+       }
+       
+       if (!rule) {
+               ret = -1;
+               goto end;
+       }
+
+       *_rule = rule;
+       ret = offset;
+
+end:
+       return ret;
+}
+
+LTTNG_HIDDEN
+int lttng_log_level_rule_serialize(const struct lttng_log_level_rule *rule,
+               struct lttng_payload *payload)
+{
+       int ret;
+       struct lttng_log_level_rule_comm comm;
+
+
+       if (!rule) {
+               ret = 0;
+               goto end;
+       }
+
+       comm.type = (int8_t) rule->type;
+       comm.level = (int32_t) rule->level;
+
+       DBG("Serializing log level rule of type %d", rule->type);
+       ret = lttng_dynamic_buffer_append(&payload->buffer, &comm,
+                       sizeof(comm));
+       if (ret) {
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+LTTNG_HIDDEN
+bool lttng_log_level_rule_is_equal(const struct lttng_log_level_rule *a,
+               const struct lttng_log_level_rule *b)
+{
+       bool is_equal = false;
+
+       if (a == NULL && b == NULL) {
+               /* Both are null. */
+               is_equal = true;
+               goto end;
+       }
+
+       if (a == NULL || b == NULL) {
+               /* One is NULL.*/
+               goto end;
+       }
+
+       if (a == b) {
+               /* Same object.*/
+               is_equal = true;
+               goto end;
+       }
+
+       if (a->type != b->type) {
+               goto end;
+       }
+
+       if (a->level != b->level) {
+               goto end;
+       }
+
+       is_equal = true;
+
+end:
+       return is_equal;
+}
+
+LTTNG_HIDDEN
+struct lttng_log_level_rule * lttng_log_level_rule_copy(const struct lttng_log_level_rule *source)
+{
+       struct lttng_log_level_rule *copy = NULL;
+
+       assert(source);
+
+       copy = zmalloc(sizeof(struct lttng_log_level_rule));
+       if (!copy) {
+               goto end;
+       }
+
+       copy->type = source->type;
+       copy->level = source->level;
+end:
+       return copy;
+}
+
+LTTNG_HIDDEN
+void lttng_log_level_rule_to_loglevel(
+               const struct lttng_log_level_rule *log_level_rule,
+               enum lttng_loglevel_type *loglevel_type,
+               int *loglevel_value)
+{
+       assert(log_level_rule);
+
+       switch(log_level_rule->type)
+       {
+       case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
+               *loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
+               break;
+       case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
+               *loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
+               break;
+       default:
+               abort();
+       }
+
+       *loglevel_value = log_level_rule->level;
+}
+
+LTTNG_HIDDEN
+unsigned long lttng_log_level_rule_hash(
+               const struct lttng_log_level_rule *log_level_rule)
+{
+       unsigned long hash;
+       enum lttng_log_level_rule_status llr_status;
+       int log_level_value;
+       enum lttng_log_level_rule_type type;
+
+       assert(log_level_rule);
+
+       type = lttng_log_level_rule_get_type(log_level_rule);
+
+       switch (type) {
+       case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
+               llr_status = lttng_log_level_rule_exactly_get_level(
+                               log_level_rule, &log_level_value);
+               break;
+       case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
+               llr_status = lttng_log_level_rule_at_least_as_severe_as_get_level(
+                               log_level_rule, &log_level_value);
+               break;
+       default:
+               abort();
+               break;
+       }
+
+       assert(llr_status == LTTNG_LOG_LEVEL_RULE_STATUS_OK);
+
+       hash = hash_key_ulong((void *) (unsigned long) type, lttng_ht_seed);
+
+       hash ^= hash_key_ulong((void *) (unsigned long) log_level_value,
+                       lttng_ht_seed);
+
+       return hash;
+}
This page took 0.026877 seconds and 5 git commands to generate.