{-| This module provides a convenient way to decode a 'Manager' from json string There is a 'Config' type in "Logging.Config.Type" module, it is an instance of 'FromJSON', 1) decode 'Config' from json string, 2) construct an 'Manager' from 'Config'. All 'Maybe' fileds can be omitted, the default value will be used, e.g. 1) 'List' type field will use '[]' as default 2) 'Purelude.Bool' type filed will use False as default 3) if the field is an instance of 'Data.Default.Default', use 'def' 4) an appropriate value as default for other fields In fact, you can decode 'Config' from an empty json (object) string, @ manager <- getManager "{}" -- enable the 'OverloadedStrings' extension @ it will create a manager with a root sink (i.e. 'Logging.defaultRoot'), the 'Logging.defaultRoot' will be used when the root sink is omitted. Here is a json string template: @ { \"sinks\": { \"root\": { \"handlers\": [\"console\", \"file\"] }, \"App.Json\": { \"handlers\": [\"file\"], \"propagate\": false }, \"App.Yaml\": { \"handlers\": [\"rotate\"], \"propagate\": false } }, \"handlers\": { \"console\": { \"type\": \"StreamHandler\", \"level\": \"DEBUG\", \"formatter\": \"simple\", \"stream\": \"stderr\" }, \"file\": { \"type\": \"FileHandler\", \"level\": \"Level 100\", \"filterer\": [\"App.Json\"], \"formatter\": \"standard\", \"file\": \"/etc\/my\/json.log\", \"encoding\": \"utf8\" }, \"rotate\": { \"type\": \"RotatingFileHandler\", \"level\": \"INFO\", \"filterer\": [\"App.Yaml\"], \"formatter\": \"standard\", \"file\": \"/etc\/my\/yaml.log\", \"encoding\": \"utf8\", \"maxBytes\": 1048576, \"backupCount\": 10 } }, \"formatters\": { \"simple\": \"{message}\", \"standard\": \"{asctime:%Y-%m-%dT%H:%M:%S%6Q%z} - {level} - {logger}] {message}\" }, \"disabled\": false, \"catchUncaughtException\": true } @ -} module Logging.Config.Json (getManager, getManagerFile) where import Control.Exception import Data.Aeson import Data.ByteString import Prelude hiding (readFile) import Logging.Config.Type import Logging.Manager -- | decode a 'Manager' from strict 'ByteString' -- -- @since 0.4.0 getManager :: ByteString -> IO Manager getManager bs = case eitherDecodeStrict bs of Left msg -> throw $ ConfigException msg Right config -> createManager config -- | decode a 'Manager' from a file -- -- @since 0.4.0 getManagerFile :: FilePath -> IO Manager getManagerFile path = getManager =<< catch (readFile path) reThrow where reThrow :: SomeException -> IO a reThrow e = throw $ ConfigException $ displayException e