diff --git a/src/metric.cpp b/src/metric.cpp index bb278b5..ef36ab1 100644 --- a/src/metric.cpp +++ b/src/metric.cpp @@ -856,6 +856,10 @@ struct Metric { Metric::LabelSets label_sets = Metric::build_label_sets(plan.arena); + // Use temporary arena for formatting static text (will be interned to + // global arena) + ArenaAllocator temp_arena(8192); // 8KB for temporary formatting + // Helper function to append an additional label to existing Prometheus // format auto append_label_to_format = @@ -872,7 +876,7 @@ struct Metric { if (base_format.empty()) { // Create new format: {key="value"} size_t required_size = 2 + key_value_size; // {} - char *buf = plan.arena.allocate(required_size); + char *buf = temp_arena.allocate(required_size); char *p = buf; *p++ = '{'; std::memcpy(p, key.data(), key.length()); @@ -905,7 +909,7 @@ struct Metric { // Append to existing format: {existing,key="value"} size_t required_size = base_format.length() + 1 + key_value_size; // comma + key="value", replace } - char *buf = plan.arena.allocate(required_size); + char *buf = temp_arena.allocate(required_size); char *p = buf; // Copy everything except the closing } std::memcpy(p, base_format.data(), base_format.length() - 1); @@ -948,7 +952,7 @@ struct Metric { for (const auto &[name, family] : get_counter_families()) { // Add HELP line auto help_line = format( - plan.arena, "%s# HELP %.*s %.*s\n# TYPE %.*s counter", + temp_arena, "%s# HELP %.*s %.*s\n# TYPE %.*s counter", is_first_static ? "" : "\n", static_cast(name.length()), name.data(), static_cast(family->help.length()), family->help.data(), static_cast(name.length()), name.data()); @@ -958,7 +962,7 @@ struct Metric { for (const auto &[labels_key, callback] : family->callbacks) { plan.instructions.push_back(CallCounterCallback{&callback}); auto static_text = format( - plan.arena, "%.*s\n%.*s%.*s ", static_cast(help_line.size()), + temp_arena, "%.*s\n%.*s%.*s ", static_cast(help_line.size()), help_line.data(), static_cast(name.length()), name.data(), static_cast(labels_key.prometheus_format.length()), labels_key.prometheus_format.data()); @@ -972,7 +976,7 @@ struct Metric { plan.instructions.push_back( AggregateCounter{data.thread_states, data.global_state}); auto static_text = format( - plan.arena, "%.*s\n%.*s%.*s ", static_cast(help_line.size()), + temp_arena, "%.*s\n%.*s%.*s ", static_cast(help_line.size()), help_line.data(), static_cast(name.length()), name.data(), static_cast(data.labels_key.prometheus_format.length()), data.labels_key.prometheus_format.data()); @@ -986,7 +990,7 @@ struct Metric { for (const auto &[name, family] : get_gauge_families()) { // Add HELP line auto help_line = format( - plan.arena, "%s# HELP %.*s %.*s\n# TYPE %.*s gauge", + temp_arena, "%s# HELP %.*s %.*s\n# TYPE %.*s gauge", is_first_static ? "" : "\n", static_cast(name.length()), name.data(), static_cast(family->help.length()), family->help.data(), static_cast(name.length()), name.data()); @@ -996,7 +1000,7 @@ struct Metric { for (const auto &[labels_key, callback] : family->callbacks) { plan.instructions.push_back(CallGaugeCallback{&callback}); auto static_text = format( - plan.arena, "%.*s\n%.*s%.*s ", static_cast(help_line.size()), + temp_arena, "%.*s\n%.*s%.*s ", static_cast(help_line.size()), help_line.data(), static_cast(name.length()), name.data(), static_cast(labels_key.prometheus_format.length()), labels_key.prometheus_format.data()); @@ -1009,7 +1013,7 @@ struct Metric { for (const auto &data : family_data) { plan.instructions.push_back(AggregateGauge{data.instance_state}); auto static_text = format( - plan.arena, "%.*s\n%.*s%.*s ", static_cast(help_line.size()), + temp_arena, "%.*s\n%.*s%.*s ", static_cast(help_line.size()), help_line.data(), static_cast(name.length()), name.data(), static_cast(data.labels_key.prometheus_format.length()), data.labels_key.prometheus_format.data()); @@ -1022,7 +1026,7 @@ struct Metric { size_t histogram_family_idx = 0; for (const auto &[name, family] : get_histogram_families()) { auto help_line = format( - plan.arena, "%s# HELP %.*s %.*s\n# TYPE %.*s histogram", + temp_arena, "%s# HELP %.*s %.*s\n# TYPE %.*s histogram", is_first_static ? "" : "\n", static_cast(name.length()), name.data(), static_cast(family->help.length()), family->help.data(), static_cast(name.length()), name.data()); @@ -1036,11 +1040,11 @@ struct Metric { // Static text for explicit buckets for (size_t i = 0; i < data.bucket_count; ++i) { - auto bucket_value = static_format(plan.arena, family->buckets[i]); + auto bucket_value = static_format(temp_arena, family->buckets[i]); auto labels = append_label_to_format( data.labels_key.prometheus_format, "le", bucket_value); auto static_text = - format(plan.arena, "%.*s\n%.*s_bucket%.*s ", + format(temp_arena, "%.*s\n%.*s_bucket%.*s ", static_cast(help_line.size()), help_line.data(), static_cast(name.length()), name.data(), static_cast(labels.length()), labels.data()); @@ -1052,14 +1056,14 @@ struct Metric { auto inf_labels = append_label_to_format( data.labels_key.prometheus_format, "le", "+Inf"); auto inf_static_text = - format(plan.arena, "\n%.*s_bucket%.*s ", + format(temp_arena, "\n%.*s_bucket%.*s ", static_cast(name.length()), name.data(), static_cast(inf_labels.length()), inf_labels.data()); plan.static_text.push_back(intern_static_text(inf_static_text)); // Static text for sum auto sum_static_text = - format(plan.arena, "\n%.*s_sum%.*s ", + format(temp_arena, "\n%.*s_sum%.*s ", static_cast(name.length()), name.data(), static_cast(data.labels_key.prometheus_format.length()), data.labels_key.prometheus_format.data()); @@ -1067,7 +1071,7 @@ struct Metric { // Static text for count auto count_static_text = - format(plan.arena, "\n%.*s_count%.*s ", + format(temp_arena, "\n%.*s_count%.*s ", static_cast(name.length()), name.data(), static_cast(data.labels_key.prometheus_format.length()), data.labels_key.prometheus_format.data());