{- Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. -} {-# LANGUAGE ImplicitParams #-} -- | -- This module allows you to log things to stderr. Make sure to initialize your -- application using 'Facebook.Init.initFacebook' or -- 'Facebook.Init.withFacebook' beforehand. Otherwise you're going to get a -- cryptic "Logging before InitGoogleLogging() is written to STDERR" error. module Util.Log.String ( vlog , vlogIsOn , logInfo , logWarning , logError , logFatal ) where import Control.Monad import Control.Monad.IO.Class (MonadIO, liftIO) import Foreign.C import GHC.Stack import Util.Log.Internal -- | Equivalent to @VLOG(level)@, except that in Haskell we only evaluate -- the message if verbosity at the desired level is enabled. Note that -- this lazy evaluation of the message only applies to 'vlog', not to -- any of the other logging functions. vlog :: (MonadIO m, HasCallStack) => Int -> String -> m () vlog level msg = liftIO $ do b <- vlogIsOn level when b $ logCommon c_glog_verbose (getCaller $ getCallStack callStack) msg -- | The calling point is actually right next to the head as the head is the -- current function (in this case it would be logInfo/Warning/Error/Fatal). getCaller :: [(String, SrcLoc)] -> (String, CInt) getCaller cs = case cs of -- Take the first element of the stack if it exists ((_,sl):_) -> (srcLocFile sl, fromIntegral $ srcLocStartLine sl) _ -> ("Unknown stack trace", 0) -- | Log message at severity level @INFO@. logInfo :: (MonadIO m, HasCallStack) => String -> m () logInfo msg = liftIO $ logCommon c_glog_info (getCaller $ getCallStack callStack) msg -- | Log message at severity level @WARNING@. logWarning :: (MonadIO m, HasCallStack) => String -> m () logWarning msg = liftIO $ logCommon c_glog_warning (getCaller $ getCallStack callStack) msg -- | Log message at severity level @ERROR@. logError :: (MonadIO m, HasCallStack) => String -> m () logError msg = liftIO $ logCommon c_glog_error (getCaller $ getCallStack callStack) msg -- | Log message at severity level @FATAL@. This will terminate the program -- after the message is logged. logFatal :: (MonadIO m, HasCallStack) => String -> m () logFatal msg = liftIO $ logCommon c_glog_fatal (getCaller $ getCallStack callStack) msg logCommon :: (CString -> CInt -> CString -> IO ()) -> (String, CInt) -> String -> IO () logCommon fn (file, lineNumber) msg = withCString file $ \file_cstring -> withCString msg $ \msg_cstring -> fn file_cstring lineNumber msg_cstring