co-log

Composable Contravariant Comonadic Logging Library

https://github.com/kowainik/co-log

Version on this page:0.2.0@rev:1
LTS Haskell 22.14:0.6.1.0
Stackage Nightly 2024-03-29:0.6.1.0
Latest on Hackage:0.6.1.0

See all snapshots co-log appears in

MPL-2.0 licensed by Kowainik
Maintained by [email protected]
This version can be pinned in stack with:co-log-0.2.0@sha256:74d7cce4ae960ac932676686fbb65670037bcccf8ff2ebb3973e9a8ab579e75a,3981
# co-log

[![Hackage](https://img.shields.io/hackage/v/co-log.svg)](https://hackage.haskell.org/package/co-log)
[![MPL-2.0 license](https://img.shields.io/badge/license-MPL--2.0-blue.svg)](https://github.com/kowainik/co-log/blob/master/LICENSE)
[![Build status](https://secure.travis-ci.org/kowainik/co-log.svg)](https://travis-ci.org/kowainik/co-log)


Logging library based on [`co-log-core`](../co-log-core) package. Provides
ready-to-go implementation of logging. This README contains _How to_ tutorial on
using this library. This tutorial explains step by step how to integrate
`co-log` into small basic project, specifically how to replace `putStrLn` used
for logging with library provided logging.

All code below can be compiled and run with the following commands:

```shell
$ cabal new-build co-log
$ cabal new-exec readme
```

## Preamble: imports and language extensions

Since this is a literate haskell file, we need to specify all our language
extensions and imports up front.

```haskell
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}

import Colog (Message, WithLog, cmap, fmtMessage, logDebug, logInfo, logTextStdout, logWarning,
usingLoggerT)
import Control.Monad.IO.Class (MonadIO, liftIO)

import Data.Semigroup ((<>))
import qualified Data.Text as Text
import qualified Data.Text.IO as TextIO

```

## Simple IO function example

Consider the following function that reads lines from `stdin` and outputs
different feedback depending on the line size.

```haskell
processLinesBasic :: IO ()
processLinesBasic = do
line <- TextIO.getLine
case Text.length line of
0 -> do
-- here goes logging
TextIO.putStrLn ">>>> Empty input"
processLinesBasic
n -> do
TextIO.putStrLn ">>>> Correct input"
TextIO.putStrLn $ "Line length: " <> Text.pack (show n)
```

This code mixes application logic with logging of the steps. It's convenient to
have logging to observe behavior of the application. But `putStrLn` is very
simple and primitive way to log things.

## Using `co-log` library

In order to use `co-log` library, we need to refactor `processLinesBasic`
function in the following way:

```haskell
processLinesLog :: (WithLog env Message m, MonadIO m) => m ()
processLinesLog = do
line <- liftIO TextIO.getLine
case Text.length line of
0 -> do
-- here goes logging
logWarning "Empty input"
processLinesLog
n -> do
logDebug "Correct line"
logInfo $ "Line length: " <> Text.pack (show n)
```

Let's summarize required changes:

1. Make type more polymorphic: `(WithLog env Message m, MonadIO m) => m ()`
2. Add `liftIO` to all `IO` functions.
3. Replace `putStrLn` with proper `log*` function.

## Running actions

Let's run both functions:

```haskell
main :: IO ()
main = do
processLinesBasic

let action = cmap fmtMessage logTextStdout
usingLoggerT action processLinesLog
```

And here is how output looks like:

![screenshot from 2018-09-17 20-52-01](https://user-images.githubusercontent.com/4276606/45623973-8bafb900-babb-11e8-9e20-4369a5a8e5ff.png)

Changes

Change log

co-log uses PVP Versioning. The change log is available on GitHub.

0.2.0 — Nov 15, 2018

  • #45: Introduce approach for concurrent log writing.
  • #46: Moves logStringStdout, logStringStderr, logStringHandle, withLogStringFile from Colog.Actions to Colog.Core.IO
  • #77: Remove relude from dependencies. Add HLint check to Travis CI.
  • #64: Introduce basic benchmarks.
  • #20: Add experimental support for logger rotation (see Colog.Rotation module).
  • #39: Support GHC-8.2.2 and GHC-8.6.2.

0.1.0

  • #37: Add bounds to all dependencies. Move Prelude to the other-modules section.

0.0.0

  • Initially created.