Merge pull request #4705 from yglukhov/js-logging

Logging compatible with js
This commit is contained in:
Dominik Picheta 2016-09-04 15:52:34 +02:00 • committed by GitHub
commit 63851b2c91
2 changed files with 122 additions and 108 deletions

View file

@ -47,7 +47,9 @@
## **Warning:** The global list of handlers is a thread var, this means that ## **Warning:** The global list of handlers is a thread var, this means that
## the handlers must be re-added in each thread. ## the handlers must be re-added in each thread.
import strutils, os, times import strutils, times
when not defined(js):
import os
type type
Level* = enum ## logging level Level* = enum ## logging level
@ -77,6 +79,8 @@ type
ConsoleLogger* = ref object of Logger ## logger that writes the messages to the ConsoleLogger* = ref object of Logger ## logger that writes the messages to the
## console ## console
when not defined(js):
type
FileLogger* = ref object of Logger ## logger that writes the messages to a file FileLogger* = ref object of Logger ## logger that writes the messages to a file
file*: File ## the wrapped file. file*: File ## the wrapped file.
@ -90,8 +94,9 @@ type
logFiles: int # how many log files already created, e.g. basename.1, basename.2... logFiles: int # how many log files already created, e.g. basename.1, basename.2...
bufSize: int # size of output buffer (-1: use system defaults, 0: unbuffered, >0: fixed buffer size) bufSize: int # size of output buffer (-1: use system defaults, 0: unbuffered, >0: fixed buffer size)
{.deprecated: [TLevel: Level, PLogger: Logger, PConsoleLogger: ConsoleLogger, {.deprecated: [PFileLogger: FileLogger, PRollingFileLogger: RollingFileLogger].}
PFileLogger: FileLogger, PRollingFileLogger: RollingFileLogger].}
{.deprecated: [TLevel: Level, PLogger: Logger, PConsoleLogger: ConsoleLogger].}
var var
level {.threadvar.}: Level ## global log filter level {.threadvar.}: Level ## global log filter
@ -112,7 +117,7 @@ proc substituteLog*(frmt: string, level: Level, args: varargs[string, `$`]): str
else: else:
inc(i) inc(i)
var v = "" var v = ""
var app = getAppFilename() let app = when defined(js): "" else: getAppFilename()
while frmt[i] in IdentChars: while frmt[i] in IdentChars:
v.add(toLower(frmt[i])) v.add(toLower(frmt[i]))
inc(i) inc(i)
@ -121,8 +126,10 @@ proc substituteLog*(frmt: string, level: Level, args: varargs[string, `$`]): str
of "time": result.add(getClockStr()) of "time": result.add(getClockStr())
of "datetime": result.add(getDateStr() & "T" & getClockStr()) of "datetime": result.add(getDateStr() & "T" & getClockStr())
of "app": result.add(app) of "app": result.add(app)
of "appdir": result.add(app.splitFile.dir) of "appdir":
of "appname": result.add(app.splitFile.name) when not defined(js): result.add(app.splitFile.dir)
of "appname":
when not defined(js): result.add(app.splitFile.name)
of "levelid": result.add(LevelNames[level][0]) of "levelid": result.add(LevelNames[level][0])
of "levelname": result.add(LevelNames[level]) of "levelname": result.add(LevelNames[level])
else: discard else: discard
@ -139,9 +146,21 @@ method log*(logger: Logger, level: Level, args: varargs[string, `$`]) {.
method log*(logger: ConsoleLogger, level: Level, args: varargs[string, `$`]) = method log*(logger: ConsoleLogger, level: Level, args: varargs[string, `$`]) =
## Logs to the console using ``logger`` only. ## Logs to the console using ``logger`` only.
if level >= logging.level and level >= logger.levelThreshold: if level >= logging.level and level >= logger.levelThreshold:
writeLine(stdout, substituteLog(logger.fmtStr, level, args)) let ln = substituteLog(logger.fmtStr, level, args)
when defined(js):
let cln: cstring = ln
{.emit: "console.log(`cln`);".}
else:
writeLine(stdout, ln)
if level in {lvlError, lvlFatal}: flushFile(stdout) if level in {lvlError, lvlFatal}: flushFile(stdout)
proc newConsoleLogger*(levelThreshold = lvlAll, fmtStr = defaultFmtStr): ConsoleLogger =
## Creates a new console logger. This logger logs to the console.
new result
result.fmtStr = fmtStr
result.levelThreshold = levelThreshold
when not defined(js):
method log*(logger: FileLogger, level: Level, args: varargs[string, `$`]) = method log*(logger: FileLogger, level: Level, args: varargs[string, `$`]) =
## Logs to a file using ``logger`` only. ## Logs to a file using ``logger`` only.
if level >= logging.level and level >= logger.levelThreshold: if level >= logging.level and level >= logger.levelThreshold:
@ -153,12 +172,6 @@ proc defaultFilename*(): string =
var (path, name, _) = splitFile(getAppFilename()) var (path, name, _) = splitFile(getAppFilename())
result = changeFileExt(path / name, "log") result = changeFileExt(path / name, "log")
proc newConsoleLogger*(levelThreshold = lvlAll, fmtStr = defaultFmtStr): ConsoleLogger =
## Creates a new console logger. This logger logs to the console.
new result
result.fmtStr = fmtStr
result.levelThreshold = levelThreshold
proc newFileLogger*(filename = defaultFilename(), proc newFileLogger*(filename = defaultFilename(),
mode: FileMode = fmAppend, mode: FileMode = fmAppend,
levelThreshold = lvlAll, levelThreshold = lvlAll,
@ -323,10 +336,11 @@ proc getLogFilter*(): Level =
when not defined(testing) and isMainModule: when not defined(testing) and isMainModule:
var L = newConsoleLogger() var L = newConsoleLogger()
when not defined(js):
var fL = newFileLogger("test.log", fmtStr = verboseFmtStr) var fL = newFileLogger("test.log", fmtStr = verboseFmtStr)
var rL = newRollingFileLogger("rolling.log", fmtStr = verboseFmtStr) var rL = newRollingFileLogger("rolling.log", fmtStr = verboseFmtStr)
addHandler(L)
addHandler(fL) addHandler(fL)
addHandler(rL) addHandler(rL)
addHandler(L)
for i in 0 .. 25: for i in 0 .. 25:
info("hello", i) info("hello", i)

View file

@ -228,8 +228,8 @@ proc jsTests(r: var TResults, cat: Category, options: string) =
"varres/tvartup", "misc/tints", "misc/tunsignedinc"]: "varres/tvartup", "misc/tints", "misc/tunsignedinc"]:
test "tests/" & testfile & ".nim" test "tests/" & testfile & ".nim"
for testfile in ["pure/strutils", "pure/json", "pure/random", "pure/times"]: for testfile in ["strutils", "json", "random", "times", "logging"]:
test "lib/" & testfile & ".nim" test "lib/pure/" & testfile & ".nim"
# ------------------------- manyloc ------------------------------------------- # ------------------------- manyloc -------------------------------------------
#proc runSpecialTests(r: var TResults, options: string) = #proc runSpecialTests(r: var TResults, options: string) =