Add the ability to filter by log level and namespace.
This commit is contained in:
parent
982680d972
commit
34add1a729
@ -1,6 +1,6 @@
|
|||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
author = "Jonathan Bernard"
|
author = "Jonathan Bernard"
|
||||||
description = "Small utility to pretty-print strucutured logs."
|
description = "Small utility to pretty-print strucutured logs."
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@ -10,5 +10,5 @@ bin = @["slfmt"]
|
|||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
|
||||||
requires "nim >= 2.2.0"
|
requires @["nim >= 2.2.0", "docopt"]
|
||||||
requires "timeutils"
|
requires "timeutils"
|
||||||
|
@ -1,19 +1,34 @@
|
|||||||
import std/[json, sequtils, streams, strutils, terminal, times]
|
import std/[json, options, sequtils, streams, strutils, terminal, times]
|
||||||
import timeutils
|
import timeutils
|
||||||
#import docopt
|
import docopt
|
||||||
|
|
||||||
const VERSION = "0.1.0"
|
from std/logging import Level
|
||||||
|
|
||||||
# const USAGE = """Usage:
|
const VERSION = "0.1.2"
|
||||||
# slfmt
|
|
||||||
#
|
const USAGE = """Usage:
|
||||||
# Options:
|
slfmt [options]
|
||||||
#
|
|
||||||
# -h, --help Print this usage and help information
|
Options:
|
||||||
|
|
||||||
|
-h, --help Print this usage and help information
|
||||||
|
-l, --log-level <lvl> Only show log events at or above this level
|
||||||
|
-n, --namespace <ns> Only show log events from this namespace
|
||||||
|
"""
|
||||||
|
|
||||||
const fieldDisplayOrder = @[
|
const fieldDisplayOrder = @[
|
||||||
"scope", "level", "ts", "code", "sid", "sub", "msg", "err", "stack", "method", "args"]
|
"scope", "level", "ts", "code", "sid", "sub", "msg", "err", "stack", "method", "args"]
|
||||||
|
|
||||||
|
func parseLogLevel(s: string): Level =
|
||||||
|
case s.toUpper
|
||||||
|
of "DEBUG": result = Level.lvlDebug
|
||||||
|
of "INFO": result = Level.lvlInfo
|
||||||
|
of "NOTICE": result = Level.lvlNotice
|
||||||
|
of "WARN": result = Level.lvlWarn
|
||||||
|
of "ERROR": result = Level.lvlError
|
||||||
|
of "FATAL": result = Level.lvlFatal
|
||||||
|
else: result = Level.lvlAll
|
||||||
|
|
||||||
func decorate(
|
func decorate(
|
||||||
s: string,
|
s: string,
|
||||||
fg = fgDefault,
|
fg = fgDefault,
|
||||||
@ -42,6 +57,8 @@ proc formatField(name: string, value: JsonNode): string =
|
|||||||
of "err": strVal = decorate(value.getStr, fgRed)
|
of "err": strVal = decorate(value.getStr, fgRed)
|
||||||
of "msg": strVal = decorate(value.getStr, fgYellow)
|
of "msg": strVal = decorate(value.getStr, fgYellow)
|
||||||
of "stack": strVal = decorate(value.getStr, fgBlack, {styleBright})
|
of "stack": strVal = decorate(value.getStr, fgBlack, {styleBright})
|
||||||
|
else:
|
||||||
|
if value.kind == JString: strVal = decorate(value.getStr)
|
||||||
else: strVal = pretty(value)
|
else: strVal = pretty(value)
|
||||||
|
|
||||||
let valLines = splitLines(strVal)
|
let valLines = splitLines(strVal)
|
||||||
@ -49,10 +66,7 @@ proc formatField(name: string, value: JsonNode): string =
|
|||||||
result &= "\n" & valLines.mapIt(" " & it).join("\n") & "\n"
|
result &= "\n" & valLines.mapIt(" " & it).join("\n") & "\n"
|
||||||
else: result &= strVal & "\n"
|
else: result &= strVal & "\n"
|
||||||
|
|
||||||
proc prettyPrintFormat(logLine: string): string =
|
proc prettyPrintFormat(logJson: JsonNode): string =
|
||||||
try:
|
|
||||||
var logJson = parseJson(logLine)
|
|
||||||
|
|
||||||
result = '-'.repeat(terminalWidth()) & "\n"
|
result = '-'.repeat(terminalWidth()) & "\n"
|
||||||
|
|
||||||
# Print the known fields in order first
|
# Print the known fields in order first
|
||||||
@ -66,14 +80,37 @@ proc prettyPrintFormat(logLine: string): string =
|
|||||||
|
|
||||||
result &= "\n"
|
result &= "\n"
|
||||||
|
|
||||||
except ValueError, JsonParsingError:
|
proc parseLogLine(logLine: string): JsonNode =
|
||||||
result = logLine
|
result = parseJson(logLine)
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
try:
|
try:
|
||||||
|
let args = docopt(USAGE, version = VERSION)
|
||||||
|
|
||||||
|
let logLevel =
|
||||||
|
if args["--log-level"]: some(parseLogLevel($args["--log-level"]))
|
||||||
|
else: none[Level]()
|
||||||
|
|
||||||
|
let namespace =
|
||||||
|
if args["--namespace"]: some($args["--namespace"])
|
||||||
|
else: none[string]()
|
||||||
|
|
||||||
var line: string = ""
|
var line: string = ""
|
||||||
let sin = newFileStream(stdin)
|
let sin = newFileStream(stdin)
|
||||||
while(sin.readLine(line)): stdout.writeLine(prettyPrintFormat(line))
|
while(sin.readLine(line)):
|
||||||
|
try:
|
||||||
|
let logJson = parseLogLine(line)
|
||||||
|
|
||||||
|
if logLevel.isSome and logJson.hasKey("level"):
|
||||||
|
let lvl = parseLogLevel(logJson["level"].getStr)
|
||||||
|
if lvl < logLevel.get: continue
|
||||||
|
|
||||||
|
if namespace.isSome and logJson.hasKey("scope"):
|
||||||
|
if not logJson["scope"].getStr.startsWith(namespace.get): continue
|
||||||
|
|
||||||
|
stdout.writeLine(prettyPrintFormat(logJson))
|
||||||
|
except ValueError, JsonParsingError:
|
||||||
|
stdout.writeLine(line)
|
||||||
except:
|
except:
|
||||||
stderr.writeLine("slfmt - FATAL: " & getCurrentExceptionMsg())
|
stderr.writeLine("slfmt - FATAL: " & getCurrentExceptionMsg())
|
||||||
stderr.writeLine(getCurrentException().getStackTrace())
|
stderr.writeLine(getCurrentException().getStackTrace())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user