2021-04-29 12:47:30 +00:00
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
|
|
|
{-# LANGUAGE QuasiQuotes #-}
|
2021-09-23 10:53:01 +00:00
|
|
|
{-# LANGUAGE DataKinds #-}
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
2020-01-11 20:15:05 +00:00
|
|
|
|
2020-07-21 23:08:58 +00:00
|
|
|
{-|
|
|
|
|
Module : GHCup.Utils.Logger
|
|
|
|
Description : logger definition
|
|
|
|
Copyright : (c) Julian Ospald, 2020
|
2020-07-30 18:04:02 +00:00
|
|
|
License : LGPL-3.0
|
2020-07-21 23:08:58 +00:00
|
|
|
Maintainer : hasufell@hasufell.de
|
|
|
|
Stability : experimental
|
2021-05-14 21:09:45 +00:00
|
|
|
Portability : portable
|
2020-07-21 23:08:58 +00:00
|
|
|
|
|
|
|
Here we define our main logger.
|
|
|
|
-}
|
2020-01-11 20:15:05 +00:00
|
|
|
module GHCup.Utils.Logger where
|
|
|
|
|
2021-07-21 13:43:45 +00:00
|
|
|
import GHCup.Types
|
|
|
|
import GHCup.Types.Optics
|
2021-09-23 10:53:01 +00:00
|
|
|
import {-# SOURCE #-} GHCup.Utils.File.Common
|
2021-04-29 12:47:30 +00:00
|
|
|
import GHCup.Utils.String.QQ
|
2020-01-11 20:15:05 +00:00
|
|
|
|
2021-07-21 13:43:45 +00:00
|
|
|
import Control.Exception.Safe
|
2020-01-11 20:15:05 +00:00
|
|
|
import Control.Monad
|
2020-08-05 19:50:39 +00:00
|
|
|
import Control.Monad.IO.Class
|
2021-07-21 13:43:45 +00:00
|
|
|
import Control.Monad.Reader
|
2021-09-23 10:53:01 +00:00
|
|
|
import Data.Text ( Text )
|
|
|
|
import Optics
|
2020-01-11 20:15:05 +00:00
|
|
|
import Prelude hiding ( appendFile )
|
2021-09-23 10:53:01 +00:00
|
|
|
import System.Console.Pretty
|
2021-05-14 21:09:45 +00:00
|
|
|
import System.FilePath
|
2020-01-11 20:15:05 +00:00
|
|
|
import System.IO.Error
|
2021-04-29 12:47:30 +00:00
|
|
|
import Text.Regex.Posix
|
2020-01-11 20:15:05 +00:00
|
|
|
|
|
|
|
import qualified Data.ByteString as B
|
2021-05-14 21:09:45 +00:00
|
|
|
import GHCup.Utils.Prelude
|
2021-09-23 10:53:01 +00:00
|
|
|
import qualified Data.Text as T
|
2020-01-11 20:15:05 +00:00
|
|
|
|
2021-09-23 10:53:01 +00:00
|
|
|
logInfo :: ( MonadReader env m
|
|
|
|
, LabelOptic' "loggerConfig" A_Lens env LoggerConfig
|
|
|
|
, MonadIO m
|
|
|
|
)
|
|
|
|
=> Text
|
|
|
|
-> m ()
|
|
|
|
logInfo = logInternal Info
|
|
|
|
|
|
|
|
logWarn :: ( MonadReader env m
|
|
|
|
, LabelOptic' "loggerConfig" A_Lens env LoggerConfig
|
|
|
|
, MonadIO m
|
|
|
|
)
|
|
|
|
=> Text
|
|
|
|
-> m ()
|
|
|
|
logWarn = logInternal Warn
|
|
|
|
|
|
|
|
logDebug :: ( MonadReader env m
|
|
|
|
, LabelOptic' "loggerConfig" A_Lens env LoggerConfig
|
|
|
|
, MonadIO m
|
|
|
|
)
|
|
|
|
=> Text
|
|
|
|
-> m ()
|
|
|
|
logDebug = logInternal Debug
|
|
|
|
|
|
|
|
logError :: ( MonadReader env m
|
|
|
|
, LabelOptic' "loggerConfig" A_Lens env LoggerConfig
|
|
|
|
, MonadIO m
|
|
|
|
)
|
|
|
|
=> Text
|
|
|
|
-> m ()
|
|
|
|
logError = logInternal Error
|
|
|
|
|
|
|
|
|
|
|
|
logInternal :: ( MonadReader env m
|
|
|
|
, LabelOptic' "loggerConfig" A_Lens env LoggerConfig
|
|
|
|
, MonadIO m
|
|
|
|
) => LogLevel
|
|
|
|
-> Text
|
|
|
|
-> m ()
|
|
|
|
logInternal logLevel msg = do
|
|
|
|
LoggerConfig {..} <- gets @"loggerConfig"
|
|
|
|
let color' c = if fancyColors then color c else id
|
|
|
|
let style' = case logLevel of
|
|
|
|
Debug -> style Bold . color' Blue
|
|
|
|
Info -> style Bold . color' Green
|
|
|
|
Warn -> style Bold . color' Yellow
|
|
|
|
Error -> style Bold . color' Red
|
|
|
|
let l = case logLevel of
|
|
|
|
Debug -> style' "[ Debug ]"
|
|
|
|
Info -> style' "[ Info ]"
|
|
|
|
Warn -> style' "[ Warn ]"
|
|
|
|
Error -> style' "[ Error ]"
|
|
|
|
let strs = T.split (== '\n') msg
|
|
|
|
let out = case strs of
|
|
|
|
[] -> T.empty
|
|
|
|
(x:xs) ->
|
|
|
|
foldr (\a b -> a <> "\n" <> b) mempty
|
|
|
|
. ((l <> " " <> x) :)
|
|
|
|
. fmap (\line' -> style' "[ ... ] " <> line' )
|
|
|
|
$ xs
|
|
|
|
|
|
|
|
when (lcPrintDebug || (not lcPrintDebug && (logLevel /= Debug)))
|
|
|
|
$ liftIO $ consoleOutter out
|
|
|
|
|
|
|
|
-- raw output
|
|
|
|
let lr = case logLevel of
|
|
|
|
Debug -> "Debug:"
|
|
|
|
Info -> "Info:"
|
|
|
|
Warn -> "Warn:"
|
|
|
|
Error -> "Error:"
|
|
|
|
let outr = lr <> " " <> msg <> "\n"
|
|
|
|
liftIO $ fileOutter outr
|
2020-01-11 20:15:05 +00:00
|
|
|
|
|
|
|
|
2021-07-21 13:43:45 +00:00
|
|
|
initGHCupFileLogging :: ( MonadReader env m
|
|
|
|
, HasDirs env
|
|
|
|
, MonadIO m
|
|
|
|
, MonadMask m
|
|
|
|
) => m FilePath
|
|
|
|
initGHCupFileLogging = do
|
|
|
|
Dirs { logsDir } <- getDirs
|
2021-05-14 21:09:45 +00:00
|
|
|
let logfile = logsDir </> "ghcup.log"
|
2021-07-21 13:43:45 +00:00
|
|
|
logFiles <- liftIO $ findFiles
|
|
|
|
logsDir
|
|
|
|
(makeRegexOpts compExtended
|
|
|
|
execBlank
|
|
|
|
([s|^.*\.log$|] :: B.ByteString)
|
|
|
|
)
|
2021-07-22 13:45:08 +00:00
|
|
|
forM_ logFiles $ hideError doesNotExistErrorType . recycleFile . (logsDir </>)
|
2021-04-29 12:47:30 +00:00
|
|
|
|
2021-07-21 13:43:45 +00:00
|
|
|
liftIO $ writeFile logfile ""
|
|
|
|
pure logfile
|