]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Project] Re-implement counters method
authorVsevolod Stakhov <vsevolod@rspamd.com>
Sun, 17 Apr 2022 19:12:16 +0000 (20:12 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Sun, 17 Apr 2022 19:12:16 +0000 (20:12 +0100)
src/libserver/symcache/symcache_impl.cxx
src/libserver/symcache/symcache_internal.hxx

index 74d7db7248b9782fbd25be29a698653712464b53..a324fe523acfd4d611363a68d146408117e01f85 100644 (file)
@@ -731,7 +731,7 @@ auto symcache::validate(bool strict) -> bool
 
        while (g_hash_table_iter_next(&it, &k, &v)) {
                auto ignore_symbol = false;
-               auto sym_def = (struct rspamd_symbol *)v;
+               auto sym_def = (struct rspamd_symbol *) v;
 
                if (sym_def && (sym_def->flags &
                                                (RSPAMD_SYMBOL_FLAG_IGNORE_METRIC | RSPAMD_SYMBOL_FLAG_DISABLED))) {
@@ -739,7 +739,7 @@ auto symcache::validate(bool strict) -> bool
                }
 
                if (!ignore_symbol) {
-                       if (!items_by_symbol.contains((const char *)k)) {
+                       if (!items_by_symbol.contains((const char *) k)) {
                                msg_warn_cache (
                                                "symbol '%s' has its score defined but there is no "
                                                "corresponding rule registered",
@@ -750,7 +750,7 @@ auto symcache::validate(bool strict) -> bool
                        }
                }
                else if (sym_def->flags & RSPAMD_SYMBOL_FLAG_DISABLED) {
-                       auto item = get_item_by_name_mut((const char *)k, false);
+                       auto item = get_item_by_name_mut((const char *) k, false);
 
                        if (item) {
                                item->enabled = FALSE;
@@ -761,6 +761,74 @@ auto symcache::validate(bool strict) -> bool
        return ret;
 }
 
+auto symcache::counters() const -> ucl_object_t *
+{
+       auto *top = ucl_object_typed_new(UCL_ARRAY);
+       constexpr const auto round_float = [](const auto x, const int digits) -> auto {
+               const auto power10 = ::pow(10, digits);
+               return (::floor(x * power10) / power10);
+       };
+
+       for (auto &pair: items_by_symbol) {
+               auto &item = pair.second;
+               auto symbol = pair.first;
+
+               auto *obj = ucl_object_typed_new(UCL_OBJECT);
+               ucl_object_insert_key(obj, ucl_object_fromlstring(symbol.data(), symbol.size()),
+                               "symbol", 0, false);
+
+               if (item->is_virtual()) {
+                       if (!(item->flags & SYMBOL_TYPE_GHOST)) {
+                               const auto *parent = item->get_parent(*this);
+                               ucl_object_insert_key(obj,
+                                               ucl_object_fromdouble(round_float(item->st->weight, 3)),
+                                               "weight", 0, false);
+                               ucl_object_insert_key(obj,
+                                               ucl_object_fromdouble(round_float(parent->st->avg_frequency, 3)),
+                                               "frequency", 0, false);
+                               ucl_object_insert_key(obj,
+                                               ucl_object_fromint(parent->st->total_hits),
+                                               "hits", 0, false);
+                               ucl_object_insert_key(obj,
+                                               ucl_object_fromdouble(round_float(parent->st->avg_time, 3)),
+                                               "time", 0, false);
+                       }
+                       else {
+                               ucl_object_insert_key(obj,
+                                               ucl_object_fromdouble(round_float(item->st->weight, 3)),
+                                               "weight", 0, false);
+                               ucl_object_insert_key(obj,
+                                               ucl_object_fromdouble(0.0),
+                                               "frequency", 0, false);
+                               ucl_object_insert_key(obj,
+                                               ucl_object_fromdouble(0.0),
+                                               "hits", 0, false);
+                               ucl_object_insert_key(obj,
+                                               ucl_object_fromdouble(0.0),
+                                               "time", 0, false);
+                       }
+               }
+               else {
+                       ucl_object_insert_key(obj,
+                                       ucl_object_fromdouble(round_float(item->st->weight, 3)),
+                                       "weight", 0, false);
+                       ucl_object_insert_key(obj,
+                                       ucl_object_fromdouble(round_float(item->st->avg_frequency, 3)),
+                                       "frequency", 0, false);
+                       ucl_object_insert_key(obj,
+                                       ucl_object_fromint(item->st->total_hits),
+                                       "hits", 0, false);
+                       ucl_object_insert_key(obj,
+                                       ucl_object_fromdouble(round_float(item->st->avg_time, 3)),
+                                       "time", 0, false);
+               }
+
+               ucl_array_append(top, obj);
+       }
+
+       return top;
+}
+
 auto cache_item::get_parent(const symcache &cache) const -> const cache_item *
 {
        if (is_virtual()) {
index 05f3e10cc3ebd68df65ceafcf2b7afde8192a541..dea2ff6476c8cebc2134115cda62ae238bf9faef 100644 (file)
@@ -257,6 +257,10 @@ public:
                return std::holds_alternative<normal_item>(specific) &&
                        (type == symcache_item_type::FILTER);
        }
+       /**
+        * Returns true if a symbol should have some score defined
+        * @return
+        */
        auto is_scoreable() const -> bool {
                return (type == symcache_item_type::FILTER) ||
                                is_virtual() ||
@@ -540,6 +544,12 @@ public:
         * @return
         */
        auto validate(bool strict) -> bool;
+
+       /**
+        * Returns counters for the cache
+        * @return
+        */
+       auto counters() const -> ucl_object_t *;
 };
 
 /*