| go.mod | ||
| lib.go | ||
| README.md | ||
Purpose
Vlog extends the structured log JSONHandler with sending logs to a VictoriaLogs instance for central logging.
Logs are first queued to a buffered channel processed by go-routine loop which transform and send the log to the server.
In case of network error, queue getting full - anything that doesn't get a HTTP 200 from VictoriaLogs; logs get stored to disk to be processed at intervals.
Streams are set to separate application runs to instances of it running on different servers.
Usage
package main
import (
// External
"git.gibonuddevalla.se/go/vlog"
// Standard
"log/slog"
"os"
"time"
)
func main() {
opts := slog.HandlerOptions{
Level: slog.LevelInfo, // Minimum level to display.
}
handler := vlog.New(
os.Stdout,
opts,
"/tmp/vlog_spool", // Spool directory when logs can't be sent.
"https://log.hum.se/", // URL to VictoriaLogs instance.
"vlog", // Application name.
"srv01", // System/server that runs the instance.
"dev", // Instance name.
)
log := slog.New(handler)
for {
log.Warn("server", "foo", "bar", "baz", 123)
time.Sleep(time.Second * 1)
}
}
Logging stream
The stream is created with:
- application name.
- system name running the software.
- instance name (like dev or prod).
- run, which is automated to YYMMDD_HHMMSS when application is started.
These are prefixed with log, see JSON data below.
Logging data
Application log attributes (foo, baz in the example code) are added to the top level log entry.
The vlog library adds go build information (git repo and such) and a runtime trace when sending logs with level warn, warn or error.
The info level is excepted to this since it would probably be used the most for regular data that wouldn't lead to any troubleshooting. Making the trace eats a bit of performance.
{
"_time": "2026-02-14T08:43:02.760194943Z",
"_stream_id": "0000000000000000926515688d74d64c8facef73b36a02b5",
"_stream": "{log.application=\"vlog\",log.instance=\"dev\",log.run=\"260214_094242\",log.system=\"srv01\"}",
"_msg": "server",
"baz": "123",
"foo": "bar",
"log.application": "vlog",
"log.instance": "dev",
"log.level": "WARN",
"log.run": "260214_094242",
"log.system": "srv01",
"log.build": "{\"GoVersion\":\"go1.25.4\",\"Path\":\"hum\",\"Main\":{\"Path\":\"hum\",\"Version\":\"(devel)\"},\"Deps\":[{\"Path\":\"git.gibonuddevalla.se/go/vlog\",\"Version\":\"(devel)\"}],\"Settings\":[{\"Key\":\"-buildmode\",\"Value\":\"exe\"},{\"Key\":\"-compiler\",\"Value\":\"gc\"},{\"Key\":\"CGO_ENABLED\",\"Value\":\"1\"},{\"Key\":\"CGO_CFLAGS\"},{\"Key\":\"CGO_CPPFLAGS\"},{\"Key\":\"CGO_CXXFLAGS\"},{\"Key\":\"CGO_LDFLAGS\"},{\"Key\":\"GOARCH\",\"Value\":\"amd64\"},{\"Key\":\"GOOS\",\"Value\":\"linux\"},{\"Key\":\"GOAMD64\",\"Value\":\"v1\"}]}",
"log.trace": "goroutine 1 [running]:\nruntime/debug.Stack()\n\t/usr/local/go/src/runtime/debug/stack.go:26 +0x5e\ngit.gibonuddevalla.se/go/vlog.(*VictoriaHandler).queue(_, {{0xc25c2b45ad4fa77f, 0x4a9205feb, 0x9bf140}, {0x7339a5, 0x6}, 0x4, 0x65125f, {{{0x73345d, 0x3}, ...}, ...}, ...})\n\t/tmp/foo/vlog/lib.go:146 +0x65\ngit.gibonuddevalla.se/go/vlog.VictoriaHandler.Handle({0xc000074080, {0x7335b3, 0x4}, {0x733793, 0x5}, {0x733466, 0x3}, {0x73842d, 0x14}, {0x7aec30, ...}, ...}, ...)\n\t/tmp/foo/vlog/lib.go:75 +0x65\nlog/slog.(*Logger).log(0xc0000f3f30, {0x7aebf8?, 0x9e03c0?}, 0x4, {0x7339a5, 0x6}, {0xc0000f3ef0, 0x4, 0x4})\n\t/usr/local/go/src/log/slog/logger.go:256 +0x208\nlog/slog.(*Logger).Warn(...)\n\t/usr/local/go/src/log/slog/logger.go:219\nmain.main()\n\t/tmp/foo/hum/main.go:31 +0x1a6\n"
}