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 = (Builder -> Builder -> Builder forall a. Semigroup a => a -> a -> a <> Builder newline) (Builder -> Builder) -> (RegistrySample -> Builder) -> RegistrySample -> Builder forall b c a. (b -> c) -> (a -> b) -> a -> c . [Builder] -> Builder forall a. Monoid a => [a] -> a mconcat ([Builder] -> Builder) -> (RegistrySample -> [Builder]) -> RegistrySample -> Builder forall b c a. (b -> c) -> (a -> b) -> a -> c . Builder -> [Builder] -> [Builder] forall a. a -> [a] -> [a] intersperse Builder newline ([Builder] -> [Builder]) -> (RegistrySample -> [Builder]) -> RegistrySample -> [Builder] forall b c a. (b -> c) -> (a -> b) -> a -> c . ([(MetricId, MetricSample)] -> Builder) -> [[(MetricId, MetricSample)]] -> [Builder] forall a b. (a -> b) -> [a] -> [b] map [(MetricId, MetricSample)] -> Builder encodeMetricGroup ([[(MetricId, MetricSample)]] -> [Builder]) -> (RegistrySample -> [[(MetricId, MetricSample)]]) -> RegistrySample -> [Builder] forall b c a. (b -> c) -> (a -> b) -> a -> c . [(MetricId, MetricSample)] -> [[(MetricId, MetricSample)]] forall b. [(MetricId, b)] -> [[(MetricId, b)]] groupByName ([(MetricId, MetricSample)] -> [[(MetricId, MetricSample)]]) -> (RegistrySample -> [(MetricId, MetricSample)]) -> RegistrySample -> [[(MetricId, MetricSample)]] forall b c a. (b -> c) -> (a -> b) -> a -> c . Map MetricId MetricSample -> [(MetricId, MetricSample)] forall k a. Map k a -> [(k, a)] Map.toList (Map MetricId MetricSample -> [(MetricId, MetricSample)]) -> (RegistrySample -> Map MetricId MetricSample) -> RegistrySample -> [(MetricId, MetricSample)] forall b c a. (b -> c) -> (a -> b) -> a -> c . RegistrySample -> Map MetricId MetricSample unRegistrySample where groupByName :: [(MetricId, b)] -> [[(MetricId, b)]] groupByName = ((MetricId, b) -> (MetricId, b) -> Bool) -> [(MetricId, b)] -> [[(MetricId, b)]] forall a. (a -> a -> Bool) -> [a] -> [[a]] groupBy (Name -> Name -> Bool forall a. Eq a => a -> a -> Bool (==) (Name -> Name -> Bool) -> ((MetricId, b) -> Name) -> (MetricId, b) -> (MetricId, b) -> Bool forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c `on` (MetricId -> Name name (MetricId -> Name) -> ((MetricId, b) -> MetricId) -> (MetricId, b) -> Name forall b c a. (b -> c) -> (a -> b) -> a -> c . (MetricId, b) -> MetricId 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 Builder -> Builder -> Builder forall a. Semigroup a => a -> a -> a <> Builder newline Builder -> Builder -> Builder forall a. Semigroup a => a -> a -> a <> [Builder] -> Builder forall a. Monoid a => [a] -> a mconcat (Builder -> [Builder] -> [Builder] forall a. a -> [a] -> [a] intersperse Builder newline ([Builder] -> [Builder]) -> [Builder] -> [Builder] forall a b. (a -> b) -> a -> b $ ((MetricId, MetricSample) -> Builder) -> [(MetricId, MetricSample)] -> [Builder] forall a b. (a -> b) -> [a] -> [b] map (MetricId, MetricSample) -> Builder encodeMetric [(MetricId, MetricSample)] group) where (MetricId mid, MetricSample sample) = [(MetricId, MetricSample)] -> (MetricId, MetricSample) forall a. [a] -> a head [(MetricId, MetricSample)] group encodeMetric :: (MetricId, MetricSample) -> Builder encodeMetric :: (MetricId, MetricSample) -> Builder encodeMetric (MetricId mid, MetricSample sample) = (CounterSample -> Builder) -> (GaugeSample -> Builder) -> (HistogramSample -> Builder) -> (SummarySample -> Builder) -> MetricSample -> Builder 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) (MetricId -> SummarySample -> Builder forall a. a encodeSummary MetricId mid) MetricSample sample where encodeSummary :: a encodeSummary = a forall a. HasCallStack => a undefined encodeCounter :: MetricId -> CounterSample -> Builder encodeCounter :: MetricId -> CounterSample -> Builder encodeCounter MetricId mid CounterSample counter = MetricId -> Builder encodeMetricId MetricId mid Builder -> Builder -> Builder forall a. Semigroup a => a -> a -> a <> Builder space Builder -> Builder -> Builder 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 Builder -> Builder -> Builder forall a. Semigroup a => a -> a -> a <> Builder space Builder -> Builder -> Builder forall a. Semigroup a => a -> a -> a <> Double -> Builder forall f. RealFloat f => f -> Builder encodeDouble (GaugeSample -> Double unGaugeSample GaugeSample gauge)