-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
1,798 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
name: "log-ci" | ||
|
||
on: | ||
push: | ||
branches: | ||
- "feat**" | ||
- "fix**" | ||
- "hotfix**" | ||
- "chore**" | ||
paths: | ||
- "log/**.go" | ||
- "log/go.mod" | ||
- "log/go.sum" | ||
pull_request: | ||
types: | ||
- opened | ||
- synchronize | ||
- reopened | ||
branches: | ||
- main | ||
paths: | ||
- "log/**.go" | ||
- "log/go.mod" | ||
- "log/go.sum" | ||
|
||
jobs: | ||
ci: | ||
uses: ./.github/workflows/common-ci.yml | ||
secrets: inherit | ||
with: | ||
module: "log" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
run: | ||
timeout: 5m | ||
concurrency: 8 | ||
|
||
linters: | ||
enable: | ||
- asasalint | ||
- asciicheck | ||
- bidichk | ||
- bodyclose | ||
- containedctx | ||
- contextcheck | ||
- cyclop | ||
- decorder | ||
- dogsled | ||
- durationcheck | ||
- errcheck | ||
- errchkjson | ||
- errname | ||
- errorlint | ||
- exhaustive | ||
- forbidigo | ||
- forcetypeassert | ||
- gocognit | ||
- goconst | ||
- gocritic | ||
- gocyclo | ||
- godot | ||
- godox | ||
- gofmt | ||
- goheader | ||
- gomoddirectives | ||
- gomodguard | ||
- goprintffuncname | ||
- gosec | ||
- gosimple | ||
- govet | ||
- grouper | ||
- importas | ||
- ineffassign | ||
- interfacebloat | ||
- logrlint | ||
- maintidx | ||
- makezero | ||
- misspell | ||
- nestif | ||
- nilerr | ||
- nilnil | ||
- nlreturn | ||
- nolintlint | ||
- nosprintfhostport | ||
- prealloc | ||
- predeclared | ||
- promlinter | ||
- reassign | ||
- staticcheck | ||
- tenv | ||
- thelper | ||
- tparallel | ||
- typecheck | ||
- unconvert | ||
- unparam | ||
- unused | ||
- usestdlibvars | ||
- whitespace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
# Log Module | ||
|
||
[![ci](https://github.com/ankorstore/yokai/actions/workflows/log-ci.yml/badge.svg)](https://github.com/ankorstore/yokai/actions/workflows/log-ci.yml) | ||
[![go report](https://goreportcard.com/badge/github.com/ankorstore/yokai/log)](https://goreportcard.com/report/github.com/ankorstore/yokai/log) | ||
[![codecov](https://codecov.io/gh/ankorstore/yokai/graph/badge.svg?token=5s0g5WyseS&flag=log)](https://app.codecov.io/gh/ankorstore/yokai/tree/main/log) | ||
[![PkgGoDev](https://pkg.go.dev/badge/github.com/ankorstore/yokai/log)](https://pkg.go.dev/github.com/ankorstore/yokai/log) | ||
|
||
> Logging module based on [Zerolog](https://github.com/rs/zerolog). | ||
<!-- TOC --> | ||
* [Installation](#installation) | ||
* [Documentation](#documentation) | ||
* [Usage](#usage) | ||
* [Context](#context) | ||
* [Testing](#testing) | ||
<!-- TOC --> | ||
|
||
## Installation | ||
|
||
```shell | ||
go get github.com/ankorstore/yokai/log | ||
``` | ||
|
||
## Documentation | ||
|
||
This module provides a [Logger](logger.go), offering all [Zerolog](https://github.com/rs/zerolog) methods. | ||
|
||
### Usage | ||
|
||
To create a `Logger`: | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"os" | ||
|
||
"github.com/ankorstore/yokai/log" | ||
"github.com/rs/zerolog" | ||
) | ||
|
||
var logger, _ = log.NewDefaultLoggerFactory().Create() | ||
|
||
// equivalent to: | ||
var logger, _ = log.NewDefaultLoggerFactory().Create( | ||
log.WithServiceName("default"), // adds {"service":"default"} to log records | ||
log.WithLevel(zerolog.InfoLevel), // logs records with level >= info | ||
log.WithOutputWriter(os.Stdout), // sends logs records to stdout | ||
) | ||
``` | ||
|
||
To use the `Logger`: | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"github.com/ankorstore/yokai/log" | ||
) | ||
|
||
func main() { | ||
logger, _ := log.NewDefaultLoggerFactory().Create() | ||
|
||
logger.Info().Msg("some message") // {"level:"info", "service":"default", "message":"some message"} | ||
} | ||
``` | ||
|
||
See [Zerolog](https://github.com/rs/zerolog) documentation for more details about available methods. | ||
|
||
### Context | ||
|
||
This module provides the `log.CtxLogger()` function that allow to extract the logger from a `context.Context`. | ||
|
||
If no logger is found in context, a [default](https://github.com/rs/zerolog/blob/master/ctx.go) Zerolog based logger will be used. | ||
|
||
### Testing | ||
|
||
This module provides a [TestLogBuffer](logtest/buffer.go), recording log records to be able to assert on them after logging: | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/ankorstore/yokai/log" | ||
"github.com/ankorstore/yokai/log/logtest" | ||
) | ||
|
||
func main() { | ||
buffer := logtest.NewDefaultTestLogBuffer() | ||
|
||
logger, _ := log.NewDefaultLoggerFactory().Create(log.WithOutputWriter(buffer)) | ||
|
||
logger.Info().Msg("some message example") | ||
|
||
// test on attributes exact matching | ||
hasRecord, _ := buffer.HasRecord(map[string]interface{}{ | ||
"level": "info", | ||
"message": "some message example", | ||
}) | ||
|
||
fmt.Printf("has record: %v", hasRecord) // has record: true | ||
|
||
// test on attributes partial matching | ||
containRecord, _ := buffer.ContainRecord(map[string]interface{}{ | ||
"level": "info", | ||
"message": "message", | ||
}) | ||
|
||
fmt.Printf("contain record: %v", containRecord) // contain record: true | ||
} | ||
``` | ||
|
||
You can also use the provided [test assertion helpers](logtest/assert.go) in your tests: | ||
- `AssertHasLogRecord`: to assert on exact attributes match | ||
- `AssertHasNotLogRecord`: to assert on exact attributes non match | ||
- `AssertContainLogRecord`: to assert on partial attributes match | ||
- `AssertContainNotLogRecord`: to assert on partial attributes non match | ||
|
||
```go | ||
package main_test | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/ankorstore/yokai/log" | ||
"github.com/ankorstore/yokai/log/logtest" | ||
) | ||
|
||
func TestLogger(t *testing.T) { | ||
buffer := logtest.NewDefaultTestLogBuffer() | ||
|
||
logger, _ := log.NewDefaultLoggerFactory().Create(log.WithOutputWriter(buffer)) | ||
|
||
logger.Info().Msg("some message example") | ||
|
||
// assertion success | ||
logtest.AssertHasLogRecord(t, buffer, map[string]interface{}{ | ||
"level": "info", | ||
"message": "some message example", | ||
}) | ||
|
||
// assertion success | ||
logtest.AssertHasNotLogRecord(t, buffer, map[string]interface{}{ | ||
"level": "info", | ||
"message": "some invalid example", | ||
}) | ||
|
||
// assertion success | ||
logtest.AssertContainLogRecord(t, buffer, map[string]interface{}{ | ||
"level": "info", | ||
"message": "message", | ||
}) | ||
|
||
// assertion success | ||
logtest.AssertContainNotLogRecord(t, buffer, map[string]interface{}{ | ||
"level": "info", | ||
"message": "invalid", | ||
}) | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package log | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/rs/zerolog" | ||
"go.opentelemetry.io/otel/trace" | ||
) | ||
|
||
// CtxLogger retrieves a [Logger] from a provided context (or creates and appends a new one if missing). | ||
// | ||
// It automatically adds the traceID and spanID log fields depending on current tracing context. | ||
func CtxLogger(ctx context.Context) *Logger { | ||
fields := make(map[string]interface{}) | ||
|
||
spanContext := trace.SpanContextFromContext(ctx) | ||
if spanContext.HasTraceID() { | ||
fields["traceID"] = spanContext.TraceID().String() | ||
} | ||
if spanContext.HasSpanID() { | ||
fields["spanID"] = spanContext.SpanID().String() | ||
} | ||
|
||
if len(fields) > 0 { | ||
logger := zerolog.Ctx(ctx).With().Fields(fields).Logger() | ||
|
||
return &Logger{&logger} | ||
} | ||
|
||
return &Logger{zerolog.Ctx(ctx)} | ||
} |
Oops, something went wrong.