sloglint

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 12, 2023 License: MPL-2.0 Imports: 12 Imported by: 2

README

sloglint

checks pkg.go.dev goreportcard codecov

A Go linter that ensures consistent code style when using log/slog.

📌 About

The log/slog API allows two different types of arguments: key-value pairs and attributes. While people may have different opinions about which one is better, most seem to agree on one thing: it should be consistent. With sloglint you can enforce various rules for log/slog based on your preferred code style.

🚀 Features

  • Enforce not mixing key-value pairs and attributes (default)
  • Enforce using either key-value pairs only or attributes only (optional)
  • Enforce using methods that accept a context (optional)
  • Enforce using static log messages (optional)
  • Enforce using constants instead of raw keys (optional)
  • Enforce a single key naming convention (optional)
  • Enforce putting arguments on separate lines (optional)

📦 Install

sloglint is integrated into golangci-lint, and this is the recommended way to use it.

To enable the linter, add the following lines to .golangci.yml:

linters:
  enable:
    - sloglint

Alternatively, you can download a prebuilt binary from the Releases page to use sloglint standalone.

📋 Usage

Run golangci-lint with sloglint enabled. See the list of available options to configure the linter.

When using sloglint standalone, pass the options as flags of the same name.

No mixed arguments

The no-mixed-args option causes sloglint to report mixing key-values pairs and attributes within a single function call:

slog.Info("a user has logged in", "user_id", 42, slog.String("ip_address", "192.0.2.0")) // sloglint: key-value pairs and attributes should not be mixed

It is enabled by default.

Key-value pairs only

The kv-only option causes sloglint to report any use of attributes:

slog.Info("a user has logged in", slog.Int("user_id", 42)) // sloglint: attributes should not be used
Attributes only

In contrast, the attr-only option causes sloglint to report any use of key-value pairs:

slog.Info("a user has logged in", "user_id", 42) // sloglint: key-value pairs should not be used
Context only

Some slog.Handler implementations make use of the given context.Context (e.g. to access context values). For them to work properly, you need to pass a context to all logger calls. The context-only option causes sloglint to report the use of methods without a context:

slog.Info("a user has logged in") // sloglint: methods without a context should not be used

This report can be fixed by using the equivalent method with the Context suffix:

slog.InfoContext(ctx, "a user has logged in")
Static messages

To get the most out of structured logging, you may want to require log messages to be static. The static-msg option causes sloglint to report non-static messages:

slog.Info(fmt.Sprintf("a user with id %d has logged in", 42)) // sloglint: message should be a string literal or a constant

The report can be fixed by moving dynamic values to arguments:

slog.Info("a user has logged in", "user_id", 42)
No raw keys

To prevent typos, you may want to forbid the use of raw keys altogether. The no-raw-keys option causes sloglint to report the use of strings as keys (including slog.Attr calls, e.g. slog.Int("user_id", 42)):

slog.Info("a user has logged in", "user_id", 42) // sloglint: raw keys should not be used

This report can be fixed by using either constants...

const UserId = "user_id"

slog.Info("a user has logged in", UserId, 42)

...or custom slog.Attr constructors:

func UserId(value int) slog.Attr { return slog.Int("user_id", value) }

slog.Info("a user has logged in", UserId(42))

[!TIP] Such helpers can be automatically generated for you by the sloggen tool. Give it a try too!

Key naming convention

To ensure consistency in logs, you may want to enforce a single key naming convention. The key-naming-case option causes sloglint to report keys written in a case other than the given one:

slog.Info("a user has logged in", "user-id", 42) // sloglint: keys should be written in snake_case

Possible values are snake, kebab, camel, or pascal.

Arguments on separate lines

To improve code readability, you may want to put arguments on separate lines, especially when using key-value pairs. The args-on-sep-lines option causes sloglint to report 2+ arguments on the same line:

slog.Info("a user has logged in", "user_id", 42, "ip_address", "192.0.2.0") // sloglint: arguments should be put on separate lines

This report can be fixed by reformatting the code:

slog.Info("a user has logged in",
    "user_id", 42,
    "ip_address", "192.0.2.0",
)

Documentation

Overview

Package sloglint implements the sloglint analyzer.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New(opts *Options) *analysis.Analyzer

New creates a new sloglint analyzer.

Types

type Options

type Options struct {
	NoMixedArgs    bool   // Enforce not mixing key-value pairs and attributes (default true).
	KVOnly         bool   // Enforce using key-value pairs only (overrides NoMixedArgs, incompatible with AttrOnly).
	AttrOnly       bool   // Enforce using attributes only (overrides NoMixedArgs, incompatible with KVOnly).
	ContextOnly    bool   // Enforce using methods that accept a context.
	StaticMsg      bool   // Enforce using static log messages.
	NoRawKeys      bool   // Enforce using constants instead of raw keys.
	KeyNamingCase  string // Enforce a single key naming convention ("snake", "kebab", "camel", or "pascal").
	ArgsOnSepLines bool   // Enforce putting arguments on separate lines.
}

Options are options for the sloglint analyzer.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL