Add weaseldb_metrics_memory_bytes
This commit is contained in:
@@ -425,10 +425,22 @@ struct Metric {
|
||||
return *internedStaticText;
|
||||
}
|
||||
|
||||
// Registry of all thread arenas for memory tracking
|
||||
static auto &get_thread_arenas() {
|
||||
using ThreadArenaMap =
|
||||
std::unordered_map<std::thread::id, ArenaAllocator *>;
|
||||
static ThreadArenaMap *threadArenas = new ThreadArenaMap();
|
||||
return *threadArenas;
|
||||
}
|
||||
|
||||
// Thread cleanup for per-family thread-local storage
|
||||
struct ThreadInit {
|
||||
ArenaAllocator arena;
|
||||
ThreadInit() {}
|
||||
ThreadInit() {
|
||||
// Register this thread's arena for memory tracking
|
||||
std::unique_lock<std::mutex> _{mutex};
|
||||
get_thread_arenas()[std::this_thread::get_id()] = &arena;
|
||||
}
|
||||
~ThreadInit() {
|
||||
// Accumulate thread-local state into global state before cleanup
|
||||
// THREAD SAFETY: All operations below are protected by the global mutex,
|
||||
@@ -442,6 +454,9 @@ struct Metric {
|
||||
++Metric::registration_version;
|
||||
auto thread_id = std::this_thread::get_id();
|
||||
|
||||
// Unregister this thread's arena from memory tracking
|
||||
get_thread_arenas().erase(thread_id);
|
||||
|
||||
// Accumulate counter families
|
||||
for (auto &[name, family] : Metric::get_counter_families()) {
|
||||
auto thread_it = family->per_thread_state.find(thread_id);
|
||||
@@ -1609,8 +1624,38 @@ union MetricValue {
|
||||
uint64_t as_uint64;
|
||||
};
|
||||
|
||||
// Memory usage calculation callback for metrics system self-monitoring
|
||||
static double calculate_metrics_memory_usage() {
|
||||
std::size_t total_bytes = 0;
|
||||
|
||||
// 1. Global arena memory
|
||||
total_bytes += Metric::get_global_arena().total_allocated();
|
||||
|
||||
// 2. Per-thread arenas (safe because we're already holding the global mutex)
|
||||
for (const auto &[thread_id, arena_ptr] : Metric::get_thread_arenas()) {
|
||||
total_bytes += arena_ptr->total_allocated();
|
||||
}
|
||||
|
||||
// 3. Cached plan arena
|
||||
if (Metric::cached_plan) {
|
||||
total_bytes += Metric::cached_plan->arena.total_allocated();
|
||||
}
|
||||
|
||||
return static_cast<double>(total_bytes);
|
||||
}
|
||||
|
||||
// New three-phase render implementation
|
||||
std::span<std::string_view> render(ArenaAllocator &arena) {
|
||||
// Initialize self-monitoring metrics (before taking global lock)
|
||||
static auto memory_gauge = []() {
|
||||
auto gauge = create_gauge("weaseldb_metrics_memory_bytes",
|
||||
"Total memory usage of the metrics system "
|
||||
"including global and per-thread arenas");
|
||||
gauge.register_callback({}, calculate_metrics_memory_usage);
|
||||
return gauge;
|
||||
}();
|
||||
(void)memory_gauge; // Suppress unused variable warning
|
||||
|
||||
// Hold lock throughout all phases to prevent registry changes
|
||||
// THREAD SAFETY: Global mutex protects cached_plan initialization and access,
|
||||
// prevents races during static member initialization at program startup
|
||||
|
||||
Reference in New Issue
Block a user