{-# 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 a. a -> IO a
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 -> String -> Maybe ProcStat
forall s a. RE s a -> [s] -> Maybe a
RE.match RE Char ProcStat
parseProcStat (String -> Maybe ProcStat)
-> (Text -> String) -> Text -> Maybe ProcStat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
unpack (Text -> Maybe ProcStat) -> IO Text -> IO (Maybe ProcStat)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO Text
readFile ( ProcessID -> String
procPidDir ProcessID
pid String -> String -> String
</> String
"stat" )
SampleGroup
processOpenFds <-
ProcessID -> IO SampleGroup
collectProcessOpenFds ProcessID
pid
Maybe SampleGroup
processMaxFds <-
ProcessID -> IO (Maybe SampleGroup)
collectProcessMaxFds ProcessID
pid
[SampleGroup] -> IO [SampleGroup]
forall a. a -> IO a
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 m a. Monoid m => (a -> m) -> Maybe a -> m
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
([String] -> SampleGroup) -> IO [String] -> IO SampleGroup
forall a b. (a -> b) -> IO a -> IO b
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)
-> ([String] -> Int) -> [String] -> SampleGroup
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length )
( String -> IO [String]
listDirectory ( ProcessID -> String
procPidDir ProcessID
pid String -> String -> String
</> String
"fd" ) )
collectProcessMaxFds :: ProcessID -> IO ( Maybe SampleGroup )
collectProcessMaxFds :: ProcessID -> IO (Maybe SampleGroup)
collectProcessMaxFds ProcessID
pid = do
[String]
limitLines <-
String -> [String]
lines (String -> [String]) -> (Text -> String) -> Text -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
unpack (Text -> [String]) -> IO Text -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO Text
readFile ( ProcessID -> String
procPidDir ProcessID
pid String -> String -> String
</> String
"limits" )
case (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter ( String
"Max open files" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` ) [String]
limitLines of
( String -> [String]
words -> String
_max : String
_open : String
_files : String
n : [String]
_ ) : [String]
_ ->
Maybe SampleGroup -> IO (Maybe SampleGroup)
forall a. a -> IO a
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
( String -> Int
forall a. Read a => String -> a
read String
n :: Int )
)
)
[String]
_ ->
Maybe SampleGroup -> IO (Maybe SampleGroup)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe SampleGroup
forall a. Maybe a
Nothing
procPidDir :: ProcessID -> FilePath
procPidDir :: ProcessID -> String
procPidDir ProcessID
pid =
String
"/" String -> String -> String
</> String
"proc" String -> String -> String
</> ProcessID -> String
forall a. Show a => a -> String
show ProcessID
pid
procStatToMetrics :: ProcStat -> [ SampleGroup ]
procStatToMetrics :: ProcStat -> [SampleGroup]
procStatToMetrics ProcStat{ Int64
utime :: Int64
utime :: ProcStat -> Int64
utime, Int64
stime :: Int64
stime :: ProcStat -> Int64
stime, Int64
starttime :: Int64
starttime :: ProcStat -> Int64
starttime, Int64
vsize :: Int64
vsize :: ProcStat -> Int64
vsize, Int64
rss :: Int64
rss :: ProcStat -> 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 a. a -> Maybe a
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 :: forall a. Show a => Text -> Text -> SampleType -> a -> SampleGroup
metric Text
metricName Text
metricHelp SampleType
metricType a
value =
Info -> SampleType -> [Sample] -> SampleGroup
SampleGroup
Info{Text
metricName :: Text
metricHelp :: Text
metricName :: Text
metricHelp :: Text
..}
SampleType
metricType
[ Text -> LabelPairs -> ByteString -> Sample
Sample
Text
metricName
[]
( String -> ByteString
forall a. IsString a => String -> a
fromString ( a -> String
forall a. Show a => a -> String
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
((String, Int64, String) -> Int64)
-> Maybe (String, Int64, String) -> Maybe Int64
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ( \( String
_, Int64
a, String
_ ) -> Int64
a ) (Maybe (String, Int64, String) -> Maybe Int64)
-> (Text -> Maybe (String, Int64, String)) -> Text -> Maybe Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RE Char Int64 -> String -> Maybe (String, Int64, String)
forall s a. RE s a -> [s] -> Maybe ([s], a, [s])
RE.findFirstInfix ( RE Char String
"btime " RE Char String -> RE Char Int64 -> RE Char Int64
forall a b. RE Char a -> RE Char b -> RE Char b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> RE Char Int64
forall a. Num a => RE Char a
RE.decimal ) (String -> Maybe (String, Int64, String))
-> (Text -> String) -> Text -> Maybe (String, Int64, String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
unpack
(Text -> Maybe Int64) -> IO Text -> IO (Maybe Int64)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO Text
readFile String
"/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 -> String -> String
[ProcStat] -> String -> String
ProcStat -> String
(Int -> ProcStat -> String -> String)
-> (ProcStat -> String)
-> ([ProcStat] -> String -> String)
-> Show ProcStat
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> ProcStat -> String -> String
showsPrec :: Int -> ProcStat -> String -> String
$cshow :: ProcStat -> String
show :: ProcStat -> String
$cshowList :: [ProcStat] -> String -> String
showList :: [ProcStat] -> String -> String
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 String
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String -> RE Char String
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 String -> RE Char String
forall a b. RE Char a -> RE Char b -> RE Char b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> RE Char Char -> RE Char String
forall a. RE Char a -> RE Char [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
RE.some RE Char Char
forall s. RE s s
RE.anySym RE Char String -> RE Char Char -> RE Char String
forall a b. RE Char a -> RE Char b -> RE Char a
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 String
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char Int64
-> RE Char (Int64 -> Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char (a -> b) -> RE Char a -> RE Char b
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 a b. RE Char (a -> b) -> RE Char a -> RE Char b
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 String -> RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String -> RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String -> RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String -> RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String -> RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char String -> RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char (Int64 -> Int64 -> Int64 -> ProcStat)
-> RE Char Int64 -> RE Char (Int64 -> Int64 -> ProcStat)
forall a b. RE Char (a -> b) -> RE Char a -> RE Char b
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 a b. RE Char (a -> b) -> RE Char a -> RE Char b
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 a b. RE Char (a -> b) -> RE Char a -> RE Char b
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 String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
any
RE Char ProcStat -> RE Char String -> RE Char ProcStat
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char String
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 a b. RE Char a -> RE Char b -> 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 String -> RE Char a
forall a b. RE Char a -> RE Char b -> RE Char a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RE Char Char -> RE Char String
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 String
any =
RE Char String -> RE Char String
forall {a}. RE Char a -> RE Char a
token ( RE Char Char -> RE Char String
forall s a. RE s a -> RE s [a]
RE.few RE Char Char
forall s. RE s s
RE.anySym )