Skip to content

Latest commit

 

History

History
executable file
·
108 lines (80 loc) · 5.77 KB

logger.md

File metadata and controls

executable file
·
108 lines (80 loc) · 5.77 KB

Loggr: Advanced Structured Logger for Go

Overview

Slog is a highly configurable logging library for Go that supports structured and color-coded log outputs. Designed for both development and production use, Slog offers detailed control over log levels, custom formatting, and supports performance insights by including time stamps and source locations.

Features

  • Multiple Log Levels: Supports various log levels including Debug, Info, Trace, Warn, Error, and Fatal.
  • Color-Coded Output: Utilizes gookit/color for color-coded log messages that enhance readability.
  • Structured Logging: Logs can be structured as JSON for easy parsing and processing in log management systems.
  • Dynamic Log Level Control: Log levels can be adjusted at runtime through environment variables (GODEBUG).
  • Detailed Debug Information: Includes timestamps, log levels, package information, and code locations in logs.
  • Error Handling Helpers: Provides helpers for checking and logging errors (Chk function).
  • Customizable Output: Supports redirection of log output to any io.Writer.

Dev machine filesystem hygiene

It is advisable to take care with the location you store your source code from which you build released binaries that it not leak information.

My personal recommendation is to follow the old "GOPATH" structure.

Make a folder at the root of your user home directory src, and then create directories for each git hosting URL, such as github.com and then place your repositories in a directory tree that matches the URLs, as with this one src/mleku.online/git/log. Then, as root, create a folder in the root with the path /src and then link the root URL directories down from your home folder to the /src in the root.

In this way, the log prints will then show (as my releases for this one) /src/mleku.online/git/log/... for code locations, and you will be able to click them in the terminal of editors like Goland and jump to the place where the log statement is found.

The timestamp is in seconds, with 9 decimal places to represent nanoseconds after the decimal point.

The format is designed for optimal readability by humans while maintaining readability by machines, unsurprisingly similar to Go syntax itself and for the same reasons.

This will also enable bulk capture and filtering of the logs. They are written by default to os.Stderr to appear as expected in the systemd journal if you run the application this way.

The writer is a singleton value (package local variable) so if you create a writer that logs to disk or streams the logs to a socket or whatever, in the one application the same writer will be used and funnel all the output through it.

Developer notes about the logger

Due to its high performance at rendering and its programmable custom hyperlink capability, VTE based terminal Tilix is the best option for Linux developers, if you are on windows or mac, there is options but the main author of this repo doesn't and refuses to use such abominations.

The performance of the Goland terminal, which does this by default and manages its relative path interpretation based on the current opened project, is abysmal if there is long lines, probably due to it being written in highly abstracted Java rather than C like VTE's rexept hyperlink engine.

So if you use VSCode or other non-Goland IDE, you may want to change the invocation in the following command and script to fit the relevant too; the provided versions here work with Goland so long as it has had a goland launch script deployed to your $PATH somewhere.

The following are a pair of custom hyperlink specifications, extracted using dconf-editor, from the path /com/gexperts/Tilix/custom-hyperlinks that works to give you absolute and relative paths when you are using the slog logger that is used throughout this project and also on several of the dependencies that live at the same git hosting address:

[
  '([/]([a-zA-Z@0-9-_.]+/)+([a-zA-Z@0-9-_.]+)):([0-9]+)$,goland --line $4 $1,false',
  '([^/]([a-zA-Z@0-9-_.]+/)+([a-zA-Z@0-9-_.]+)):([0-9]+),openhyperlink $1 $4,false'
]

Two additional small scripts need to be added to your path and marked executable in order to allow you to change the absolute path prefix in the second of these two entries:

openhyperlink should look like this:

#!/usr/bin/bash
goland --line $2 $(cat ~/.currpath)/$1

and to set that .currpath file to contain a useful path:

currpath

#!/usr/bin/bash
echo $(pwd)>~/.currpath
echo .currpath set to $(< ~/.currpath)

This will then assume any relative code locations like app/broadcasting.go:32 will have the value from ~/.currpath prefixed in, and you can invoke currpath at the root of your repository in order to have the relative paths work.

The logger doesn't generate relative paths, as this is an additional complexity between the logger code and the environment that is not worth doing anything about, you could add an invocation of currpath to your . bashrc and when you open the terminal in that location it would automatically be set, but if you open a terminal elsewhere it would overwrite it.

The reason for having the relative paths is that when you execute your code if there is syntax or other errors that prevent compilation, the Go tooling prints them as module-relative paths, which also may get confusing if you have got a project with multiple go modules in it.

I personally believe that there should be one go.mod in a project, as I have seen the results of this in the btcd and lnd projects and it has led to multiple cases of self-imports of different versions from the same codebase, which is an abomination and the go modules equivalent of spaghetti - how are you going to debug that mess?