packages feed

prometheus-proc 0.1.0.0 → 0.1.1.0

raw patch · 3 files changed

+93/−27 lines, 3 filesdep +directorydep +textPVP ok

version bump matches the API change (PVP)

Dependencies added: directory, text

API changes (from Hackage documentation)

Files

ChangeLog.md view
@@ -1,3 +1,15 @@+# 0.1.1.0 -- 2019-05-23++* Change all use of `Int` to `Int64`. `Int` is only guaranteed to be able to+  represent values up to 2^29-1, but entries in /proc/stat can often exceed that+  (for example processes with a high resident memory usage) on 32-bit machines.++* Export `process_open_fds`, a count of the number of entries in+  `/proc/$PID/fd`.++* Export `process_max_fds`, which exports the soft ulimit of the maximum number+  of file descriptors this process may open.+ # 0.1.0.0 -- 2019-01-15  * Initial release.
prometheus-proc.cabal view
@@ -1,5 +1,5 @@ name:                prometheus-proc-version:             0.1.0.0+version:             0.1.1.0 synopsis:            Export metrics from /proc for the current process homepage:            https://github.com/fimad/prometheus-haskell license:             BSD3@@ -18,10 +18,12 @@ library   exposed-modules:     Prometheus.Metric.Proc   build-depends:       base >=4.10 && <4.13+                     , directory >= 1.2.5.0 && < 1.4                      , filepath >=1.4 && <1.5-                     , unix-memory >=0.1 && <0.2-                     , unix >=2.7 && <2.8-                     , regex-applicative >=0.3 && <0.4                      , prometheus-client >= 1.0.0 && < 1.1+                     , regex-applicative >=0.3 && <0.4+                     , text >= 0.7 && < 1.3+                     , unix >=2.7 && <2.8+                     , unix-memory >=0.1 && <0.2   hs-source-dirs:      src   default-language:    Haskell2010
src/Prometheus/Metric/Proc.hs view
@@ -2,6 +2,7 @@ {-# language NamedFieldPuns #-} {-# language OverloadedStrings #-} {-# language RecordWildCards #-}+{-# language ViewPatterns #-}  {-| @@ -12,14 +13,21 @@ module Prometheus.Metric.Proc ( ProcMetrics(..), procMetrics ) where  import Data.Char ( isSpace )-import Data.Maybe ( catMaybes )+import Data.Int ( Int64 )+import Data.List ( isPrefixOf )+import Data.Maybe ( catMaybes, maybeToList ) import Data.String ( fromString )+import Data.Text ( Text, unpack )+import Data.Text.IO ( readFile ) import Foreign.C+import Prelude hiding ( readFile ) import Prometheus+import System.Directory ( listDirectory ) import System.FilePath import System.IO.Unsafe import System.Posix.Memory ( sysconfPageSize ) import System.Posix.Process ( getProcessID )+import System.Posix.Types ( ProcessID ) import qualified Text.Regex.Applicative as RE import qualified Text.Regex.Applicative.Common as RE @@ -62,14 +70,56 @@     getProcessID    mprocStat <--      RE.match parseProcStat <$> readFile ( "/" </> "proc" </> show pid </> "stat" )+      RE.match parseProcStat . unpack <$> readFile ( procPidDir pid </> "stat" ) +  processOpenFds <-+    collectProcessOpenFds pid++  processMaxFds <-+    collectProcessMaxFds pid+   return-    ( foldMap ( toMetrics ) mprocStat )+    ( [ processOpenFds ]+        <> maybeToList processMaxFds+        <> foldMap ( procStatToMetrics ) mprocStat+    )  -toMetrics :: ProcStat -> [ SampleGroup ]-toMetrics ProcStat{ utime, stime, starttime, vsize, rss } =+collectProcessOpenFds :: ProcessID -> IO SampleGroup+collectProcessOpenFds pid = do+  fmap+    ( metric "process_open_fds" "Number of open file descriptors." GaugeType . length )+    ( listDirectory ( procPidDir pid </> "fd" ) )+++collectProcessMaxFds :: ProcessID -> IO ( Maybe SampleGroup )+collectProcessMaxFds pid = do+  limitLines <-+    lines . unpack <$> readFile ( procPidDir pid </> "limits" )++  case filter ( "Max open files" `isPrefixOf` ) limitLines of+    ( words -> _max : _open : _files : n : _ ) : _ ->+      return+        ( Just+            ( metric+                "process_max_fds"+                "Maximum number of open file descriptors."+                GaugeType+                ( read n :: Int )+            )+        )++    _ ->+      return Nothing+++procPidDir :: ProcessID -> FilePath+procPidDir pid =+  "/" </> "proc" </> show pid+++procStatToMetrics :: ProcStat -> [ SampleGroup ]+procStatToMetrics ProcStat{ utime, stime, starttime, vsize, rss } =   catMaybes     [ Just process_cpu_seconds_total     , process_start_time_seconds@@ -110,21 +160,23 @@         "process_resident_memory_bytes"         "Resident memory size in bytes."         GaugeType-        ( rss * sysconfPageSize )+        ( rss * fromIntegral sysconfPageSize ) -    metric metricName metricHelp metricType value =-      SampleGroup-        Info{..}-        metricType-        [ Sample-            metricName-            []-            ( fromString ( show value ) )-        ] +metric :: Show a => Text -> Text -> SampleType -> a -> SampleGroup+metric metricName metricHelp metricType value =+  SampleGroup+    Info{..}+    metricType+    [ Sample+        metricName+        []+        ( fromString ( show value ) )+    ] + -- | Convert a number of clock ticks into the corresponding duration in seconds.-fromTicks :: Int -> Double+fromTicks :: Int64 -> Double fromTicks ticks =   fromIntegral ticks / fromIntegral clk_tck @@ -141,27 +193,27 @@  -} {-# NOINLINE mbtime #-}-mbtime :: Maybe Int+mbtime :: Maybe Int64 mbtime = unsafePerformIO $ do-  fmap ( \( _, a, _ ) -> a ) . RE.findFirstInfix ( "btime " *> RE.decimal )+  fmap ( \( _, a, _ ) -> a ) . RE.findFirstInfix ( "btime " *> RE.decimal ) . unpack     <$> readFile "/proc/stat"   -- | Specific metrics from @/proc/xyz/stat@ that we are interested in. data ProcStat = ProcStat-  { utime :: Int+  { utime :: Int64     -- ^ Amount of time that this process has been scheduled in user mode,     -- measured in clock ticks (divide by sysconf(_SC_CLK_TCK)).-  , stime :: Int+  , stime :: Int64     -- ^ Amount of time that this process has been scheduled in kernel mode,     -- measured in clock ticks (divide by sysconf(_SC_CLK_TCK)).-  , starttime :: Int+  , starttime :: Int64     -- ^ The time the process started after system boot. In kernels before Linux     -- 2.6, this value was expressed in jiffies. Since Linux 2.6, the value is     -- expressed in clock ticks (divide by sysconf(_SC_CLK_TCK)).-  , vsize :: Int+  , vsize :: Int64     -- ^ Virtual memory size in bytes.-  , rss :: Int+  , rss :: Int64     -- ^ Resident Set Size: number of pages the process has in real memory. This     -- is just the pages which count toward text, data, or stack space. This     -- does not include pages which have not been demand-loaded in, or which are