From 694884febce032c949b0bee54a558461b68d2ed4 Mon Sep 17 00:00:00 2001 From: Denis Zubarev Date: Fri, 19 Jun 2026 14:18:45 +0300 Subject: [PATCH 1/6] first version --- .../kphp-light/stdlib/output-functions.txt | 6 + runtime-light/k2-platform/k2-api.h | 14 ++ runtime-light/k2-platform/k2-header.h | 12 ++ runtime-light/stdlib/output/metrics.h | 161 ++++++++++++++++++ tests/python/lib/k2_server.py | 1 + 5 files changed, 194 insertions(+) create mode 100644 runtime-light/stdlib/output/metrics.h diff --git a/builtin-functions/kphp-light/stdlib/output-functions.txt b/builtin-functions/kphp-light/stdlib/output-functions.txt index 9dc5ef66ba..4e0894c3eb 100644 --- a/builtin-functions/kphp-light/stdlib/output-functions.txt +++ b/builtin-functions/kphp-light/stdlib/output-functions.txt @@ -19,3 +19,9 @@ function print ($v ::: string) ::: int; function echo ($v ::: string) ::: void; function dbg_echo ($v ::: string) ::: void; function var_dump ($v ::: any) ::: void; + +function write_metric_value ($metric_name ::: string, $tags ::: string[], $value ::: float, $timestamp ::: int = 0, $monitoring_system ::: int = 0) ::: void; +function write_metric_values_array ($metric_name ::: string, $tags ::: string[], $values ::: float[], $timestamp ::: int = 0, $monitoring_system ::: int = 0) ::: void; +function write_metric_count ($metric_name ::: string, $tags ::: string[], $count ::: float, $timestamp ::: int = 0, $monitoring_system ::: int = 0) ::: void; +function write_metric_increment ($metric_name ::: string, $tags ::: string[], $timestamp ::: int = 0, $monitoring_system ::: int = 0) ::: void; +function flush_metrics ($monitoring_system ::: int = 0) ::: void; diff --git a/runtime-light/k2-platform/k2-api.h b/runtime-light/k2-platform/k2-api.h index 617dad5e3f..104ad9cb31 100644 --- a/runtime-light/k2-platform/k2-api.h +++ b/runtime-light/k2-platform/k2-api.h @@ -24,6 +24,8 @@ #include #define K2_API_HEADER_H +#include "runtime-common/core/allocator/script-allocator.h" +#include "runtime-common/core/std/containers.h" #include "runtime-light/k2-platform/k2-header.h" #undef K2_API_HEADER_H @@ -72,6 +74,10 @@ using StreamStatus = StreamStatus; using UpdateStatus = UpdateStatus; +using MonitoringSystem = MonitoringSystem; + +using MetricValueMask = MetricValueMask; + using TimePoint = TimePoint; using SystemTime = SystemTime; @@ -245,6 +251,14 @@ inline std::expected madvise(void* addr, size_t length, int32_t a return {}; } +inline void write_serialized_metric(kphp::stl::vector buf, k2::MonitoringSystem ms) noexcept { + k2_write_serialized_metric(buf.data(), buf.size(), ms); +} + +inline void flush_metrics(k2::MonitoringSystem ms) noexcept { + k2_flush_metrics(ms); +} + inline void please_shutdown(k2::descriptor descriptor) noexcept { k2_please_shutdown(descriptor); } diff --git a/runtime-light/k2-platform/k2-header.h b/runtime-light/k2-platform/k2-header.h index 25b8789f7f..e3d460f095 100644 --- a/runtime-light/k2-platform/k2-header.h +++ b/runtime-light/k2-platform/k2-header.h @@ -97,6 +97,10 @@ enum UpdateStatus { NewDescriptor = 2, }; +enum MonitoringSystem { StatsHouse }; + +enum MetricValueMask : uint32_t { VALUE_MASK = 0, VALUES_ARRAY_MASK = 1, COUNT_MASK = 2, INC_MASK = 3 }; + struct ImageInfo { // Base const char* image_name; @@ -382,6 +386,14 @@ void* k2_mmap(uint64_t* md, void* addr, size_t length, int32_t prot, int32_t fla * Semantically equivalent to libc's `madvise` function. */ int32_t k2_madvise(void* addr, size_t length, int32_t advise); +/** + * + * @param buf + * @param buf_len + * @param ms + */ +void k2_write_serialized_metric(uint8_t* buf, size_t buf_len, MonitoringSystem ms); +void k2_flush_metrics(enum MonitoringSystem ms); /** * Sets `StreamStatus.please_whutdown_write=true` for the component on the diff --git a/runtime-light/stdlib/output/metrics.h b/runtime-light/stdlib/output/metrics.h new file mode 100644 index 0000000000..9e9a71e1ab --- /dev/null +++ b/runtime-light/stdlib/output/metrics.h @@ -0,0 +1,161 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2026 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#pragma once + +#include +#include + +#include "runtime-common/core/allocator/script-allocator.h" +#include "runtime-common/core/runtime-core.h" +#include "runtime-common/core/std/containers.h" +#include "runtime-light/k2-platform/k2-api.h" + +struct MetricBuffer { +private: + using buf_vector = kphp::stl::vector; + using hasher_type = decltype([](const string& s) noexcept { return static_cast(s.hash()); }); + + string metric_name; + kphp::stl::unordered_map tags; + size_t msg_size{0}; + + MetricBuffer(std::string_view metric_name) noexcept + : metric_name{metric_name.data(), static_cast(metric_name.length())}, + tags{} { + this->msg_size += MetricBuffer::string_sizeof(metric_name); + } + + template + requires std::is_arithmetic_v + static void store_number(buf_vector& buf, const T& number) noexcept { + const auto* src = static_cast(static_cast(&number)); + buf.insert(buf.end(), src, src + sizeof(T)); + } + + static void store_string(buf_vector& buf, const std::string_view& string) noexcept { + MetricBuffer::store_number(buf, string.size()); + buf.insert(buf.end(), string.begin(), string.end()); + } + + void store_msg(buf_vector& buf) const noexcept { + MetricBuffer::store_number(buf, this->msg_size); + MetricBuffer::store_string(buf, std::string_view{this->metric_name.c_str(), this->metric_name.size()}); + for (const auto& [tag_name, tag_value] : this->tags) { + MetricBuffer::store_string(buf, std::string_view{tag_name.c_str(), tag_name.size()}); + MetricBuffer::store_string(buf, std::string_view{tag_value.c_str(), tag_value.size()}); + } + } + + static size_t string_sizeof(const std::string_view& string) noexcept { + return sizeof(size_t) + string.size(); + } + +public: + static MetricBuffer builder(std::string_view metric_name) noexcept { + return MetricBuffer(metric_name); + } + + // ----------------------------------------------------------------- + static MetricBuffer from_php(const string& metric_name, const array& tags) noexcept { + auto builder = MetricBuffer::builder({metric_name.c_str(), metric_name.size()}); + for (const auto& it : tags) { + if (it.is_string_key()) { + const auto& tag_key = it.get_string_key(); + const auto& tag_val = it.get_value(); + builder.set_tag({tag_key.c_str(), tag_key.size()}, {tag_val.c_str(), tag_val.size()}); + } + } + return builder; + } + // ----------------------------------------------------------------- + + MetricBuffer& set_tag(std::string_view tag_name, std::string_view tag_value) noexcept { + this->tags[string{tag_name.data(), static_cast(tag_name.size())}] = + string{tag_value.data(), static_cast(tag_value.size())}; + this->msg_size += MetricBuffer::string_sizeof(tag_name) + MetricBuffer::string_sizeof(tag_value); + return *this; + } + + buf_vector build_value(double value, uint32_t timestamp) const noexcept { + buf_vector buf{}; + buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(double) + sizeof(size_t) + this->msg_size); + + MetricBuffer::store_number(buf, timestamp); + MetricBuffer::store_number(buf, static_cast(k2::MetricValueMask::VALUE_MASK)); + MetricBuffer::store_number(buf, value); + this->store_msg(buf); + return buf; + } + + buf_vector build_values_array(const kphp::stl::vector& values, uint32_t timestamp) const noexcept { + buf_vector buf{}; + buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(size_t) + sizeof(double) * values.size() + sizeof(size_t) + this->msg_size); + + MetricBuffer::store_number(buf, timestamp); + MetricBuffer::store_number(buf, static_cast(k2::MetricValueMask::VALUES_ARRAY_MASK)); + MetricBuffer::store_number(buf, values.size()); + for (const auto& value : values) { + MetricBuffer::store_number(buf, value); + } + this->store_msg(buf); + return buf; + } + + buf_vector build_count(double count, uint32_t timestamp) const noexcept { + buf_vector buf{}; + buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(double) + sizeof(size_t) + this->msg_size); + + MetricBuffer::store_number(buf, timestamp); + MetricBuffer::store_number(buf, static_cast(k2::MetricValueMask::COUNT_MASK)); + MetricBuffer::store_number(buf, count); + this->store_msg(buf); + return buf; + } + + buf_vector build_increment(uint32_t timestamp) const noexcept { + buf_vector buf{}; + buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(size_t) + this->msg_size); + + MetricBuffer::store_number(buf, timestamp); + MetricBuffer::store_number(buf, static_cast(k2::MetricValueMask::INC_MASK)); + this->store_msg(buf); + return buf; + } +}; + +// ----------------------------------------------------------------- + +inline void f$write_metric_value(const string& metric_name, const array& tags, double value, int64_t monitoring_system = 0) noexcept { + auto builder = MetricBuffer::from_php(metric_name, tags); + auto timestamp{std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()}; + k2::write_serialized_metric(builder.build_value(value, static_cast(timestamp)), static_cast(monitoring_system)); +} + +inline void f$write_metric_values_array(const string& metric_name, const array& tags, const array& values, + int64_t monitoring_system = 0) noexcept { + auto builder = MetricBuffer::from_php(metric_name, tags); + auto timestamp{std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()}; + kphp::stl::vector vec{}; + for (const auto& it : values) { + vec.push_back(it.get_value()); + } + k2::write_serialized_metric(builder.build_values_array(vec, static_cast(timestamp)), static_cast(monitoring_system)); +} + +inline void f$write_metric_count(const string& metric_name, const array& tags, double count, int64_t monitoring_system = 0) noexcept { + auto builder = MetricBuffer::from_php(metric_name, tags); + auto timestamp{std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()}; + k2::write_serialized_metric(builder.build_count(count, static_cast(timestamp)), static_cast(monitoring_system)); +} + +inline void f$write_metric_increment(const string& metric_name, const array& tags, int64_t monitoring_system = 0) noexcept { + auto builder = MetricBuffer::from_php(metric_name, tags); + auto timestamp{std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()}; + k2::write_serialized_metric(builder.build_increment(static_cast(timestamp)), static_cast(monitoring_system)); +} + +inline void f$flush_metrics(int64_t monitoring_system = 0) noexcept { + k2::flush_metrics(static_cast(monitoring_system)); +} diff --git a/tests/python/lib/k2_server.py b/tests/python/lib/k2_server.py index f31fdfa254..ac5961bafc 100644 --- a/tests/python/lib/k2_server.py +++ b/tests/python/lib/k2_server.py @@ -71,6 +71,7 @@ def _process_json_log(self, log_record): log_record.pop("file", "") log_record.pop("line", "") log_record.pop("hostname", "") + log_record.pop("cluster", "") # convert raw string to python dict tags = log_record.get("tags") From 2b7be26d31f6592fe964c1e0d07e4ac7f6084bd6 Mon Sep 17 00:00:00 2001 From: Denis Zubarev Date: Fri, 19 Jun 2026 19:04:00 +0300 Subject: [PATCH 2/6] added metric builder + write_serialized_metric to k2-api --- .../kphp-light/stdlib/output-functions.txt | 1 - runtime-light/k2-platform/k2-api.h | 8 +- runtime-light/k2-platform/k2-header.h | 3 +- runtime-light/stdlib/output/metrics.h | 133 ++++++++++-------- 4 files changed, 76 insertions(+), 69 deletions(-) diff --git a/builtin-functions/kphp-light/stdlib/output-functions.txt b/builtin-functions/kphp-light/stdlib/output-functions.txt index 4e0894c3eb..30537540a5 100644 --- a/builtin-functions/kphp-light/stdlib/output-functions.txt +++ b/builtin-functions/kphp-light/stdlib/output-functions.txt @@ -24,4 +24,3 @@ function write_metric_value ($metric_name ::: string, $tags ::: string[], $value function write_metric_values_array ($metric_name ::: string, $tags ::: string[], $values ::: float[], $timestamp ::: int = 0, $monitoring_system ::: int = 0) ::: void; function write_metric_count ($metric_name ::: string, $tags ::: string[], $count ::: float, $timestamp ::: int = 0, $monitoring_system ::: int = 0) ::: void; function write_metric_increment ($metric_name ::: string, $tags ::: string[], $timestamp ::: int = 0, $monitoring_system ::: int = 0) ::: void; -function flush_metrics ($monitoring_system ::: int = 0) ::: void; diff --git a/runtime-light/k2-platform/k2-api.h b/runtime-light/k2-platform/k2-api.h index 104ad9cb31..b353a69b76 100644 --- a/runtime-light/k2-platform/k2-api.h +++ b/runtime-light/k2-platform/k2-api.h @@ -251,12 +251,8 @@ inline std::expected madvise(void* addr, size_t length, int32_t a return {}; } -inline void write_serialized_metric(kphp::stl::vector buf, k2::MonitoringSystem ms) noexcept { - k2_write_serialized_metric(buf.data(), buf.size(), ms); -} - -inline void flush_metrics(k2::MonitoringSystem ms) noexcept { - k2_flush_metrics(ms); +inline void write_serialized_metric(kphp::stl::vector serialized_metric, k2::MonitoringSystem ms) noexcept { + k2_write_serialized_metric(serialized_metric.data(), serialized_metric.size(), ms); } inline void please_shutdown(k2::descriptor descriptor) noexcept { diff --git a/runtime-light/k2-platform/k2-header.h b/runtime-light/k2-platform/k2-header.h index e3d460f095..cd51c12bd7 100644 --- a/runtime-light/k2-platform/k2-header.h +++ b/runtime-light/k2-platform/k2-header.h @@ -386,14 +386,15 @@ void* k2_mmap(uint64_t* md, void* addr, size_t length, int32_t prot, int32_t fla * Semantically equivalent to libc's `madvise` function. */ int32_t k2_madvise(void* addr, size_t length, int32_t advise); + /** + * ... * * @param buf * @param buf_len * @param ms */ void k2_write_serialized_metric(uint8_t* buf, size_t buf_len, MonitoringSystem ms); -void k2_flush_metrics(enum MonitoringSystem ms); /** * Sets `StreamStatus.please_whutdown_write=true` for the component on the diff --git a/runtime-light/stdlib/output/metrics.h b/runtime-light/stdlib/output/metrics.h index 9e9a71e1ab..c81c3324f4 100644 --- a/runtime-light/stdlib/output/metrics.h +++ b/runtime-light/stdlib/output/metrics.h @@ -4,47 +4,48 @@ #pragma once +#include #include #include +#include "common/mixin/movable_only.h" #include "runtime-common/core/allocator/script-allocator.h" #include "runtime-common/core/runtime-core.h" #include "runtime-common/core/std/containers.h" #include "runtime-light/k2-platform/k2-api.h" -struct MetricBuffer { +struct MetricsBuffer final : vk::movable_only { private: - using buf_vector = kphp::stl::vector; + using bytes_vector = kphp::stl::vector; using hasher_type = decltype([](const string& s) noexcept { return static_cast(s.hash()); }); string metric_name; kphp::stl::unordered_map tags; size_t msg_size{0}; - MetricBuffer(std::string_view metric_name) noexcept - : metric_name{metric_name.data(), static_cast(metric_name.length())}, - tags{} { - this->msg_size += MetricBuffer::string_sizeof(metric_name); + MetricsBuffer(std::string_view metric_name) noexcept + : metric_name{metric_name.data(), static_cast(metric_name.length())} { + this->msg_size += MetricsBuffer::string_sizeof(metric_name); } template requires std::is_arithmetic_v - static void store_number(buf_vector& buf, const T& number) noexcept { + static void store_number(bytes_vector& buf, const T& number) noexcept { const auto* src = static_cast(static_cast(&number)); buf.insert(buf.end(), src, src + sizeof(T)); } - static void store_string(buf_vector& buf, const std::string_view& string) noexcept { - MetricBuffer::store_number(buf, string.size()); + static void store_string(bytes_vector& buf, const std::string_view& string) noexcept { + MetricsBuffer::store_number(buf, string.size()); buf.insert(buf.end(), string.begin(), string.end()); } - void store_msg(buf_vector& buf) const noexcept { - MetricBuffer::store_number(buf, this->msg_size); - MetricBuffer::store_string(buf, std::string_view{this->metric_name.c_str(), this->metric_name.size()}); + void store_msg(bytes_vector& buf) const noexcept { + MetricsBuffer::store_number(buf, this->msg_size); + MetricsBuffer::store_string(buf, std::string_view{this->metric_name.c_str(), this->metric_name.size()}); for (const auto& [tag_name, tag_value] : this->tags) { - MetricBuffer::store_string(buf, std::string_view{tag_name.c_str(), tag_name.size()}); - MetricBuffer::store_string(buf, std::string_view{tag_value.c_str(), tag_value.size()}); + MetricsBuffer::store_string(buf, std::string_view{tag_name.c_str(), tag_name.size()}); + MetricsBuffer::store_string(buf, std::string_view{tag_value.c_str(), tag_value.size()}); } } @@ -52,74 +53,90 @@ struct MetricBuffer { return sizeof(size_t) + string.size(); } + static uint32_t s_timestamp_now() noexcept { + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + } + public: - static MetricBuffer builder(std::string_view metric_name) noexcept { - return MetricBuffer(metric_name); + static MetricsBuffer metric(std::string_view metric_name) noexcept { + return MetricsBuffer{metric_name}; } // ----------------------------------------------------------------- - static MetricBuffer from_php(const string& metric_name, const array& tags) noexcept { - auto builder = MetricBuffer::builder({metric_name.c_str(), metric_name.size()}); + static MetricsBuffer from_php(const string& metric_name, const array& tags) noexcept { + auto builder = MetricsBuffer::metric({metric_name.c_str(), metric_name.size()}); for (const auto& it : tags) { if (it.is_string_key()) { const auto& tag_key = it.get_string_key(); const auto& tag_val = it.get_value(); - builder.set_tag({tag_key.c_str(), tag_key.size()}, {tag_val.c_str(), tag_val.size()}); + builder.tag({tag_key.c_str(), tag_key.size()}, {tag_val.c_str(), tag_val.size()}); } } return builder; } // ----------------------------------------------------------------- - MetricBuffer& set_tag(std::string_view tag_name, std::string_view tag_value) noexcept { + MetricsBuffer& tag(std::string_view tag_name, std::string_view tag_value) noexcept { this->tags[string{tag_name.data(), static_cast(tag_name.size())}] = string{tag_value.data(), static_cast(tag_value.size())}; - this->msg_size += MetricBuffer::string_sizeof(tag_name) + MetricBuffer::string_sizeof(tag_value); + this->msg_size += MetricsBuffer::string_sizeof(tag_name) + MetricsBuffer::string_sizeof(tag_value); return *this; } - buf_vector build_value(double value, uint32_t timestamp) const noexcept { - buf_vector buf{}; - buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(double) + sizeof(size_t) + this->msg_size); + bytes_vector build_value(double value, std::optional timestamp = std::nullopt) const noexcept { + bytes_vector buf{}; + buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(double) + sizeof(size_t) + + this->msg_size); // timestamp_u32 + value_mask_u32 + value_f64 + msg_size_usize + msg_len - MetricBuffer::store_number(buf, timestamp); - MetricBuffer::store_number(buf, static_cast(k2::MetricValueMask::VALUE_MASK)); - MetricBuffer::store_number(buf, value); + uint32_t s_timestamp{timestamp.value_or(MetricsBuffer::s_timestamp_now())}; + + MetricsBuffer::store_number(buf, s_timestamp); + MetricsBuffer::store_number(buf, static_cast(k2::MetricValueMask::VALUE_MASK)); + MetricsBuffer::store_number(buf, value); this->store_msg(buf); return buf; } - buf_vector build_values_array(const kphp::stl::vector& values, uint32_t timestamp) const noexcept { - buf_vector buf{}; - buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(size_t) + sizeof(double) * values.size() + sizeof(size_t) + this->msg_size); + bytes_vector build_values_array(const kphp::stl::vector& values, + std::optional timestamp = std::nullopt) const noexcept { + bytes_vector buf{}; + buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(size_t) + sizeof(double) * values.size() + sizeof(size_t) + + this->msg_size); // timestamp_u32 + value_mask_u32 + array_len_usize + value_f64*array_len + msg_size_usize + msg_len + + uint32_t s_timestamp{timestamp.value_or(MetricsBuffer::s_timestamp_now())}; - MetricBuffer::store_number(buf, timestamp); - MetricBuffer::store_number(buf, static_cast(k2::MetricValueMask::VALUES_ARRAY_MASK)); - MetricBuffer::store_number(buf, values.size()); + MetricsBuffer::store_number(buf, s_timestamp); + MetricsBuffer::store_number(buf, static_cast(k2::MetricValueMask::VALUES_ARRAY_MASK)); + MetricsBuffer::store_number(buf, values.size()); for (const auto& value : values) { - MetricBuffer::store_number(buf, value); + MetricsBuffer::store_number(buf, value); } this->store_msg(buf); return buf; } - buf_vector build_count(double count, uint32_t timestamp) const noexcept { - buf_vector buf{}; - buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(double) + sizeof(size_t) + this->msg_size); + bytes_vector build_count(double count, std::optional timestamp = std::nullopt) const noexcept { + bytes_vector buf{}; + buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(double) + sizeof(size_t) + + this->msg_size); // timestamp_u32 + value_mask_u32 + count_f64 + msg_size_usize + msg_len - MetricBuffer::store_number(buf, timestamp); - MetricBuffer::store_number(buf, static_cast(k2::MetricValueMask::COUNT_MASK)); - MetricBuffer::store_number(buf, count); + uint32_t s_timestamp{timestamp.value_or(MetricsBuffer::s_timestamp_now())}; + + MetricsBuffer::store_number(buf, s_timestamp); + MetricsBuffer::store_number(buf, static_cast(k2::MetricValueMask::COUNT_MASK)); + MetricsBuffer::store_number(buf, count); this->store_msg(buf); return buf; } - buf_vector build_increment(uint32_t timestamp) const noexcept { - buf_vector buf{}; - buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(size_t) + this->msg_size); + bytes_vector build_increment(std::optional timestamp = std::nullopt) const noexcept { + bytes_vector buf{}; + buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(size_t) + this->msg_size); // timestamp_u32 + value_mask_u32 + msg_size_usize + msg_len + + uint32_t s_timestamp{timestamp.value_or(MetricsBuffer::s_timestamp_now())}; - MetricBuffer::store_number(buf, timestamp); - MetricBuffer::store_number(buf, static_cast(k2::MetricValueMask::INC_MASK)); + MetricsBuffer::store_number(buf, s_timestamp); + MetricsBuffer::store_number(buf, static_cast(k2::MetricValueMask::INC_MASK)); this->store_msg(buf); return buf; } @@ -127,16 +144,15 @@ struct MetricBuffer { // ----------------------------------------------------------------- -inline void f$write_metric_value(const string& metric_name, const array& tags, double value, int64_t monitoring_system = 0) noexcept { - auto builder = MetricBuffer::from_php(metric_name, tags); - auto timestamp{std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()}; +inline void f$write_metric_value(const string& metric_name, const array& tags, double value, uint32_t timestamp = 0, + int64_t monitoring_system = 0) noexcept { + auto builder = MetricsBuffer::from_php(metric_name, tags); k2::write_serialized_metric(builder.build_value(value, static_cast(timestamp)), static_cast(monitoring_system)); } -inline void f$write_metric_values_array(const string& metric_name, const array& tags, const array& values, +inline void f$write_metric_values_array(const string& metric_name, const array& tags, const array& values, uint32_t timestamp = 0, int64_t monitoring_system = 0) noexcept { - auto builder = MetricBuffer::from_php(metric_name, tags); - auto timestamp{std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()}; + auto builder = MetricsBuffer::from_php(metric_name, tags); kphp::stl::vector vec{}; for (const auto& it : values) { vec.push_back(it.get_value()); @@ -144,18 +160,13 @@ inline void f$write_metric_values_array(const string& metric_name, const array(timestamp)), static_cast(monitoring_system)); } -inline void f$write_metric_count(const string& metric_name, const array& tags, double count, int64_t monitoring_system = 0) noexcept { - auto builder = MetricBuffer::from_php(metric_name, tags); - auto timestamp{std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()}; +inline void f$write_metric_count(const string& metric_name, const array& tags, double count, uint32_t timestamp = 0, + int64_t monitoring_system = 0) noexcept { + auto builder = MetricsBuffer::from_php(metric_name, tags); k2::write_serialized_metric(builder.build_count(count, static_cast(timestamp)), static_cast(monitoring_system)); } -inline void f$write_metric_increment(const string& metric_name, const array& tags, int64_t monitoring_system = 0) noexcept { - auto builder = MetricBuffer::from_php(metric_name, tags); - auto timestamp{std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()}; +inline void f$write_metric_increment(const string& metric_name, const array& tags, uint32_t timestamp = 0, int64_t monitoring_system = 0) noexcept { + auto builder = MetricsBuffer::from_php(metric_name, tags); k2::write_serialized_metric(builder.build_increment(static_cast(timestamp)), static_cast(monitoring_system)); } - -inline void f$flush_metrics(int64_t monitoring_system = 0) noexcept { - k2::flush_metrics(static_cast(monitoring_system)); -} From 7bb602d40e403b24be19b63dc1f7eaa97b32ee20 Mon Sep 17 00:00:00 2001 From: Denis Zubarev Date: Fri, 19 Jun 2026 19:12:15 +0300 Subject: [PATCH 3/6] v1.0 --- .../kphp-light/stdlib/output-functions.txt | 5 --- runtime-light/stdlib/output/metrics.h | 45 +------------------ tests/python/lib/k2_server.py | 1 - 3 files changed, 1 insertion(+), 50 deletions(-) diff --git a/builtin-functions/kphp-light/stdlib/output-functions.txt b/builtin-functions/kphp-light/stdlib/output-functions.txt index 30537540a5..9dc5ef66ba 100644 --- a/builtin-functions/kphp-light/stdlib/output-functions.txt +++ b/builtin-functions/kphp-light/stdlib/output-functions.txt @@ -19,8 +19,3 @@ function print ($v ::: string) ::: int; function echo ($v ::: string) ::: void; function dbg_echo ($v ::: string) ::: void; function var_dump ($v ::: any) ::: void; - -function write_metric_value ($metric_name ::: string, $tags ::: string[], $value ::: float, $timestamp ::: int = 0, $monitoring_system ::: int = 0) ::: void; -function write_metric_values_array ($metric_name ::: string, $tags ::: string[], $values ::: float[], $timestamp ::: int = 0, $monitoring_system ::: int = 0) ::: void; -function write_metric_count ($metric_name ::: string, $tags ::: string[], $count ::: float, $timestamp ::: int = 0, $monitoring_system ::: int = 0) ::: void; -function write_metric_increment ($metric_name ::: string, $tags ::: string[], $timestamp ::: int = 0, $monitoring_system ::: int = 0) ::: void; diff --git a/runtime-light/stdlib/output/metrics.h b/runtime-light/stdlib/output/metrics.h index c81c3324f4..93254b0964 100644 --- a/runtime-light/stdlib/output/metrics.h +++ b/runtime-light/stdlib/output/metrics.h @@ -23,7 +23,7 @@ struct MetricsBuffer final : vk::movable_only { kphp::stl::unordered_map tags; size_t msg_size{0}; - MetricsBuffer(std::string_view metric_name) noexcept + explicit MetricsBuffer(std::string_view metric_name) noexcept : metric_name{metric_name.data(), static_cast(metric_name.length())} { this->msg_size += MetricsBuffer::string_sizeof(metric_name); } @@ -62,20 +62,6 @@ struct MetricsBuffer final : vk::movable_only { return MetricsBuffer{metric_name}; } - // ----------------------------------------------------------------- - static MetricsBuffer from_php(const string& metric_name, const array& tags) noexcept { - auto builder = MetricsBuffer::metric({metric_name.c_str(), metric_name.size()}); - for (const auto& it : tags) { - if (it.is_string_key()) { - const auto& tag_key = it.get_string_key(); - const auto& tag_val = it.get_value(); - builder.tag({tag_key.c_str(), tag_key.size()}, {tag_val.c_str(), tag_val.size()}); - } - } - return builder; - } - // ----------------------------------------------------------------- - MetricsBuffer& tag(std::string_view tag_name, std::string_view tag_value) noexcept { this->tags[string{tag_name.data(), static_cast(tag_name.size())}] = string{tag_value.data(), static_cast(tag_value.size())}; @@ -141,32 +127,3 @@ struct MetricsBuffer final : vk::movable_only { return buf; } }; - -// ----------------------------------------------------------------- - -inline void f$write_metric_value(const string& metric_name, const array& tags, double value, uint32_t timestamp = 0, - int64_t monitoring_system = 0) noexcept { - auto builder = MetricsBuffer::from_php(metric_name, tags); - k2::write_serialized_metric(builder.build_value(value, static_cast(timestamp)), static_cast(monitoring_system)); -} - -inline void f$write_metric_values_array(const string& metric_name, const array& tags, const array& values, uint32_t timestamp = 0, - int64_t monitoring_system = 0) noexcept { - auto builder = MetricsBuffer::from_php(metric_name, tags); - kphp::stl::vector vec{}; - for (const auto& it : values) { - vec.push_back(it.get_value()); - } - k2::write_serialized_metric(builder.build_values_array(vec, static_cast(timestamp)), static_cast(monitoring_system)); -} - -inline void f$write_metric_count(const string& metric_name, const array& tags, double count, uint32_t timestamp = 0, - int64_t monitoring_system = 0) noexcept { - auto builder = MetricsBuffer::from_php(metric_name, tags); - k2::write_serialized_metric(builder.build_count(count, static_cast(timestamp)), static_cast(monitoring_system)); -} - -inline void f$write_metric_increment(const string& metric_name, const array& tags, uint32_t timestamp = 0, int64_t monitoring_system = 0) noexcept { - auto builder = MetricsBuffer::from_php(metric_name, tags); - k2::write_serialized_metric(builder.build_increment(static_cast(timestamp)), static_cast(monitoring_system)); -} diff --git a/tests/python/lib/k2_server.py b/tests/python/lib/k2_server.py index ac5961bafc..f31fdfa254 100644 --- a/tests/python/lib/k2_server.py +++ b/tests/python/lib/k2_server.py @@ -71,7 +71,6 @@ def _process_json_log(self, log_record): log_record.pop("file", "") log_record.pop("line", "") log_record.pop("hostname", "") - log_record.pop("cluster", "") # convert raw string to python dict tags = log_record.get("tags") From f6af9d2bf689ff638c720b4b653df9deed517c64 Mon Sep 17 00:00:00 2001 From: Denis Zubarev Date: Sun, 21 Jun 2026 13:58:43 +0300 Subject: [PATCH 4/6] v1.1 --- runtime-light/k2-platform/k2-api.h | 4 ++-- runtime-light/k2-platform/k2-header.h | 22 ++++++++++++++----- .../stdlib/{output => diagnostics}/metrics.h | 11 ++++------ 3 files changed, 23 insertions(+), 14 deletions(-) rename runtime-light/stdlib/{output => diagnostics}/metrics.h (90%) diff --git a/runtime-light/k2-platform/k2-api.h b/runtime-light/k2-platform/k2-api.h index b353a69b76..0b8b8c931a 100644 --- a/runtime-light/k2-platform/k2-api.h +++ b/runtime-light/k2-platform/k2-api.h @@ -251,8 +251,8 @@ inline std::expected madvise(void* addr, size_t length, int32_t a return {}; } -inline void write_serialized_metric(kphp::stl::vector serialized_metric, k2::MonitoringSystem ms) noexcept { - k2_write_serialized_metric(serialized_metric.data(), serialized_metric.size(), ms); +inline void write_metric(const kphp::stl::vector& serialized_metric, k2::MonitoringSystem ms) noexcept { + k2_write_metric(serialized_metric.data(), serialized_metric.size(), ms); } inline void please_shutdown(k2::descriptor descriptor) noexcept { diff --git a/runtime-light/k2-platform/k2-header.h b/runtime-light/k2-platform/k2-header.h index cd51c12bd7..393921deaa 100644 --- a/runtime-light/k2-platform/k2-header.h +++ b/runtime-light/k2-platform/k2-header.h @@ -99,6 +99,16 @@ enum UpdateStatus { enum MonitoringSystem { StatsHouse }; +/* + * Serialized metric format: + * ... + * + * value_format: + * - single float value + * ... - array of float values + * - count value + * - counter increment (no payload) + */ enum MetricValueMask : uint32_t { VALUE_MASK = 0, VALUES_ARRAY_MASK = 1, COUNT_MASK = 2, INC_MASK = 3 }; struct ImageInfo { @@ -388,13 +398,15 @@ void* k2_mmap(uint64_t* md, void* addr, size_t length, int32_t prot, int32_t fla int32_t k2_madvise(void* addr, size_t length, int32_t advise); /** - * ... + * Writes a pre-serialized metric to the specified monitoring system. + * The buffer must contain a metric serialized according to the format described above + * (see `MetricValueMask` and the serialized metric format comment). * - * @param buf - * @param buf_len - * @param ms + * @param `buf` A pointer to the serialized metric data. + * @param `buf_len` The length of the serialized metric data in bytes. + * @param `ms` The target monitoring system. */ -void k2_write_serialized_metric(uint8_t* buf, size_t buf_len, MonitoringSystem ms); +void k2_write_metric(const uint8_t* buf, size_t buf_len, enum MonitoringSystem ms); /** * Sets `StreamStatus.please_whutdown_write=true` for the component on the diff --git a/runtime-light/stdlib/output/metrics.h b/runtime-light/stdlib/diagnostics/metrics.h similarity index 90% rename from runtime-light/stdlib/output/metrics.h rename to runtime-light/stdlib/diagnostics/metrics.h index 93254b0964..dc40dcef68 100644 --- a/runtime-light/stdlib/output/metrics.h +++ b/runtime-light/stdlib/diagnostics/metrics.h @@ -10,21 +10,19 @@ #include "common/mixin/movable_only.h" #include "runtime-common/core/allocator/script-allocator.h" -#include "runtime-common/core/runtime-core.h" #include "runtime-common/core/std/containers.h" #include "runtime-light/k2-platform/k2-api.h" struct MetricsBuffer final : vk::movable_only { private: using bytes_vector = kphp::stl::vector; - using hasher_type = decltype([](const string& s) noexcept { return static_cast(s.hash()); }); - string metric_name; - kphp::stl::unordered_map tags; + std::string metric_name; + kphp::stl::unordered_map tags; size_t msg_size{0}; explicit MetricsBuffer(std::string_view metric_name) noexcept - : metric_name{metric_name.data(), static_cast(metric_name.length())} { + : metric_name{metric_name} { this->msg_size += MetricsBuffer::string_sizeof(metric_name); } @@ -63,8 +61,7 @@ struct MetricsBuffer final : vk::movable_only { } MetricsBuffer& tag(std::string_view tag_name, std::string_view tag_value) noexcept { - this->tags[string{tag_name.data(), static_cast(tag_name.size())}] = - string{tag_value.data(), static_cast(tag_value.size())}; + this->tags[std::string{tag_name}] = std::string{tag_value}; this->msg_size += MetricsBuffer::string_sizeof(tag_name) + MetricsBuffer::string_sizeof(tag_value); return *this; } From 0608cf2d2ed6471c9ce762ff064b7c1e6324aa03 Mon Sep 17 00:00:00 2001 From: Denis Zubarev Date: Sun, 21 Jun 2026 14:55:45 +0300 Subject: [PATCH 5/6] rename --- runtime-light/stdlib/diagnostics/metrics.h | 56 +++++++++++----------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/runtime-light/stdlib/diagnostics/metrics.h b/runtime-light/stdlib/diagnostics/metrics.h index dc40dcef68..2b3cc402d5 100644 --- a/runtime-light/stdlib/diagnostics/metrics.h +++ b/runtime-light/stdlib/diagnostics/metrics.h @@ -13,7 +13,7 @@ #include "runtime-common/core/std/containers.h" #include "runtime-light/k2-platform/k2-api.h" -struct MetricsBuffer final : vk::movable_only { +struct MetricBuilder final : vk::movable_only { private: using bytes_vector = kphp::stl::vector; @@ -21,9 +21,9 @@ struct MetricsBuffer final : vk::movable_only { kphp::stl::unordered_map tags; size_t msg_size{0}; - explicit MetricsBuffer(std::string_view metric_name) noexcept + explicit MetricBuilder(std::string_view metric_name) noexcept : metric_name{metric_name} { - this->msg_size += MetricsBuffer::string_sizeof(metric_name); + this->msg_size += MetricBuilder::string_sizeof(metric_name); } template @@ -34,16 +34,16 @@ struct MetricsBuffer final : vk::movable_only { } static void store_string(bytes_vector& buf, const std::string_view& string) noexcept { - MetricsBuffer::store_number(buf, string.size()); + MetricBuilder::store_number(buf, string.size()); buf.insert(buf.end(), string.begin(), string.end()); } void store_msg(bytes_vector& buf) const noexcept { - MetricsBuffer::store_number(buf, this->msg_size); - MetricsBuffer::store_string(buf, std::string_view{this->metric_name.c_str(), this->metric_name.size()}); + MetricBuilder::store_number(buf, this->msg_size); + MetricBuilder::store_string(buf, std::string_view{this->metric_name.c_str(), this->metric_name.size()}); for (const auto& [tag_name, tag_value] : this->tags) { - MetricsBuffer::store_string(buf, std::string_view{tag_name.c_str(), tag_name.size()}); - MetricsBuffer::store_string(buf, std::string_view{tag_value.c_str(), tag_value.size()}); + MetricBuilder::store_string(buf, std::string_view{tag_name.c_str(), tag_name.size()}); + MetricBuilder::store_string(buf, std::string_view{tag_value.c_str(), tag_value.size()}); } } @@ -56,13 +56,13 @@ struct MetricsBuffer final : vk::movable_only { } public: - static MetricsBuffer metric(std::string_view metric_name) noexcept { - return MetricsBuffer{metric_name}; + static MetricBuilder metric(std::string_view metric_name) noexcept { + return MetricBuilder{metric_name}; } - MetricsBuffer& tag(std::string_view tag_name, std::string_view tag_value) noexcept { + MetricBuilder& tag(std::string_view tag_name, std::string_view tag_value) noexcept { this->tags[std::string{tag_name}] = std::string{tag_value}; - this->msg_size += MetricsBuffer::string_sizeof(tag_name) + MetricsBuffer::string_sizeof(tag_value); + this->msg_size += MetricBuilder::string_sizeof(tag_name) + MetricBuilder::string_sizeof(tag_value); return *this; } @@ -71,11 +71,11 @@ struct MetricsBuffer final : vk::movable_only { buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(double) + sizeof(size_t) + this->msg_size); // timestamp_u32 + value_mask_u32 + value_f64 + msg_size_usize + msg_len - uint32_t s_timestamp{timestamp.value_or(MetricsBuffer::s_timestamp_now())}; + uint32_t s_timestamp{timestamp.value_or(MetricBuilder::s_timestamp_now())}; - MetricsBuffer::store_number(buf, s_timestamp); - MetricsBuffer::store_number(buf, static_cast(k2::MetricValueMask::VALUE_MASK)); - MetricsBuffer::store_number(buf, value); + MetricBuilder::store_number(buf, s_timestamp); + MetricBuilder::store_number(buf, static_cast(k2::MetricValueMask::VALUE_MASK)); + MetricBuilder::store_number(buf, value); this->store_msg(buf); return buf; } @@ -86,13 +86,13 @@ struct MetricsBuffer final : vk::movable_only { buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(size_t) + sizeof(double) * values.size() + sizeof(size_t) + this->msg_size); // timestamp_u32 + value_mask_u32 + array_len_usize + value_f64*array_len + msg_size_usize + msg_len - uint32_t s_timestamp{timestamp.value_or(MetricsBuffer::s_timestamp_now())}; + uint32_t s_timestamp{timestamp.value_or(MetricBuilder::s_timestamp_now())}; - MetricsBuffer::store_number(buf, s_timestamp); - MetricsBuffer::store_number(buf, static_cast(k2::MetricValueMask::VALUES_ARRAY_MASK)); - MetricsBuffer::store_number(buf, values.size()); + MetricBuilder::store_number(buf, s_timestamp); + MetricBuilder::store_number(buf, static_cast(k2::MetricValueMask::VALUES_ARRAY_MASK)); + MetricBuilder::store_number(buf, values.size()); for (const auto& value : values) { - MetricsBuffer::store_number(buf, value); + MetricBuilder::store_number(buf, value); } this->store_msg(buf); return buf; @@ -103,11 +103,11 @@ struct MetricsBuffer final : vk::movable_only { buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(double) + sizeof(size_t) + this->msg_size); // timestamp_u32 + value_mask_u32 + count_f64 + msg_size_usize + msg_len - uint32_t s_timestamp{timestamp.value_or(MetricsBuffer::s_timestamp_now())}; + uint32_t s_timestamp{timestamp.value_or(MetricBuilder::s_timestamp_now())}; - MetricsBuffer::store_number(buf, s_timestamp); - MetricsBuffer::store_number(buf, static_cast(k2::MetricValueMask::COUNT_MASK)); - MetricsBuffer::store_number(buf, count); + MetricBuilder::store_number(buf, s_timestamp); + MetricBuilder::store_number(buf, static_cast(k2::MetricValueMask::COUNT_MASK)); + MetricBuilder::store_number(buf, count); this->store_msg(buf); return buf; } @@ -116,10 +116,10 @@ struct MetricsBuffer final : vk::movable_only { bytes_vector buf{}; buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(size_t) + this->msg_size); // timestamp_u32 + value_mask_u32 + msg_size_usize + msg_len - uint32_t s_timestamp{timestamp.value_or(MetricsBuffer::s_timestamp_now())}; + uint32_t s_timestamp{timestamp.value_or(MetricBuilder::s_timestamp_now())}; - MetricsBuffer::store_number(buf, s_timestamp); - MetricsBuffer::store_number(buf, static_cast(k2::MetricValueMask::INC_MASK)); + MetricBuilder::store_number(buf, s_timestamp); + MetricBuilder::store_number(buf, static_cast(k2::MetricValueMask::INC_MASK)); this->store_msg(buf); return buf; } From 12b21ac2294e0edd94a3185e5b60483101945ad2 Mon Sep 17 00:00:00 2001 From: Denis Zubarev Date: Sun, 21 Jun 2026 20:13:22 +0300 Subject: [PATCH 6/6] mask size 32bits to 8bits --- runtime-light/k2-platform/k2-header.h | 2 +- runtime-light/stdlib/diagnostics/metrics.h | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/runtime-light/k2-platform/k2-header.h b/runtime-light/k2-platform/k2-header.h index 393921deaa..f4408693ab 100644 --- a/runtime-light/k2-platform/k2-header.h +++ b/runtime-light/k2-platform/k2-header.h @@ -109,7 +109,7 @@ enum MonitoringSystem { StatsHouse }; * - count value * - counter increment (no payload) */ -enum MetricValueMask : uint32_t { VALUE_MASK = 0, VALUES_ARRAY_MASK = 1, COUNT_MASK = 2, INC_MASK = 3 }; +enum MetricValueMask : uint8_t { VALUE_MASK = 0, VALUES_ARRAY_MASK = 1, COUNT_MASK = 2, INC_MASK = 3 }; struct ImageInfo { // Base diff --git a/runtime-light/stdlib/diagnostics/metrics.h b/runtime-light/stdlib/diagnostics/metrics.h index 2b3cc402d5..36424b9a86 100644 --- a/runtime-light/stdlib/diagnostics/metrics.h +++ b/runtime-light/stdlib/diagnostics/metrics.h @@ -68,13 +68,13 @@ struct MetricBuilder final : vk::movable_only { bytes_vector build_value(double value, std::optional timestamp = std::nullopt) const noexcept { bytes_vector buf{}; - buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(double) + sizeof(size_t) + - this->msg_size); // timestamp_u32 + value_mask_u32 + value_f64 + msg_size_usize + msg_len + buf.reserve(sizeof(uint32_t) + sizeof(uint8_t) + sizeof(double) + sizeof(size_t) + + this->msg_size); // timestamp_u32 + value_mask_u8 + value_f64 + msg_size_usize + msg_len uint32_t s_timestamp{timestamp.value_or(MetricBuilder::s_timestamp_now())}; MetricBuilder::store_number(buf, s_timestamp); - MetricBuilder::store_number(buf, static_cast(k2::MetricValueMask::VALUE_MASK)); + MetricBuilder::store_number(buf, static_cast(k2::MetricValueMask::VALUE_MASK)); MetricBuilder::store_number(buf, value); this->store_msg(buf); return buf; @@ -83,13 +83,13 @@ struct MetricBuilder final : vk::movable_only { bytes_vector build_values_array(const kphp::stl::vector& values, std::optional timestamp = std::nullopt) const noexcept { bytes_vector buf{}; - buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(size_t) + sizeof(double) * values.size() + sizeof(size_t) + - this->msg_size); // timestamp_u32 + value_mask_u32 + array_len_usize + value_f64*array_len + msg_size_usize + msg_len + buf.reserve(sizeof(uint32_t) + sizeof(uint8_t) + sizeof(size_t) + sizeof(double) * values.size() + sizeof(size_t) + + this->msg_size); // timestamp_u32 + value_mask_u8 + array_len_usize + value_f64*array_len + msg_size_usize + msg_len uint32_t s_timestamp{timestamp.value_or(MetricBuilder::s_timestamp_now())}; MetricBuilder::store_number(buf, s_timestamp); - MetricBuilder::store_number(buf, static_cast(k2::MetricValueMask::VALUES_ARRAY_MASK)); + MetricBuilder::store_number(buf, static_cast(k2::MetricValueMask::VALUES_ARRAY_MASK)); MetricBuilder::store_number(buf, values.size()); for (const auto& value : values) { MetricBuilder::store_number(buf, value); @@ -100,13 +100,13 @@ struct MetricBuilder final : vk::movable_only { bytes_vector build_count(double count, std::optional timestamp = std::nullopt) const noexcept { bytes_vector buf{}; - buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(double) + sizeof(size_t) + - this->msg_size); // timestamp_u32 + value_mask_u32 + count_f64 + msg_size_usize + msg_len + buf.reserve(sizeof(uint32_t) + sizeof(uint8_t) + sizeof(double) + sizeof(size_t) + + this->msg_size); // timestamp_u32 + value_mask_u8 + count_f64 + msg_size_usize + msg_len uint32_t s_timestamp{timestamp.value_or(MetricBuilder::s_timestamp_now())}; MetricBuilder::store_number(buf, s_timestamp); - MetricBuilder::store_number(buf, static_cast(k2::MetricValueMask::COUNT_MASK)); + MetricBuilder::store_number(buf, static_cast(k2::MetricValueMask::COUNT_MASK)); MetricBuilder::store_number(buf, count); this->store_msg(buf); return buf; @@ -114,12 +114,12 @@ struct MetricBuilder final : vk::movable_only { bytes_vector build_increment(std::optional timestamp = std::nullopt) const noexcept { bytes_vector buf{}; - buf.reserve(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(size_t) + this->msg_size); // timestamp_u32 + value_mask_u32 + msg_size_usize + msg_len + buf.reserve(sizeof(uint32_t) + sizeof(uint8_t) + sizeof(size_t) + this->msg_size); // timestamp_u32 + value_mask_u8 + msg_size_usize + msg_len uint32_t s_timestamp{timestamp.value_or(MetricBuilder::s_timestamp_now())}; MetricBuilder::store_number(buf, s_timestamp); - MetricBuilder::store_number(buf, static_cast(k2::MetricValueMask::INC_MASK)); + MetricBuilder::store_number(buf, static_cast(k2::MetricValueMask::INC_MASK)); this->store_msg(buf); return buf; }