co-log
Composable Contravariant Comonadic Logging Library
https://github.com/co-log/co-log
LTS Haskell 23.1: | 0.6.1.0 |
Stackage Nightly 2024-12-09: | 0.6.1.0 |
Latest on Hackage: | 0.6.1.0 |
co-log-0.6.1.0@sha256:9047e92fcf66550bd3f83c3198061d4d748eecb6cd7f54ea5edfdc205f64381f,6442
Module documentation for 0.6.1.0
co-log
co-log
is a composable and configurable logging framework. It
combines all the benefits of Haskell idioms to provide a reasonable
and convenient interface. Although the library design uses some advanced
concepts in its core, we are striving to provide beginner-friendly API. The
library also provides the 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 the internal implementation specifics:
Co-Log Family
Co-Log is a family of repositories for a composable and configurable logging
framework co-log
.
Here is the list of currently available repositories and libraries that you can check out:
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-benchmarks |
benchmarks of the co-log library |
- |
co-log
library
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 build
$ cabal 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 Control.Monad.IO.Class (MonadIO, liftIO)
import Colog (Message, WithLog, cmap, fmtMessage, logDebug, logInfo, logTextStdout, logWarning,
usingLoggerT)
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:
- Make type more polymorphic:
(WithLog env Message m, MonadIO m) => m ()
- Add
liftIO
to allIO
functions. - Replace
putStrLn
with properlog*
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:
More Tutorials
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, please check more details here.
Changes
Changelog
co-log
uses PVP Versioning.
The changelog is available on GitHub.
0.6.1.0 - Mar 1, 2024
What’s Changed
- GA(deps): Bump actions/cache from 3 to 4 by @dependabot in https://github.com/co-log/co-log/pull/273
- docs: refine the loggert tutorials by @xieyuschen in https://github.com/co-log/co-log/pull/272
- Support ghc-9.8. by @alaendle in https://github.com/co-log/co-log/pull/270
Full Changelog: https://github.com/co-log/co-log/compare/v0.6.0.2...v0.6.1.0
0.6.0.0 - Sep 18, 2023
What’s Changed
- Support GHC-9.6 - replace
typerep-map
withdependent-map
. by @alaendle in #264 - Support GHC 9.4. by @alaendle in #252
- Add MonadUnliftIO instance by @newhoggy in #240
- Update CI tested GHC versions & workaround for GHC < 9.4.5 (run-st, primitive-unlifted) by @alaendle in #257
- Derive
MonadFail
forLoggerT
by @alaendle in #260 - docs: use relative path to benefit locally reading by @xieyuschen in #253
- docs: refine readme by @xieyuschen in #254
- tutorials: add demo for LoggerT and SimpleMsg, #84 by @xieyuschen in #256
- docs: add a link to tutorial pages and aggregate all tutorial pages by @xieyuschen in #259
- tutorials: add a tutorial for loggert and message by @xieyuschen in #261
- Create tags and upload package candidates on version bumps. by @alaendle in #265
- Added @alaendle as code owner. by @alaendle in #258
- GA(deps): Bump actions/checkout from 3 to 4 by @dependabot in #263
New Contributors
Full Changelog: https://github.com/co-log/co-log/compare/v0.5.0.0...v0.6.0.0
0.5.0.0 - Nov 2, 2022
- #230: Support GHC-9.2.
- Allow
mtl-2.3
. - Allow
vector-0.13
. - Allow
hedgehog-1.2
. - #187:
Remove
CoLog.Concurrent
module and executable. - #243: Improve printing in multiple threads.
- Drop support for GHC-8.2, GHC-8.4, GHC-8.6, GHC-8.8
0.4.0.2 — , 2021
- #223: Support GHC-9.0.1. Require typerep-map ^>= 0.4
0.4.0.1 — Apr 18, 2020
- #186: Support GHC-8.10.1.
0.4.0.0 — Jan 19, 2020
-
#120: Improve time formatting.
Old:
29-12-2019 22:00:00.000
New:
29 Dec 2019 22:00:00.000 +00:00
(by @vrom911)
-
#119: Add new message type that allows printing messages without
Severity
. (by @sphaso) -
#150: Introduce
formatWith
— beginner-friendly alias for formatting combinator. (by @chshersh) -
Use
chronos-1.1
as1.0.9
is not Windows-compatible. (by @vrom911) -
#156: Improve documentation for the
Colog.Concurrent
module. (by @chshersh) -
#124: Implement executable playground for concurrent logging. (by @chshersh)
0.3.0.0 — May 5, 2019
-
#77: Important: Use
chronos
time formatter. This is a breaking change because default field map inRichMessage
now contains different type representing time. If you use your custom formatter for time, you should change it. Othwerwise no observable differences in the library API usage will be noticed. -
#103: Breaking change: make
Message
data type polymorhic over the type of severity.Migration guide: this change is done in backwards-compatible way. If you use any fields of the
Message
data type, you should rename them according to the following scheme:messageSeverity -> msgSeverity messageStack -> msgStack messageText -> msgText
-
Export more formatting functions to make implementation of custom formatters easier.
-
#96: Add
simpleMessageAction
andrichMessageAction
to work withMessage
s. -
Use
co-log-core
of version0.2.0.0
.
0.2.0 — Nov 15, 2018
- #45: Introduce approach for concurrent log writing.
- #46:
Moves
logStringStdout
,logStringStderr
,logStringHandle
,withLogStringFile
fromColog.Actions
toColog.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 theother-modules
section.
0.0.0
- Initially created.