packages feed

wai-middleware-prometheus 0.3.0 → 1.0.0

raw patch · 2 files changed

+55/−34 lines, 2 filesdep ~prometheus-clientnew-uploaderPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: prometheus-client

API changes (from Hackage documentation)

+ Network.Wai.Middleware.Prometheus: instrumentHandlerValue :: (Request -> Text) -> Application -> Application
- Network.Wai.Middleware.Prometheus: instrumentApp :: String -> Application -> Application
+ Network.Wai.Middleware.Prometheus: instrumentApp :: Text -> Application -> Application
- Network.Wai.Middleware.Prometheus: instrumentIO :: String -> IO a -> IO a
+ Network.Wai.Middleware.Prometheus: instrumentIO :: Text -> IO a -> IO a

Files

src/Network/Wai/Middleware/Prometheus.hs view
@@ -2,21 +2,23 @@ -- metrics and for instrumenting WAI applications. {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}-module Network.Wai.Middleware.Prometheus (-    prometheus-,   PrometheusSettings (..)-,   Default.def-,   instrumentApp-,   instrumentIO-,   metricsApp-) where -import qualified Data.ByteString.Builder as BS-import qualified Data.ByteString.Char8 as BS+module Network.Wai.Middleware.Prometheus+  ( prometheus+  , PrometheusSettings(..)+  , Default.def+  , instrumentHandlerValue+  , instrumentApp+  , instrumentIO+  , metricsApp+  ) where+ import qualified Data.Default as Default import Data.Maybe (fromMaybe) import Data.Ratio ((%))+import Data.Text (Text) import qualified Data.Text as T+import Data.Text.Encoding (decodeUtf8) import qualified Network.HTTP.Types as HTTP import qualified Network.Wai as Wai import qualified Prometheus as Prom@@ -47,28 +49,41 @@     }  {-# NOINLINE requestLatency #-}-requestLatency :: Prom.Metric (Prom.Vector Prom.Label3 Prom.Histogram)-requestLatency = Prom.unsafeRegisterIO $ Prom.vector ("handler", "method", "status_code")-                                       $ Prom.histogram info Prom.defaultBuckets+requestLatency :: Prom.Vector Prom.Label3 Prom.Histogram+requestLatency = Prom.unsafeRegister $ Prom.vector ("handler", "method", "status_code")+                                     $ Prom.histogram info Prom.defaultBuckets     where info = Prom.Info "http_request_duration_seconds"                            "The HTTP request latencies in seconds." +-- | This function is used to populate the @handler@ label of all Prometheus metrics recorded by this library.+--+-- If you use this function you will likely want to override the default value+-- of 'prometheusInstrumentApp' to be false so that your app does not get double+-- instrumented.+instrumentHandlerValue ::+     (Wai.Request -> Text) -- ^ The function used to derive the "handler" value in Prometheus+  -> Wai.Application -- ^ The app to instrument+  -> Wai.Application -- ^ The instrumented app+instrumentHandlerValue f app req respond = do+  start <- getTime Monotonic+  app req $ \res -> do+    end <- getTime Monotonic+    let method = Just $ decodeUtf8 (Wai.requestMethod req)+    let status = Just $ T.pack (show (HTTP.statusCode (Wai.responseStatus res)))+    observeSeconds (f req) method status start end+    respond res+ -- | Instrument a WAI app with the default WAI metrics. -- -- If you use this function you will likely want to override the default value -- of 'prometheusInstrumentApp' to be false so that your app does not get double -- instrumented.-instrumentApp :: String           -- ^ The label used to identify this app-              -> Wai.Application  -- ^ The app to instrument-              -> Wai.Application  -- ^ The instrumented app-instrumentApp handler app req respond = do-    start <- getTime Monotonic-    app req $ \res -> do-        end <- getTime Monotonic-        let method = Just $ BS.unpack (Wai.requestMethod req)-        let status = Just $ show (HTTP.statusCode (Wai.responseStatus res))-        observeSeconds handler method status start end-        respond res+instrumentApp ::+     Text -- ^ The label used to identify this app+  -> Wai.Application -- ^ The app to instrument+  -> Wai.Application -- ^ The instrumented app+instrumentApp handler app req respond =+  instrumentHandlerValue (const handler) app req respond  -- | Instrument an IO action with timing metrics. This function can be used if -- you would like to get more fine grained metrics, for instance this can be@@ -77,7 +92,7 @@ -- If you use this function you will likely want to override the default value -- of 'prometheusInstrumentApp' to be false so that your app does not get double -- instrumented.-instrumentIO :: String  -- ^ The label used to identify this IO operation+instrumentIO :: Text    -- ^ The label used to identify this IO operation              -> IO a    -- ^ The IO action to instrument              -> IO a    -- ^ The instrumented app instrumentIO label io = do@@ -87,12 +102,12 @@     observeSeconds label Nothing Nothing start end     return result -observeSeconds :: String -> Maybe String -> Maybe String -> TimeSpec -> TimeSpec -> IO ()+observeSeconds :: Text -> Maybe Text -> Maybe Text -> TimeSpec -> TimeSpec -> IO () observeSeconds handler method status start end = do     let latency = fromRational $ toRational (toNanoSecs (end `diffTimeSpec` start) % 1000000000)-    Prom.withLabel (handler, fromMaybe "" method, fromMaybe "" status)-                   (Prom.observe latency)-                   requestLatency+    Prom.withLabel requestLatency+                   (handler, fromMaybe "" method, fromMaybe "" status)+                   (flip Prom.observe latency)  -- | Expose Prometheus metrics and instrument an application with some basic -- metrics (e.g. request latency).@@ -102,8 +117,14 @@         && Wai.pathInfo req == prometheusEndPoint         -- XXX: Should probably be "metrics" rather than "prometheus", since         -- "prometheus" can be confused with actual prometheus.-    then instrumentApp "prometheus" (const respondWithMetrics) req respond-    else instrumentApp "app" app req respond+    then+      if prometheusInstrumentPrometheus+        then instrumentApp "prometheus" (const respondWithMetrics) req respond+        else respondWithMetrics respond+    else+      if prometheusInstrumentApp+        then instrumentApp "app" app req respond+        else app req respond   -- | WAI Application that serves the Prometheus metrics page regardless of@@ -115,6 +136,6 @@                    -> IO Wai.ResponseReceived respondWithMetrics respond = do     metrics <- Prom.exportMetricsAsText-    respond $ Wai.responseBuilder HTTP.status200 headers $ BS.byteString metrics+    respond $ Wai.responseLBS HTTP.status200 headers metrics     where         headers = [(HTTP.hContentType, "text/plain; version=0.0.4")]
wai-middleware-prometheus.cabal view
@@ -1,5 +1,5 @@ name:                wai-middleware-prometheus-version:             0.3.0+version:             1.0.0 synopsis:     WAI middlware for exposing http://prometheus.io metrics. description:@@ -29,7 +29,7 @@     , clock     , data-default     , http-types-    , prometheus-client+    , prometheus-client  >=1.0.0 && <1.1     , text               >=0.11     , wai                >=3.0   ghc-options: -Wall