Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: go-kit/log
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.2.0
Choose a base ref
...
head repository: go-kit/log
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.2.1
Choose a head ref
  • 3 commits
  • 10 files changed
  • 5 contributors

Commits on Mar 20, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    2b8dc2b View commit details

Commits on Mar 30, 2022

  1. Update CI and add badges to README (#21)

    * Update CI and add badges to README
    
    CI updates:
    
    - Update Go versions (1.17.x and 1.18.x)
    - Update actions versions
    - Use actions for staticcheck
    - Drop golint (deprecated)
    - Report test coverage
    
    * Update README.md
    
    Co-authored-by: Peter Bourgon <[email protected]>
    
    * Update README.md
    
    Co-authored-by: Peter Bourgon <[email protected]>
    
    * Add staticcheck configuration file
    
    * Add package doc comment to syslog package
    
    Co-authored-by: Peter Bourgon <[email protected]>
    ChrisHines and peterbourgon authored Mar 30, 2022
    Copy the full SHA
    3752ef7 View commit details

Commits on Apr 27, 2022

  1. Allow to configure allowed levels by string value (#22)

    * feat: allow to configure level from string
    
    * fix staticcheck violation
    
    * fix UTs
    
    * fix: apply suggested changes
    
    * fix: apply some of the suggested changes
    
    * fix: more idiomatic code
    
    * Update level/level.go
    
    Co-authored-by: Márk Sági-Kazár <[email protected]>
    
    Co-authored-by: Márk Sági-Kazár <[email protected]>
    mcosta74 and sagikazarmark authored Apr 27, 2022
    Copy the full SHA
    0b69c70 View commit details
Showing with 321 additions and 24 deletions.
  1. +28 −17 .github/workflows/test.yml
  2. +5 −0 README.md
  3. +2 −2 json_logger.go
  4. +38 −0 json_logger_test.go
  5. +11 −0 level/doc.go
  6. +23 −2 level/example_test.go
  7. +52 −1 level/level.go
  8. +160 −2 level/level_test.go
  9. +1 −0 staticcheck.conf
  10. +1 −0 syslog/syslog.go
45 changes: 28 additions & 17 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,38 +1,49 @@
on: push
on:
push:
pull_request:
types: [synchronize]
name: Test
jobs:
test:
strategy:
fail-fast: false
matrix:
go-version: [1.16.x, 1.17.x]
go-version: [1.17.x, 1.18.x]
platform: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Install Go
uses: actions/setup-go@v1
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: Install staticcheck
run: go install honnef.co/go/tools/cmd/staticcheck@latest
shell: bash
- name: Install golint
run: go install golang.org/x/lint/golint@latest
shell: bash
- name: Update PATH
run: echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
shell: bash
- name: Checkout code
uses: actions/checkout@v1
- name: Fmt
if: matrix.platform != 'windows-latest' # :(
run: "diff <(gofmt -d .) <(printf '')"
shell: bash
- name: Vet
run: go vet ./...
- name: Staticcheck
run: staticcheck ./...
- name: Lint
run: golint ./...
uses: dominikh/staticcheck-action@v1
with:
install-go: false
cache-key: ${{ matrix.go-version }}
- name: Test
run: go test -race ./...
- name: Test coverage
run: go test -coverprofile="cover.out" ./... # quotes needed for powershell
- name: Send coverage
uses: shogo82148/actions-goveralls@v1
with:
path-to-profile: cover.out
flag-name: go${{ matrix.go-version }}-${{ matrix.os }}
parallel: true
# notifies that all test jobs are finished.
finish:
needs: test
runs-on: ubuntu-latest
steps:
- uses: shogo82148/actions-goveralls@v1
with:
parallel-finished: true
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# package log

[![Go Reference](https://pkg.go.dev/badge/github.com/go-kit/log.svg)](https://pkg.go.dev/github.com/go-kit/log)
[![Go Report Card](https://goreportcard.com/badge/go-kit/log)](https://goreportcard.com/report/go-kit/log)
[![GitHub Actions](https://github.com/go-kit/log/actions/workflows/test.yml/badge.svg)](https://github.com/go-kit/log/actions/workflows/test.yml)
[![Coverage Status](https://coveralls.io/repos/github/go-kit/log/badge.svg?branch=main)](https://coveralls.io/github/go-kit/log?branch=main)

`package log` provides a minimal interface for structured logging in services.
It may be wrapped to encode conventions, enforce type-safety, provide leveled
logging, and so on. It can be used for both typical application log events,
4 changes: 2 additions & 2 deletions json_logger.go
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ func safeString(str fmt.Stringer) (s string) {
if v := reflect.ValueOf(str); v.Kind() == reflect.Ptr && v.IsNil() {
s = "NULL"
} else {
panic(panicVal)
s = fmt.Sprintf("PANIC in String method: %v", panicVal)
}
}
}()
@@ -82,7 +82,7 @@ func safeError(err error) (s interface{}) {
if v := reflect.ValueOf(err); v.Kind() == reflect.Ptr && v.IsNil() {
s = nil
} else {
panic(panicVal)
s = fmt.Sprintf("PANIC in Error method: %v", panicVal)
}
}
}()
38 changes: 38 additions & 0 deletions json_logger_test.go
Original file line number Diff line number Diff line change
@@ -60,6 +60,19 @@ func TestJSONLoggerNilStringerKey(t *testing.T) {
}
}

func TestJSONLoggerPanicStringerValue(t *testing.T) {
t.Parallel()

buf := &bytes.Buffer{}
logger := log.NewJSONLogger(buf)
if err := logger.Log("k", unsafeStringer{}); err != nil {
t.Fatal(err)
}
if want, have := `{"k":"PANIC in String method: error"}`+"\n", buf.String(); want != have {
t.Errorf("\nwant %#v\nhave %#v", want, have)
}
}

func TestJSONLoggerNilErrorValue(t *testing.T) {
t.Parallel()

@@ -73,6 +86,19 @@ func TestJSONLoggerNilErrorValue(t *testing.T) {
}
}

func TestJSONLoggerPanicErrorValue(t *testing.T) {
t.Parallel()

buf := &bytes.Buffer{}
logger := log.NewJSONLogger(buf)
if err := logger.Log("err", unsafeError{}); err != nil {
t.Fatal(err)
}
if want, have := `{"err":"PANIC in Error method: error"}`+"\n", buf.String(); want != have {
t.Errorf("\nwant %#v\nhave %#v", want, have)
}
}

func TestJSONLoggerNoHTMLEscape(t *testing.T) {
t.Parallel()
buf := &bytes.Buffer{}
@@ -160,6 +186,18 @@ func (s stringError) Error() string {
return string(s)
}

type unsafeStringer struct{}

func (s unsafeStringer) String() string {
panic("error")
}

type unsafeError struct{}

func (s unsafeError) Error() string {
panic("error")
}

func BenchmarkJSONLoggerSimple(b *testing.B) {
benchmarkRunner(b, log.NewJSONLogger(ioutil.Discard), baseMessage)
}
11 changes: 11 additions & 0 deletions level/doc.go
Original file line number Diff line number Diff line change
@@ -7,6 +7,17 @@
// logger = level.NewFilter(logger, level.AllowInfo()) // <--
// logger = log.With(logger, "ts", log.DefaultTimestampUTC)
//
// It's also possible to configure log level from a string. For instance from
// a flag, environment variable or configuration file.
//
// fs := flag.NewFlagSet("myprogram")
// lvl := fs.String("log", "info", "debug, info, warn, error")
//
// var logger log.Logger
// logger = log.NewLogfmtLogger(os.Stderr)
// logger = level.NewFilter(logger, level.Allow(level.ParseDefault(*lvl, level.InfoValue()))) // <--
// logger = log.With(logger, "ts", log.DefaultTimestampUTC)
//
// Then, at the callsites, use one of the level.Debug, Info, Warn, or Error
// helper methods to emit leveled log events.
//
25 changes: 23 additions & 2 deletions level/example_test.go
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ package level_test

import (
"errors"
"flag"
"os"

"github.com/go-kit/log"
@@ -34,6 +35,26 @@ func Example_filtered() {
level.Debug(logger).Log("next item", 17) // filtered

// Output:
// level=error caller=example_test.go:32 err="bad data"
// level=info caller=example_test.go:33 event="data saved"
// level=error caller=example_test.go:33 err="bad data"
// level=info caller=example_test.go:34 event="data saved"
}

func Example_parsed() {
fs := flag.NewFlagSet("example", flag.ExitOnError)
lvl := fs.String("log-level", "", `"debug", "info", "warn" or "error"`)
fs.Parse([]string{"-log-level", "info"})

// Set up logger with level filter.
logger := log.NewLogfmtLogger(os.Stdout)
logger = level.NewFilter(logger, level.Allow(level.ParseDefault(*lvl, level.DebugValue())))
logger = log.With(logger, "caller", log.DefaultCaller)

// Use level helpers to log at different levels.
level.Error(logger).Log("err", errors.New("bad data"))
level.Info(logger).Log("event", "data saved")
level.Debug(logger).Log("next item", 17) // filtered

// Output:
// level=error caller=example_test.go:53 err="bad data"
// level=info caller=example_test.go:54 event="data saved"
}
53 changes: 52 additions & 1 deletion level/level.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
package level

import "github.com/go-kit/log"
import (
"errors"
"strings"

"github.com/go-kit/log"
)

// ErrInvalidLevelString is returned whenever an invalid string is passed to Parse.
var ErrInvalidLevelString = errors.New("invalid level string")

// Error returns a logger that includes a Key/ErrorValue pair.
func Error(logger log.Logger) log.Logger {
@@ -66,6 +74,22 @@ func (l *logger) Log(keyvals ...interface{}) error {
// Option sets a parameter for the leveled logger.
type Option func(*logger)

// Allow the provided log level to pass.
func Allow(v Value) Option {
switch v {
case debugValue:
return AllowDebug()
case infoValue:
return AllowInfo()
case warnValue:
return AllowWarn()
case errorValue:
return AllowError()
default:
return AllowNone()
}
}

// AllowAll is an alias for AllowDebug.
func AllowAll() Option {
return AllowDebug()
@@ -100,6 +124,33 @@ func allowed(allowed level) Option {
return func(l *logger) { l.allowed = allowed }
}

// Parse a string to its corresponding level value. Valid strings are "debug",
// "info", "warn", and "error". Strings are normalized via strings.TrimSpace and
// strings.ToLower.
func Parse(level string) (Value, error) {
switch strings.TrimSpace(strings.ToLower(level)) {
case debugValue.name:
return debugValue, nil
case infoValue.name:
return infoValue, nil
case warnValue.name:
return warnValue, nil
case errorValue.name:
return errorValue, nil
default:
return nil, ErrInvalidLevelString
}
}

// ParseDefault calls Parse and returns the default Value on error.
func ParseDefault(level string, def Value) Value {
v, err := Parse(level)
if err != nil {
return def
}
return v
}

// ErrNotAllowed sets the error to return from Log when it squelches a log
// event disallowed by the configured Allow[Level] option. By default,
// ErrNotAllowed is nil; in this case the log event is squelched with no
Loading