Skip to content

PagingMatt/flog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

91 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

flog

Lightweight, functional logger for OCaml.

Build status Packagist

API documentation for the package can be viewed here.

Usage

The idea behind this library is to give a very functional interface to log OCaml code via, even though the action of logging itself might intrinsically be non-functional. Your code need-not suffer from such icki-ness though!

To use the library you need to start by choosing the Consumer implementation you want to use. This is important as it determines how your log messages get handled. flog provides a selection of these for you to choose from, but if none are suitable then you can implement one of your own (I promised that this was an extendable library!)

...
module ConsoleLogger = Logger(ConsoleConsumer)
...

Once you've applied the Logger functor to a Consumer implementation you are ready to start logging. As this is a 'functional-y' library this is done from within a monad, you lift up into the monad via Logger.start. This lift does no logging itself.

...
let x = 2 in
ConsoleLogger.start x
...

Now your value is wrapped in the monad there are four infix operators that can drive your computation. The first two are used to drive computation, while the second two are used to record logs.

val (=>=) : 'a t -> ('a -> 'b) -> 'b t

val (=>|) : 'a t -> ('a -> 'b t) -> 'b t

val (==|) : 'a t -> Message.t -> 'a t

val (=|=) : 'a t -> ('a -> Message.t) -> 'a t

If you need to just apply a function to the wrapped value and the function knows nothing about flog you can use =>= to drive the wrapped value along.

...
let f x = x + 1
...
ConsoleLogger.start 2
=>= f
...

If you need to apply a function to the wrapped value and that function itself returns a value wrapped in the logging monad then you can use =>| (monad bind). This benefits from one of the cool things about this library which is the assumption that any consumer of log messages is implemented following the monoid laws. This means that they can be associatively combined - making this bind operator able to combine two streams of logging.

...
let f x = ConsoleLogger.start (x + 1)
...
ConsoleLogger.start 2
=>| f
...

To actually pass a log message down to a consumer you can use ==|. This operator will pass the current value along to the result of the operator with no change while adding the message being applied to the consumer.

...
ConsoleLogger.start x
==| Message.make None Information "Hello, world."
...

As well as logging a concrete message, it is also useful to be able to build a message from a value at a given point in the program. You can use =|= to do this which will apply your current value to its parameter and let the underlying consumer handle the resulting message while the same value is passed forward unaltered.

...
ConsoleLogger.start "Hello, world."
=|= (fun m -> Message.make None Information m)
...

Finally when logging is complete you can drop back out of the monad with the Logger.stop function. This unwraps the value wrapped by the logger type and also contractually calls flush on the underlying consumer. flush may pass some state back in the form of a set of messages.

...
ConsoleLogger.start x
|> ConsoleLogger.stop
|> fun x,ms ->
  match ms with
  | None          -> ...
  | Some messages -> ...
...

The result of these? A nice functional-looking, concise logging library:

...
module ConsoleLogger = Logger(ConsoleConsumer)
...
let f x = x + 1
let g x = ConsoleLogger.start (x + 1)
...
ConsoleLogger.start 2
=>= f
==| Message.make None Information "Hello, world."
=|= (fun y -> Message.make None Trace (string_of_int y))
=>| g
|> ConsoleLogger.stop
|> fun x,ms -> ...
...

Acknowledgements

.gitignore

The .gitignore file for this repository was generated by gitignore.io. To generate the same file go here.

About

Lightweight, functional logger for OCaml.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages