{-# language ForeignFunctionInterface #-}
{-# language NamedFieldPuns #-}
{-# language OverloadedStrings #-}
{-# language RecordWildCards #-}
{-# language ViewPatterns #-}
module Prometheus.Metric.Proc ( ProcMetrics(..), procMetrics ) where
import Data.Char ( isSpace )
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
data ProcMetrics =
ProcMetrics
procMetrics :: Prometheus.Metric ProcMetrics
procMetrics :: Metric ProcMetrics
procMetrics =
IO (ProcMetrics, IO [SampleGroup]) -> Metric ProcMetrics
forall s. IO (s, IO [SampleGroup]) -> Metric s
Metric ( (ProcMetrics, IO [SampleGroup])
-> IO (ProcMetrics, IO [SampleGroup])
forall (m :: * -> *) a. Monad m => a -> m a
return ( ProcMetrics
ProcMetrics, IO [SampleGroup]
collect ) )
foreign import ccall unsafe
clk_tck :: CLong
collect :: IO [ SampleGroup ]
collect :: IO [SampleGroup]
collect = do
ProcessID
pid <-
IO ProcessID
getProcessID
Maybe ProcStat
mprocStat <-
RE Char ProcStat -> [Char] -> Maybe ProcStat
forall s a. RE s a -> [s] -> Maybe a
RE.match RE Char ProcStat
parseProcStat ([Char] -> Maybe ProcStat)
-> (Text -> [Char]) -> Text -> Maybe ProcStat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
unpack (Text -> Maybe ProcStat) -> IO Text -> IO (Maybe ProcStat)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> IO Text
readFile ( ProcessID -> [Char]
procPidDir ProcessID
pid [Char] -> [Char] -> [Char]
</> [Char]
"stat" )
SampleGroup
processOpenFds <-
ProcessID -> IO SampleGroup
collectProcessOpenFds ProcessID
pid
Maybe SampleGroup
processMaxFds <-
ProcessID -> IO (Maybe SampleGroup)
collectProcessMaxFds ProcessID
pid
[SampleGroup] -> IO [SampleGroup]
forall (m :: * -> *) a. Monad m => a -> m a
return
( [ SampleGroup
processOpenFds ]
[SampleGroup] -> [SampleGroup] -> [SampleGroup]
forall a. Semigroup a => a -> a -> a
<> Maybe SampleGroup -> [SampleGroup]
forall a. Maybe a -> [a]
maybeToList Maybe SampleGroup
processMaxFds
[SampleGroup] -> [SampleGroup] -> [SampleGroup]
forall a. Semigroup a => a -> a -> a
<> (ProcStat -> [SampleGroup]) -> Maybe ProcStat -> [SampleGroup]
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ( ProcStat -> [SampleGroup]
procStatToMetrics ) Maybe ProcStat
mprocStat
)
collectProcessOpenFds :: ProcessID -> IO SampleGroup
collectProcessOpenFds :: ProcessID -> IO SampleGroup
collectProcessOpenFds ProcessID
pid = do
([[Char]] -> SampleGroup) -> IO [[Char]] -> IO SampleGroup
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
( Text -> Text -> SampleType -> Int -> SampleGroup
forall a. Show a => Text -> Text -> SampleType -> a -> SampleGroup
metric Text
"process_open_fds" Text
"Number of open file descriptors." SampleType
GaugeType (Int -> SampleGroup)
-> ([[Char]] -> Int) -> [[Char]] -> SampleGroup
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Char]] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length )
( [Char] -> IO [[Char]]
listDirectory ( ProcessID -> [Char]
procPidDir ProcessID
pid [Char] -> [Char] -> [Char]
</> [Char]
"fd" ) )
collectProcessMaxFds :: ProcessID -> IO ( Maybe SampleGroup )
collectProcessMaxFds :: ProcessID -> IO (Maybe SampleGroup)
collectProcessMaxFds ProcessID
pid = do
[[Char]]
limitLines <-
[Char] -> [[Char]]
lines ([Char] -> [[Char]]) -> (Text -> [Char]) -> Text -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
unpack (Text -> [[Char]]) -> IO Text -> IO [[Char]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> IO Text
readFile ( ProcessID -> [Char]
procPidDir ProcessID
pid [Char] -> [Char] -> [Char]
</> [Char]
"limits" )
case ([Char] -> Bool) -> [[Char]] -> [[Char]]
forall a. (a -> Bool) -> [a] -> [a]
filter ( [Char]
"Max open files" [Char] -> [Char] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` ) [[Char]]
limitLines of
( [Char] -> [[Char]]
words -> [Char]
_max : [Char]
_open : [Char]
_files : [Char]
n : [[Char]]
_ ) : [[Char]]
_ ->
Maybe SampleGroup -> IO (Maybe SampleGroup)
forall (m :: * -> *) a. Monad m => a -> m a
return
( SampleGroup -> Maybe SampleGroup
forall a. a -> Maybe a
Just
( Text -> Text -> SampleType -> Int -> SampleGroup
forall a. Show a => Text -> Text -> SampleType -> a -> SampleGroup
metric
Text
"process_max_fds"
Text
"Maximum number of open file descriptors."
SampleType
GaugeType
( [Char] -> Int
forall a. Read a => [Char] -> a
read [Char]
n :: Int )
)
)
[[Char]]
_ ->
Maybe SampleGroup -> IO (Maybe SampleGroup)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe SampleGroup
forall a. Maybe a
Nothing
procPidDir :: ProcessID -> FilePath
procPidDir :: ProcessID -> [Char]
procPidDir ProcessID
pid =
[Char]
"/" [Char] -> [Char] -> [Char]
</> [Char]
"proc" [Char] -> [Char] -> [Char]
</> ProcessID -> [Char]
forall a. Show a => a -> [Char]
show ProcessID
pid
procStatToMetrics :: ProcStat -> [ SampleGroup ]
procStatToMetrics :: ProcStat -> [SampleGroup]
procStatToMetrics ProcStat{ Int64
utime :: ProcStat -> Int64
utime :: Int64
utime, Int64
stime :: ProcStat -> Int64
stime :: Int64
stime, Int64
starttime :: ProcStat -> Int64
starttime :: Int64
starttime, Int64
vsize :: ProcStat -> Int64
vsize :: Int64
vsize, Int64
rss :: ProcStat -> Int64
rss :: Int64
rss } =
[Maybe SampleGroup] -> [SampleGroup]
forall a. [Maybe a] -> [a]
catMaybes
[ SampleGroup -> Maybe SampleGroup
forall a. a -> Maybe a
Just SampleGroup
process_cpu_seconds_total
, Maybe SampleGroup
process_start_time_seconds
, SampleGroup -> Maybe SampleGroup
forall a. a -> Maybe a
Just SampleGroup
process_virtual_memory_bytes
, SampleGroup -> Maybe SampleGroup
forall a. a -> Maybe a
Just SampleGroup
process_resident_memory_bytes
]
where
process_cpu_seconds_total :: SampleGroup
process_cpu_seconds_total =
Text -> Text -> SampleType -> Double -> SampleGroup
forall a. Show a => Text -> Text -> SampleType -> a -> SampleGroup
metric
Text
"process_cpu_seconds_total"
Text
"Total user and system CPU time spent in seconds."
SampleType
CounterType
( Int64 -> Double
fromTicks ( Int64
utime Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
+ Int64
stime ) )
process_start_time_seconds :: Maybe SampleGroup
process_start_time_seconds = do
Int64
btime <-
Maybe Int64
mbtime
SampleGroup -> Maybe SampleGroup
forall (m :: * -> *) a. Monad m => a -> m a
return
( Text -> Text -> SampleType -> Double -> SampleGroup
forall a. Show a => Text -> Text -> SampleType -> a -> SampleGroup
metric
Text
"process_start_time_seconds"
Text
"Start time of the process since unix epoch in seconds."
SampleType
GaugeType
( Int64 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
btime Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Int64 -> Double
fromTicks Int64
starttime )
)
process_virtual_memory_bytes :: SampleGroup
process_virtual_memory_bytes =
Text -> Text -> SampleType -> Int64 -> SampleGroup
forall a. Show a => Text -> Text -> SampleType -> a -> SampleGroup
metric
Text
"process_virtual_memory_bytes"
Text
"Virtual memory size in bytes."
SampleType
GaugeType
Int64
vsize
process_resident_memory_bytes :: SampleGroup
process_resident_memory_bytes =
Text -> Text -> SampleType -> Int64 -> SampleGroup
forall a. Show a => Text -> Text -> SampleType -> a -> SampleGroup
metric
Text
"process_resident_memory_bytes"
Text
"Resident memory size in bytes."
SampleType
GaugeType
( Int64
rss Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
* Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
sysconfPageSize )
metric :: Show a => Text -> Text -> SampleType -> a -> SampleGroup
metric :: Text -> Text -> SampleType -> a -> SampleGroup
metric Text
metricName Text
metricHelp SampleType
metricType a
value =
Info -> SampleType -> [Sample] -> SampleGroup
SampleGroup
Info :: Text -> Text -> Info
Info{Text
metricName :: Text
metricHelp :: Text
metricHelp :: Text
metricName :: Text
..}
SampleType
metricType
[ Text -> LabelPairs -> ByteString -> Sample
Sample
Text
metricName
[]
( [Char] -> ByteString
forall a. IsString a => [Char] -> a
fromString ( a -> [Char]
forall a. Show a => a -> [Char]
show a
value ) )
]
fromTicks :: Int64 -> Double
fromTicks :: Int64 -> Double
fromTicks Int64
ticks =
Int64 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
ticks Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ CLong -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral CLong
clk_tck
{-# NOINLINE mbtime #-}
mbtime :: Maybe Int64
mbtime :: Maybe Int64
mbtime = IO (Maybe Int64) -> Maybe Int64
forall a. IO a -> a
unsafePerformIO (IO (Maybe Int64) -> Maybe Int64)
-> IO (Maybe Int64) -> Maybe Int64
forall a b. (a -> b) -> a -> b
$ do
(([Char], Int64, [Char]) -> Int64)
-> Maybe ([Char], Int64, [Char]) -> Maybe Int64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ( \( [Char]
_, Int64
a, [Char]
_ ) -> Int64
a ) (Maybe ([Char], Int64, [Char]) -> Maybe Int64)
-> (Text -> Maybe ([Char], Int64, [Char])) -> Text -> Maybe Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RE Char Int64 -> [Char] -> Maybe ([Char], Int64, [Char])
forall s a. RE s a -> [s] -> Maybe ([s], a, [s])
RE.findFirstInfix ( RE Char [Char]
"btime " RE Char [Char] -> RE Char Int64 -> RE Char Int64
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> RE Char Int64
forall a. Num a => RE Char a
RE.decimal ) ([Char] -> Maybe ([Char], Int64, [Char]))
-> (Text -> [Char]) -> Text -> Maybe ([Char], Int64, [Char])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
unpack
(Text -> Maybe Int64) -> IO Text -> IO (Maybe Int64)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> IO Text
readFile [Char]
"/proc/stat"
data ProcStat = ProcStat
{ ProcStat -> Int64
utime :: Int64
, ProcStat -> Int64
stime :: Int64
, ProcStat -> Int64
starttime :: Int64
, ProcStat -> Int64
vsize :: Int64
, :: Int64
}
deriving
( Int -> ProcStat -> [Char] -> [Char]
[ProcStat] -> [Char] -> [Char]
ProcStat -> [Char]
(Int -> ProcStat -> [Char] -> [Char])
-> (ProcStat -> [Char])
-> ([ProcStat] -> [Char] -> [Char])
-> Show ProcStat
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
showList :: [ProcStat] -> [Char] -> [Char]
$cshowList :: [ProcStat] -> [Char] -> [Char]
show :: ProcStat -> [Char]
$cshow :: ProcStat -> [Char]
showsPrec :: Int -> ProcStat -> [Char] -> [Char]
$cshowsPrec :: Int -> ProcStat -> [Char] -> [Char]
Show )
parseProcStat :: RE.RE Char ProcStat
parseProcStat :: RE Char ProcStat
parseProcStat =
Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat
ProcStat
(Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char]
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char]
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char] -> RE Char [Char]
forall a. RE Char a -> RE Char a
token ( Char -> RE Char Char
forall s. Eq s => s -> RE s s
RE.sym Char
'(' RE Char Char -> RE Char [Char] -> RE Char [Char]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> RE Char Char -> RE Char [Char]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
RE.some RE Char Char
forall s. RE s s
RE.anySym RE Char [Char] -> RE Char Char -> RE Char [Char]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> RE Char Char
forall s. Eq s => s -> RE s s
RE.sym Char
')' )
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char]
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char]
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char]
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char]
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char]
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char]
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char]
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char]
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char]
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char]
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char]
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char Int64
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> RE Char Int64 -> RE Char Int64
forall a. RE Char a -> RE Char a
token RE Char Int64
forall a. Num a => RE Char a
RE.decimal
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char Int64 -> RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> RE Char Int64 -> RE Char Int64
forall a. RE Char a -> RE Char a
token RE Char Int64
forall a. Num a => RE Char a
RE.decimal
RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char] -> RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char] -> RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char] -> RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char] -> RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char] -> RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char [Char] -> RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char Int64 -> RE Char (Int64 -> Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> RE Char Int64 -> RE Char Int64
forall a. RE Char a -> RE Char a
token RE Char Int64
forall a. Num a => RE Char a
RE.decimal
RE Char (Int64 -> Int64 -> ProcStat)
-> RE Char Int64 -> RE Char (Int64 -> ProcStat)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> RE Char Int64 -> RE Char Int64
forall a. RE Char a -> RE Char a
token RE Char Int64
forall a. Num a => RE Char a
RE.decimal
RE Char (Int64 -> ProcStat) -> RE Char Int64 -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> RE Char Int64 -> RE Char Int64
forall a. RE Char a -> RE Char a
token RE Char Int64
forall a. Num a => RE Char a
RE.decimal
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
RE Char ProcStat -> RE Char [Char] -> RE Char ProcStat
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char [Char]
any
where
token :: RE Char a -> RE Char a
token RE Char a
a =
RE Char a
a RE Char a -> RE Char Char -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Char -> Bool) -> RE Char Char
forall s. (s -> Bool) -> RE s s
RE.psym Char -> Bool
isSpace RE Char a -> RE Char [Char] -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char Char -> RE Char [Char]
forall s a. RE s a -> RE s [a]
RE.few ( (Char -> Bool) -> RE Char Char
forall s. (s -> Bool) -> RE s s
RE.psym Char -> Bool
isSpace )
any :: RE Char [Char]
any =
RE Char [Char] -> RE Char [Char]
forall a. RE Char a -> RE Char a
token ( RE Char Char -> RE Char [Char]
forall s a. RE s a -> RE s [a]
RE.few RE Char Char
forall s. RE s s
RE.anySym )