Skip to main content

lading_capture/
json.rs

1//! JSON form of a Lading capture Line, meant to be read line by line from a
2//! file.
3
4use rustc_hash::FxHashMap;
5use serde::{Deserialize, Serialize};
6use uuid::Uuid;
7
8#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
9#[serde(rename_all = "snake_case")]
10/// The kinds of metrics that are recorded in [`Line`].
11pub enum MetricKind {
12    /// A monotonically increasing value.
13    Counter,
14    /// A point-at-time value.
15    Gauge,
16}
17
18#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
19/// The value for [`Line`].
20#[serde(untagged)]
21pub enum LineValue {
22    /// A signless integer, 64 bits wide
23    Int(u64),
24    /// A floating point, 64 bits wide
25    Float(f64),
26}
27
28impl LineValue {
29    /// Get an f64 representation of this value. Extremely large integers will be truncated.
30    #[must_use]
31    #[allow(clippy::cast_precision_loss)]
32    pub fn as_f64(&self) -> f64 {
33        match self {
34            LineValue::Int(int) => *int as f64,
35            LineValue::Float(float) => *float,
36        }
37    }
38}
39
40impl std::fmt::Display for LineValue {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        match self {
43            LineValue::Int(int) => write!(f, "{int}"),
44            LineValue::Float(float) => write!(f, "{float}"),
45        }
46    }
47}
48
49#[derive(Debug, Serialize, Deserialize)]
50/// The structure of a capture file line.
51pub struct Line {
52    /// An id that is mostly unique to this run, allowing us to distinguish
53    /// duplications of the same observational setup.
54    pub run_id: Uuid,
55    /// The time in milliseconds that this line was written.
56    pub time: u128,
57    /// The "fetch index". Previous versions of lading scraped prometheus
58    /// metrics from their targets and kept an increment index of polls. Now
59    /// this records the number of times the internal metrics cache has been
60    /// flushed.
61    pub fetch_index: u64,
62    /// The name of the metric recorded by this line.
63    pub metric_name: String,
64    /// The kind of metric recorded by this line.
65    pub metric_kind: MetricKind,
66    /// The value of the metric on this line.
67    pub value: LineValue,
68    #[serde(flatten)]
69    /// The labels associated with this metric.
70    pub labels: FxHashMap<String, String>,
71}
72
73impl Line {
74    #[must_use]
75    #[allow(clippy::cast_possible_truncation)]
76    /// Returns the number of seconds since unix epoch
77    pub fn seconds_since_epoch(&self) -> u64 {
78        let seconds: u128 = self.time / 1_000;
79        seconds as u64
80    }
81}