Files
yore/src/Yore/Log.hs
T

37 lines
1.3 KiB
Haskell

module Yore.Log (Yore.Log.error, info, setup) where
import Control.Monad.IO.Class (MonadIO (..))
import Data.Time (ZonedTime, getZonedTime)
import Data.Time.Format (defaultTimeLocale, formatTime)
import GHC.Stack (HasCallStack, SrcLoc (..), callStack, getCallStack)
import System.IO (BufferMode (..), hSetBuffering, stdout)
import Text.Printf (printf)
import qualified Data.Text as Text
import qualified Data.Text.IO as TextIO
setup :: IO ()
setup = hSetBuffering stdout LineBuffering
info :: (HasCallStack, MonadIO m) => String -> m ()
info = doLog "INF"
error :: (HasCallStack, MonadIO m) => String -> m ()
error = doLog "ERR"
doLog :: (HasCallStack, MonadIO m) => String -> String -> m ()
doLog level msg = liftIO $ do
now <- getZonedTime
let location = getLocation $ getCallStack callStack
TextIO.putStrLn $ Text.pack $ printf "(%s) (%s) (%s) %s" (iso8601Show now) level location msg
where
getLocation :: [(String, SrcLoc)] -> String
-- First entry is always a function from this module, skip it
getLocation (_ : (_, srcLoc) : _) = printf "%s:%d" (srcLocFile srcLoc) (srcLocStartLine srcLoc)
getLocation _ = ""
-- | Unlike 'Data.Time.Format.ISO8601.iso8601Show', this function
-- aligns the second decimals. This is purely for asthetic reasons.
iso8601Show :: ZonedTime -> String
iso8601Show = formatTime defaultTimeLocale "%FT%T%02Q%Ez"