{-| This is an internal module. The public interface is re-exported by "OpenTelemetry.Eventlog" This module implements the instruments of the metrics portion of the OpenTelemetry API. It is reexported by "OpenTelemetry.Eventlog" and should be used by importing that. The way to use the 'Instrument' type is throught the 'add', 'record' or 'observe' functions (depending on the instrument type) which capture metrics on a given instrument. Usage: @ import OpenTelemetry.Eventlog aCounter :: Counter aCounter = Counter "myCounter" anObserver :: ValueObserver anObserver = ValueObserver "myObserver" main :: IO () main = do add aCounter 3 record anObserver 40 @ -} {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE StandaloneDeriving #-} module OpenTelemetry.Metrics_Internal ( Instrument(..) , SomeInstrument(..) -- * Synonyms for specific types of Instrument , Counter , UpDownCounter , ValueRecorder , SumObserver , UpDownSumObserver , ValueObserver -- * Used for indexing Instrument. All possible combinations are covered , Synchronicity(..) , Additivity(..) , Monotonicity(..) , InstrumentName , InstrumentId , instrumentName , instrumentId ) where import Data.Hashable (Hashable(..)) import Data.ByteString as BS import Data.Word data Synchronicity = Synchronous | Asynchronous data Additivity = Additive | NonAdditive data Monotonicity = Monotonic | NonMonotonic type InstrumentName = BS.ByteString type InstrumentId = Word64 type Counter = Instrument 'Synchronous 'Additive 'Monotonic type UpDownCounter = Instrument 'Synchronous 'Additive 'NonMonotonic type ValueRecorder = Instrument 'Synchronous 'NonAdditive 'NonMonotonic type SumObserver = Instrument 'Asynchronous 'Additive 'Monotonic type UpDownSumObserver = Instrument 'Asynchronous 'Additive 'NonMonotonic type ValueObserver = Instrument 'Asynchronous 'NonAdditive 'NonMonotonic -- TODO: Support tags -- | An OpenTelemetry instrument as defined in the OpenTelemetry Metrics API -- () data Instrument (s :: Synchronicity) (a :: Additivity) (m :: Monotonicity) where Counter :: InstrumentName -> InstrumentId -> Counter UpDownCounter :: InstrumentName -> InstrumentId -> UpDownCounter ValueRecorder :: InstrumentName -> InstrumentId -> ValueRecorder SumObserver :: InstrumentName -> InstrumentId -> SumObserver UpDownSumObserver :: InstrumentName -> InstrumentId -> UpDownSumObserver ValueObserver :: InstrumentName -> InstrumentId -> ValueObserver -- | Existential wrapper for 'Instrument'. Use when the exact type of Instrument does not matter. data SomeInstrument = forall s a m. SomeInstrument (Instrument s a m) instrumentName :: Instrument s a m -> InstrumentName instrumentName (Counter n _) = n instrumentName (UpDownCounter n _) = n instrumentName (ValueRecorder n _) = n instrumentName (SumObserver n _) = n instrumentName (UpDownSumObserver n _) = n instrumentName (ValueObserver n _) = n instrumentId :: Instrument s a m -> InstrumentId instrumentId (Counter _ i) = i instrumentId (UpDownCounter _ i) = i instrumentId (ValueRecorder _ i) = i instrumentId (SumObserver _ i) = i instrumentId (UpDownSumObserver _ i) = i instrumentId (ValueObserver _ i) = i deriving instance Show (Instrument s a m) deriving instance Eq (Instrument s a m) instance Show SomeInstrument where show (SomeInstrument i) = show i instance Eq SomeInstrument where (SomeInstrument i1) == (SomeInstrument i2) = case (i1, i2) of (Counter s1 id1, Counter s2 id2) -> s1 == s2 && id1 == id2 (UpDownCounter s1 id1, UpDownCounter s2 id2) -> s1 == s2 && id1 == id2 (ValueRecorder s1 id1, ValueRecorder s2 id2) -> s1 == s2 && id1 == id2 (SumObserver s1 id1, SumObserver s2 id2) -> s1 == s2 && id1 == id2 (UpDownSumObserver s1 id1, UpDownSumObserver s2 id2) -> s1 == s2 && id1 == id2 (ValueObserver s1 id1, ValueObserver s2 id2) -> s1 == s2 && id1 == id2 (_, _) -> False instance Hashable (Instrument s a m) where hashWithSalt s i = s `hashWithSalt` (constructorIdx i) `hashWithSalt` (instrumentName i) where constructorIdx :: Instrument s a m -> Int constructorIdx Counter{} = 0 constructorIdx UpDownCounter{} = 1 constructorIdx ValueRecorder{} = 2 constructorIdx SumObserver{} = 3 constructorIdx UpDownSumObserver{} = 4 constructorIdx ValueObserver{} = 5 instance Hashable SomeInstrument where hashWithSalt s (SomeInstrument i) = hashWithSalt s i