diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /toolkit/components/glean/build_scripts/glean_parser_ext/templates/jog_factory.jinja2 | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/glean/build_scripts/glean_parser_ext/templates/jog_factory.jinja2')
-rw-r--r-- | toolkit/components/glean/build_scripts/glean_parser_ext/templates/jog_factory.jinja2 | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/toolkit/components/glean/build_scripts/glean_parser_ext/templates/jog_factory.jinja2 b/toolkit/components/glean/build_scripts/glean_parser_ext/templates/jog_factory.jinja2 new file mode 100644 index 0000000000..96973d38a4 --- /dev/null +++ b/toolkit/components/glean/build_scripts/glean_parser_ext/templates/jog_factory.jinja2 @@ -0,0 +1,148 @@ +// -*- mode: Rust -*- + +// AUTOGENERATED BY glean_parser. DO NOT EDIT. +{# The rendered source is autogenerated, but this +Jinja2 template is not. Please file bugs! #} + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/// This file contains factory implementation information for the +/// JOG Runtime Registration module. +/// It is responsible for being able to build metrics and pings described at runtime. +/// It is generated to keep it in sync with how the runtime definitions are defined. + +use std::borrow::Cow; +use std::sync::atomic::{AtomicU32, Ordering}; +use crate::private::{ + CommonMetricData, + Lifetime, + MemoryUnit, + TimeUnit, + Ping, + LabeledMetric, +{% for metric_type_name in metric_types.keys() if not metric_type_name.startswith('labeled_') %} + {{ metric_type_name|Camelize }}Metric, +{% endfor %}}; +use crate::private::traits::HistogramType; + +pub(crate) static DYNAMIC_METRIC_BIT: u32 = {{runtime_metric_bit}}; +// 2**DYNAMIC_METRIC_BIT + 1 (+1 because we reserve the 0 metric id) +static NEXT_METRIC_ID: AtomicU32 = AtomicU32::new({{2**runtime_metric_bit + 1}}); +#[cfg(feature = "with_gecko")] // only used in submit_ping_by_id, which is gecko-only. +pub(crate) static DYNAMIC_PING_BIT: u32 = {{runtime_ping_bit}}; +// 2**DYNAMIC_PING_BIT + 1 (+1 because we reserve the 0 ping id) +static NEXT_PING_ID: AtomicU32 = AtomicU32::new({{2**runtime_ping_bit + 1}}); + +pub(crate) mod __jog_metric_maps { + use crate::metrics::DynamicLabel; + use crate::private::MetricId; + use crate::private::{ + Ping, + LabeledMetric, + NoExtraKeys, + {% for metric_type_name in metric_types.keys() %} + {{ metric_type_name|Camelize }}Metric, + {% endfor %} + }; + use once_cell::sync::Lazy; + use std::collections::HashMap; + use std::sync::{Arc, RwLock}; + +{% for metric_type_name in metric_types.keys() if metric_type_name != "event" and not metric_type_name.startswith('labeled_') %} + pub static {{ metric_type_name.upper() }}_MAP: Lazy<Arc<RwLock<HashMap<MetricId, {{ metric_type_name|Camelize }}Metric>>>> = + Lazy::new(|| Arc::new(RwLock::new(HashMap::new()))); + +{% endfor %} +{# Labeled metrics are special because they're LabeledMetric<Labeled{Counter|Boolean|...}Metric> #} +{% for metric_type_name in metric_types.keys() if metric_type_name.startswith('labeled_') %} + pub static {{ metric_type_name.upper() }}_MAP: Lazy<Arc<RwLock<HashMap<MetricId, LabeledMetric<{{ metric_type_name|Camelize }}Metric, DynamicLabel>>>>> = + Lazy::new(|| Arc::new(RwLock::new(HashMap::new()))); + +{% endfor %} + pub static PING_MAP: Lazy<Arc<RwLock<HashMap<u32, Ping>>>> = + Lazy::new(|| Arc::new(RwLock::new(HashMap::new()))); + +{# Event metrics are special because they're EventMetric<K> #} + pub static EVENT_MAP: Lazy<Arc<RwLock<HashMap<MetricId, EventMetric<NoExtraKeys>>>>> = + Lazy::new(|| Arc::new(RwLock::new(HashMap::new()))); +} + +#[derive(Debug)] +struct MetricTypeNotFoundError(String); +impl std::error::Error for MetricTypeNotFoundError {} +impl std::fmt::Display for MetricTypeNotFoundError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Metric type {} not found", self.0) + } +} + +/// Creates and registers a metric, returning its type+id. +pub fn create_and_register_metric( + metric_type: &str, +{# The rest of these are handrolled because it proved easier than maintaining a +map of argument name to argument type. I may regret this if I need it again. #} +{# In order of util.common_metric_args and util.extra_metric_args, because why not. #} + category: String, + name: String, + send_in_pings: Vec<String>, + lifetime: Lifetime, + disabled: bool, + time_unit: Option<TimeUnit>, + memory_unit: Option<MemoryUnit>, + allowed_extra_keys: Option<Vec<String>>, +{# Skipping reason_codes since that's a ping thing. #} + range_min: Option<u64>, + range_max: Option<u64>, + bucket_count: Option<u64>, + histogram_type: Option<HistogramType>, + numerators: Option<Vec<CommonMetricData>>, +{# And, don't forget the list of acceptable labels for a labeled metric. #} + labels: Option<Vec<Cow<'static, str>>>, +) -> Result<(u32, u32), Box<dyn std::error::Error>> { + let metric_id = NEXT_METRIC_ID.fetch_add(1, Ordering::SeqCst); + let metric32 = match metric_type { +{% for metric_type_name, metric_type in metric_types.items() %} + "{{ metric_type_name }}" => { + let metric = {{ metric_type_name|Camelize if not metric_type_name.startswith('labeled_') else "Labeled"}}Metric::{% if metric_type_name == 'event' %}with_runtime_extra_keys{% else %}new{% endif %}(metric_id.into(), CommonMetricData { + {% for arg_name in common_metric_data_args if arg_name in metric_type.args %} + {{ arg_name }}, + {% endfor %} + ..Default::default() + } + {%- for arg_name in metric_type.args if arg_name not in common_metric_data_args -%} + , {{ arg_name }}.unwrap() + {%- endfor -%} + {%- if metric_type_name.startswith('labeled_') -%} + , labels + {%- endif -%} + ); + let metric32: u32 = ({{metric_type.id}} << {{ID_BITS}}) | metric_id; + assert!( + __jog_metric_maps::{{metric_type_name.upper()}}_MAP.write()?.insert(metric_id.into(), metric).is_none(), + "We should never insert a runtime metric with an already-used id." + ); + metric32 + } +{% endfor %} + _ => return Err(Box::new(MetricTypeNotFoundError(metric_type.to_string()))) + }; + Ok((metric32, metric_id)) +} + +/// Creates and registers a ping, returning its id. +pub fn create_and_register_ping( + ping_name: String, + include_client_id: bool, + send_if_empty: bool, + reason_codes: Vec<String>, +) -> Result<u32, Box<dyn std::error::Error>> { + let ping_id = NEXT_PING_ID.fetch_add(1, Ordering::SeqCst); + let ping = Ping::new(ping_name, include_client_id, send_if_empty, reason_codes); + assert!( + __jog_metric_maps::PING_MAP.write()?.insert(ping_id.into(), ping).is_none(), + "We should never insert a runtime ping with an already-used id." + ); + Ok(ping_id) +} |