Skip to content

Commit

Permalink
feat(metrics): support Gauge<u32, AtomicU32> type (#191)
Browse files Browse the repository at this point in the history
Signed-off-by: koushiro <koushiro.cqx@gmail.com>
  • Loading branch information
koushiro committed Mar 7, 2024
1 parent 4eecdc3 commit de27234
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 21 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.22.2]

### Added

- Added `Gauge<u32, AtomicU32>` implementation.
See [PR 191].

[PR 191]: https://github.com/prometheus/client_rust/pull/191

## [0.22.1]

### Added
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "prometheus-client"
version = "0.22.1"
version = "0.22.2"
authors = ["Max Inden <mail@max-inden.de>"]
edition = "2021"
description = "Open Metrics client library allowing users to natively instrument applications."
Expand Down
14 changes: 12 additions & 2 deletions src/encoding.rs
Expand Up @@ -544,6 +544,12 @@ pub trait EncodeGaugeValue {
fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error>;
}

impl EncodeGaugeValue for u32 {
fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
encoder.encode_u32(*self)
}
}

impl EncodeGaugeValue for i64 {
fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
encoder.encode_i64(*self)
Expand All @@ -568,13 +574,17 @@ enum GaugeValueEncoderInner<'a> {
}

impl<'a> GaugeValueEncoder<'a> {
fn encode_f64(&mut self, v: f64) -> Result<(), std::fmt::Error> {
for_both_mut!(self, GaugeValueEncoderInner, e, e.encode_f64(v))
fn encode_u32(&mut self, v: u32) -> Result<(), std::fmt::Error> {
for_both_mut!(self, GaugeValueEncoderInner, e, e.encode_u32(v))
}

fn encode_i64(&mut self, v: i64) -> Result<(), std::fmt::Error> {
for_both_mut!(self, GaugeValueEncoderInner, e, e.encode_i64(v))
}

fn encode_f64(&mut self, v: f64) -> Result<(), std::fmt::Error> {
for_both_mut!(self, GaugeValueEncoderInner, e, e.encode_f64(v))
}
}

impl<'a> From<text::GaugeValueEncoder<'a>> for GaugeValueEncoder<'a> {
Expand Down
4 changes: 4 additions & 0 deletions src/encoding/protobuf.rs
Expand Up @@ -323,6 +323,10 @@ pub(crate) struct GaugeValueEncoder<'a> {
}

impl<'a> GaugeValueEncoder<'a> {
pub fn encode_u32(&mut self, v: u32) -> Result<(), std::fmt::Error> {
self.encode_i64(v as i64)
}

pub fn encode_i64(&mut self, v: i64) -> Result<(), std::fmt::Error> {
*self.value = openmetrics_data_model::gauge_value::Value::IntValue(v);
Ok(())
Expand Down
13 changes: 11 additions & 2 deletions src/encoding/text.rs
Expand Up @@ -423,9 +423,9 @@ impl<'a> std::fmt::Debug for GaugeValueEncoder<'a> {
}

impl<'a> GaugeValueEncoder<'a> {
pub fn encode_f64(&mut self, v: f64) -> Result<(), std::fmt::Error> {
pub fn encode_u32(&mut self, v: u32) -> Result<(), std::fmt::Error> {
self.writer.write_str(" ")?;
self.writer.write_str(dtoa::Buffer::new().format(v))?;
self.writer.write_str(itoa::Buffer::new().format(v))?;
Ok(())
}

Expand All @@ -434,6 +434,12 @@ impl<'a> GaugeValueEncoder<'a> {
self.writer.write_str(itoa::Buffer::new().format(v))?;
Ok(())
}

pub fn encode_f64(&mut self, v: f64) -> Result<(), std::fmt::Error> {
self.writer.write_str(" ")?;
self.writer.write_str(dtoa::Buffer::new().format(v))?;
Ok(())
}
}

pub(crate) struct ExemplarValueEncoder<'a> {
Expand Down Expand Up @@ -565,6 +571,7 @@ mod tests {
use crate::metrics::{counter::Counter, exemplar::CounterWithExemplar};
use pyo3::{prelude::*, types::PyModule};
use std::borrow::Cow;
use std::sync::atomic::AtomicU32;

#[test]
fn encode_counter() {
Expand Down Expand Up @@ -632,6 +639,8 @@ mod tests {
let mut registry = Registry::default();
let gauge: Gauge = Gauge::default();
registry.register("my_gauge", "My gauge", gauge);
let gauge = Gauge::<u32, AtomicU32>::default();
registry.register("u32_gauge", "Gauge::<u32, AtomicU32>", gauge);

let mut encoded = String::new();

Expand Down
58 changes: 42 additions & 16 deletions src/metrics/gauge.rs
Expand Up @@ -6,7 +6,7 @@ use crate::encoding::{EncodeGaugeValue, EncodeMetric, MetricEncoder};

use super::{MetricType, TypedMetric};
use std::marker::PhantomData;
use std::sync::atomic::{AtomicI32, Ordering};
use std::sync::atomic::{AtomicI32, AtomicU32, Ordering};
#[cfg(not(any(target_arch = "mips", target_arch = "powerpc")))]
use std::sync::atomic::{AtomicI64, AtomicU64};
use std::sync::Arc;
Expand Down Expand Up @@ -134,55 +134,81 @@ pub trait Atomic<N> {
fn get(&self) -> N;
}

#[cfg(not(any(target_arch = "mips", target_arch = "powerpc")))]
impl Atomic<i64> for AtomicI64 {
fn inc(&self) -> i64 {
impl Atomic<i32> for AtomicI32 {
fn inc(&self) -> i32 {
self.inc_by(1)
}

fn inc_by(&self, v: i64) -> i64 {
fn inc_by(&self, v: i32) -> i32 {
self.fetch_add(v, Ordering::Relaxed)
}

fn dec(&self) -> i64 {
fn dec(&self) -> i32 {
self.dec_by(1)
}

fn dec_by(&self, v: i64) -> i64 {
fn dec_by(&self, v: i32) -> i32 {
self.fetch_sub(v, Ordering::Relaxed)
}

fn set(&self, v: i64) -> i64 {
fn set(&self, v: i32) -> i32 {
self.swap(v, Ordering::Relaxed)
}

fn get(&self) -> i64 {
fn get(&self) -> i32 {
self.load(Ordering::Relaxed)
}
}

impl Atomic<i32> for AtomicI32 {
fn inc(&self) -> i32 {
impl Atomic<u32> for AtomicU32 {
fn inc(&self) -> u32 {
self.inc_by(1)
}

fn inc_by(&self, v: i32) -> i32 {
fn inc_by(&self, v: u32) -> u32 {
self.fetch_add(v, Ordering::Relaxed)
}

fn dec(&self) -> i32 {
fn dec(&self) -> u32 {
self.dec_by(1)
}

fn dec_by(&self, v: i32) -> i32 {
fn dec_by(&self, v: u32) -> u32 {
self.fetch_sub(v, Ordering::Relaxed)
}

fn set(&self, v: i32) -> i32 {
fn set(&self, v: u32) -> u32 {
self.swap(v, Ordering::Relaxed)
}

fn get(&self) -> i32 {
fn get(&self) -> u32 {
self.load(Ordering::Relaxed)
}
}

#[cfg(not(any(target_arch = "mips", target_arch = "powerpc")))]
impl Atomic<i64> for AtomicI64 {
fn inc(&self) -> i64 {
self.inc_by(1)
}

fn inc_by(&self, v: i64) -> i64 {
self.fetch_add(v, Ordering::Relaxed)
}

fn dec(&self) -> i64 {
self.dec_by(1)
}

fn dec_by(&self, v: i64) -> i64 {
self.fetch_sub(v, Ordering::Relaxed)
}

fn set(&self, v: i64) -> i64 {
self.swap(v, Ordering::Relaxed)
}

fn get(&self) -> i64 {
self.load(Ordering::Relaxed)
}
}
Expand Down

0 comments on commit de27234

Please sign in to comment.