module System.Metrics.Prometheus.Encode.Text ( encodeMetrics, ) where import Data.ByteString.Builder (Builder) import Data.Function (on) import Data.List ( groupBy, intersperse, ) import qualified Data.Map as Map import Data.Monoid ((<>)) import System.Metrics.Prometheus.Encode.Text.Histogram (encodeHistogram) import System.Metrics.Prometheus.Encode.Text.MetricId ( encodeDouble, encodeHeader, encodeInt, encodeMetricId, newline, space, ) import System.Metrics.Prometheus.Metric ( MetricSample (..), metricSample, ) import System.Metrics.Prometheus.Metric.Counter (CounterSample (..)) import System.Metrics.Prometheus.Metric.Gauge (GaugeSample (..)) import System.Metrics.Prometheus.MetricId (MetricId (..)) import System.Metrics.Prometheus.Registry (RegistrySample (..)) encodeMetrics :: RegistrySample -> Builder encodeMetrics :: RegistrySample -> Builder encodeMetrics = (forall a. Semigroup a => a -> a -> a <> Builder newline) forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a. Monoid a => [a] -> a mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a. a -> [a] -> [a] intersperse Builder newline forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a b. (a -> b) -> [a] -> [b] map [(MetricId, MetricSample)] -> Builder encodeMetricGroup forall b c a. (b -> c) -> (a -> b) -> a -> c . forall {b}. [(MetricId, b)] -> [[(MetricId, b)]] groupByName forall b c a. (b -> c) -> (a -> b) -> a -> c . forall k a. Map k a -> [(k, a)] Map.toList forall b c a. (b -> c) -> (a -> b) -> a -> c . RegistrySample -> Map MetricId MetricSample unRegistrySample where groupByName :: [(MetricId, b)] -> [[(MetricId, b)]] groupByName = forall a. (a -> a -> Bool) -> [a] -> [[a]] groupBy (forall a. Eq a => a -> a -> Bool (==) forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c `on` (MetricId -> Name name forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a b. (a, b) -> a fst)) encodeMetricGroup :: [(MetricId, MetricSample)] -> Builder encodeMetricGroup :: [(MetricId, MetricSample)] -> Builder encodeMetricGroup [(MetricId, MetricSample)] group = MetricId -> MetricSample -> Builder encodeHeader MetricId mid MetricSample sample forall a. Semigroup a => a -> a -> a <> Builder newline forall a. Semigroup a => a -> a -> a <> forall a. Monoid a => [a] -> a mconcat (forall a. a -> [a] -> [a] intersperse Builder newline forall a b. (a -> b) -> a -> b $ forall a b. (a -> b) -> [a] -> [b] map (MetricId, MetricSample) -> Builder encodeMetric [(MetricId, MetricSample)] group) where (MetricId mid, MetricSample sample) = forall a. [a] -> a head [(MetricId, MetricSample)] group encodeMetric :: (MetricId, MetricSample) -> Builder encodeMetric :: (MetricId, MetricSample) -> Builder encodeMetric (MetricId mid, MetricSample sample) = forall a. (CounterSample -> a) -> (GaugeSample -> a) -> (HistogramSample -> a) -> (SummarySample -> a) -> MetricSample -> a metricSample (MetricId -> CounterSample -> Builder encodeCounter MetricId mid) (MetricId -> GaugeSample -> Builder encodeGauge MetricId mid) (MetricId -> HistogramSample -> Builder encodeHistogram MetricId mid) (forall {a}. a encodeSummary MetricId mid) MetricSample sample where encodeSummary :: a encodeSummary = forall a. HasCallStack => a undefined encodeCounter :: MetricId -> CounterSample -> Builder encodeCounter :: MetricId -> CounterSample -> Builder encodeCounter MetricId mid CounterSample counter = MetricId -> Builder encodeMetricId MetricId mid forall a. Semigroup a => a -> a -> a <> Builder space forall a. Semigroup a => a -> a -> a <> Int -> Builder encodeInt (CounterSample -> Int unCounterSample CounterSample counter) encodeGauge :: MetricId -> GaugeSample -> Builder encodeGauge :: MetricId -> GaugeSample -> Builder encodeGauge MetricId mid GaugeSample gauge = MetricId -> Builder encodeMetricId MetricId mid forall a. Semigroup a => a -> a -> a <> Builder space forall a. Semigroup a => a -> a -> a <> forall f. RealFloat f => f -> Builder encodeDouble (GaugeSample -> Double unGaugeSample GaugeSample gauge)