Skip to content

Commit

Permalink
Fix example of overriding Logger (digitallyinduced#1944)
Browse files Browse the repository at this point in the history
* Fix example of overriding Logger

* Start add guide

* Log also anon users

* tabs

* Complete example

* Apply suggestions from code review

* Improve code readability

* Code review fixes

* Apply suggestions from code review
  • Loading branch information
amitaibu authored Apr 2, 2024
1 parent ab4ecd0 commit 9d52ad2
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 11 deletions.
51 changes: 51 additions & 0 deletions Guide/logging.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -198,5 +198,56 @@ Would log a timestamp as:

> Sunday, 2020-1-31 22:10:21
### Decorating the Logs with the User ID

You can override the default logger and have it decorated with additional information. A typical use case is adding the current user's ID or name to the log messages.


```haskell
-- Web/FrontController.hs

-- Add imports
import IHP.Log.Types as Log
import IHP.Controller.Context

instance InitControllerContext WebApplication where
initContext = do
initAuthentication @User
-- ... your other initContext code

putContext userIdLogger

userIdLogger :: (?context :: ControllerContext) => Logger
userIdLogger =
defaultLogger { Log.formatter = userIdFormatter defaultLogger.formatter }
where
defaultLogger = ?context.frameworkConfig.logger


userIdFormatter :: (?context :: ControllerContext) => Log.LogFormatter -> Log.LogFormatter
userIdFormatter existingFormatter time level string =
existingFormatter time level (prependUserId string)

prependUserId :: (?context :: ControllerContext) => LogStr -> LogStr
prependUserId string =
toLogStr $ userInfo <> show string
where
userInfo =
case currentUserOrNothing of
Just currentUser -> "Authenticated user ID: " <> show currentUser.id <> " "
Nothing -> "Anonymous user: "
```

From your controller you can now add a log message

```haskell
action PostsAction = do
Log.debug ("This log message should have user info" :: Text)
-- Rest of the action code.
```

In your log output, you will see the user info prepended to the log message.

```
[30-Mar-2024 18:28:29] Authenticated user ID: 5f32a9e3-da09-48d8-9712-34c935a72c7a "This log message should have user info"
```
37 changes: 26 additions & 11 deletions IHP/Controller/Context.hs
Original file line number Diff line number Diff line change
Expand Up @@ -143,21 +143,36 @@ instance HasField "frameworkConfig" ControllerContext FrameworkConfig where
--
-- This can be useful to customize the log formatter for all actions of an app:
--
-- > import IHP.Log.Types
-- > -- Web/FrontController.hs
-- >
-- > import IHP.Log.Types as Log
-- > import IHP.Controller.Context
-- >
-- >
-- > instance InitControllerContext WebApplication where
-- > initContext = do
-- > let defaultLogger :: Logger = ?context.frameworkConfig.logger
-- > let withUserIdLogger :: Logger = { Log.formatter = userIdFormatter defaultLogger.formatter }
-- > putContext withUserIdLogger
-- >
-- > userIdFormatter :: (?context :: Context) => Log.LogFormatter -> Log.LogFormatter
-- > -- ... your other initContext code
-- >
-- > putContext userIdLogger
-- >
-- > userIdLogger :: (?context :: ControllerContext) => Logger
-- > userIdLogger =
-- > defaultLogger { Log.formatter = userIdFormatter defaultLogger.formatter }
-- > where
-- > defaultLogger = ?context.frameworkConfig.logger
-- >
-- >
-- > userIdFormatter :: (?context :: ControllerContext) => Log.LogFormatter -> Log.LogFormatter
-- > userIdFormatter existingFormatter time level string =
-- > existingFormatter time level (prependUserId string)
-- >
-- > preprendUserId :: (?context :: Context) => Text -> Text
-- > preprendUserId string = "userId: " <> show currentUserId <> " " <> string
-- > existingFormatter time level (prependUserId string)
-- >
-- > prependUserId :: (?context :: ControllerContext) => LogStr -> LogStr
-- > prependUserId string =
-- > toLogStr $ userInfo <> show string
-- > where
-- > userInfo =
-- > case currentUserOrNothing of
-- > Just currentUser -> "Authenticated user ID: " <> show currentUser.id <> " "
-- > Nothing -> "Anonymous user: "
--
-- This design mistake should be fixed in IHP v2
instance HasField "logger" ControllerContext Logger where
Expand Down

0 comments on commit 9d52ad2

Please sign in to comment.