{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE OverloadedStrings #-} module Main where import Data.Char (toLower) import Data.Monoid ((<>)) import System.Console.CmdArgs.Implicit import System.Log.Formatter import System.Log.Handler (setFormatter) import System.Log.Handler.Simple import System.Log.Handler.Syslog import System.Log.Logger import System.Metrics import System.Remote.Monitoring (forkServerWith) import Text.Show.Pretty (ppShow) import Cerberus.Lib data Options = Options { proxyUrl :: String , debug :: Bool , proxyPort :: Int , port :: Int , maxNbReqBySeconds :: Int , infoPort :: Int , cacheSize :: Integer , backendCache :: String , redisHost :: String , redisPort :: Int , redisPass :: Maybe String } deriving (Show, Data, Typeable) options :: Options options = Options { debug = False &= help "Debug mode" , proxyUrl = ("api.projectoxford.ai" :: String) &= name "proxy-url" &= help "External HTTPS URL to proxy to." &= typ "HOST" , backendCache = "LRU" &= name "backend-cache" &= help "Could be LRU or Redis" , proxyPort = 443 &= name "proxy-port" &= help "External Port default 443" , port = 3000 &= help "port to listen to" , maxNbReqBySeconds = 60 &= name "max-nb-req-by-sec" &= help "max number of requests by seconds" , infoPort = 8000 &= help "port to look at monitoring infos" &= name "info-port" , cacheSize = 10000000 &= name "cache-size" &= help "size of cache" , redisHost = "localhost" &= name "redis-host" &= help "Redis host" &= groupname "Redis" , redisPort = 6379 &= name "redis-port" &= help "Redis port" &= groupname "Redis" , redisPass = Nothing &= name "redis-password" &= groupname "Redis" } &= program "cerberus" &= summary "cerberus v0.1 © Vigiglobe 2015" initLogging :: Bool -> IO () initLogging debugMode = do let defaultLevel = if debugMode then DEBUG else WARNING h <- fileHandler "cerberus.log" defaultLevel >>= \lh -> return (setFormatter lh (simpleLogFormatter "[$time : $loggername : $prio] $msg")) updateGlobalLogger rootLoggerName (addHandler h) s <- openlog "tornado" [PID] LOCAL7 defaultLevel updateGlobalLogger rootLoggerName (addHandler s) updateGlobalLogger rootLoggerName (setLevel defaultLevel) main :: IO () main = do opts <- cmdArgsRun (cmdArgsMode options) initLogging (debug opts) putStrLn (ppShow opts) store <- newStore req <- createCounter "cerberus.requests_count" store reqF <- createCounter "cerberus.requests_followed_count" store reqC <- createCounter "cerberus.requests_cached_count" store _ <- forkServerWith store "localhost" (infoPort opts) putStrLn ("Go to http://localhost:" <> show (port opts) <> " to reach https://" <> proxyUrl opts <> ":" <> show (proxyPort opts)) let backend = case map toLower (backendCache opts) of "redis" -> Redis "lru" -> LRU _ -> error "Unrecognized backend cache should be LRU or Redis." proxyOpts = ProxyOpts req reqF reqC (cacheSize opts) (port opts) (proxyUrl opts) (proxyPort opts) (fromIntegral (maxNbReqBySeconds opts)) backend (redisHost opts) (redisPort opts) (redisPass opts) serveProxy proxyOpts