amazonka-core-2.0: src/Amazonka/Data/Log.hs
-- |
-- Module : Amazonka.Data.Log
-- Copyright : (c) 2013-2023 Brendan Hay
-- License : Mozilla Public License, v. 2.0.
-- Maintainer : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
-- Stability : provisional
-- Portability : non-portable (GHC extensions)
module Amazonka.Data.Log where
import Amazonka.Data.ByteString
import Amazonka.Data.Headers
import Amazonka.Data.Path
import Amazonka.Data.Query
import Amazonka.Data.Text
import Amazonka.Prelude
import qualified Data.ByteString as BS
import qualified Data.ByteString.Builder as Build
import qualified Data.ByteString.Lazy as LBS
import qualified Data.CaseInsensitive as CI
import qualified Data.List as List
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import qualified Data.Text.Lazy as LText
import qualified Data.Text.Lazy.Encoding as LText
import qualified Network.HTTP.Client as Client
import qualified Network.HTTP.Types as HTTP
import qualified Numeric
class ToLog a where
-- | Convert a value to a loggable builder.
build :: a -> ByteStringBuilder
instance ToLog ByteStringBuilder where
build = id
instance ToLog ByteStringLazy where
build = Build.lazyByteString
instance ToLog ByteString where
build = Build.byteString
instance ToLog Int where
build = Build.intDec
instance ToLog Int8 where
build = Build.int8Dec
instance ToLog Int16 where
build = Build.int16Dec
instance ToLog Int32 where
build = Build.int32Dec
instance ToLog Int64 where
build = Build.int64Dec
instance ToLog Integer where
build = Build.integerDec
instance ToLog Word where
build = Build.wordDec
instance ToLog Word8 where
build = Build.word8Dec
instance ToLog Word16 where
build = Build.word16Dec
instance ToLog Word32 where
build = Build.word32Dec
instance ToLog Word64 where
build = Build.word64Dec
instance ToLog UTCTime where
build = Build.stringUtf8 . show
instance ToLog Float where
build = build . ($ "") . Numeric.showFFloat Nothing
instance ToLog Double where
build = build . ($ "") . Numeric.showFFloat Nothing
instance ToLog Text where
build = build . Text.encodeUtf8
instance ToLog TextLazy where
build = build . LText.encodeUtf8
instance ToLog Char where
build = build . Text.singleton
instance ToLog [Char] where
build = build . LText.pack
instance ToLog HTTP.StdMethod where
build = build . HTTP.renderStdMethod
instance ToLog QueryString where
build = build . toBS
instance ToLog EscapedPath where
build = build . toBS
-- | Intercalate a list of 'ByteStringBuilder's with newlines.
buildLines :: [ByteStringBuilder] -> ByteStringBuilder
buildLines = mconcat . List.intersperse "\n"
instance ToLog a => ToLog (CI a) where
build = build . CI.foldedCase
instance ToLog a => ToLog (Maybe a) where
build Nothing = "Nothing"
build (Just x) = "Just " <> build x
instance ToLog Bool where
build True = "True"
build False = "False"
instance ToLog HTTP.Status where
build x = build (HTTP.statusCode x) <> " " <> build (HTTP.statusMessage x)
instance ToLog [HTTP.Header] where
build =
mconcat
. List.intersperse "; "
. map (\(k, v) -> build k <> ": " <> build v)
instance ToLog HTTP.HttpVersion where
build HTTP.HttpVersion {httpMajor, httpMinor} =
"HTTP/"
<> build httpMajor
<> build '.'
<> build httpMinor
instance ToLog Client.RequestBody where
build = \case
Client.RequestBodyBuilder n _ -> " <builder:" <> build n <> ">"
Client.RequestBodyStream n _ -> " <stream:" <> build n <> ">"
Client.RequestBodyLBS lbs
| n <= 4096 -> build lbs
| otherwise -> " <lazy:" <> build n <> ">"
where
n = LBS.length lbs
Client.RequestBodyBS bs
| n <= 4096 -> build bs
| otherwise -> " <strict:" <> build n <> ">"
where
n = BS.length bs
_ -> " <chunked>"
instance ToLog Client.HttpException where
build x = "[HttpException] {\n" <> build (show x) <> "\n}"
instance ToLog Client.HttpExceptionContent where
build x = "[HttpExceptionContent] {\n" <> build (show x) <> "\n}"
instance ToLog Client.Request where
build x =
buildLines
[ "[Client Request] {",
" host = " <> build (Client.host x) <> ":" <> build (Client.port x),
" secure = " <> build (Client.secure x),
" method = " <> build (Client.method x),
" target = " <> build target,
" timeout = " <> build (show (Client.responseTimeout x)),
" redirects = " <> build (Client.redirectCount x),
" path = " <> build (Client.path x),
" query = " <> build (Client.queryString x),
" headers = " <> build (Client.requestHeaders x),
" body = " <> build (Client.requestBody x),
"}"
]
where
target = hAMZTarget `lookup` Client.requestHeaders x
instance ToLog (Client.Response a) where
build x =
buildLines
[ "[Client Response] {",
" status = " <> build (Client.responseStatus x),
" headers = " <> build (Client.responseHeaders x),
"}"
]