Compare commits

...

4 Commits
0.2.0 ... main

Author SHA1 Message Date
8b0a684dab Explicitly require docopt v0.7.1 or above. 2025-05-13 09:56:44 -05:00
4efc72e8ae Correctly handle nested JSON fields when using compact formatting. 2025-02-04 17:35:00 -06:00
2291b75c0a Tweak line wrapping for long-keyed, short-values fields. 2025-01-20 23:06:07 -06:00
11cc9c9a39 Fix bug when a line happens to parse as JSON but isn't an object.
For example, if `false` happened to be the only value on a line, this
would be parsed as valid JSON (a boolean) but it is not a structured log
message that slfmt should try to parse and format.
2025-01-20 21:24:22 -06:00
2 changed files with 15 additions and 6 deletions

View File

@ -1,6 +1,6 @@
# Package
version = "0.2.0"
version = "0.2.3"
author = "Jonathan Bernard"
description = "Small utility to pretty-print strucutured logs."
license = "MIT"
@ -10,5 +10,5 @@ bin = @["slfmt"]
# Dependencies
requires @["nim >= 2.2.0", "docopt"]
requires @["nim >= 2.2.0", "docopt >= 0.7.1"]
requires @["timeutils", "zero_functional"]

View File

@ -4,7 +4,7 @@ import docopt, timeutils, zero_functional
from std/logging import Level
from std/sequtils import toSeq
const VERSION = "0.2.0"
const VERSION = "0.2.3"
const USAGE = """Usage:
slfmt [options]
@ -63,7 +63,7 @@ proc fullFormatField(name: string, value: JsonNode): string =
else: strVal = pretty(value)
let valLines = splitLines(strVal)
if name.len > 10 or strVal.len + 16 > terminalWidth() or valLines.len > 1:
if name.len + strVal.len + 6 > terminalWidth() or valLines.len > 1:
result &= "\n" & valLines.mapIt(" " & it).join("\n") & "\n"
else: result &= strVal & "\n"
@ -98,14 +98,21 @@ proc compactFormat(logJson: JsonNode): string =
filter(not ["level", "scope", "ts", "msg"].contains(it[0]))
let restMsg = join(restNodes -->
map("$1: $2" % [decorate(it[0], fgCyan), it[1].getStr]), " ")
map("$1: $2" % [
decorate(it[0], fgCyan),
if it[1].kind == JString: it[1].getStr
else: pretty(it[1]),
" "]))
if restMsg.len + result.len + 2 < terminalWidth():
result &= " " & restMsg
else:
var line = " "
for (key, val) in restNodes:
let field = "$1: $2" % [decorate(key, fgCyan), val.getStr]
let fieldVal =
if val.kind == JString: val.getStr
else: pretty(val)
let field = "$1: $2" % [decorate(key, fgCyan), fieldVal]
if line.len + field.len + 2 > terminalWidth():
result &= "\n " & line
line = " "
@ -134,6 +141,8 @@ when isMainModule:
while(sin.readLine(line)):
try:
let logJson = parseLogLine(line)
if logJson.kind != JObject:
raise newException(JsonParsingError, "Expected a JSON object")
if logLevel.isSome and logJson.hasKey("level"):
let lvl = parseLogLevel(logJson["level"].getStr)