Allow users to set log flushing rules (#20817)
* Add flushThreshold to std/logging loggers * Remove duplicate field * Add -d:nimFlushAllLogs for changing default flush behavior globally * Add changelog entry for log flushing change * Flush all log levels by default in Nim v2
This commit is contained in:
parent
d901d3b8c5
commit
1daf43fb14
2 changed files with 38 additions and 17 deletions
|
|
@ -100,6 +100,8 @@
|
||||||
This warning will become an error in future versions! Use a `cast` operation
|
This warning will become an error in future versions! Use a `cast` operation
|
||||||
like `cast[cstring](x)` instead.
|
like `cast[cstring](x)` instead.
|
||||||
|
|
||||||
|
- `logging` will default to flushing all log level messages. To get the legacy behaviour of only flushing Error and Fatal messages, use `-d:nimV1LogFlushBehavior`.
|
||||||
|
|
||||||
## Standard library additions and changes
|
## Standard library additions and changes
|
||||||
|
|
||||||
[//]: # "Changes:"
|
[//]: # "Changes:"
|
||||||
|
|
@ -119,6 +121,7 @@
|
||||||
- `std/oids` now uses `int64` to store time internally (before it was int32).
|
- `std/oids` now uses `int64` to store time internally (before it was int32).
|
||||||
- `std/uri.Uri` dollar `$` improved, precalculates the `string` result length from the `Uri`.
|
- `std/uri.Uri` dollar `$` improved, precalculates the `string` result length from the `Uri`.
|
||||||
- `std/uri.Uri.isIpv6` is now exported.
|
- `std/uri.Uri.isIpv6` is now exported.
|
||||||
|
- `std/logging.ConsoleLogger` and `FileLogger` now have a `flushThreshold` attribute to set what log message levels are automatically flushed. For Nim v1 use `-d:nimFlushAllLogs` to automatically flush all message levels. Flushing all logs is the default behavior for Nim v2.
|
||||||
|
|
||||||
|
|
||||||
- `std/net.IpAddress` dollar `$` improved, uses a fixed capacity for the `string` result based from the `IpAddressFamily`.
|
- `std/net.IpAddress` dollar `$` improved, uses a fixed capacity for the `string` result based from the `IpAddressFamily`.
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,8 @@
|
||||||
##
|
##
|
||||||
## .. warning::
|
## .. warning::
|
||||||
## For loggers that log to a console or to files, only error and fatal
|
## For loggers that log to a console or to files, only error and fatal
|
||||||
## messages will cause their output buffers to be flushed immediately.
|
## messages will cause their output buffers to be flushed immediately by default.
|
||||||
## Use the `flushFile proc <syncio.html#flushFile,File>`_ to flush the buffer
|
## set ``flushThreshold`` when creating the logger to change this.
|
||||||
## manually if needed.
|
|
||||||
##
|
##
|
||||||
## Handlers
|
## Handlers
|
||||||
## --------
|
## --------
|
||||||
|
|
@ -200,6 +199,15 @@ const
|
||||||
## If a different format string is preferred, refer to the
|
## If a different format string is preferred, refer to the
|
||||||
## `documentation about format strings<#basic-usage-format-strings>`_
|
## `documentation about format strings<#basic-usage-format-strings>`_
|
||||||
## for more information, including a list of available variables.
|
## for more information, including a list of available variables.
|
||||||
|
defaultFlushThreshold = when NimMajor >= 2:
|
||||||
|
when defined(nimV1LogFlushBehavior): lvlError else: lvlAll
|
||||||
|
else:
|
||||||
|
when defined(nimFlushAllLogs): lvlAll else: lvlError
|
||||||
|
## The threshold above which log messages to file-like loggers
|
||||||
|
## are automatically flushed.
|
||||||
|
##
|
||||||
|
## By default, only error and fatal messages are logged,
|
||||||
|
## but defining ``-d:nimFlushAllLogs`` will make all levels be flushed
|
||||||
|
|
||||||
type
|
type
|
||||||
Logger* = ref object of RootObj
|
Logger* = ref object of RootObj
|
||||||
|
|
@ -228,6 +236,8 @@ type
|
||||||
## * `FileLogger<#FileLogger>`_
|
## * `FileLogger<#FileLogger>`_
|
||||||
## * `RollingFileLogger<#RollingFileLogger>`_
|
## * `RollingFileLogger<#RollingFileLogger>`_
|
||||||
useStderr*: bool ## If true, writes to stderr; otherwise, writes to stdout
|
useStderr*: bool ## If true, writes to stderr; otherwise, writes to stdout
|
||||||
|
flushThreshold*: Level ## Only messages that are at or above this
|
||||||
|
## threshold will be flushed immediately
|
||||||
|
|
||||||
when not defined(js):
|
when not defined(js):
|
||||||
type
|
type
|
||||||
|
|
@ -243,6 +253,8 @@ when not defined(js):
|
||||||
## * `ConsoleLogger<#ConsoleLogger>`_
|
## * `ConsoleLogger<#ConsoleLogger>`_
|
||||||
## * `RollingFileLogger<#RollingFileLogger>`_
|
## * `RollingFileLogger<#RollingFileLogger>`_
|
||||||
file*: File ## The wrapped file
|
file*: File ## The wrapped file
|
||||||
|
flushThreshold*: Level ## Only messages that are at or above this
|
||||||
|
## threshold will be flushed immediately
|
||||||
|
|
||||||
RollingFileLogger* = ref object of FileLogger
|
RollingFileLogger* = ref object of FileLogger
|
||||||
## A logger that writes log messages to a file while performing log
|
## A logger that writes log messages to a file while performing log
|
||||||
|
|
@ -348,8 +360,8 @@ method log*(logger: ConsoleLogger, level: Level, args: varargs[string, `$`]) =
|
||||||
## `setLogFilter proc<#setLogFilter,Level>`_.
|
## `setLogFilter proc<#setLogFilter,Level>`_.
|
||||||
##
|
##
|
||||||
## **Note:** Only error and fatal messages will cause the output buffer
|
## **Note:** Only error and fatal messages will cause the output buffer
|
||||||
## to be flushed immediately. Use the `flushFile proc
|
## to be flushed immediately by default. Set ``flushThreshold`` when creating
|
||||||
## <syncio.html#flushFile,File>`_ to flush the buffer manually if needed.
|
## the logger to change this.
|
||||||
##
|
##
|
||||||
## See also:
|
## See also:
|
||||||
## * `log method<#log.e,FileLogger,Level,varargs[string,]>`_
|
## * `log method<#log.e,FileLogger,Level,varargs[string,]>`_
|
||||||
|
|
@ -380,12 +392,12 @@ method log*(logger: ConsoleLogger, level: Level, args: varargs[string, `$`]) =
|
||||||
if logger.useStderr:
|
if logger.useStderr:
|
||||||
handle = stderr
|
handle = stderr
|
||||||
writeLine(handle, ln)
|
writeLine(handle, ln)
|
||||||
if level in {lvlError, lvlFatal}: flushFile(handle)
|
if level >= logger.flushThreshold: flushFile(handle)
|
||||||
except IOError:
|
except IOError:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc newConsoleLogger*(levelThreshold = lvlAll, fmtStr = defaultFmtStr,
|
proc newConsoleLogger*(levelThreshold = lvlAll, fmtStr = defaultFmtStr,
|
||||||
useStderr = false): ConsoleLogger =
|
useStderr = false, flushThreshold = defaultFlushThreshold): ConsoleLogger =
|
||||||
## Creates a new `ConsoleLogger<#ConsoleLogger>`_.
|
## Creates a new `ConsoleLogger<#ConsoleLogger>`_.
|
||||||
##
|
##
|
||||||
## By default, log messages are written to ``stdout``. If ``useStderr`` is
|
## By default, log messages are written to ``stdout``. If ``useStderr`` is
|
||||||
|
|
@ -409,6 +421,7 @@ proc newConsoleLogger*(levelThreshold = lvlAll, fmtStr = defaultFmtStr,
|
||||||
new result
|
new result
|
||||||
result.fmtStr = fmtStr
|
result.fmtStr = fmtStr
|
||||||
result.levelThreshold = levelThreshold
|
result.levelThreshold = levelThreshold
|
||||||
|
result.flushThreshold = flushThreshold
|
||||||
result.useStderr = useStderr
|
result.useStderr = useStderr
|
||||||
|
|
||||||
when not defined(js):
|
when not defined(js):
|
||||||
|
|
@ -424,8 +437,8 @@ when not defined(js):
|
||||||
##
|
##
|
||||||
## **Notes:**
|
## **Notes:**
|
||||||
## * Only error and fatal messages will cause the output buffer
|
## * Only error and fatal messages will cause the output buffer
|
||||||
## to be flushed immediately. Use the `flushFile proc
|
## to be flushed immediately by default. Set ``flushThreshold`` when creating
|
||||||
## <syncio.html#flushFile,File>`_ to flush the buffer manually if needed.
|
## the logger to change this.
|
||||||
## * This method is not available for the JavaScript backend.
|
## * This method is not available for the JavaScript backend.
|
||||||
##
|
##
|
||||||
## See also:
|
## See also:
|
||||||
|
|
@ -443,7 +456,7 @@ when not defined(js):
|
||||||
## fileLog.log(lvlError, "error code is: ", 404)
|
## fileLog.log(lvlError, "error code is: ", 404)
|
||||||
if level >= logging.level and level >= logger.levelThreshold:
|
if level >= logging.level and level >= logger.levelThreshold:
|
||||||
writeLine(logger.file, substituteLog(logger.fmtStr, level, args))
|
writeLine(logger.file, substituteLog(logger.fmtStr, level, args))
|
||||||
if level in {lvlError, lvlFatal}: flushFile(logger.file)
|
if level >= logger.flushThreshold: flushFile(logger.file)
|
||||||
|
|
||||||
proc defaultFilename*(): string =
|
proc defaultFilename*(): string =
|
||||||
## Returns the filename that is used by default when naming log files.
|
## Returns the filename that is used by default when naming log files.
|
||||||
|
|
@ -454,7 +467,8 @@ when not defined(js):
|
||||||
|
|
||||||
proc newFileLogger*(file: File,
|
proc newFileLogger*(file: File,
|
||||||
levelThreshold = lvlAll,
|
levelThreshold = lvlAll,
|
||||||
fmtStr = defaultFmtStr): FileLogger =
|
fmtStr = defaultFmtStr,
|
||||||
|
flushThreshold = defaultFlushThreshold): FileLogger =
|
||||||
## Creates a new `FileLogger<#FileLogger>`_ that uses the given file handle.
|
## Creates a new `FileLogger<#FileLogger>`_ that uses the given file handle.
|
||||||
##
|
##
|
||||||
## **Note:** This proc is not available for the JavaScript backend.
|
## **Note:** This proc is not available for the JavaScript backend.
|
||||||
|
|
@ -478,13 +492,15 @@ when not defined(js):
|
||||||
new(result)
|
new(result)
|
||||||
result.file = file
|
result.file = file
|
||||||
result.levelThreshold = levelThreshold
|
result.levelThreshold = levelThreshold
|
||||||
|
result.flushThreshold = flushThreshold
|
||||||
result.fmtStr = fmtStr
|
result.fmtStr = fmtStr
|
||||||
|
|
||||||
proc newFileLogger*(filename = defaultFilename(),
|
proc newFileLogger*(filename = defaultFilename(),
|
||||||
mode: FileMode = fmAppend,
|
mode: FileMode = fmAppend,
|
||||||
levelThreshold = lvlAll,
|
levelThreshold = lvlAll,
|
||||||
fmtStr = defaultFmtStr,
|
fmtStr = defaultFmtStr,
|
||||||
bufSize: int = -1): FileLogger =
|
bufSize: int = -1,
|
||||||
|
flushThreshold = defaultFlushThreshold): FileLogger =
|
||||||
## Creates a new `FileLogger<#FileLogger>`_ that logs to a file with the
|
## Creates a new `FileLogger<#FileLogger>`_ that logs to a file with the
|
||||||
## given filename.
|
## given filename.
|
||||||
##
|
##
|
||||||
|
|
@ -508,7 +524,7 @@ when not defined(js):
|
||||||
## var formatLog = newFileLogger("formatted.log", fmtStr=verboseFmtStr)
|
## var formatLog = newFileLogger("formatted.log", fmtStr=verboseFmtStr)
|
||||||
## var errorLog = newFileLogger("errors.log", levelThreshold=lvlError)
|
## var errorLog = newFileLogger("errors.log", levelThreshold=lvlError)
|
||||||
let file = open(filename, mode, bufSize = bufSize)
|
let file = open(filename, mode, bufSize = bufSize)
|
||||||
newFileLogger(file, levelThreshold, fmtStr)
|
newFileLogger(file, levelThreshold, fmtStr, flushThreshold)
|
||||||
|
|
||||||
# ------
|
# ------
|
||||||
|
|
||||||
|
|
@ -540,7 +556,8 @@ when not defined(js):
|
||||||
levelThreshold = lvlAll,
|
levelThreshold = lvlAll,
|
||||||
fmtStr = defaultFmtStr,
|
fmtStr = defaultFmtStr,
|
||||||
maxLines: Positive = 1000,
|
maxLines: Positive = 1000,
|
||||||
bufSize: int = -1): RollingFileLogger =
|
bufSize: int = -1,
|
||||||
|
flushThreshold = defaultFlushThreshold): RollingFileLogger =
|
||||||
## Creates a new `RollingFileLogger<#RollingFileLogger>`_.
|
## Creates a new `RollingFileLogger<#RollingFileLogger>`_.
|
||||||
##
|
##
|
||||||
## Once the current log file being written to contains ``maxLines`` lines,
|
## Once the current log file being written to contains ``maxLines`` lines,
|
||||||
|
|
@ -576,6 +593,7 @@ when not defined(js):
|
||||||
result.curLine = 0
|
result.curLine = 0
|
||||||
result.baseName = filename
|
result.baseName = filename
|
||||||
result.baseMode = mode
|
result.baseMode = mode
|
||||||
|
result.flushThreshold = flushThreshold
|
||||||
|
|
||||||
result.logFiles = countFiles(filename)
|
result.logFiles = countFiles(filename)
|
||||||
|
|
||||||
|
|
@ -602,8 +620,8 @@ when not defined(js):
|
||||||
##
|
##
|
||||||
## **Notes:**
|
## **Notes:**
|
||||||
## * Only error and fatal messages will cause the output buffer
|
## * Only error and fatal messages will cause the output buffer
|
||||||
## to be flushed immediately. Use the `flushFile proc
|
## to be flushed immediately by default. Set ``flushThreshold`` when creating
|
||||||
## <syncio.html#flushFile,File>`_ to flush the buffer manually if needed.
|
## the logger to change this.
|
||||||
## * This method is not available for the JavaScript backend.
|
## * This method is not available for the JavaScript backend.
|
||||||
##
|
##
|
||||||
## See also:
|
## See also:
|
||||||
|
|
@ -629,7 +647,7 @@ when not defined(js):
|
||||||
bufSize = logger.bufSize)
|
bufSize = logger.bufSize)
|
||||||
|
|
||||||
writeLine(logger.file, substituteLog(logger.fmtStr, level, args))
|
writeLine(logger.file, substituteLog(logger.fmtStr, level, args))
|
||||||
if level in {lvlError, lvlFatal}: flushFile(logger.file)
|
if level >= logger.flushThreshold: flushFile(logger.file)
|
||||||
logger.curLine.inc
|
logger.curLine.inc
|
||||||
|
|
||||||
# --------
|
# --------
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue