co-log: Composable Contravariant Comonadic Logging Library

[ comonad, contravariant, library, logging, mpl, program ] [ Propose Tags ]

The default implementation of logging based on co-log-core.

The ideas behind this package are described in the following blog post:


[Skip to Readme]
Versions [faq] 0.0.0, 0.1.0, 0.2.0, 0.3.0.0
Change log CHANGELOG.md
Dependencies ansi-terminal (>=0.9 && <0.11), base (>=4.10.0.0 && <4.13), bytestring (>=0.10.8 && <0.11), chronos (>=1.0.4 && <1.1), co-log, co-log-core (>=0.2.0.0 && <0.3), containers (>=0.5.7 && <0.7), contravariant (==1.5.*), directory (>=1.3.0 && <1.4), filepath (>=1.4.1 && <1.5), mtl (>=2.2.2 && <2.3), stm (>=2.4 && <2.6), text (>=1.2.3 && <1.3), transformers (==0.5.*), typerep-map (>=0.3.2 && <0.4) [details]
License MPL-2.0
Copyright 2018-2019 Kowainik
Author Dmitrii Kovanikov
Maintainer Kowainik <xrom.xkov@gmail.com>
Revised Revision 3 made by shersh at Thu Sep 19 10:58:59 UTC 2019
Category Logging, Contravariant, Comonad
Home page https://github.com/kowainik/co-log
Bug tracker https://github.com/kowainik/co-log/issues
Source repo head: git clone https://github.com/kowainik/co-log.git
Uploaded by shersh at Sun May 5 13:39:47 UTC 2019
Distributions LTSHaskell:0.2.0, NixOS:0.3.0.0, Stackage:0.3.0.0
Executables tutorial-custom, tutorial-intro, readme, play-colog
Downloads 659 total (126 in the last 30 days)
Rating 2.25 (votes: 2) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs uploaded by user [build log]
All reported builds failed as of 2019-05-05 [all 1 reports]

Modules

[Index] [Quick Jump]

Downloads

Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.

Maintainer's Corner

For package maintainers and hackage trustees


Readme for co-log-0.3.0.0

[back to package description]

co-log

Hackage Stackage LTS Stackage Nightly MPL-2.0 license Build status

Logging library based on 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:

$ 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.

{-# 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.

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:

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:

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