@@ -30,6 +30,7 @@ import qualified Data.Text.IO as T
3030import qualified Data.ByteString.Lazy.Char8 as BS8
3131import Data.Version (showVersion)
3232import Language.PureScript.Ide
33+import Language.PureScript.Ide.Command
3334import Language.PureScript.Ide.Util
3435import Language.PureScript.Ide.Error
3536import Language.PureScript.Ide.Types
@@ -45,7 +46,6 @@ import System.Info as SysInfo
4546import System.FilePath
4647import System.IO hiding (putStrLn, print)
4748import System.IO.Error (isEOFError)
48−
4949import qualified Paths_purescript as Paths
5050
5151listenOnLocalhost :: PortNumber -> IO Socket
@@ -69,11 +69,12 @@ data Options = Options
6969 , optionsNoWatch :: Bool
7070 , optionsPolling :: Bool
7171 , optionsDebug :: Bool
72+ , optionsLoglevel :: IdeLogLevel
7273 } deriving (Show)
7374
7475main :: IO ()
7576main = do
76− opts'@(Options dir globs outputPath port noWatch polling debug) <- Opts.execParser opts
77+ opts'@(Options dir globs outputPath port noWatch polling debug logLevel) <- Opts.execParser opts
7778 when debug (putText "Parsed Options:" *> print opts')
7879 maybe (pure ()) setCurrentDirectory dir
7980 ideState <- newTVarIO emptyIdeState
@@ -88,8 +89,8 @@ main = do
8889
8990 unless noWatch $
9091 void (forkFinally (watcher polling ideState fullOutputPath) print)
91−
92− let conf = Configuration {confDebug = debug, confOutputPath = outputPath, confGlobs = globs}
92+ -- TODO: deprecate and get rid of `debug`
93+ let conf = Configuration {confLogLevel = if debug then LogDebug else logLevel, confOutputPath = outputPath, confGlobs = globs}
9394 env = IdeEnvironment {ideStateVar = ideState, ideConfiguration = conf}
9495 startServer port env
9596 where
@@ -103,7 +104,17 @@ main = do
103104 <*> Opts.switch (Opts.long "no-watch")
104105 <*> flipIfWindows (Opts.switch (Opts.long "polling"))
105106 <*> Opts.switch (Opts.long "debug")
107+ <*> (parseLogLevel <$> Opts.strOption
108+ (Opts.long "log-level"
109+ `mappend` Opts.value ""
110+ `mappend` Opts.help "One of \"debug\", \"perf\", \"all\" or \"none\""))
106111 opts = Opts.info (version <*> Opts.helper <*> parser) mempty
112+ parseLogLevel s = case s of
113+ "debug" -> LogDebug
114+ "perf" -> LogPerf
115+ "all" -> LogAll
116+ "none" -> LogNone
117+ _ -> LogDefault
107118 version = Opts.abortOption
108119 (InfoMsg (showVersion Paths.version))
109120 (Opts.long "version" `mappend` Opts.help "Show the version number")
@@ -115,10 +126,8 @@ main = do
115126startServer :: PortNumber -> IdeEnvironment -> IO ()
116127startServer port env = withSocketsDo $ do
117128 sock <- listenOnLocalhost port
118− runLogger (runReaderT (forever (loop sock)) env)
129+ runLogger (confLogLevel (ideConfiguration env)) (runReaderT (forever (loop sock)) env)
119130 where
120− runLogger = runStdoutLoggingT . filterLogger (\_ _ -> confDebug (ideConfiguration env))
121−
122131 loop :: (Ide m, MonadLogger m) => Socket -> m ()
123132 loop sock = do
124133 accepted <- runExceptT $ acceptCommand sock
@@ -127,7 +136,11 @@ startServer port env = withSocketsDo $ do
127136 Right (cmd, h) -> do
128137 case decodeT cmd of
129138 Just cmd' -> do
130− result <- runExceptT (handleCommand cmd')
139+ let message duration =
140+ "Command " <> commandName cmd'
141+ <> " took "
142+ <> displayTimeSpec duration
143+ result <- logPerf message (runExceptT (handleCommand cmd'))
131144 -- $(logDebug) ("Answer was: " <> T.pack (show result))
132145 liftIO (hFlush stdout)
133146 case result of
@@ -140,7 +153,6 @@ startServer port env = withSocketsDo $ do
140153 hFlush stdout
141154 liftIO (hClose h)
142155
143−
144156acceptCommand :: (MonadIO m, MonadLogger m, MonadError Text m)
145157 => Socket -> m (Text, Handle)
146158acceptCommand sock = do