Skip to content

Commit

Permalink
V8 RC1 (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dean Karn authored May 31, 2022
1 parent c55d790 commit 50e31b8
Show file tree
Hide file tree
Showing 41 changed files with 491 additions and 4,189 deletions.
51 changes: 51 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
on:
push:
branches:
- master
pull_request:
name: Test
jobs:
test:
strategy:
matrix:
go-version: [1.18.x]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}

- name: Checkout code
uses: actions/checkout@v3

- name: Restore Cache
uses: actions/cache@v3
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-v1-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-v1-go-
- name: Test
run: go test -race -covermode=atomic -coverprofile="profile.cov" ./...

- name: Send Coverage
if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.18.x'
uses: shogo82148/actions-goveralls@v1
with:
path-to-profile: profile.cov

golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v3
with:
go-version: 1.18.x
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.46.2
26 changes: 0 additions & 26 deletions .travis.yml

This file was deleted.

28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [8.0.0] - 2022-05-30
### Added
- Automatic file, line and package addition to error log when using `WithError`.

### Removed
- Handlers with dependencies; now encouraged to be separate packages.

### Changed
- Byte Pool now exposed through function only.
- Default error format function and output of wrapped error information.
- Tags & Types are now deduplicated in the default error format function.
- Updated to latest deps.
- CI to use GitHub Actions.
- Documentation.
- Default timestamp format to RFC3339Nano.
- Console logger uses builder pattern.


[Unreleased]: https://github.com/go-playground/log/compare/v8.0.0...HEAD
[8.0.0]: https://github.com/go-playground/log/compare/v7.0.2...v8.0.0
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2018 Go Playground
Copyright (c) 2022 Go Playground

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
12 changes: 9 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
GOCMD=GO111MODULE=on go

lint:
go vet ./...
linters-install:
@golangci-lint --version >/dev/null 2>&1 || { \
echo "installing linting tools..."; \
brew install golangci-lint; \
}

lint: linters-install
@golangci-lint run

test:
$(GOCMD) test -cover -race ./...

bench:
$(GOCMD) test -run=NONE -bench=. -benchmem ./...

.PHONY: test lint
.PHONY: test lint linters-install
104 changes: 40 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,51 @@
## log
<img align="right" src="https://raw.githubusercontent.com/go-playground/log/master/logo.png">![Project status](https://img.shields.io/badge/version-7.0.2-green.svg)
[![Build Status](https://travis-ci.org/go-playground/log.svg?branch=master)](https://travis-ci.org/go-playground/log)
<img align="right" src="https://raw.githubusercontent.com/go-playground/log/master/logo.png">![Project status](https://img.shields.io/badge/version-8.0.0-green.svg)
[![Test](https://github.com/go-playground/log/actions/workflows/go.yml/badge.svg)](https://github.com/go-playground/log/actions/workflows/go.yml)
[![Coverage Status](https://coveralls.io/repos/github/go-playground/log/badge.svg?branch=master)](https://coveralls.io/github/go-playground/log?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/log)](https://goreportcard.com/report/github.com/go-playground/log)
[![GoDoc](https://godoc.org/github.com/go-playground/log?status.svg)](https://godoc.org/github.com/go-playground/log)
![License](https://img.shields.io/dub/l/vibe-d.svg)
[![Gitter](https://badges.gitter.im/go-playground/log.svg)](https://gitter.im/go-playground/log?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)

Log is a simple, highly configurable, Structured Logging library

Why another logging library?
----------------------------
There's allot of great stuff out there, but also thought a log library could be made more configurable using per handler log levels.
There's a lot of great stuff out there, but this library contains a number of unique features noted below using *.

Features
--------
- [x] Logger is simple, only logic to create the log entry and send it off to the handlers and they take it from there.
- [x] Ability to specify which log levels get sent to each handler
- [x] Built-in console, syslog, http, HipChat, json and email handlers
- [x] Logger is simple, only logic to create the log entry and send it off to the handlers, they take it from there.
- [x] Handlers are simple to write + easy to register + easy to remove
- [x] Default logger for quick prototyping and cli applications. It is automatically removed when you register one of your own.
- [x] Logger is a singleton ( one of the few instances a singleton is desired ) so the root package registers which handlers are used and any libraries just follow suit.
- [x] Convenient context helpers `GetContext` & `SetContext`
- [x] Works with go-playground/errors extracting types and tags when used with `WithError`, is the default
- [x] Works with pkg/errors when used with `WithError`, must set using `SetWithErrFn`
- [x] Works with segmentio/errors-go extracting types and tags when used with `WithError`, must set using `SetWithErrFn`
- [x] *Ability to specify which log levels get sent to each handler
- [x] *Handlers & Log Levels are configurable at runtime.
- [x] *`WithError` automatically extracts and adds file, line and package in error output.
- [x] *Convenient context helpers `GetContext` & `SetContext`
- [x] *Works with go-playground/errors extracting wrapped errors, types and tags when used with the `WithError` interface. This is the default but configurable to support more or other error libraries using `SetWithErrorFn`.
- [x] *Default logger for quick prototyping and cli applications. It is automatically removed when you register one of your own.

Installation
-----------

Use go get

```go
go get -u github.com/go-playground/log/v7
go get github.com/go-playground/log/v8@latest
```

Usage
------
import the log package, it is recommended to set up at least one handler, but there is a default console logger.
import the log package.
```go
package main

import (
"errors"
"io"

"github.com/go-playground/log/v7"
"github.com/go-playground/log/v7/handlers/console"
"github.com/go-playground/errors/v5"
"github.com/go-playground/log/v8"
)

func main() {
// There is a default logger with the same settings
// once any other logger is registered the default logger is removed.
cLog := console.New(true)
log.AddHandler(cLog, log.AllLevels...)

// Trace
defer log.WithTrace().Info("time to run")

Expand All @@ -66,10 +58,15 @@ func main() {
log.Alert("alert")
// log.Fatal("fatal") // this will call os.Exit(1)

err := errors.New("the is an error")
err := errors.New("this is the inner error").AddTags(errors.T("inner", "tag"))
err = errors.Wrap(err, "this is the wrapping error").AddTags(errors.T("outer", "tag"))

// logging with fields can be used with any of the above
log.WithError(err).WithFields(log.F("key", "value")).Info("test info")

// log unwrapped error
log.WithError(io.EOF).Error("unwrapped error")

// predefined global fields
log.WithDefaultFields(log.Fields{
{"program", "test"},
Expand All @@ -96,7 +93,7 @@ import (
"bytes"
"fmt"

"github.com/go-playground/log/v7"
"github.com/go-playground/log/v8"
)

// CustomHandler is your custom handler
Expand All @@ -123,15 +120,14 @@ func (c *CustomHandler) Log(e log.Entry) {
b.WriteString(e.Message)

for _, f := range e.Fields {
fmt.Fprintf(b, " %s=%v", f.Key, f.Value)
_, _ = fmt.Fprintf(b, " %s=%v", f.Key, f.Value)
}
fmt.Println(b.String())
}

func main() {

cLog := new(CustomHandler)

log.AddHandler(cLog, log.AllLevels...)

// Trace
Expand All @@ -149,48 +145,34 @@ func main() {
// logging with fields can be used with any of the above
log.WithField("key", "value").Info("test info")
}

```

Log Level Definitions
---------------------

**DebugLevel** - Info useful to developers for debugging the application, not useful during operations.

**InfoLevel** - Normal operational messages - may be harvested for reporting, measuring throughput, etc. - no action required.

**NoticeLevel** - Normal but significant condition. Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot potential problems - no immediate action required.

**WarnLevel** - Warning messages, not an error, but indication that an error will occur if action is not taken, e.g. file system 85% full - each item must be resolved within a given time.

**ErrorLevel** - Non-urgent failures, these should be relayed to developers or admins; each item must be resolved within a given time.

**PanicLevel** - A "panic" condition usually affecting multiple apps/servers/sites. At this level it would usually notify all tech staff on call.

**AlertLevel** - Action must be taken immediately. Should be corrected immediately, therefore notify staff who can fix the problem. An example would be the loss of a primary ISP connection.

**FatalLevel** - Should be corrected immediately, but indicates failure in a primary system, an example is a loss of a backup ISP connection. ( same as SYSLOG CRITICAL )
| Level | Description |
|--------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Debug | Info useful to developers for debugging the application, not useful during normal operations. |
| Info | Normal operational messages which may be harvested for reporting, measuring throughput, etc. no action required. |
| Notice | Normal but significant condition. Events that are unusual but not error conditions eg. might be summarized in an email to developers or admins to spot potential problems - no immediate action required. |
| Warn | Warning messages, not an error, but indication that an error will occur if action is not taken, e.g. file system 85% full. Each item must be resolved within a given time. |
| Error | Non-urgent failures, these should be relayed to developers or admins; each item must be resolved within a given time. |
| Panic | A "panic" condition usually affecting multiple apps/servers/sites. At this level it would usually notify all tech staff on call. |
| Alert | Action must be taken immediately. Should be corrected immediately, therefore notify staff who can fix the problem. An example would be the loss of a primary ISP connection. |
| Fatal | Should be corrected immediately, but indicates failure in a primary system, an example is a loss of a backup ISP connection. ( same as SYSLOG CRITICAL ) |

Handlers
-------------
Pull requests for new handlers are welcome, please provide test coverage is all I ask.
Pull requests for new handlers are welcome when they don't pull in dependencies, it is preferred to have a dedicated package in this case.

| Handler | Description | Docs |
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| console | Allows for log messages to be sent to a any writer, default os.Stderr | [![GoDoc](https://godoc.org/github.com/go-playground/log/handlers/console?status.svg)](https://godoc.org/github.com/go-playground/log/handlers/console) |
| syslog | Allows for log messages to be sent via syslog, includes TLS support. | [![GoDoc](https://godoc.org/github.com/go-playground/log/handlers/syslog?status.svg)](https://godoc.org/github.com/go-playground/log/handlers/syslog) |
| http | Allows for log messages to be sent via http. Can use the HTTP handler as a base for creating other handlers requiring http transmission. | [![GoDoc](https://godoc.org/github.com/go-playground/log/handlers/http?status.svg)](https://godoc.org/github.com/go-playground/log/handlers/http) |
| email | Allows for log messages to be sent via email. | [![GoDoc](https://godoc.org/github.com/go-playground/log/handlers/email?status.svg)](https://godoc.org/github.com/go-playground/log/handlers/email) |
| hipchat | Allows for log messages to be sent to a hipchat room. | [![GoDoc](https://godoc.org/github.com/go-playground/log/handlers/http/hipchat?status.svg)](https://godoc.org/github.com/go-playground/log/handlers/http/hipchat) |
| json | Allows for log messages to be sent to any wrtier in json format. | [![GoDoc](https://godoc.org/github.com/go-playground/log/handlers/json?status.svg)](https://godoc.org/github.com/go-playground/log/handlers/json) |

Package Versioning
----------
I'm jumping on the vendoring bandwagon, you should vendor this package as I will not
be creating different version with gopkg.in like allot of my other libraries.

Why? because my time is spread pretty thin maintaining all of the libraries I have + LIFE,
it is so freeing not to worry about it and will help me keep pouring out bigger and better
things for you the community.
This package strictly adheres to semantic versioning guidelines.

Benchmarks
----------
Expand All @@ -200,14 +182,8 @@ make one log library better than another!
```go
go test --bench=. -benchmem=true
goos: darwin
goarch: amd64
pkg: github.com/go-playground/log/benchmarks
BenchmarkLogConsoleTenFieldsParallel-8 2000000 946 ns/op 1376 B/op 16 allocs/op
BenchmarkLogConsoleSimpleParallel-8 5000000 296 ns/op 200 B/op 4 allocs/op
goarch: arm64
pkg: github.com/go-playground/log/v8/benchmarks
BenchmarkLogConsoleTenFieldsParallel-8 2392591 503.3 ns/op 648 B/op 12 allocs/op
BenchmarkLogConsoleSimpleParallel-8 4595101 269.9 ns/op 56 B/op 2 allocs/op
```

Special Thanks
--------------
Special thanks to the following libraries that inspired
* [logrus](https://github.com/Sirupsen/logrus) - Structured, pluggable logging for Go.
* [apex log](https://github.com/apex/log) - Structured logging package for Go.
11 changes: 9 additions & 2 deletions _examples/basic/main.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package main

import (
"io"

"github.com/go-playground/errors/v5"
"github.com/go-playground/log/v7"
"github.com/go-playground/log/v8"
)

func main() {
Expand All @@ -18,10 +20,15 @@ func main() {
log.Alert("alert")
// log.Fatal("fatal") // this will call os.Exit(1)

err := errors.New("the is an error")
err := errors.New("this is the inner error").AddTags(errors.T("inner", "tag"))
err = errors.Wrap(err, "this is the wrapping error").AddTags(errors.T("outer", "tag"))

// logging with fields can be used with any of the above
log.WithError(err).WithFields(log.F("key", "value")).Info("test info")

// log unwrapped error
log.WithError(io.EOF).Error("unwrapped error")

// predefined global fields
log.WithDefaultFields(log.Fields{
{"program", "test"},
Expand Down
5 changes: 2 additions & 3 deletions _examples/custom-handler/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"bytes"
"fmt"

"github.com/go-playground/log/v7"
"github.com/go-playground/log/v8"
)

// CustomHandler is your custom handler
Expand All @@ -31,15 +31,14 @@ func (c *CustomHandler) Log(e log.Entry) {
b.WriteString(e.Message)

for _, f := range e.Fields {
fmt.Fprintf(b, " %s=%v", f.Key, f.Value)
_, _ = fmt.Fprintf(b, " %s=%v", f.Key, f.Value)
}
fmt.Println(b.String())
}

func main() {

cLog := new(CustomHandler)

log.AddHandler(cLog, log.AllLevels...)

// Trace
Expand Down
Loading

0 comments on commit 50e31b8

Please sign in to comment.