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 as Numeric
class ToLog a where
build :: a -> ByteStringBuilder
instance ToLog ByteStringBuilder where
build :: ByteStringBuilder -> ByteStringBuilder
build = ByteStringBuilder -> ByteStringBuilder
forall a. a -> a
id
instance ToLog ByteStringLazy where
build :: ByteStringLazy -> ByteStringBuilder
build = ByteStringLazy -> ByteStringBuilder
Build.lazyByteString
instance ToLog ByteString where
build :: ByteString -> ByteStringBuilder
build = ByteString -> ByteStringBuilder
Build.byteString
instance ToLog Int where
build :: Int -> ByteStringBuilder
build = Int -> ByteStringBuilder
Build.intDec
instance ToLog Int8 where
build :: Int8 -> ByteStringBuilder
build = Int8 -> ByteStringBuilder
Build.int8Dec
instance ToLog Int16 where
build :: Int16 -> ByteStringBuilder
build = Int16 -> ByteStringBuilder
Build.int16Dec
instance ToLog Int32 where
build :: Int32 -> ByteStringBuilder
build = Int32 -> ByteStringBuilder
Build.int32Dec
instance ToLog Int64 where
build :: Int64 -> ByteStringBuilder
build = Int64 -> ByteStringBuilder
Build.int64Dec
instance ToLog Integer where
build :: Integer -> ByteStringBuilder
build = Integer -> ByteStringBuilder
Build.integerDec
instance ToLog Word where
build :: Word -> ByteStringBuilder
build = Word -> ByteStringBuilder
Build.wordDec
instance ToLog Word8 where
build :: Word8 -> ByteStringBuilder
build = Word8 -> ByteStringBuilder
Build.word8Dec
instance ToLog Word16 where
build :: Word16 -> ByteStringBuilder
build = Word16 -> ByteStringBuilder
Build.word16Dec
instance ToLog Word32 where
build :: Word32 -> ByteStringBuilder
build = Word32 -> ByteStringBuilder
Build.word32Dec
instance ToLog Word64 where
build :: Word64 -> ByteStringBuilder
build = Word64 -> ByteStringBuilder
Build.word64Dec
instance ToLog UTCTime where
build :: UTCTime -> ByteStringBuilder
build = String -> ByteStringBuilder
Build.stringUtf8 (String -> ByteStringBuilder)
-> (UTCTime -> String) -> UTCTime -> ByteStringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> String
forall a. Show a => a -> String
show
instance ToLog Float where
build :: Float -> ByteStringBuilder
build = String -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (String -> ByteStringBuilder)
-> (Float -> String) -> Float -> ByteStringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
"") ((String -> String) -> String)
-> (Float -> String -> String) -> Float -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Int -> Float -> String -> String
forall a. RealFloat a => Maybe Int -> a -> String -> String
Numeric.showFFloat Maybe Int
forall a. Maybe a
Nothing
instance ToLog Double where
build :: Double -> ByteStringBuilder
build = String -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (String -> ByteStringBuilder)
-> (Double -> String) -> Double -> ByteStringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
"") ((String -> String) -> String)
-> (Double -> String -> String) -> Double -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Int -> Double -> String -> String
forall a. RealFloat a => Maybe Int -> a -> String -> String
Numeric.showFFloat Maybe Int
forall a. Maybe a
Nothing
instance ToLog Text where
build :: Text -> ByteStringBuilder
build = ByteString -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (ByteString -> ByteStringBuilder)
-> (Text -> ByteString) -> Text -> ByteStringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
Text.encodeUtf8
instance ToLog TextLazy where
build :: TextLazy -> ByteStringBuilder
build = ByteStringLazy -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (ByteStringLazy -> ByteStringBuilder)
-> (TextLazy -> ByteStringLazy) -> TextLazy -> ByteStringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextLazy -> ByteStringLazy
LText.encodeUtf8
instance ToLog Char where
build :: Char -> ByteStringBuilder
build = Text -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (Text -> ByteStringBuilder)
-> (Char -> Text) -> Char -> ByteStringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Text
Text.singleton
instance ToLog [Char] where
build :: String -> ByteStringBuilder
build = TextLazy -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (TextLazy -> ByteStringBuilder)
-> (String -> TextLazy) -> String -> ByteStringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> TextLazy
LText.pack
instance ToLog HTTP.StdMethod where
build :: StdMethod -> ByteStringBuilder
build = ByteString -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (ByteString -> ByteStringBuilder)
-> (StdMethod -> ByteString) -> StdMethod -> ByteStringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StdMethod -> ByteString
HTTP.renderStdMethod
instance ToLog QueryString where
build :: QueryString -> ByteStringBuilder
build = ByteString -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (ByteString -> ByteStringBuilder)
-> (QueryString -> ByteString) -> QueryString -> ByteStringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QueryString -> ByteString
forall a. ToByteString a => a -> ByteString
toBS
instance ToLog EscapedPath where
build :: EscapedPath -> ByteStringBuilder
build = ByteString -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (ByteString -> ByteStringBuilder)
-> (EscapedPath -> ByteString) -> EscapedPath -> ByteStringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EscapedPath -> ByteString
forall a. ToByteString a => a -> ByteString
toBS
buildLines :: [ByteStringBuilder] -> ByteStringBuilder
buildLines :: [ByteStringBuilder] -> ByteStringBuilder
buildLines = [ByteStringBuilder] -> ByteStringBuilder
forall a. Monoid a => [a] -> a
mconcat ([ByteStringBuilder] -> ByteStringBuilder)
-> ([ByteStringBuilder] -> [ByteStringBuilder])
-> [ByteStringBuilder]
-> ByteStringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteStringBuilder -> [ByteStringBuilder] -> [ByteStringBuilder]
forall a. a -> [a] -> [a]
List.intersperse ByteStringBuilder
"\n"
instance ToLog a => ToLog (CI a) where
build :: CI a -> ByteStringBuilder
build = a -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (a -> ByteStringBuilder)
-> (CI a -> a) -> CI a -> ByteStringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CI a -> a
forall s. CI s -> s
CI.foldedCase
instance ToLog a => ToLog (Maybe a) where
build :: Maybe a -> ByteStringBuilder
build Maybe a
Nothing = ByteStringBuilder
"Nothing"
build (Just a
x) = ByteStringBuilder
"Just " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> a -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build a
x
instance ToLog Bool where
build :: Bool -> ByteStringBuilder
build Bool
True = ByteStringBuilder
"True"
build Bool
False = ByteStringBuilder
"False"
instance ToLog HTTP.Status where
build :: Status -> ByteStringBuilder
build Status
x = Int -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (Status -> Int
HTTP.statusCode Status
x) ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteStringBuilder
" " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteString -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (Status -> ByteString
HTTP.statusMessage Status
x)
instance ToLog [HTTP.Header] where
build :: [Header] -> ByteStringBuilder
build =
[ByteStringBuilder] -> ByteStringBuilder
forall a. Monoid a => [a] -> a
mconcat
([ByteStringBuilder] -> ByteStringBuilder)
-> ([Header] -> [ByteStringBuilder])
-> [Header]
-> ByteStringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteStringBuilder -> [ByteStringBuilder] -> [ByteStringBuilder]
forall a. a -> [a] -> [a]
List.intersperse ByteStringBuilder
"; "
([ByteStringBuilder] -> [ByteStringBuilder])
-> ([Header] -> [ByteStringBuilder])
-> [Header]
-> [ByteStringBuilder]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Header -> ByteStringBuilder) -> [Header] -> [ByteStringBuilder]
forall a b. (a -> b) -> [a] -> [b]
map (\(HeaderName
k, ByteString
v) -> HeaderName -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build HeaderName
k ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteStringBuilder
": " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteString -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build ByteString
v)
instance ToLog HTTP.HttpVersion where
build :: HttpVersion -> ByteStringBuilder
build HTTP.HttpVersion {Int
httpMajor :: HttpVersion -> Int
httpMajor :: Int
httpMajor, Int
httpMinor :: HttpVersion -> Int
httpMinor :: Int
httpMinor} =
ByteStringBuilder
"HTTP/"
ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> Int -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build Int
httpMajor
ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> Char -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build Char
'.'
ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> Int -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build Int
httpMinor
instance ToLog Client.RequestBody where
build :: RequestBody -> ByteStringBuilder
build = \case
Client.RequestBodyBuilder Int64
n ByteStringBuilder
_ -> ByteStringBuilder
" <builder:" ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> Int64 -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build Int64
n ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteStringBuilder
">"
Client.RequestBodyStream Int64
n GivesPopper ()
_ -> ByteStringBuilder
" <stream:" ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> Int64 -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build Int64
n ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteStringBuilder
">"
Client.RequestBodyLBS ByteStringLazy
lbs
| Int64
n Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
4096 -> ByteStringLazy -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build ByteStringLazy
lbs
| Bool
otherwise -> ByteStringBuilder
" <lazy:" ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> Int64 -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build Int64
n ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteStringBuilder
">"
where
n :: Int64
n = ByteStringLazy -> Int64
LBS.length ByteStringLazy
lbs
Client.RequestBodyBS ByteString
bs
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
4096 -> ByteString -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build ByteString
bs
| Bool
otherwise -> ByteStringBuilder
" <strict:" ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> Int -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build Int
n ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteStringBuilder
">"
where
n :: Int
n = ByteString -> Int
BS.length ByteString
bs
RequestBody
_ -> ByteStringBuilder
" <chunked>"
instance ToLog Client.HttpException where
build :: HttpException -> ByteStringBuilder
build HttpException
x = ByteStringBuilder
"[HttpException] {\n" ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> String -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (HttpException -> String
forall a. Show a => a -> String
show HttpException
x) ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteStringBuilder
"\n}"
instance ToLog Client.HttpExceptionContent where
build :: HttpExceptionContent -> ByteStringBuilder
build HttpExceptionContent
x = ByteStringBuilder
"[HttpExceptionContent] {\n" ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> String -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (HttpExceptionContent -> String
forall a. Show a => a -> String
show HttpExceptionContent
x) ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteStringBuilder
"\n}"
instance ToLog Client.Request where
build :: Request -> ByteStringBuilder
build Request
x =
[ByteStringBuilder] -> ByteStringBuilder
buildLines
[ ByteStringBuilder
"[Client Request] {",
ByteStringBuilder
" host = " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteString -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (Request -> ByteString
Client.host Request
x) ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteStringBuilder
":" ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> Int -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (Request -> Int
Client.port Request
x),
ByteStringBuilder
" secure = " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> Bool -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (Request -> Bool
Client.secure Request
x),
ByteStringBuilder
" method = " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteString -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (Request -> ByteString
Client.method Request
x),
ByteStringBuilder
" target = " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> Maybe ByteString -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build Maybe ByteString
target,
ByteStringBuilder
" timeout = " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> String -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (ResponseTimeout -> String
forall a. Show a => a -> String
show (Request -> ResponseTimeout
Client.responseTimeout Request
x)),
ByteStringBuilder
" redirects = " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> Int -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (Request -> Int
Client.redirectCount Request
x),
ByteStringBuilder
" path = " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteString -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (Request -> ByteString
Client.path Request
x),
ByteStringBuilder
" query = " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteString -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (Request -> ByteString
Client.queryString Request
x),
ByteStringBuilder
" headers = " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> [Header] -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (Request -> [Header]
Client.requestHeaders Request
x),
ByteStringBuilder
" body = " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> RequestBody -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (Request -> RequestBody
Client.requestBody Request
x),
ByteStringBuilder
"}"
]
where
target :: Maybe ByteString
target = HeaderName
hAMZTarget HeaderName -> [Header] -> Maybe ByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
`lookup` Request -> [Header]
Client.requestHeaders Request
x
instance ToLog (Client.Response a) where
build :: Response a -> ByteStringBuilder
build Response a
x =
[ByteStringBuilder] -> ByteStringBuilder
buildLines
[ ByteStringBuilder
"[Client Response] {",
ByteStringBuilder
" status = " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> Status -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (Response a -> Status
forall body. Response body -> Status
Client.responseStatus Response a
x),
ByteStringBuilder
" headers = " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> [Header] -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (Response a -> [Header]
forall body. Response body -> [Header]
Client.responseHeaders Response a
x),
ByteStringBuilder
"}"
]