yet another golang logging library
go
  • Go 93.8%
  • Makefile 6.2%
elij cacbec6ab4
All checks were successful
unit-tests / Build (push) Successful in 36s
update ci branch names
2026-04-20 17:37:56 -07:00
.forgejo/workflows update ci branch names 2026-04-20 17:37:56 -07:00
.github/workflows update CI 2025-09-21 20:01:58 -07:00
testdata fixes 2023-08-23 18:08:18 -07:00
.errcheck-excludes.txt some clean ups 2025-01-21 12:21:44 -08:00
.gitignore some clean ups 2025-01-21 12:21:44 -08:00
CHANGELOG.md add testing logger helper 2023-08-27 11:57:01 -07:00
default_logger.go fixes 2023-08-23 18:08:18 -07:00
doc.go move to codeberg 2025-12-16 17:18:37 -08:00
flagset.go just return boolean directly 2023-08-16 15:03:38 -07:00
flagset_test.go add testing logger helper 2023-08-27 11:57:01 -07:00
formatwriter_json.go some clean ups 2025-01-21 12:21:44 -08:00
formatwriter_json_bench_test.go add EmitAttrs and Attrs to avoid some Map overhead 2023-08-23 17:17:05 -07:00
formatwriter_json_test.go move to codeberg 2025-12-16 17:18:37 -08:00
formatwriter_plain.go some clean ups 2025-01-21 12:21:44 -08:00
formatwriter_plain_bench_test.go add EmitAttrs and Attrs to avoid some Map overhead 2023-08-23 17:17:05 -07:00
formatwriter_plain_test.go move to codeberg 2025-12-16 17:18:37 -08:00
formatwriter_structured.go some clean ups 2025-01-21 12:21:44 -08:00
formatwriter_structured_bench_test.go add EmitAttrs and Attrs to avoid some Map overhead 2023-08-23 17:17:05 -07:00
formatwriter_structured_test.go move to codeberg 2025-12-16 17:18:37 -08:00
go.mod move to codeberg 2025-12-16 17:18:37 -08:00
go.sum move to codeberg 2025-12-16 17:18:37 -08:00
LICENSE.md update license 2019-04-30 23:18:50 -07:00
logattr.go add creation method for Attr to avoid warnings 2023-08-23 18:20:09 -07:00
logattr_test.go move to codeberg 2025-12-16 17:18:37 -08:00
logger.go fixes 2023-08-23 18:08:18 -07:00
logger_bench_test.go updates for gotest.tools/v3 2023-08-16 15:32:31 -07:00
logger_test.go move to codeberg 2025-12-16 17:18:37 -08:00
logmap.go tests and performance improvements 2016-05-22 20:32:53 -07:00
logmap_test.go move to codeberg 2025-12-16 17:18:37 -08:00
Makefile some clean ups 2025-01-21 12:21:44 -08:00
README.md add ci 2025-12-17 15:41:48 -08:00
slicebuffer.go some clean ups 2025-01-21 12:21:44 -08:00
time.go move to codeberg 2025-12-16 17:18:37 -08:00
time_test.go move to codeberg 2025-12-16 17:18:37 -08:00
tlogger.go some clean ups 2025-01-21 12:21:44 -08:00
tlogger_test.go add testing logger helper 2023-08-27 11:57:01 -07:00

mlog

Build Status GoDoc Go Report Card

About

A purposefully basic logging library for Go (>= 1.16).

mlog only has 3 logging levels: Debug, Info, and Fatal.

Why only 3 levels?

Dave Cheney wrote a great post, that made me rethink my own approach to logging, and prompted me to start writing mlog.

How does it work?

Logging methods are:

  • Debug - conditionally (if debug is enabled) logs message at level "debug".
  • Debugf - similar to Debug, but supports printf formatting.
  • Debugm - similar to Debug, but logs an mlog.Map as extra data.
  • Info - logs message at level "info". Print is an alias for Info.
  • Infof - similar to Info, but supports printf formatting. Printf is an alias for Infof.
  • Infom - similar to Info, but logs an mlog.Map as extra data. Printm is an alias for Infom.
  • Fatal - logs message at level "fata", then calls os.Exit(1).
  • Fatalf - similar to Fatal, but supports printf formatting.
  • Fatalm - similar to Fatal, but logs an mlog.Map as extra data.

That's it!

For more info, check out the docs.

Usage

import (
    "bytes"

    "codeberg.org/dropwhile/mlog"
)

func main() {
    mlog.Info("this is a log")

    mlog.Infom("this is a log with more data", mlog.Map{
        "interesting": "data",
        "something":   42,
    })

    thing := mlog.Map(
        map[string]interface{}{
            "what‽":       "yup",
            "this-works?": "as long as it is a mlog.Map",
        },
    )

    mlog.Infom("this is also a log with more data", thing)

    mlog.Debug("this won't print")

    // set flags for the default logger
    // alternatively, you can create your own logger
    // and supply flags at creation time
    mlog.SetFlags(mlog.Ltimestamp | mlog.Ldebug)

    mlog.Debug("now this will print!")

    mlog.Debugm("can it print?", mlog.Map{
        "how_fancy": []byte{'v', 'e', 'r', 'y', '!'},
        "this_too":  bytes.NewBuffer([]byte("if fmt.Print can print it!")),
    })

    // you can use a more classical Printf type log method too.
    mlog.Debugf("a printf style debug log: %s", "here!")
    mlog.Infof("a printf style info log: %s", "here!")

    // how about logging in json?
    mlog.SetEmitter(&mlog.FormatWriterJSON{})
    mlog.Infom("something", mlog.Map{
        "one": "two",
        "three":  3,
    })

    mlog.Fatalm("time for a nap", mlog.Map{"cleanup": false})
}

Output:

time="2016-04-29T19:59:11.474362716-07:00" level="I" msg="this is a log"
time="2016-04-29T19:59:11.474506079-07:00" level="I" msg="this is a log with more data" interesting="data" something="42"
time="2016-04-29T19:59:11.474523514-07:00" level="I" msg="this is also a log with more data" this-works?="as long as it is a mlog.Map" what‽="yup"
time="2016-04-29T19:59:11.474535676-07:00" msg="now this will print!"
time="2016-04-29T19:59:11.474542467-07:00" msg="can it print?" how_fancy="[118 101 114 121 33]" this_too="if fmt.Print can print it!"
time="2016-04-29T19:59:11.474551625-07:00" msg="a printf style debug log: here!"
time="2016-04-29T19:59:11.474578991-07:00" msg="a printf style info log: here!"
{"time": "2016-04-29T19:59:11.474583762-07:00", "msg": "something" "extra": {"one": "two", "three": "3"}}
{"time": "2016-04-29T19:59:11.474604928-07:00", "msg": "time for a nap" "extra": {"cleanup": "false"}}
exit status 1

License

Released under the ISC license. See LICENSE.md file for details.