prometheus 2.2.2 → 2.2.3
raw patch · 3 files changed
+34/−7 lines, 3 filesdep ~bytestring
Dependency ranges changed: bytestring
Files
- README.md +1/−1
- prometheus.cabal +2/−2
- src/System/Metrics/Prometheus/MetricId.hs +31/−4
README.md view
@@ -69,4 +69,4 @@ - [ ] Encode name and labels on register. - [x] Implement ReaderT for Concurrent Registry. - [x] Library documentation and example.-- [ ] [Name and label validation](http://prometheus.io/docs/concepts/data_model/#metric-names-and-labels)+- [x] [Name and label validation](http://prometheus.io/docs/concepts/data_model/#metric-names-and-labels)
prometheus.cabal view
@@ -1,5 +1,5 @@ name: prometheus-version: 2.2.2+version: 2.2.3 synopsis: Prometheus Haskell Client homepage: http://github.com/bitnomial/prometheus bug-reports: http://github.com/bitnomial/prometheus/issues@@ -84,7 +84,7 @@ build-depends: base >= 4.9 && < 5 , atomic-primops >= 0.8 && < 0.9- , bytestring >= 0.10 && < 0.11+ , bytestring >= 0.10 && < 0.12 , containers >= 0.5 && < 0.7 , http-client >= 0.4 && < 0.8 , http-client-tls >= 0.3 && < 0.4
src/System/Metrics/Prometheus/MetricId.hs view
@@ -1,17 +1,25 @@+{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module System.Metrics.Prometheus.MetricId where +import Data.Char (isDigit)+import Data.Bifunctor (first) import Data.Map (Map) import qualified Data.Map as Map import Data.Monoid (Monoid) import Data.Semigroup (Semigroup)-import Data.String (IsString)+import Data.String (IsString(..)) import Data.Text (Text)+import qualified Data.Text as Text import Prelude hiding (null) +-- | Construct with 'makeName' to ensure that names use only valid characters+newtype Name = Name { unName :: Text } deriving (Show, Eq, Ord, Monoid, Semigroup) -newtype Name = Name { unName :: Text } deriving (Show, Eq, Ord, IsString, Monoid, Semigroup)+instance IsString Name where+ fromString = makeName . Text.pack+ newtype Labels = Labels { unLabels :: Map Text Text } deriving (Show, Eq, Ord, Monoid, Semigroup) @@ -23,11 +31,11 @@ addLabel :: Text -> Text -> Labels -> Labels-addLabel key val = Labels . Map.insert key val . unLabels+addLabel key val = Labels . Map.insert (makeValid key) val . unLabels fromList :: [(Text, Text)] -> Labels-fromList = Labels . Map.fromList+fromList = Labels . Map.fromList . map (first makeValid) toList :: Labels -> [(Text, Text)]@@ -36,3 +44,22 @@ null :: Labels -> Bool null = Map.null . unLabels+++-- | Make the input match the regex @[a-zA-Z_][a-zA-Z0-9_]@ which+-- defines valid metric and label names, according to+-- <https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels>+-- Replace invalid characters with @_@ and add a leading @_@ if the+-- first character is only valid as a later character.+makeValid :: Text -> Text+makeValid "" = "_"+makeValid txt = prefix_ <> Text.map (\c -> if allowedChar c then c else '_' ) txt+ where+ prefix_ = if isDigit (Text.head txt) then "_" else ""+ allowedChar :: Char -> Bool+ allowedChar c = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || isDigit c || c == '_'+++-- | Construct a 'Name', replacing disallowed characters.+makeName :: Text -> Name+makeName = Name . makeValid