Add context to logs, update readme
This commit is contained in:
parent
984a90a75c
commit
01c445213c
41
README.md
41
README.md
|
@ -10,11 +10,17 @@ import "github.com/localhots/gobelt/threadpool"
|
||||||
|
|
||||||
```go
|
```go
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
pool := threadpool.New(5)
|
ctx, cancel = context.WithTimeout(ctx, 30 * time.Second)
|
||||||
pool.Enqueue(ctx, func() {
|
defer cancel()
|
||||||
fmt.Println("Hello")
|
|
||||||
})
|
pool := threadpool.New(10)
|
||||||
pool.Close()
|
defer pool.Close()
|
||||||
|
for i := 0; i < 1000000; i++ {
|
||||||
|
i := i
|
||||||
|
pool.Enqueue(ctx, func() {
|
||||||
|
fmt.Printf("The number is %d\n", i)
|
||||||
|
})
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### File cache
|
### File cache
|
||||||
|
@ -26,8 +32,12 @@ import "github.com/localhots/gobelt/filecache"
|
||||||
```go
|
```go
|
||||||
var val int
|
var val int
|
||||||
filecache.Load(&val, "path/to/cachefile", func() interface{} {
|
filecache.Load(&val, "path/to/cachefile", func() interface{} {
|
||||||
// Expensive calls here
|
var items []Item
|
||||||
return 100
|
err := conn.Query(ctx, "SELECT * FROM items").Load(&items).Error()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Failed to load items", log.F{"error": err})
|
||||||
|
}
|
||||||
|
return items
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -38,9 +48,16 @@ import "github.com/localhots/gobelt/log"
|
||||||
```
|
```
|
||||||
|
|
||||||
```go
|
```go
|
||||||
log.Info("New user signed up", log.F{
|
ctx := context.Background()
|
||||||
"name": u.Name,
|
ctx = log.ContextWithFields(ctx, log.F{"email": params["email"]})
|
||||||
"email": u.Email,
|
|
||||||
})
|
user, err := signup(ctx, params)
|
||||||
log.Errorf("Invalid database flavor: %s", flavor)
|
if err != nil {
|
||||||
|
log.Errorf(ctx, "Signup failed: %v", err)
|
||||||
|
// [ERRO] Signup failed: db: duplicate entry email=bob@example.com
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info(ctx, "New user signed up", log.F{"id": user.ID})
|
||||||
|
// [INFO] New user signed up email=bob@example.com id=14
|
||||||
```
|
```
|
|
@ -0,0 +1,27 @@
|
||||||
|
package log
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
type logContext byte
|
||||||
|
|
||||||
|
const ctxFields logContext = iota
|
||||||
|
|
||||||
|
// ContextWithFields returns a new context with given fields added.
|
||||||
|
func ContextWithFields(ctx context.Context, f F) context.Context {
|
||||||
|
ctxf, ok := ctx.Value(ctxFields).(F)
|
||||||
|
if !ok {
|
||||||
|
ctxf = F{}
|
||||||
|
}
|
||||||
|
for k, v := range f {
|
||||||
|
ctxf[k] = v
|
||||||
|
}
|
||||||
|
return context.WithValue(ctx, ctxFields, ctxf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func contextFields(ctx context.Context) F {
|
||||||
|
f, ok := ctx.Value(ctxFields).(F)
|
||||||
|
if ok {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
return F{}
|
||||||
|
}
|
65
log/log.go
65
log/log.go
|
@ -1,6 +1,8 @@
|
||||||
package log
|
package log
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/lytics/logrus"
|
"github.com/lytics/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,58 +17,61 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug prints a debug message with given fields attached.
|
// Debug prints a debug message with given fields attached.
|
||||||
func Debug(msg string, fields ...F) {
|
func Debug(ctx context.Context, msg string, fields ...F) {
|
||||||
withFields(fields).Debug(msg)
|
withFields(mergeFields(ctx, fields)).Debug(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debugf prints a formatted debug message.
|
// Debugf prints a formatted debug message.
|
||||||
func Debugf(format string, args ...interface{}) {
|
func Debugf(ctx context.Context, format string, args ...interface{}) {
|
||||||
logrus.Debugf(format, args...)
|
withFields(contextFields(ctx)).Debugf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Info prints an info message with given fields attached.
|
// Info prints an info message with given fields attached.
|
||||||
func Info(msg string, fields ...F) {
|
func Info(ctx context.Context, msg string, fields ...F) {
|
||||||
withFields(fields).Info(msg)
|
withFields(mergeFields(ctx, fields)).Info(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Infof prints a formatted info message.
|
// Infof prints a formatted info message.
|
||||||
func Infof(format string, args ...interface{}) {
|
func Infof(ctx context.Context, format string, args ...interface{}) {
|
||||||
logrus.Infof(format, args...)
|
withFields(contextFields(ctx)).Infof(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error prints an error message with given fields attached.
|
// Error prints an error message with given fields attached.
|
||||||
func Error(msg string, fields ...F) {
|
func Error(ctx context.Context, msg string, fields ...F) {
|
||||||
withFields(fields).Error(msg)
|
withFields(mergeFields(ctx, fields)).Error(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Errorf prints a formatted error message.
|
// Errorf prints a formatted error message.
|
||||||
func Errorf(format string, args ...interface{}) {
|
func Errorf(ctx context.Context, format string, args ...interface{}) {
|
||||||
logrus.Errorf(format, args...)
|
withFields(contextFields(ctx)).Errorf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fatal prints an error message with given fields attached and then exits.
|
// Fatal prints an error message with given fields attached and then exits.
|
||||||
func Fatal(msg string, fields ...F) {
|
func Fatal(ctx context.Context, msg string, fields ...F) {
|
||||||
withFields(fields).Fatal(msg)
|
withFields(mergeFields(ctx, fields)).Fatal(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fatalf prints a formatted error message and then exits.
|
// Fatalf prints a formatted error message and then exits.
|
||||||
func Fatalf(format string, args ...interface{}) {
|
func Fatalf(ctx context.Context, format string, args ...interface{}) {
|
||||||
logrus.Fatalf(format, args...)
|
withFields(contextFields(ctx)).Fatalf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func withFields(fields []F) *logrus.Entry {
|
func mergeFields(ctx context.Context, fields []F) F {
|
||||||
switch len(fields) {
|
ctxf := contextFields(ctx)
|
||||||
case 0:
|
if len(ctxf) == 0 && len(fields) == 0 {
|
||||||
return logrus.NewEntry(Logger)
|
return nil
|
||||||
case 1:
|
|
||||||
return logrus.WithFields(logrus.Fields(fields[0]))
|
|
||||||
default:
|
|
||||||
f := F{}
|
|
||||||
for i := 0; i < len(fields); i++ {
|
|
||||||
for k, v := range fields[i] {
|
|
||||||
f[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return logrus.WithFields(logrus.Fields(f))
|
|
||||||
}
|
}
|
||||||
|
for i := 0; i < len(fields); i++ {
|
||||||
|
for k, v := range fields[i] {
|
||||||
|
ctxf[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ctxf
|
||||||
|
}
|
||||||
|
|
||||||
|
func withFields(f F) *logrus.Entry {
|
||||||
|
if len(f) == 0 {
|
||||||
|
return logrus.NewEntry(Logger)
|
||||||
|
}
|
||||||
|
return logrus.WithFields(logrus.Fields(f))
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,8 @@ package impl
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp/cmpopts"
|
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"github.com/google/go-cmp/cmp/cmpopts"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
Loading…
Reference in New Issue