In Go creating of the JSON quite simple, just pass any data in json.Marshal
, and you get the bytes with JSON. But parsing of JSON is painful, especially when you want only one field that located deep in the source JSON. You have to create all maps and structs for all places where located fields that you need. See full example on Go by Example.
lastName
from all objects in the programmers
field: gjson.Get(json, "programmers.#.lastName").Array()
. Beautiful!sjson.Set(json, "name.last", "Anderson")
.gjson
and sjson
for getting and editing values in JSON stream.jj
, but interactive. Really useful tool for constructing paths for gjson
.jj
, but with beautify, syntax highlighting, simple installation from repos and alternative syntax. This is really powerful tool with regexp, functions, many arguments, variables, Turing complete language.You can beautify output of any command that writes JSON logs to stdout just piping it to jq
:
$ go run tmp.go | jq
{
"level": "info",
"message": "hello world!"
}
{
"level": "info",
"message": "hello again",
"testInt": 0
}
However, jq
fails if the input contains non-JSON lines. I don’t know how to fix it. I’ve found isuue where authors recommend to use --seq
key for it, but it doesn’t work for me. In this case, you can use bat – a clone of cat with syntax highlighting, lines numbering, pagination and git support.
go run tmp.go | bat -l jsonnet
───────┬──────────────────────────────────────────────────────
│ STDIN
───────┼──────────────────────────────────────────────────────
1 │ broke
2 │ {"level":"info","message":"hello world!"}
3 │ broke again
4 │ {"level":"info","message":"hello again","testInt":0}
Code that I used for tests:
package main
import (
"fmt"
"os"
"time"
"github.com/francoispqt/onelog"
)
func main() {
fmt.Println("broke")
logger := onelog.New(os.Stdout, onelog.ALL)
logger.Info("hello world!")
fmt.Println("broke again")
for i := 0; true; i++ {
time.Sleep(2 * time.Second)
logger.InfoWith("hello again").Int("testInt", i).Write()
}
}