Composable Contravariant Comonadic Logging Library

Version on this page:
LTS Haskell 22.26:
Stackage Nightly 2024-06-22:
Latest on Hackage:

See all snapshots co-log-core appears in

MPL-2.0 licensed by Dmitrii Kovanikov
Maintained by Kowainik
This version can be pinned in stack with:co-log-core-,3574

Module documentation for

Depends on 1 package(full list with versions):
Used by 1 package in lts-18.28(full list with versions):


GitHub CI Build status Windows build MPL-2.0 license

co-log-core Hackage Stackage LTS Stackage Nightly
co-log Hackage Stackage LTS Stackage Nightly
co-log-polysemy Hackage Stackage LTS Stackage Nightly

co-log is a composable and configurable logging framework. It combines all the benefits of Haskell idioms to provide a reasonable and convenient interface. Though it uses some advanced concepts in its core, we are striving to provide beginner-friendly API. The library also contains complete documentation with a lot of beginner-friendly examples, explanations and tutorials to guide users. The combination of a pragmatic approach to logging and fundamental Haskell abstractions allows us to create a highly composable and configurable logging framework.

If you’re interested in how different Haskell typeclasses are used to implement core functions of co-log, you can read the following blog post which goes into detail about internal implementation specifics:

co-log is also modular on the level of packages. We care a lot about a low dependency footprint so you can build your logging only on top of the minimal required interface for your use-case. This repository contains the following packages:

  • co-log-core: lightweight package with basic data types and general idea which depends only on base.
  • co-log: taggless final implementation of logging library based on co-log-core.
  • co-log-polysemy: implementation of logging library based on co-log-core and the polysemy extensible effects library.
  • co-log-benchmark: benchmarks of the co-log library.

To provide a more user-friendly introduction to the library, we’ve created the tutorial series which introduces the main concepts behind co-log smoothly:

co-log also cares about concurrent logging. For this purpose we have the concurrent-playground executable where we experiment with different multithreading scenarios to test the library’s behavior. You can find it here:


co-log is compared with basic functions like putStrLn. Since IO overhead is big enough, every benchmark dumps 10K messages to output. If a benchmark’s name doesn’t contain Message then this benchmark simply dumps the string "message" to output, otherwise it works with the Message data type from the co-log library.

To run benchmarks, use the following command:

cabal v2-run co-log-bench
Benchmarks Time for 10K messages
Prelude.putStrLn 5.117ms
Text.putStrLn 9.220ms
ByteString.putStrLn 2.971ms
mempty 1.181ms
logStringStdout 5.107ms
logPrint 5.248ms
logTextStdout 5.351ms
logByteStringStdout 2.933ms
logByteStringStderr 17.482ms
ByteString > (stdout <> stderr) 17.715ms
Message > format > stdout 9.188ms
Message > format > ByteString > stdout 3.524ms
Message{callstack} > format > stdout 9.139ms
Message{callstack:5} > format > stdout 9.464ms
Message{callstack:50} > format > stdout 9.439ms
Message{Time,ThreadId} > format > stdout 54.160ms
Message{Time,ThreadId} > format > ByteString > stdout 54.137ms


Change log

co-log-core uses PVP Versioning. The change log is available on GitHub. — Apr 18, 2020

  • #186: Support GHC-8.10.1. — Jan 19, 2020

  • #139: Add (unrepresentable) Functor instance for LogAction with the custom type-error. (by @vrom911)
  • #148: Support GHC-8.8.2. (by @chshersh)
  • #122: Add the separate combinator. (by @vrom911)
  • #125: Add monadic versions of contravariant functions. (by @piq9117)
  • #138: Add hoistLogAction — higher-order transformation function. (by @jiribenes)
  • #123: Write default implementation to getLogAction via logActionL. (by @SanchayanMaity) — May 5, 2019

  • #85: Move overLogAction to HasLog typeclass
  • #101: Add logActionL lens with default implementation to HasLog type class.
  • #99: Add comonadic combinators: duplicate and multiplicate.
  • #78: Improve documentation significantly.

0.1.1 — Nov 15, 2018

  • #63: Add logPrint, logPrintStderr, logPrintHandle and withLogPrintFile to Colog.Core.IO.
  • #46: Moves logStringStdout, logStringStderr, logStringHandle, withLogStringFile from Colog.Actions to Colog.Core.IO.
  • #48: Adds liftLogIO function.
  • #49: Add <& and &>operators for unLogAction.
  • #47: Add doctest tests.
  • #13: Add .cabal file description and improve documentation.
  • #39: Support GHC-8.2.2 and GHC-8.6.2.


  • #38: Rename cbind to cmapM.

  • #37: Add base bounds.


  • Initially created.