Skip to content

Commit

Permalink
Accept a special value "null" for LOG_DESTINATION
Browse files Browse the repository at this point in the history
This parses a new value `"null"` as a `LogDestination`. On non-Windows
systems, it'll be equivalent to `"@/dev/null"`. On Windows systems,
`"@\\.\NUL"` (an explicitly-namespaced form for the `NUL` device[^1]).

Closes #50.

I chose not to investigate the open question about whether or not
`LOG_DESTINATION=NUL` would already Just Work. I decided it didn't
matter, for two reasons:

1. While it's likely "specifying `NUL`" may conceptually work, it's very
   possible you still need to practically use `LOG_DESTINATION=\\.\NUL`
   to do it.

   That would not be very discoverable and the escaping required would
   be quite error-prone, making the `null` sugar valuable.

2. Mixed-OS teams attempting to have null as a default in (e.g.) `.env`
   can't do so today.

   Without this sugar, such teams would have to concretely pick
   `/dev/null` or `NUL`.

Together, this seemed like enough to warrant the small bit of alias
complexity.

[^1]: https://stackoverflow.com/a/58177337
  • Loading branch information
pbrisbin committed Aug 26, 2024
1 parent f6c62fd commit e02e310
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Blammo/Blammo.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: 1.18

-- This file has been generated from package.yaml by hpack version 0.36.0.
-- This file has been generated from package.yaml by hpack version 0.37.0.
--
-- see: https://github.com/sol/hpack

Expand Down
2 changes: 1 addition & 1 deletion Blammo/README.lhs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ setting the format to `json` will automatically enable it (with
| ----------- | --------------------------- | ----------------------------------------- |
| Format | `setLogSettingsFormat` | `LOG_FORMAT=tty\|json` |
| Level(s) | `setLogSettingsLevels` | `LOG_LEVEL=<level>[,<source:level>,...]` |
| Destination | `setLogSettingsDestination` | `LOG_DESTINATION=stdout\|stderr\|@<path>` |
| Destination | `setLogSettingsDestination` | `LOG_DESTINATION=stdout\|stderr\|null\|@<path>` |
| Color | `setLogSettingsColor ` | `LOG_COLOR=auto\|always\|never` |
| Breakpoint | `setLogSettingsBreakpoint` | `LOG_BREAKPOINT=<number>` |
| Concurrency | `setLogSettingsConcurrency` | `LOG_CONCURRENCY=<number>` |
Expand Down
15 changes: 14 additions & 1 deletion Blammo/src/Blammo/Logging/LogSettings.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import qualified Blammo.Logging.LogSettings.LogLevels as LogLevels
import Control.Monad.IO.Class (MonadIO (..))
import Control.Monad.Logger.Aeson
import System.IO (Handle, hIsTerminalDevice)
import qualified System.Info

data LogSettings = LogSettings
{ lsLevels :: LogLevels
Expand All @@ -65,12 +66,13 @@ readLogDestination :: String -> Either String LogDestination
readLogDestination = \case
"stdout" -> Right LogDestinationStdout
"stderr" -> Right LogDestinationStderr
"null" -> Right $ LogDestinationFile nullDevice
('@' : path) -> Right $ LogDestinationFile path
x ->
Left $
"Invalid log destination "
<> x
<> ", must be stdout, stderr, or @{path}"
<> ", must be stdout, stderr, null, or @{path}"

data LogFormat
= LogFormatJSON
Expand Down Expand Up @@ -196,3 +198,14 @@ shouldColorAuto LogSettings {..} f = case lsColor of
shouldColorHandle :: MonadIO m => LogSettings -> Handle -> m Bool
shouldColorHandle settings h =
shouldColorAuto settings $ liftIO $ hIsTerminalDevice h

-- | @/dev/null@ or @NUL@ on windows
--
-- See <https://stackoverflow.com/a/58177337>.
nullDevice :: FilePath
nullDevice
| System.Info.os == windowsOS = "\\\\.\\NUL"
| otherwise = "/dev/null"

windowsOS :: String
windowsOS = "mingw32"
6 changes: 3 additions & 3 deletions Blammo/src/Blammo/Logging/LogSettings/Env.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
-- - @LOG_LEVEL@: a known log level (case insensitive) and optional levels by
-- source. See "Logging.LogSettings.LogLevels".
--
-- - @LOG_DESTINATION@: the string @stderr@ or @stdout@ (case sensitive), or
-- @\@{path}@ to log to the file at @path@. Unrecognized values will produce
-- and error.
-- - @LOG_DESTINATION@: the string @stderr@, @stdout@ or @null@, (case
-- sensitive), or @\@{path}@ to log to the file at @path@. Unrecognized values
-- will produce an error.
--
-- - @LOG_FORMAT@: the string @tty@ or @json@. Unrecognized values will produce
-- an error.
Expand Down

0 comments on commit e02e310

Please sign in to comment.