jcarpenter2
jcarpenter2

Reputation: 5468

hslogger disable output to console

The following is supposed to configure hslogger for a Happstack application:

main = do
  accessLogHandler <- fileHandler "access" INFO
  updateGlobalLogger "Happstack.Server.AccessLog.Combined" (setLevel INFO)
  updateGlobalLogger "Happstack.Server.AccessLog.Combined" (setHandlers [accessLogHandler])
  simpleHTTP nullConf app

Access logs are going both to my "access" file and to stderr. According to this page, setHandlers is supposed to "Set the Logger's list of handlers to the list supplied. All existing handlers are removed first." I had assumed that console output would be an "existing handler", but apparently it is not.

How do you deactivate hslogger's console output?

Upvotes: 1

Views: 121

Answers (1)

Shersh
Shersh

Reputation: 9169

Okay, I spent about an hour and a half to figure this out. Code of hslogger is not very clean and doesn't make it easy to understand it.

EXPLANATION

Printing in terminal happens because there exist rootLogger with rootLoggerName = "" and stderr handler. When you print something to specific logger you also print to all parents of this exact logger. It happens so that rootLoggerName is one of parents for Happstack.Server.AccessLog.Combined.

SOLUTION

The way I found to disable terminal logging is just to set all handler of root logger name to empty list, like this:

updateGlobalLogger rootLoggerName (setHandlers [])

Unfortunately, this exact code won't compile because type of [] is too ambiguous for setHandlers. You can solve this type inference issue with -XTypeApplications extension. Here is the full code example:

{-# LANGUAGE TypeApplications #-}

import GHC.IO.Handle (Handle)
import System.Log.Logger
import System.Log.Handler.Simple

main :: IO ()
main = do
  accessLogHandler <- fileHandler "access" INFO
  let name = "Happstack.Server.AccessLog.Combined"
  updateGlobalLogger name (setHandlers [accessLogHandler])
  updateGlobalLogger name (setLevel INFO)
  updateGlobalLogger rootLoggerName (setHandlers @(GenericHandler Handle) [])
  infoM name "Hello!"

This infoM will print only to file and won't print to terminal.

Upvotes: 1

Related Questions