@@ -0,0 +1,184 @@
1+-- ------------------------------------------------------------ [ Category.idr ]
2+-- Module : Category.idr
3+-- Copyright : (c) The Idris Community
4+-- License : see LICENSE
5+-- --------------------------------------------------------------------- [ EOH ]
6+||| A logging effect that allows messages to be logged using both
7+||| numerical levels and user specified categories. The higher the
8+||| logging level the grater in verbosity the logging.
10+||| In this effect the resource we are computing over is the logging
11+||| level itself and the list of categories to show.
12+module Effect.Logging.Category
15+import public Effect.Logging.Level
19+-- -------------------------------------------------------- [ Logging Resource ]
21+||| The Logging details, this is the resource that the effect is
23+record LogRes (a : Type) where
25+ getLevel : LogLevel n
26+ getCategories : List a
28+instance (Show a) => Show (LogRes a) where
29+ show (MkLogRes l cs) = unwords ["Log Settings:", show l, show cs]
31+instance Default (LogRes a) where
32+ default = MkLogRes OFF Nil
34+-- ------------------------------------------------------- [ Effect Definition ]
36+||| A Logging effect to log levels and categories.
37+data Logging : Effect where
40+ ||| @lvl The logging level it should appear at.
41+ ||| @cats The categories it should appear under.
42+ ||| @msg The message to log.
43+ Log : (Show a, Eq a) =>
47+ -> sig Logging () (LogRes a)
49+ ||| Change the logging level.
51+ ||| @nlvl The new logging level
52+ SetLogLvl : (Show a, Eq a) =>
53+ (nlvl : LogLevel n) ->
54+ sig Logging () (LogRes a) (LogRes a)
56+ ||| Change the categories to show.
58+ ||| @ncats The new categories.
59+ SetLogCats : (Show a, Eq a) =>
61+ sig Logging () (LogRes a) (LogRes a)
63+ ||| Initialise the logging.
65+ ||| @nlvl The new logging level.
66+ ||| @ncats The categories to show.
67+ InitLogger : (Show a, Eq a) =>
68+ (nlvl : LogLevel n) ->
70+ sig Logging () (LogRes a) (LogRes a)
72+-- -------------------------------------------------------------- [ IO Handler ]
74+instance Handler Logging IO where
75+ handle st (SetLogLvl nlvl) k = do
76+ let newSt = record {getLevel = nlvl} st
78+ handle st (SetLogCats newcs) k = do
79+ let newSt = record {getCategories = newcs} st
82+ handle st (InitLogger l cs) k = do
83+ let newSt = MkLogRes l cs
86+ handle st (Log l cs' msg) k = do
87+ case cmpLevel l (getLevel st) of
90+ let res = and $ map (\x => elem x cs') (getCategories st)
91+ let prompt = if isNil (getCategories st)
92+ then unwords [show l, ":"]
93+ else unwords [show l, ":", show (getCategories st), ":"]
94+ if res || isNil (getCategories st)
96+ putStrLn $ unwords [prompt, msg]
101+-- ------------------------------------------------------- [ Effect Descriptor ]
103+||| The Logging effect.
105+||| @a The type used to differentiate categories.
106+LOG : (a : Type) -> EFFECT
107+LOG a = MkEff (LogRes a) Logging
109+-- ----------------------------------------------------------- [ Effectful API ]
111+||| Change the logging level.
113+||| @l The new logging level.
114+setLoglvl : (Show a, Eq a) => (l : LogLevel n) -> Eff () [LOG a]
115+setLoglvl l = call $ SetLogLvl l
117+||| Change the categories to show.
119+||| @cs The new categories.
120+setLogCats : (Show a, Eq a) => (cs : List a) -> Eff () [LOG a]
121+setLogCats cs = call $ SetLogCats cs
123+||| Initialise the Logger.
125+||| @l The logging level.
126+||| @cs The categories to show.
127+initLogger : (Show a, Eq a) => (l : LogLevel n)
130+initLogger l cs = call $ InitLogger l cs
132+||| Log the given message at the given level indicated by a natural number and assign it the list of categories.
134+||| @l The logging level.
135+||| @cs The logging categories.
136+||| @m THe message to be logged.
137+log : (Show a, Eq a) => (l : LogLevel n)
141+log l cs msg = call $ Log l cs msg
143+||| Log the given message at the given level indicated by a natural number and assign it the list of categories.
145+||| @l The logging level.
146+||| @cs The logging categories.
147+||| @m THe message to be logged.
148+logN : (Show a, Eq a) => (l : Nat)
149+ -> {auto prf : LTE l 70}
153+logN l cs msg = call $ Log (getProof lvl) cs msg
155+ lvl : (n ** LogLevel n)
156+ lvl = case cast {to=String} (cast {to=Int} l) of
158+ "10" => (_ ** TRACE)
159+ "20" => (_ ** DEBUG)
162+ "50" => (_ ** FATAL)
163+ "60" => (_ ** ERROR)
164+ _ => (_ ** CUSTOM l)
166+trace : (Show a, Eq a) => List a -> String -> Eff () [LOG a]
167+trace cs msg = call $ Log TRACE cs msg
169+debug : (Show a, Eq a) => List a -> String -> Eff () [LOG a]
170+debug cs msg = call $ Log DEBUG cs msg
172+info : (Show a, Eq a) => List a -> String -> Eff () [LOG a]
173+info cs msg = call $ Log INFO cs msg
175+warn : (Show a, Eq a) => List a -> String -> Eff () [LOG a]
176+warn cs msg = call $ Log WARN cs msg
178+fatal : (Show a, Eq a) => List a -> String -> Eff () [LOG a]
179+fatal cs msg = call $ Log FATAL cs msg
181+error : (Show a, Eq a) => List a -> String -> Eff () [LOG a]
182+error cs msg = call $ Log ERROR cs msg
184+-- --------------------------------------------------------------------- [ EOF ]