-
Notifications
You must be signed in to change notification settings - Fork 0
/
Log.hs
72 lines (56 loc) · 2.18 KB
/
Log.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wall -Werror #-}
module Log where
import Color
import Control.Concurrent.Async
import Control.Concurrent.Chan
import Data.Aeson
import Data.Bifunctor (bimap)
import qualified Data.ByteString.Lazy as LBS
import Data.Text.Encoding.Error
import qualified Data.Text.Lazy as Text
import Data.Text.Lazy.Encoding
import qualified Data.Text.Lazy.IO as TextIO
import System.IO
-- |Entries that can be fed to a `LogQueue`
data LogEntry = LogEntry Message
-- ^A log message originating from some service
| EndOfLog
-- ^A /Poison Pill/ to stop the logging thread
deriving (Eq, Show)
logEntry :: Text.Text -> Color -> LBS.ByteString -> LogEntry
logEntry o col c = LogEntry $ Message o col c
data Message = Message { origin :: Text.Text
, color :: Color
, msg :: LBS.ByteString
}
deriving (Eq, Show)
type LogQueue = Chan LogEntry
safeDecodeUtf8 :: LBS.ByteString -> Text.Text
safeDecodeUtf8 = decodeUtf8With lenientDecode
tailLogs :: LogQueue
-> Handle
-> IO (Async ())
tailLogs logSource logSink = do
let doLog = do
entry <- readChan logSource
case entry of
LogEntry out -> do
let
jsonMsg :: Either Text.Text Value
jsonMsg = jsonFromText $ msg out
fullMsg = either
(const $ object ["node" .= origin out, "log" .= object [ "message" .= (safeDecodeUtf8 $ msg out :: Text.Text)]])
(\ m -> object ["node" .= origin out, "log" .= m ])
jsonMsg
msgString = colorise (color out) $ jsonToText fullMsg
TextIO.hPutStrLn logSink msgString
doLog
EndOfLog ->
pure ()
async doLog
jsonFromText :: (FromJSON a) => LBS.ByteString -> Either Text.Text a
jsonFromText = bimap Text.pack id . eitherDecode
jsonToText :: (ToJSON a) => a -> Text.Text
jsonToText = decodeUtf8 . encode