1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
// Copyright 2021 Twitter, Inc.
// Licensed under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
use crate::{Metric, Value};
use std::any::Any;
use std::sync::atomic::{AtomicU64, Ordering};
/// A counter. Can be incremented or added to.
///
/// In case of overflow the counter will wrap around. However, internally it
/// uses an unsigned 64-bit integer so for most use cases this should be
/// unlikely.
///
/// # Example
/// ```
/// # use metriken::{metric, Counter};
/// #[metric(name = "my.custom.metric")]
/// static MY_COUNTER: Counter = Counter::new();
///
/// fn a_method() {
/// MY_COUNTER.increment();
/// // ...
/// }
/// # a_method();
/// ```
#[derive(Default, Debug)]
pub struct Counter(AtomicU64);
impl Counter {
/// Create a counter initialized to 0.
pub const fn new() -> Self {
Self::with_value(0)
}
/// Create a counter initialized to `value`.
pub const fn with_value(value: u64) -> Self {
Self(AtomicU64::new(value))
}
#[inline]
pub fn increment(&self) -> u64 {
self.add(1)
}
#[inline]
pub fn add(&self, value: u64) -> u64 {
self.0.fetch_add(value, Ordering::Relaxed)
}
#[inline]
pub fn value(&self) -> u64 {
self.0.load(Ordering::Relaxed)
}
#[inline]
pub fn set(&self, value: u64) -> u64 {
self.0.swap(value, Ordering::Relaxed)
}
#[inline]
pub fn reset(&self) -> u64 {
self.set(0)
}
}
impl Metric for Counter {
fn as_any(&self) -> Option<&dyn Any> {
Some(self)
}
fn value(&self) -> Option<Value> {
Some(Value::Counter(self.value()))
}
}