packages feed

wai-middleware-prometheus 0.1.0.1 → 0.1.1

raw patch · 2 files changed

+36/−20 lines, 2 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Network.Wai.Middleware.Prometheus: instance Default PrometheusSettings
- Network.Wai.Middleware.Prometheus: prometheusEndPoint :: PrometheusSettings -> [Text]
- Network.Wai.Middleware.Prometheus: prometheusInstrumentApp :: PrometheusSettings -> Bool
- Network.Wai.Middleware.Prometheus: prometheusInstrumentPrometheus :: PrometheusSettings -> Bool
+ Network.Wai.Middleware.Prometheus: [prometheusEndPoint] :: PrometheusSettings -> [Text]
+ Network.Wai.Middleware.Prometheus: [prometheusInstrumentApp] :: PrometheusSettings -> Bool
+ Network.Wai.Middleware.Prometheus: [prometheusInstrumentPrometheus] :: PrometheusSettings -> Bool
+ Network.Wai.Middleware.Prometheus: instance Data.Default.Class.Default Network.Wai.Middleware.Prometheus.PrometheusSettings
+ Network.Wai.Middleware.Prometheus: metricsApp :: Application

Files

src/Network/Wai/Middleware/Prometheus.hs view
@@ -8,11 +8,14 @@ ,   Default.def ,   instrumentApp ,   instrumentIO+,   metricsApp ) where -import Data.Time.Clock (diffUTCTime, getCurrentTime)+import Data.Time.Clock (UTCTime, diffUTCTime, getCurrentTime) import qualified Data.ByteString.Builder as BS+import qualified Data.ByteString.Char8 as BS import qualified Data.Default as Default+import Data.Maybe (fromMaybe) import qualified Data.Text as T import qualified Network.HTTP.Types as HTTP import qualified Network.Wai as Wai@@ -43,8 +46,10 @@     }  {-# NOINLINE requestLatency #-}-requestLatency :: Prom.Metric (Prom.Vector Prom.Label1 Prom.Summary)-requestLatency = Prom.unsafeRegisterIO $ Prom.vector "handler"+-- XXX: https://prometheus.io/docs/practices/naming/ says this should be+-- _seconds, not _microseconds.+requestLatency :: Prom.Metric (Prom.Vector Prom.Label3 Prom.Summary)+requestLatency = Prom.unsafeRegisterIO $ Prom.vector ("handler", "method", "status_code")                                        $ Prom.summary info Prom.defaultQuantiles     where info = Prom.Info "http_request_duration_microseconds"                            "The HTTP request latencies in microseconds."@@ -57,8 +62,14 @@ 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 =-    observeMicroSeconds handler (app req respond)+instrumentApp handler app req respond = do+    start <- getCurrentTime+    app req $ \res -> do+        end <- getCurrentTime+        let method = Just $ BS.unpack (Wai.requestMethod req)+        let status = Just $ show (HTTP.statusCode (Wai.responseStatus res))+        observeMicroSeconds handler method status start end+        respond res  -- | 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@@ -70,31 +81,36 @@ instrumentIO :: String  -- ^ The label used to identify this IO operation              -> IO a    -- ^ The IO action to instrument              -> IO a    -- ^ The instrumented app-instrumentIO = observeMicroSeconds--observeMicroSeconds :: String -> IO a -> IO a-observeMicroSeconds handler io = do+instrumentIO label io = do     start  <- getCurrentTime     result <- io     end    <- getCurrentTime-    let latency = fromRational $ toRational (end `diffUTCTime` start) * 1000000-    Prom.withLabel handler (Prom.observe latency) requestLatency+    observeMicroSeconds label Nothing Nothing start end     return result +observeMicroSeconds :: String -> Maybe String -> Maybe String -> UTCTime -> UTCTime -> IO ()+observeMicroSeconds handler method status start end = do+    let latency = fromRational $ toRational (end `diffUTCTime` start) * 1000000+    Prom.withLabel (handler, fromMaybe "" method, fromMaybe "" status)+                   (Prom.observe latency)+                   requestLatency+ -- | Expose Prometheus metrics and instrument an application with some basic -- metrics (e.g. request latency). prometheus :: PrometheusSettings -> Wai.Middleware prometheus PrometheusSettings{..} app req respond =     if     Wai.requestMethod req == HTTP.methodGet         && Wai.pathInfo req == prometheusEndPoint-    then measure measureMetrics "prometheus" $ respondWithMetrics respond-    else measure measureApp "app" $ app req respond-    where-        measureMetrics = prometheusInstrumentPrometheus-        measureApp = prometheusInstrumentApp-        measure shouldInstrument handler io-            | shouldInstrument = observeMicroSeconds handler io-            | otherwise        = io+        -- 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+++-- | WAI Application that serves the Prometheus metrics page regardless of+-- what the request is.+metricsApp :: Wai.Application+metricsApp = const respondWithMetrics  respondWithMetrics :: (Wai.Response -> IO Wai.ResponseReceived)                    -> IO Wai.ResponseReceived
wai-middleware-prometheus.cabal view
@@ -1,5 +1,5 @@ name:                wai-middleware-prometheus-version:             0.1.0.1+version:             0.1.1 synopsis:     WAI middlware for exposing http://prometheus.io metrics. description: