{-# LANGUAGE OverloadedStrings #-} module Logger where import Data.List import qualified Data.ByteString.Char8 as B import qualified Data.Text as T import qualified Data.Text.Encoding as TE import Network.Wai import Data.Time.LocalTime import Data.Time.Format import System.Directory import System.FilePath import Network.Socket hostIp :: SockAddr -> String hostIp saddr = T.unpack $ head (T.splitOn (T.pack ":") (T.pack $ show saddr)) unpackJust :: Maybe B.ByteString -> B.ByteString unpackJust s = case s of Just i -> i Nothing -> "" formatLog :: String -> LocalTime -> Request -> T.Text formatLog fmt t r = foldl' (\t (r1,r2) -> T.replace r1 r2 t) (T.pack fmt) [ ("%ip",(T.pack (hostIp $ remoteHost r))), ("%headers",(T.pack (show (requestHeaders r)))), ("%remote",(T.pack (show $ remoteHost r))), ("%path",(T.pack (show $ rawPathInfo r))), ("%query",(T.pack (show $ rawQueryString r))), ("%host",(T.pack (show $ unpackJust (requestHeaderHost r)))), ("%method",(T.pack (show (requestMethod r)))), ("%time",(T.pack (show t))) ] class Logger a where log :: a -> LocalTime -> Request -> IO () data FileLogger = FileLogger { path :: FilePath, logFormat :: String } instance Logger FileLogger where log f t r = mkdir >> B.appendFile fullPath (TE.encodeUtf8 $ formatLog (logFormat f) t r) where mkdir = createDirectoryIfMissing True (takeDirectory fullPath) fullPath = path f ++ "/" ++ (hostIp $ remoteHost r) ++ (formatTime defaultTimeLocale "/%Y/%m/%d.log" t)