packages feed

co-log 0.5.0.0 → 0.6.0.0

raw patch · 16 files changed

+496/−264 lines, 16 filesdep +dependent-mapdep +dependent-sumdep +run-stdep −typerep-mapdep ~ansi-terminaldep ~basedep ~bytestringnew-component:exe:tutorial-loggertnew-component:exe:tutorial-loggert-simplenew-uploader

Dependencies added: dependent-map, dependent-sum, run-st, unliftio-core

Dependencies removed: typerep-map

Dependency ranges changed: ansi-terminal, base, bytestring, co-log-core, doctest, exceptions, hedgehog, mtl, text

Files

CHANGELOG.md view
@@ -3,33 +3,58 @@ `co-log` uses [PVP Versioning][1]. The changelog is available [on GitHub][2]. +## 0.6.0.0 - Sep 18, 2023++### What's Changed++* Support GHC-9.6 - replace `typerep-map` with `dependent-map`. by @alaendle in [#264](https://github.com/co-log/co-log/pull/264)+* Support GHC 9.4. by @alaendle in [#252](https://github.com/co-log/co-log/pull/252)+* Add MonadUnliftIO instance by @newhoggy in [#240](https://github.com/co-log/co-log/pull/240)+* Update CI tested GHC versions & workaround for GHC < 9.4.5 (run-st, primitive-unlifted) by @alaendle in [#257](https://github.com/co-log/co-log/pull/257)+* Derive `MonadFail` for `LoggerT` by @alaendle in [#260](https://github.com/co-log/co-log/pull/260)+* docs: use relative path to benefit locally reading by @xieyuschen in [#253](https://github.com/co-log/co-log/pull/253)+* docs: refine readme by @xieyuschen in [#254](https://github.com/co-log/co-log/pull/254)+* tutorials: add demo for LoggerT and SimpleMsg, #84 by @xieyuschen in [#256](https://github.com/co-log/co-log/pull/256)+* docs: add a link to tutorial pages and aggregate all tutorial pages by @xieyuschen in [#259](https://github.com/co-log/co-log/pull/259)+* tutorials: add a tutorial for loggert and message by @xieyuschen in [#261](https://github.com/co-log/co-log/pull/261)+* Create tags and upload package candidates on version bumps. by @alaendle in [#265](https://github.com/co-log/co-log/pull/265)+* Added @alaendle as code owner. by @alaendle in [#258](https://github.com/co-log/co-log/pull/258)+* GA(deps): Bump actions/checkout from 3 to 4 by @dependabot in [#263](https://github.com/co-log/co-log/pull/263)++### New Contributors++* @xieyuschen made their first contribution in [#253](https://github.com/co-log/co-log/pull/253)+* @newhoggy made their first contribution in [#240](https://github.com/co-log/co-log/pull/240)++**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](https://github.com/kowainik/co-log/issues/230):+* [#230](https://github.com/co-log/co-log/issues/230):   Support GHC-9.2. * Allow `mtl-2.3`. * Allow `vector-0.13`. * Allow `hedgehog-1.2`.-* [#187](https://github.com/kowainik/co-log/issues/187):+* [#187](https://github.com/co-log/co-log/issues/187):   Remove `CoLog.Concurrent` module and executable.-* [#243](https://github.com/kowainik/co-log/pull/243):+* [#243](https://github.com/co-log/co-log/pull/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 — <M> <d>, 2021 -* [#223](https://github.com/kowainik/co-log/pulls/223):+* [#223](https://github.com/co-log/co-log/pulls/223):   Support GHC-9.0.1.   Require typerep-map ^>= 0.4  ## 0.4.0.1 — Apr 18, 2020 -* [#186](https://github.com/kowainik/co-log/issues/186):+* [#186](https://github.com/co-log/co-log/issues/186):   Support GHC-8.10.1.  ## 0.4.0.0 — Jan 19, 2020 -* [#120](https://github.com/kowainik/co-log/issues/120):+* [#120](https://github.com/co-log/co-log/issues/120):   Improve time formatting.    Old: `29-12-2019 22:00:00.000`@@ -37,39 +62,39 @@   New: `29 Dec 2019 22:00:00.000 +00:00`    (by [@vrom911](https://github.com/vrom911))-* [#144](https://github.com/kowainik/co-log/issues/144):+* [#144](https://github.com/co-log/co-log/issues/144):   Add Windows CI check.   (by [@vrom911](https://github.com/vrom911))-* [#148](https://github.com/kowainik/co-log/issues/148):+* [#148](https://github.com/co-log/co-log/issues/148):   Support GHC-8.8.2.   (by [@chshersh](https://github.com/chshersh))-* [#119](https://github.com/kowainik/co-log/issues/119):+* [#119](https://github.com/co-log/co-log/issues/119):   Add new message type that allows printing messages without   `Severity`.   (by [@sphaso](https://github.com/sphaso))-* [#150](https://github.com/kowainik/co-log/issues/150):+* [#150](https://github.com/co-log/co-log/issues/150):   Introduce `formatWith` — beginner-friendly alias for formatting combinator.   (by [@chshersh](https://github.com/chshersh)) * Use `chronos-1.1` as `1.0.9` is not Windows-compatible.   (by [@vrom911](https://github.com/vrom911))-* [#156](https://github.com/kowainik/co-log/issues/156):+* [#156](https://github.com/co-log/co-log/issues/156):   Improve documentation for the `Colog.Concurrent` module.   (by [@chshersh](https://github.com/chshersh))-* [#146](https://github.com/kowainik/co-log/issues/146):+* [#146](https://github.com/co-log/co-log/issues/146):   Allow `ansi-terminal-0.10`.   (by [@mpilgrem](https://github.com/mpilgrem))-* [#124](https://github.com/kowainik/co-log/issues/124):+* [#124](https://github.com/co-log/co-log/issues/124):   Implement executable playground for concurrent logging.   (by [@chshersh](https://github.com/chshersh))  ## 0.3.0.0 — May 5, 2019 -* [#77](https://github.com/kowainik/co-log/issues/77):+* [#77](https://github.com/co-log/co-log/issues/77):   **Important:** Use `chronos` time formatter. This is a breaking change because   default field map in `RichMessage` 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](https://github.com/kowainik/co-log/issues/103):+* [#103](https://github.com/co-log/co-log/issues/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@@ -81,30 +106,30 @@   messageText     -> msgText   ``` * Export more formatting functions to make implementation of custom formatters easier.-* [#96](https://github.com/kowainik/co-log/issues/96):+* [#96](https://github.com/co-log/co-log/issues/96):   Add `simpleMessageAction` and `richMessageAction` to work with `Message`s. * Use `co-log-core` of version `0.2.0.0`.  ## 0.2.0 — Nov 15, 2018 -* [#45](https://github.com/kowainik/co-log/issues/45):+* [#45](https://github.com/co-log/co-log/issues/45):   Introduce approach for concurrent log writing.-* [#46](https://github.com/kowainik/co-log/issues/46):+* [#46](https://github.com/co-log/co-log/issues/46):   Moves `logStringStdout`, `logStringStderr`, `logStringHandle`,   `withLogStringFile` from `Colog.Actions` to `Colog.Core.IO`-* [#77](https://github.com/kowainik/co-log/issues/77):+* [#77](https://github.com/co-log/co-log/issues/77):   Remove `relude` from dependencies.   Add HLint check to Travis CI.-* [#64](https://github.com/kowainik/co-log/issues/64):+* [#64](https://github.com/co-log/co-log/issues/64):   Introduce basic benchmarks.-* [#20](https://github.com/kowainik/co-log/issues/20):+* [#20](https://github.com/co-log/co-log/issues/20):   Add experimental support for logger rotation (see `Colog.Rotation` module).-* [#39](https://github.com/kowainik/co-log/issues/39):+* [#39](https://github.com/co-log/co-log/issues/39):   Support GHC-8.2.2 and GHC-8.6.2.  ## 0.1.0 -* [#37](https://github.com/kowainik/co-log/issues/37):+* [#37](https://github.com/co-log/co-log/issues/37):   Add bounds to all dependencies. Move `Prelude` to the   `other-modules` section. @@ -113,4 +138,4 @@ * Initially created.  [1]: https://pvp.haskell.org-[2]: https://github.com/kowainik/co-log/releases+[2]: https://github.com/co-log/co-log/releases
README.lhs view
@@ -1,9 +1,9 @@ # co-log -![Co-logo](https://user-images.githubusercontent.com/8126674/80955687-92f21a80-8df7-11ea-90d3-422dafdc8391.png)+<img align="left" width="180" height="180" src="https://user-images.githubusercontent.com/8126674/80955687-92f21a80-8df7-11ea-90d3-422dafdc8391.png"> -[![GitHub CI](https://github.com/kowainik/co-log/workflows/CI/badge.svg)](https://github.com/kowainik/co-log/actions)-[![MPL-2.0 license](https://img.shields.io/badge/license-MPL--2.0-blue.svg)](https://github.com/kowainik/co-log/blob/main/LICENSE)+[![GitHub CI](https://github.com/co-log/co-log/workflows/CI/badge.svg)](https://github.com/co-log/co-log/actions)+[![MPL-2.0 license](https://img.shields.io/badge/license-MPL--2.0-blue.svg)](https://github.com/co-log/co-log/blob/main/LICENSE)  `co-log` is a composable and configurable logging framework. It combines all the benefits of Haskell idioms to provide a reasonable@@ -14,11 +14,13 @@ 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: Composable Contravariant Combinatorial Comonadic Configurable Convenient Logging](https://kowainik.github.io/posts/2018-09-25-co-log)+- [co-log: Composable Contravariant Combinatorial Comonadic Configurable Convenient Logging](https://kowainik.github.io/posts/2018-09-25-co-log)  ## Co-Log Family @@ -28,12 +30,12 @@ Here is the list of currently available repositories and libraries that you can check out: -|                                                                   |                                                                                                                                                        |                                    |-| :---------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------- |-| [`co-log-core`](https://github.com/co-log/co-log-core)            | lightweight package with basic data types and general idea which depends only on `base`                                                                | [![Hackage][hk-img-core]][hk-core] |-| [`co-log`](https://github.com/co-log/co-log)                      | taggless final implementation of logging library based on `co-log-core`                                                                                | [![Hackage][hk-img]][hk]           |-| [`co-log-polysemy`](https://github.com/co-log/co-log-polysemy)    | implementation of logging library based on `co-log-core` and the [`polysemy`](http://hackage.haskell.org/package/polysemy) extensible effects library. | [![Hackage][hk-img-ps]][hk-ps]     |-| [`co-log-benchmarks`](https://github.com/co-log/co-log-benchmarks) | benchmarks of the `co-log` library                                                                                                                     | -+|                                                                    |                                                                                                                                                        |                                    |+| :----------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------- |+| [`co-log-core`](https://github.com/co-log/co-log-core)             | lightweight package with basic data types and general idea which depends only on `base`                                                                | [![Hackage][hk-img-core]][hk-core] |+| [`co-log`](https://github.com/co-log/co-log)                       | taggless final implementation of logging library based on `co-log-core`                                                                                | [![Hackage][hk-img]][hk]           |+| [`co-log-polysemy`](https://github.com/co-log/co-log-polysemy)     | implementation of logging library based on `co-log-core` and the [`polysemy`](http://hackage.haskell.org/package/polysemy) extensible effects library. | [![Hackage][hk-img-ps]][hk-ps]     |+| [`co-log-benchmarks`](https://github.com/co-log/co-log-benchmarks) | benchmarks of the `co-log` library                                                                                                                     | -                                  |  ## `co-log` library @@ -137,16 +139,7 @@  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:--* [Intro: Using `LogAction`](https://github.com/co-log/co-log/blob/main/tutorials/1-intro/Intro.md)-* [Using custom monad that stores `LogAction` inside its environment](https://github.com/co-log/co-log/blob/main/tutorials/2-custom/Custom.md)--`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:--* [tutorials/Concurrent.hs](tutorials/Concurrent.hs)+smoothly, please [check more details here](./tutorials/README.md).  [hk-img]: https://img.shields.io/hackage/v/co-log.svg?logo=haskell [hk-img-ps]: https://img.shields.io/hackage/v/co-log-polysemy.svg?logo=haskell
README.md view
@@ -1,9 +1,9 @@ # co-log -![Co-logo](https://user-images.githubusercontent.com/8126674/80955687-92f21a80-8df7-11ea-90d3-422dafdc8391.png)+<img align="left" width="180" height="180" src="https://user-images.githubusercontent.com/8126674/80955687-92f21a80-8df7-11ea-90d3-422dafdc8391.png"> -[![GitHub CI](https://github.com/kowainik/co-log/workflows/CI/badge.svg)](https://github.com/kowainik/co-log/actions)-[![MPL-2.0 license](https://img.shields.io/badge/license-MPL--2.0-blue.svg)](https://github.com/kowainik/co-log/blob/main/LICENSE)+[![GitHub CI](https://github.com/co-log/co-log/workflows/CI/badge.svg)](https://github.com/co-log/co-log/actions)+[![MPL-2.0 license](https://img.shields.io/badge/license-MPL--2.0-blue.svg)](https://github.com/co-log/co-log/blob/main/LICENSE)  `co-log` is a composable and configurable logging framework. It combines all the benefits of Haskell idioms to provide a reasonable@@ -14,11 +14,13 @@ 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: Composable Contravariant Combinatorial Comonadic Configurable Convenient Logging](https://kowainik.github.io/posts/2018-09-25-co-log)+- [co-log: Composable Contravariant Combinatorial Comonadic Configurable Convenient Logging](https://kowainik.github.io/posts/2018-09-25-co-log)  ## Co-Log Family @@ -28,12 +30,12 @@ Here is the list of currently available repositories and libraries that you can check out: -|                                                                   |                                                                                                                                                        |                                    |-| :---------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------- |-| [`co-log-core`](https://github.com/co-log/co-log-core)            | lightweight package with basic data types and general idea which depends only on `base`                                                                | [![Hackage][hk-img-core]][hk-core] |-| [`co-log`](https://github.com/co-log/co-log)                      | taggless final implementation of logging library based on `co-log-core`                                                                                | [![Hackage][hk-img]][hk]           |-| [`co-log-polysemy`](https://github.com/co-log/co-log-polysemy)    | implementation of logging library based on `co-log-core` and the [`polysemy`](http://hackage.haskell.org/package/polysemy) extensible effects library. | [![Hackage][hk-img-ps]][hk-ps]     |-| [`co-log-benchmarks`](https://github.com/co-log/co-log-benchmarks) | benchmarks of the `co-log` library                                                                                                                     | -+|                                                                    |                                                                                                                                                        |                                    |+| :----------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------- |+| [`co-log-core`](https://github.com/co-log/co-log-core)             | lightweight package with basic data types and general idea which depends only on `base`                                                                | [![Hackage][hk-img-core]][hk-core] |+| [`co-log`](https://github.com/co-log/co-log)                       | taggless final implementation of logging library based on `co-log-core`                                                                                | [![Hackage][hk-img]][hk]           |+| [`co-log-polysemy`](https://github.com/co-log/co-log-polysemy)     | implementation of logging library based on `co-log-core` and the [`polysemy`](http://hackage.haskell.org/package/polysemy) extensible effects library. | [![Hackage][hk-img-ps]][hk-ps]     |+| [`co-log-benchmarks`](https://github.com/co-log/co-log-benchmarks) | benchmarks of the `co-log` library                                                                                                                     | -                                  |  ## `co-log` library @@ -137,16 +139,7 @@  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:--* [Intro: Using `LogAction`](https://github.com/co-log/co-log/blob/main/tutorials/1-intro/Intro.md)-* [Using custom monad that stores `LogAction` inside its environment](https://github.com/co-log/co-log/blob/main/tutorials/2-custom/Custom.md)--`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:--* [tutorials/Concurrent.hs](tutorials/Concurrent.hs)+smoothly, please [check more details here](./tutorials/README.md).  [hk-img]: https://img.shields.io/hackage/v/co-log.svg?logo=haskell [hk-img-ps]: https://img.shields.io/hackage/v/co-log-polysemy.svg?logo=haskell
co-log.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.4 name:                co-log-version:             0.5.0.0+version:             0.6.0.0 synopsis:            Composable Contravariant Comonadic Logging Library description:     The default implementation of logging based on [co-log-core](http://hackage.haskell.org/package/co-log-core).@@ -9,13 +9,13 @@     .     * [co-log: Composable Contravariant Combinatorial Comonadic Configurable Convenient Logging](https://kowainik.github.io/posts/2018-09-25-co-log) -homepage:            https://github.com/kowainik/co-log-bug-reports:         https://github.com/kowainik/co-log/issues+homepage:            https://github.com/co-log/co-log+bug-reports:         https://github.com/co-log/co-log/issues license:             MPL-2.0 license-file:        LICENSE author:              Dmitrii Kovanikov maintainer:          Kowainik <xrom.xkov@gmail.com>-copyright:           2018-2022 Kowainik+copyright:           2018-2022 Kowainik, 2023 Co-Log category:            Logging, Contravariant, Comonad build-type:          Simple stability:           provisional@@ -23,14 +23,16 @@                      README.md tested-with:         GHC == 8.10.7                      GHC == 9.0.2-                     GHC == 9.2.4+                     GHC == 9.2.8+                     GHC == 9.4.7+                     GHC == 9.6.2  source-repository head   type:                git-  location:            https://github.com/kowainik/co-log.git+  location:            https://github.com/co-log/co-log.git  common common-options-  build-depends:       base >= 4.14 && < 4.17+  build-depends:       base >= 4.14 && < 4.19    ghc-options:         -Wall                        -Wcompat@@ -72,10 +74,17 @@   if os(windows)     buildable:         False   build-depends:       co-log-core+                       , text    build-tool-depends:  markdown-unlit:markdown-unlit   ghc-options:         -pgmL markdown-unlit +common tutorial-depends+  import: tutorial-options+  build-depends:     co-log+                     , mtl++ library   import:              common-options   hs-source-dirs:      src@@ -87,20 +96,24 @@                            Colog.Pure                            Colog.Rotation -  build-depends:       ansi-terminal >= 0.10 && < 0.12-                     , bytestring >= 0.10.8 && < 0.12+  build-depends:       ansi-terminal >= 1.0 && < 1.1+                     , bytestring >= 0.10.8 && < 0.13                      , co-log-core ^>= 0.3                      , containers >= 0.5.7 && < 0.7                      , contravariant ^>= 1.5                      , directory ^>= 1.3.0-                     , exceptions >= 0.8.3+                     , exceptions >= 0.8.3 && < 0.11                      , filepath ^>= 1.4.1                      , mtl >= 2.2.2 && < 2.4-                     , text >= 1.2.3 && < 2.1+                     , text >= 1.2.3 && < 2.2                      , chronos ^>= 1.1 && < 1.2                      , transformers >= 0.5 && < 0.7-                     , typerep-map ^>= 0.5+                     , dependent-sum >= 0.7 && < 0.8+                     , dependent-map >= 0.4 && < 0.5+                     , unliftio-core ^>= 0.2                      , vector >= 0.12.0.3 && < 0.14+  if impl(ghc < 9.4.5)+    build-depends:     run-st <= 0.1.3.0  executable play-colog   import:              common-options@@ -109,7 +122,7 @@    build-depends:       co-log                      , mtl-                     , typerep-map+                     , dependent-map    ghc-options:         -threaded                        -rtsopts@@ -131,31 +144,42 @@   build-depends:       co-log                      , text -executable tutorial-intro-  import:              tutorial-options-  main-is:             tutorials/1-intro/Intro.lhs--executable tutorial-custom-  import:              tutorial-options-  main-is:             tutorials/2-custom/Custom.lhs-  build-depends:       co-log-                     , mtl- test-suite test-co-log   import:              common-options   build-depends:       co-log                      , co-log-core-                     , hedgehog >= 1.0 && < 1.3+                     , hedgehog >= 1.0 && < 1.5   hs-source-dirs:      test   main-is:             Property.hs   type:                exitcode-stdio-1.0  test-suite co-log-doctest   import:              common-options+  -- Disable `doctest` on windows since it couldn't handle qualified imports reliable (which leads to errors like "Not in scope: `C.timeToOffsetDatetime'").+  if os(windows)+    buildable:         False   type:                exitcode-stdio-1.0   hs-source-dirs:      test   main-is:             Doctest.hs -  build-depends:       doctest >= 0.16.0 && < 0.21+  build-depends:       doctest >= 0.16.0 && < 0.23                      , Glob ^>= 0.10.0   ghc-options:         -threaded+++executable tutorial-intro+  import:              tutorial-options+  main-is:             tutorials/1-intro/Intro.lhs++executable tutorial-loggert-simple+  import:              tutorial-depends+  main-is:             tutorials/2-loggert/loggert.lhs+  +executable tutorial-loggert+  import:              tutorial-depends+  main-is:             tutorials/3-loggert-with-message/loggert.lhs++executable tutorial-custom+  import:              tutorial-depends+  main-is:             tutorials/custom/Custom.lhs+
src/Colog.hs view
@@ -1,7 +1,6 @@ {- |-Copyright:  (c) 2018-2022 Kowainik+Copyright:  (c) 2018-2022 Kowainik, 2023 Co-Log SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>  This package contains @mtl@ implementation of composable, contravariant and comonadic logging based on @co-log-core@.
src/Colog/Actions.hs view
@@ -1,7 +1,6 @@ {- |-Copyright:  (c) 2018-2022 Kowainik+Copyright:  (c) 2018-2022 Kowainik, 2023 Co-Log SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>  Logging actions for various text types. -}
src/Colog/Contra.hs view
@@ -3,9 +3,8 @@ {-# LANGUAGE CPP #-}  {- |-Copyright:  (c) 2018-2022 Kowainik+Copyright:  (c) 2018-2022 Kowainik, 2023 Co-Log SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>  This module contains 'LogAction' orphan instances of @contravariant@ classes. -}
src/Colog/Message.hs view
@@ -5,13 +5,11 @@ {-# LANGUAGE FlexibleInstances     #-} {-# LANGUAGE GADTs                 #-} {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE OverloadedLabels      #-} {-# LANGUAGE TypeFamilies          #-}  {- |-Copyright:  (c) 2018-2022 Kowainik+Copyright:  (c) 2018-2022 Kowainik, 2023 Co-Log SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>  This module contains logging messages data types along with the formatting and logging actions for them.@@ -65,21 +63,21 @@        , upgradeMessageAction        ) where -import Prelude hiding (log)+import Prelude hiding (lookup, log)  import Control.Concurrent (ThreadId, myThreadId) import Control.Exception (Exception, displayException) import Control.Monad.IO.Class (MonadIO (..))+import Data.Dependent.Map (DMap, fromList, lookup)+import Data.Dependent.Sum (DSum ((:=>))) import Data.Kind (Type) import Data.Text (Text) import Data.Text.Lazy (toStrict)-import Data.TypeRepMap (TypeRepMap)-import GHC.Exts (IsList (..))-import GHC.OverloadedLabels (IsLabel (..)) import GHC.Stack (CallStack, SrcLoc (..), callStack, getCallStack, withFrozenCallStack)-import GHC.TypeLits (KnownSymbol, Symbol)+import GHC.TypeLits (Symbol) import System.Console.ANSI (Color (..), ColorIntensity (Vivid), ConsoleLayer (Foreground), SGR (..),                             setSGRCode)+import Type.Reflection (TypeRep, typeRep)  import Colog.Core (LogAction, Severity (..), cmap) import Colog.Monad (WithLog, logMsg)@@ -89,7 +87,6 @@ import qualified Data.Text as T import qualified Data.Text.Lazy.Builder as TB import qualified Data.Text.Lazy.Builder.Int as TB-import qualified Data.TypeRepMap as TM import qualified Data.Vector as Vector  ----------------------------------------------------------------------------@@ -297,15 +294,6 @@ unMessageField (MessageField f) = f {-# INLINE unMessageField #-} -instance (KnownSymbol fieldName, a ~ m (FieldType fieldName))-      => IsLabel fieldName (a -> TM.WrapTypeable (MessageField m)) where-#if MIN_VERSION_base(4,11,0)-    fromLabel field = TM.WrapTypeable $ MessageField @fieldName field-#else-    fromLabel field = TM.WrapTypeable $ MessageField  @_ @fieldName field-#endif-    {-# INLINE fromLabel #-}- -- | Helper function to deal with 'MessageField' when looking it up in the 'FieldMap'. extractField     :: Applicative m@@ -322,7 +310,7 @@ {- | Depedent map from type level strings to the corresponding types. See 'FieldType' for mapping between names and types. -}-type FieldMap (m :: Type -> Type) = TypeRepMap (MessageField m)+type FieldMap m = DMap TypeRep (MessageField m)  {- | Default message map that contains actions to extract 'ThreadId' and 'C.Time'. Basically, the following mapping:@@ -334,8 +322,8 @@ -} defaultFieldMap :: MonadIO m => FieldMap m defaultFieldMap = fromList-    [ #threadId  (liftIO myThreadId)-    , #posixTime (liftIO C.now)+    [ typeRep @"threadId"  :=> MessageField (liftIO myThreadId)+    , typeRep @"posixTime" :=> MessageField (liftIO C.now)     ]  {- | Contains additional data to 'Message' to display more verbose information.@@ -413,8 +401,8 @@     -> (Maybe ThreadId -> Maybe C.Time -> msg -> Text)     -> m Text fmtRichMessageCustomDefault RichMsg{..} formatter = do-    maybeThreadId  <- extractField $ TM.lookup @"threadId"  richMsgMap-    maybePosixTime <- extractField $ TM.lookup @"posixTime" richMsgMap+    maybeThreadId  <- extractField $ lookup (typeRep @"threadId")  richMsgMap+    maybePosixTime <- extractField $ lookup (typeRep @"posixTime") richMsgMap     pure $ formatter maybeThreadId maybePosixTime richMsgMsg  {- | Shows time in the following format:
src/Colog/Monad.hs view
@@ -1,9 +1,8 @@ {-# LANGUAGE InstanceSigs #-}  {- |-Copyright:  (c) 2018-2022 Kowainik+Copyright:  (c) 2018-2022 Kowainik, 2023 Co-Log SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>  Core of the @mtl@ implementation. -}@@ -22,6 +21,7 @@ import Prelude hiding (log)  import Control.Monad.IO.Class (MonadIO (..))+import Control.Monad.IO.Unlift (MonadUnliftIO (..)) import Control.Monad.Reader (MonadReader (..), ReaderT (..), asks) import Control.Monad.Trans.Class (MonadTrans (..)) import Data.Foldable (traverse_)@@ -34,8 +34,9 @@ -} newtype LoggerT msg m a = LoggerT     { runLoggerT :: ReaderT (LogAction (LoggerT msg m) msg) m a-    } deriving newtype ( Functor, Applicative, Monad, MonadIO+    } deriving newtype ( Functor, Applicative, Monad, MonadIO, MonadFail                        , MonadReader (LogAction (LoggerT msg m) msg)+                       , MonadUnliftIO                        )  instance MonadTrans (LoggerT msg) where
src/Colog/Pure.hs view
@@ -1,7 +1,6 @@ {- |-Copyright:  (c) 2018-2022 Kowainik+Copyright:  (c) 2018-2022 Kowainik, 2023 Co-Log SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com>  Pure implementation of logging action. -}
src/Colog/Rotation.hs view
@@ -1,7 +1,6 @@ {- |-Copyright:  (c) 2018-2022 Kowainik+Copyright:  (c) 2018-2022 Kowainik, 2023 Co-Log SPDX-License-Identifier: MPL-2.0-Maintainer: Kowainik <xrom.xkov@gmail.com> Stability:  experimental  __NOTE:__ This functionality is not to be considered stable
− tutorials/2-custom/Custom.lhs
@@ -1,136 +0,0 @@-# Using a custom monad that stores `LogAction` inside its environment--This tutorial covers the more advanced topic of using the `co-log` library with-a custom application monad.--You can run this tutorial by executing the following command:--```shell-cabal new-run tutorial-custom-```--## 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 DerivingStrategies    #-}-{-# LANGUAGE FlexibleContexts      #-}-{-# LANGUAGE FlexibleInstances     #-}-{-# LANGUAGE InstanceSigs          #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE PatternSynonyms       #-}--import Prelude hiding (log)--import Colog (pattern D, HasLog (..), pattern I, LogAction, Message, WithLog, log,-              richMessageAction)-import Control.Monad.IO.Class (MonadIO)-import Control.Monad.Reader (MonadReader, ReaderT (..))-```--## Application environment--If you have a complex Haskell application, then you are likely to also have-non-trivial settings that configure your application environment. The-environment may store various parameters relevant to your application's-behavior. Interestingly, we can store a `LogAction` inside the same-environment to use it for our logging functions.--The environment for your application may look like this:--```haskell-data Env m = Env-    { envServerPort :: !Int-    , envLogAction  :: !(LogAction m Message)-    }-```--Several notes about this data type:--1. It stores different parameters, like the server port.-2. It stores a `LogAction` that can log values of the `Message` type-from `co-log` in the `m` monad.-3. `Env` is parameterized by type variable `m` which is going to be the-application monad.--The next step is to define an instance of the `HasLog` typeclass for the `Env`-data type. This instance will specify how to get and update the `LogAction`-stored inside the environment.--```haskell-instance HasLog (Env m) Message m where-    getLogAction :: Env m -> LogAction m Message-    getLogAction = envLogAction-    {-# INLINE getLogAction #-}--    setLogAction :: LogAction m Message -> Env m -> Env m-    setLogAction newLogAction env = env { envLogAction = newLogAction }-    {-# INLINE setLogAction #-}-```--That's it! `co-log` requires very little boilerplate.--## Application monad--Now let's define our application monad:--```haskell-newtype App a = App-    { unApp :: ReaderT (Env App) IO a-    } deriving newtype (Functor, Applicative, Monad, MonadIO, MonadReader (Env App))-```--This monad stores `Env` parameterized by the monad itself in its context.-Nothing special is required here to tell the monad how to use the logger.--## Example--`co-log` relies on the tagless final technique for writing functions. So you-define your monadic actions with the `WithLog` constraint that allows you to-perform logging:--```haskell-example :: WithLog env Message m => m ()-example = do-    log D "First message..."-    log I "Second message..."-```--The `WithLog` constraint has three type parameters: the application environment,-the type of the message and the monad. Function `log` takes two parameters:-the logger severity and the log message's text.--## Running example--Now we are ready to execute this action.--First, let's create an example environment:--```haskell-simpleEnv :: Env App-simpleEnv = Env-    { envServerPort = 8081-    , envLogAction  = richMessageAction-    }-```--Then we need to define a function that performs actions of type `App`:--```haskell-runApp :: Env App -> App a -> IO a-runApp env app = runReaderT (unApp app) env-```--Putting it all together, we can specialize the `WithLog` constraint to our-`App` monad and run our example.--```haskell-main :: IO ()-main = runApp simpleEnv example-```--And the output will look like this:--![co-log output example](https://user-images.githubusercontent.com/8126674/71579355-1b804780-2af4-11ea-97eb-3f220011fd8d.png)
+ tutorials/2-loggert/loggert.lhs view
@@ -0,0 +1,96 @@+# Simple Message and LoggerT++This tutorial will show you how to use LoggerT and Simple message to log with more information in a more flexiable way.++You can run this tutorial by executing the following command:++```shell+cabal new-run tutorial-loggert-simple+```++## 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+{-# OPTIONS_GHC -Wno-unused-top-binds #-}+{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE DerivingStrategies         #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE OverloadedStrings          #-}++module Main (main) where++import Prelude hiding (log)+import Data.Text (Text,append)+import Colog ( LogAction, SimpleMsg , usingLoggerT,+              WithLog, cmap, logText,fmtSimpleMessage,formatWith,+              logTextStderr,logTextStdout+              )+```++## LoggerT+The `LoggerT` monad transformer wraps a ReaderT that keeps `LogAction` in its context. It denotes a +computation of logging. So you define your monadic actions with the `WithLog` constraint that allows you to perform logging:+```haskell+example1 :: WithLog env SimpleMsg m => m ()+example1 = do+    logText "this is a demo log for simple message!"++example2 :: WithLog env SimpleMsg m => m ()+example2 = do+    logText "you see the demo log for simple message again!\n"+```+The `WithLog` constraint has three type parameters: the application environment,+the type of the message and the monad. The actions constraint by `WithLog` could be used as `LoggerT`.+++## Simple Message+The simple message is data type without `severity`. It contains a callstack information and a text message.+```idris+data SimpleMsg = SimpleMsg+    { simpleMsgStack :: !CallStack+    , simpleMsgText  :: !Text+    }+```+When logging, simple messages require a format for transforming from simple messages to text. We can either use `formatWith` or its alias `cmap`+to combine it with the `LogAction`.++```haskell+logStdoutAction :: LogAction IO SimpleMsg+logStdoutAction = cmap fmtSimpleMessage logTextStdout++logStdErrAction :: LogAction IO SimpleMsg+logStdErrAction = formatWith fmtSimpleMessage logTextStderr+```+What's more, it's available to define a own formatter.+```haskell+selfDefinedFmtSimpleMessage :: SimpleMsg -> Text+selfDefinedFmtSimpleMessage = append "+ self defined behavior: " . fmtSimpleMessage++logByOwnFormatterAction :: LogAction IO SimpleMsg+logByOwnFormatterAction = formatWith selfDefinedFmtSimpleMessage logTextStderr+```++## Running example++Now we are ready to execute those actions defined above.+```haskell+main :: IO ()+main = do+    usingLoggerT logStdoutAction example1+    usingLoggerT logStdoutAction example2+    usingLoggerT logStdErrAction example1+    usingLoggerT logStdErrAction example2+    usingLoggerT logByOwnFormatterAction example1+    usingLoggerT logByOwnFormatterAction example2+```++Run command `cabal new-run tutorial-loggert-simple`.++And the output will look like this:++![](../img/2-loggert-output.jpg)
+ tutorials/3-loggert-with-message/loggert.lhs view
@@ -0,0 +1,117 @@+# Message and LoggerT++The previous tutorial shows how to use `LoggerT` with simple message.+This tutorial will show you how to use LoggerT together with messages with more details(e.g. severity).++You can run this tutorial by executing the following command:++```shell+cabal new-run tutorial-loggert+```++## Preamble: imports and language extensions++```haskell+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# OPTIONS_GHC -Wno-unused-top-binds #-}++module Main (main) where++import Colog (+    LogAction,+    Message,+    Msg (..),+    WithLog,+    cmap,+    fmtMessage,+    formatWith,+    logError,+    logInfo,+    logTextStderr,+    logTextStdout,+    msgSeverity,+    msgText,+    richMessageAction,+    showSeverity,+    usingLoggerT,+ )++import Data.Text (Text)+import Prelude hiding (log)+```++## LoggerT++The `LoggerT` monad transformer wraps a ReaderT that keeps `LogAction` in its context. It denotes a+computation of logging. So you define your monadic actions with the `WithLog` constraint that allows you to perform logging.+The `Message` allows you to log with severity.++```haskell+example1 :: WithLog env Message m => m ()+example1 = do+    logInfo "this is a demo log for message!"++example2 :: WithLog env Message m => m ()+example2 = do+    logError "Mayday! Mayday! Here is an example of error log\n"+```++The `WithLog` constraint has three type parameters:++- `env` – application environment+- `msg` – type of the message+- `m` – monad++The actions constraint by `WithLog` could be used as `LoggerT`.++## Message++The message is parametrized by the `Severity` type through `Msg`, which is a general logging message data type.++```idris+type Message = Msg Severity+data Msg sev = Msg+    { msgSeverity :: !sev+    , msgStack    :: !CallStack+    , msgText     ::  Text+    }+```++Hence, besides printing the callstack, as the `LoggerT` with simple message tutorial shows, this example supports printing severity and thread id as well.++```haskell+logStdoutAction :: LogAction IO Message+logStdoutAction = cmap fmtMessage logTextStdout++fmtMessageWithoutSourceLoc :: Message -> Text+fmtMessageWithoutSourceLoc Msg{..} =+    showSeverity msgSeverity+        <> msgText++logStdErrActionWithoutStackAction :: LogAction IO Message+logStdErrActionWithoutStackAction = formatWith fmtMessageWithoutSourceLoc logTextStderr+```++## Running example++Now we are ready to execute those actions defined above.++```haskell+main :: IO ()+main = do+    usingLoggerT logStdoutAction example1+    usingLoggerT logStdoutAction example2+    usingLoggerT logStdErrActionWithoutStackAction example1+    usingLoggerT logStdErrActionWithoutStackAction example2+    usingLoggerT richMessageAction example1+    usingLoggerT richMessageAction example2+```++Run command `cabal new-run tutorial-loggert`, and the output will look like this:++![](../img/3-loggert-message.jpg)
tutorials/Main.hs view
@@ -28,8 +28,8 @@               logWarning, pattern D, runPureLog, upgradeMessageAction, usingLoggerT, withLog,               withLogTextFile, (*<), (<&), (>$), (>$<), (>*), (>*<), (>|<)) -import qualified Data.TypeRepMap as TM-+import Data.Dependent.Map (delete)+import Type.Reflection (typeRep)  example :: WithLog env Message m => m () example = do@@ -188,7 +188,7 @@      let fullMessageAction = upgradeMessageAction defaultFieldMap richMessageAction     let semiMessageAction = upgradeMessageAction-                                (TM.delete @"threadId" defaultFieldMap)+                                (delete (typeRep @"threadId") defaultFieldMap)                                 richMessageAction      runApp simpleMessageAction
+ tutorials/custom/Custom.lhs view
@@ -0,0 +1,136 @@+# Using a custom monad that stores `LogAction` inside its environment++This tutorial covers the more advanced topic of using the `co-log` library with+a custom application monad.++You can run this tutorial by executing the following command:++```shell+cabal new-run tutorial-custom+```++## 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 DerivingStrategies    #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE InstanceSigs          #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PatternSynonyms       #-}++import Prelude hiding (log)++import Colog (pattern D, HasLog (..), pattern I, LogAction, Message, WithLog, log,+              richMessageAction)+import Control.Monad.IO.Class (MonadIO)+import Control.Monad.Reader (MonadReader, ReaderT (..))+```++## Application environment++If you have a complex Haskell application, then you are likely to also have+non-trivial settings that configure your application environment. The+environment may store various parameters relevant to your application's+behavior. Interestingly, we can store a `LogAction` inside the same+environment to use it for our logging functions.++The environment for your application may look like this:++```haskell+data Env m = Env+    { envServerPort :: !Int+    , envLogAction  :: !(LogAction m Message)+    }+```++Several notes about this data type:++1. It stores different parameters, like the server port.+2. It stores a `LogAction` that can log values of the `Message` type+from `co-log` in the `m` monad.+3. `Env` is parameterized by type variable `m` which is going to be the+application monad.++The next step is to define an instance of the `HasLog` typeclass for the `Env`+data type. This instance will specify how to get and update the `LogAction`+stored inside the environment.++```haskell+instance HasLog (Env m) Message m where+    getLogAction :: Env m -> LogAction m Message+    getLogAction = envLogAction+    {-# INLINE getLogAction #-}++    setLogAction :: LogAction m Message -> Env m -> Env m+    setLogAction newLogAction env = env { envLogAction = newLogAction }+    {-# INLINE setLogAction #-}+```++That's it! `co-log` requires very little boilerplate.++## Application monad++Now let's define our application monad:++```haskell+newtype App a = App+    { unApp :: ReaderT (Env App) IO a+    } deriving newtype (Functor, Applicative, Monad, MonadIO, MonadReader (Env App))+```++This monad stores `Env` parameterized by the monad itself in its context.+Nothing special is required here to tell the monad how to use the logger.++## Example++`co-log` relies on the tagless final technique for writing functions. So you+define your monadic actions with the `WithLog` constraint that allows you to+perform logging:++```haskell+example :: WithLog env Message m => m ()+example = do+    log D "First message..."+    log I "Second message..."+```++The `WithLog` constraint has three type parameters: the application environment,+the type of the message and the monad. Function `log` takes two parameters:+the logger severity and the log message's text.++## Running example++Now we are ready to execute this action.++First, let's create an example environment:++```haskell+simpleEnv :: Env App+simpleEnv = Env+    { envServerPort = 8081+    , envLogAction  = richMessageAction+    }+```++Then we need to define a function that performs actions of type `App`:++```haskell+runApp :: Env App -> App a -> IO a+runApp env app = runReaderT (unApp app) env+```++Putting it all together, we can specialize the `WithLog` constraint to our+`App` monad and run our example.++```haskell+main :: IO ()+main = runApp simpleEnv example+```++And the output will look like this:++![co-log output example](https://user-images.githubusercontent.com/8126674/71579355-1b804780-2af4-11ea-97eb-3f220011fd8d.png)