on master help sign in
Merge pull request #2376 from jfdm/logging-effect

Effectful Logging.

commit6784f7a65c1263a171fb9b3ced545e7c1e4a3b59 authorNiklas Larsson <metaniklas@gmail.com> dateThu 6 Aug 2015, 18:09 (11 years ago) parentb6c9ef844dad1c
9 files changed+217−4
idris.cabal+5 libs/effects/Effect/Logging/Default.idr+57 libs/effects/Effect/Logging/Level.idr+49 libs/effects/Effect/Logging/Simple.idr+48 libs/effects/effects.ipkg+15−4 test/effects005/defaultlog.idr+18 test/effects005/expected+5 test/effects005/run+6 test/effects005/simplelog.idr+14
idris.cabal+5
@@ -126,6 +126,7 @@ Extra-source-files:
126126 libs/effects/Makefile
127127 libs/effects/effects.ipkg
128128 libs/effects/Effect/*.idr
129+ libs/effects/Effect/Logging/*.idr
129130 libs/effects/*.idr
130131
131132 test/Makefile
@@ -425,6 +426,10 @@ Extra-source-files:
425426 test/effects004/*.idr
426427 test/effects004/expected
427428 test/effects004/input
429+ test/effects005/run
430+ test/effects005/*.idr
431+ test/effects005/expected
432+
428433
429434 test/error001/run
430435 test/error001/*.idr
libs/effects/Effect/Logging/Default.idrnew file+57
@@ -0,0 +1,57 @@
1+-- ------------------------------------------------------------- [ Default.idr ]
2+-- Module : Default.idr
3+-- Copyright : (c) The Idris Community
4+-- License : see LICENSE
5+-- --------------------------------------------------------------------- [ EOH ]
6+
7+||| A logging effect that allows messages to be logged using both
8+||| numerical levels and user specified categories. The higher the
9+||| logging level the grater in verbosity the logging.
10+|||
11+||| In this effect the resource we are computing over is the logging
12+||| level itself and the list of categories to show.
13+|||
14+module Effect.Logging.Default
15+
16+import Effects
17+import public Effect.Logging.Level
18+
19+import Control.IOExcept -- TODO Add IOExcept Logger.
20+
21+||| A Logging effect to log levels and categories.
22+data Logging : Effect where
23+ Log : (Eq a, Show a) =>
24+ (lvl : Nat)
25+ -> (cats : List a)
26+ -> (msg : String)
27+ -> Logging () (Nat,List a) (\v => (Nat,List a))
28+
29+||| The Logging effect.
30+|||
31+||| @cTy The type used to differentiate categories.
32+LOG : (cTy : Type) -> EFFECT
33+LOG a = MkEff (Nat, List a) Logging
34+
35+instance Handler Logging IO where
36+ handle (l,cs) (Log lvl cs' msg) k = do
37+ case lvl <= l of
38+ False => k () (l,cs)
39+ True => do
40+ let res = and $ map (\x => elem x cs') cs
41+ let prompt = if isNil cs then "" else show cs
42+ if res || isNil cs
43+ then do
44+ printLn $ unwords [show lvl, ":", prompt, ":", msg]
45+ k () (l,cs)
46+ else k () (l,cs)
47+
48+||| Log the given message at the given level and assign it the list of categories.
49+|||
50+||| @l The logging level.
51+||| @cs The logging categories.
52+||| @m THe message to be logged.
53+log : (Show a, Eq a) => (l : Nat)
54+ -> (cs : List a) -> (m : String) -> Eff () [LOG a]
55+log lvl cs msg = call $ Log lvl cs msg
56+
57+-- --------------------------------------------------------------------- [ EOF ]
libs/effects/Effect/Logging/Level.idrnew file+49
@@ -0,0 +1,49 @@
1+-- -------------------------------------------------------------- [ Levels.idr ]
2+-- Module : Levels.idr
3+-- Copyright : (c) Jan de Muijnck-Hughes
4+-- License : see LICENSE
5+-- --------------------------------------------------------------------- [ EOH ]
6+||| Common aliases and definitions of Logging Levels.
7+module Effect.Logging.Level
8+
9+%access public
10+-- ---------------------------------------------- [ Nat Derived Logging Levels ]
11+--
12+-- Several aliases have been defined to aide in semantic use of the
13+-- logging levels. These aliases have come from the Log4j family of
14+-- loggers.
15+
16+||| No events will be logged.
17+OFF : Nat
18+OFF = 0
19+
20+||| A severe error that will prevent the application from continuing.
21+FATAL : Nat
22+FATAL = 1
23+
24+||| An error in the application, possibly recoverable.
25+ERROR : Nat
26+ERROR = 2
27+
28+||| An event that might possible lead to an error.
29+WARN : Nat
30+WARN = 3
31+
32+||| An event for informational purposes.
33+INFO : Nat
34+INFO = 4
35+
36+||| A general debugging event.
37+DEBUG : Nat
38+DEBUG = 5
39+
40+||| A fine-grained debug message, typically capturing the flow through
41+||| the application.
42+TRACE : Nat
43+TRACE = 6
44+
45+||| All events should be logged.
46+ALL : Nat
47+ALL = 7
48+
49+-- --------------------------------------------------------------------- [ EOF ]
libs/effects/Effect/Logging/Simple.idrnew file+48
@@ -0,0 +1,48 @@
1+-- -------------------------------------------------------------- [ Simple.idr ]
2+-- Module : Logging.idr
3+-- Copyright : (c) The Idris Community
4+-- License : see LICENSE
5+--------------------------------------------------------------------- [ EOH ]
6+
7+||| A simple logging effect that allows messages to be logged at
8+||| different numerical level. The higher the number the grater in
9+||| verbosity the logging.
10+|||
11+||| In this effect the resource we are computing over is the logging
12+||| level itself.
13+|||
14+module Effect.Logging.Simple
15+
16+import Effects
17+import public Effect.Logging.Level
18+
19+import Control.IOExcept -- TODO Add IO Logging Handler
20+
21+||| A Logging effect that displays a logging message to be logged at a
22+||| certain level.
23+data Logging : Effect where
24+ Log : (lvl : Nat)
25+ -> (msg : String)
26+ -> Logging () Nat (\v => Nat)
27+
28+||| A Logging Effect.
29+LOG : EFFECT
30+LOG = MkEff Nat Logging
31+
32+-- For logging in the IO context
33+instance Handler Logging IO where
34+ handle l (Log lvl msg) k = do
35+ case lvl <= l of
36+ False => k () l
37+ True => do
38+ printLn $ unwords [show lvl, ":", msg]
39+ k () l
40+
41+||| Log `msg` at the given level.
42+|||
43+||| @l The level to log.
44+||| @m The message to log.
45+log : (l : Nat) -> (m : String) -> Eff () [LOG]
46+log lvl msg = call $ Log lvl msg
47+
48+-- --------------------------------------------------------------------- [ EOF ]
libs/effects/effects.ipkg+15−4
@@ -1,9 +1,20 @@
11package effects
22
33opts = "--nobasepkgs -i ../prelude -i ../base"
4−modules = Effects, Effect.Default, Effect.Monad,
54
6− Effect.Exception, Effect.File, Effect.State,
7− Effect.Random, Effect.StdIO, Effect.Select,
8− Effect.Memory, Effect.System, Effect.Trans
5+modules = Effects
6+ , Effect.Default
7+ , Effect.Monad
98
9+ , Effect.Exception
10+ , Effect.File
11+ , Effect.State
12+ , Effect.Random
13+ , Effect.StdIO
14+ , Effect.Select
15+ , Effect.Memory
16+ , Effect.System
17+ , Effect.Trans
18+ , Effect.Logging.Level
19+ , Effect.Logging.Simple
20+ , Effect.Logging.Default
test/effects005/defaultlog.idrnew file+18
@@ -0,0 +1,18 @@
1+import Effects
2+import Effect.Logging.Default
3+
4+func : Nat -> Eff () [LOG String]
5+func x = do
6+ log WARN Nil $ unwords ["I do nothing with", show x]
7+ pure ()
8+
9+doubleFunc : Nat -> Eff Nat [LOG String]
10+doubleFunc x = do
11+ log WARN ["NumOPS"] $ unwords ["Doing the double with", show x ]
12+ func x
13+ pure (x+x)
14+
15+main : IO ()
16+main = do
17+ x <- runInit [(ALL,["NumOPS"])] (doubleFunc 3)
18+ printLn x
test/effects005/expectednew file+5
@@ -0,0 +1,5 @@
1+"3 : Doing the double with 3"
2+6
3+8
4+"3 : [\"NumOPS\"] : Doing the double with 3"
5+6
test/effects005/runnew file+6
@@ -0,0 +1,6 @@
1+#!/usr/bin/env bash
2+idris $@ simplelog.idr -o simple -p effects
3+./simple
4+idris $@ defaultlog.idr -o default -p effects
5+./default
6+rm -f simple default *.ibc
test/effects005/simplelog.idrnew file+14
@@ -0,0 +1,14 @@
1+import Effects
2+import Effect.Logging.Simple
3+
4+doubleFunc : Nat -> Eff Nat [LOG]
5+doubleFunc x = do
6+ log WARN $ unwords ["Doing the double with", show x ]
7+ pure (x+x)
8+
9+main : IO ()
10+main = do
11+ x <- runInit [ALL] (doubleFunc 3)
12+ printLn x
13+ y <- runInit [OFF] (doubleFunc 4)
14+ printLn y