kemba

package module
v1.2.1 Latest Latest
Warning

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

Go to latest
Published: Jan 9, 2024 License: MIT Imports: 12 Imported by: 34

README

kemba

Go Report Card Coverage Status go.dev reference Mentioned in Awesome Go

debug logging tool inspired by https://github.com/visionmedia/debug

Why is it named kemba?

debug is more generally considered to be runtime/debug within Go. Since this takes heavy inspiration from my experiences using the npm module debug I wanted to find a word that was somewhat connected to the inspiration. According to Google translate "debug" in English translated to Icelandic results in "kemba".

Usage

The kemba logger reads the DEBUG and KEMBA environment variables to determine if a log line should be output. The logger outputs to STDERR.

When it is not set, the logger will immediately return, taking no action.

When the value is set (ex. DEBUG=example:*,tool:details and/or KEMBA=plugin:fxn:start), the logger will determine if it should be enabled when instantiated.

The value of these flags can be a simple regex alternative where a wildcard (*) are replaced with .* and all terms are prepended with ^ and appended with $. If a term does not include a wildcard, then an exact match it required.

Example of a wildcard in the middle of a tag string: DEBUG=example:*:fxn will match tags like [example:tag1:fxn, example:tag2:fxn, example:anything:fxn, ...]

To disabled colors, set the NOCOLOR environment variable to any value.

image

package main

import (
    "time"

	"github.com/clok/kemba"
)

type myType struct {
	a, b int
}

// When the DEBUG or KEMBA environment variable is set to DEBUG=example:* the kemba logger will output to STDERR
func main () {
    k := kemba.New("example:tag")
	
    var x = []myType{
    	{1, 2},
    	{3, 4},
    }
    k.Printf("%#v", x)
    // Output to os.Stderr
    // example:tag []main.myType{main.myType{a:1, b:2}, main.myType{a:3, b:4}} +0s

    // Artificial delay to demonstrate the time tagging
    time.Sleep(250 * time.Millisecond)
    k.Printf("%# v", x)
    k.Println(x)

    // Artificial delay to demonstrate the time tagging
    time.Sleep(100 * time.Millisecond)
    k.Log(x)
    // All result in the same output to os.Stderr
    // example:tag []main.myType{ +XXms
    // example:tag     {a:1, b:2},
    // example:tag     {a:3, b:4},
    // example:tag }

    // Create a new logger with an extended tag
    k1 := k.Extend("1")
    k1.Println("a string", 12, true)
    // Output to os.Stderr
    // example:tag:1 a string +0s
    // example:tag:1 int(12)
    // example:tag:1 bool(true)
}

Development

  1. Fork the clok/kemba repo
  2. Use go >= 1.16
  3. Branch & Code
  4. Run linters 🧹 golangci-lint run
  5. Commit with a Conventional Commit
  6. Open a PR

Documentation

Overview

Example
_ = os.Setenv("DEBUG", "example:*")
// OR
// _ = os.Setenv("KEMBA", "example:*")
k := New("example:tag")

type myType struct {
	a, b int
}

var x = []myType{{1, 2}, {3, 4}}
k.Printf("%#v", x)
// Output to os.Stderr
// example:tag []main.myType{main.myType{a:1, b:2}, main.myType{a:3, b:4}} +0s

// Artificial delay to demonstrate the time tagging
time.Sleep(250 * time.Millisecond)
k.Printf("%# v", x)
k.Println(x)

// Artificial delay to demonstrate the time tagging
time.Sleep(100 * time.Millisecond)
k.Log(x)
// All result in the same output to os.Stderr
// example:tag []main.myType{ +XXs
// example:tag     {a:1, b:2},
// example:tag     {a:3, b:4},
// example:tag }

// Create a new extended logger with a new tag
k1 := k.Extend("1")
k1.Println("a string", 12, true)
// Output to os.Stderr
// example:tag:1 a string +0s
// example:tag:1 int(12)
// example:tag:1 bool(true)
_ = os.Setenv("DEBUG", "")
Output:

example:tag []kemba.myType{kemba.myType{a:1, b:2}, kemba.myType{a:3, b:4}} +0s
example:tag []kemba.myType{ +250ms
example:tag     {a:1, b:2},
example:tag     {a:3, b:4},
example:tag }
example:tag []kemba.myType{ +0s
example:tag     {a:1, b:2},
example:tag     {a:3, b:4},
example:tag }
example:tag []kemba.myType{ +105ms
example:tag     {a:1, b:2},
example:tag     {a:3, b:4},
example:tag }
example:tag:1 a string +0s
example:tag:1 int(12)
example:tag:1 bool(true)

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func PickColor added in v0.7.0

func PickColor(tag string) *color.Color256

PickColor will return the same color based on input string.

We want to pick the same color for a given tag to ensure consistent output behavior.

Types

type Kemba

type Kemba struct {
	// contains filtered or unexported fields
}

Kemba is a container struct for the Kemba logger. It used to manage the state of the logger. Currently all properties are not exported.

func New

func New(tag string) *Kemba

New Returns a Kemba logging instance. It will determine if the logger should bypass logging actions or be activated.

func (*Kemba) Extend added in v0.3.0

func (k *Kemba) Extend(tag string) *Kemba

Extend returns a new Kemba logger instance that has appended the provided tag to the original logger.

New logger instance will have original `tag` value delimited with a `:` and appended with the new extended `tag` input.

Example:

k := New("test:original)
k.Log("test")
ke := k.Extend("plugin")
ke.Log("test extended")

Output:

test:original test
test:original:plugin test extended

func (*Kemba) Log

func (k *Kemba) Log(v ...interface{})

Log is an alias to Println

Example
_ = os.Setenv("DEBUG", "test:*")
k := New("test:kemba")
k.Printf("%s", "Hello")

type myType struct {
	a, b int
}
var x = []myType{{1, 2}, {3, 4}, {5, 6}}
k.Log(x)

_ = os.Setenv("DEBUG", "")
Output:

test:kemba Hello +0s
test:kemba []kemba.myType{ +0s
test:kemba     {a:1, b:2},
test:kemba     {a:3, b:4},
test:kemba     {a:5, b:6},
test:kemba }

func (*Kemba) Printf

func (k *Kemba) Printf(format string, v ...interface{})

Printf is a convenience wrapper that will apply pretty.Formatter to the passed in variables.

Calling Printf(f, x, y) is equivalent to fmt.Printf(f, pretty.Formatter(x), pretty.Formatter(y)).

Example
_ = os.Setenv("DEBUG", "test:*")
k := New("test:kemba")
k.Printf("%s", "Hello")

k1 := k.Extend("1")
k1.Printf("%s", "Hello 1")

k2 := k.Extend("2")
k2.Printf("%s", "Hello 2")

k3 := k.Extend("3")
k3.Printf("%s", "Hello 3")

s := []string{"test", "again", "third"}
k2.Printf("%# v", s)

m := map[string]int{
	"test":  1,
	"again": 1337,
	"third": 732,
}
k1.Printf("%# v", m)

type myType struct {
	a int
	b int
}
var x = []myType{{1, 2}, {3, 4}, {5, 6}}
k3.Printf("%# v", x)
k2.Printf("%#v", x)

k.Printf("%#v %#v %#v %#v %#v %#v", m, s, m, s, m, s)
_ = os.Setenv("DEBUG", "")
Output:

test:kemba Hello +0s
test:kemba:1 Hello 1 +0s
test:kemba:2 Hello 2 +0s
test:kemba:3 Hello 3 +0s
test:kemba:2 []string{"test", "again", "third"} +0s
test:kemba:1 map[string]int{"again":1337, "third":732, "test":1} +0s
test:kemba:3 []kemba.myType{ +0s
test:kemba:3     {a:1, b:2},
test:kemba:3     {a:3, b:4},
test:kemba:3     {a:5, b:6},
test:kemba:3 }
test:kemba:2 []kemba.myType{kemba.myType{a:1, b:2}, kemba.myType{a:3, b:4}, kemba.myType{a:5, b:6}} +0s
test:kemba map[string]int{"again":1337, "test":1, "third":732} []string{"test", "again", "third"} map[string]int{"again":1337, "test":1, "third":732} []string{"test", "again", "third"} map[string]int{"again":1337, "test":1, "third":732} []string{"test", "again", "third"} +0s
Example (Compact)
_ = os.Setenv("DEBUG", "test:*")
k := New("test:kemba")

type myType struct {
	a int
	b int
}
var x = []myType{{1, 2}, {3, 4}, {5, 6}}

// NOTE: The "%#v" operand for the Printf format.
k.Printf("%#v", x)
_ = os.Setenv("DEBUG", "")
Output:

test:kemba []kemba.myType{kemba.myType{a:1, b:2}, kemba.myType{a:3, b:4}, kemba.myType{a:5, b:6}} +0s
Example (Expanded)
_ = os.Setenv("DEBUG", "test:*")
k := New("test:kemba")
k.Printf("%s", "Hello")

type myType struct {
	a int
	b int
}
var x = []myType{{1, 2}, {3, 4}, {5, 6}}

// NOTE: The "%# v" operand for the Printf format.
k.Printf("%# v", x)
_ = os.Setenv("DEBUG", "")
Output:

test:kemba Hello +0s
test:kemba []kemba.myType{ +0s
test:kemba     {a:1, b:2},
test:kemba     {a:3, b:4},
test:kemba     {a:5, b:6},
test:kemba }

func (*Kemba) Println

func (k *Kemba) Println(v ...interface{})

Println is a convenience wrapper that will apply pretty.Formatter to the passed in variables.

Calling Println(x, y) is equivalent to fmt.Println(pretty.Formatter(x), pretty.Formatter(y)), but each operand is formatted with "%# v".

Example
_ = os.Setenv("DEBUG", "test:*")
k := New("test:kemba")
k.Printf("%s", "Hello")

type myType struct {
	a int
	b int
}
var x = []myType{{1, 2}, {3, 4}, {5, 6}}
k.Println(x)

_ = os.Setenv("DEBUG", "")
Output:

test:kemba Hello +0s
test:kemba []kemba.myType{ +0s
test:kemba     {a:1, b:2},
test:kemba     {a:3, b:4},
test:kemba     {a:5, b:6},
test:kemba }

Jump to

Keyboard shortcuts

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