Skip to content

Commit

Permalink
🚀 Add Logger interface and fiberlog (#2499)
Browse files Browse the repository at this point in the history
* add log for fiber

* replace log in fiber

* add Log use to adapt for log libraries

* Update app.go

Co-authored-by: Tomás Warynyca <[email protected]>

* wip: add log docs

* add WithLogger use to print key and value

* remove CtxLogger and add WithContext use to bind Context

* fix errcheck

* fix errcheck

* update log.md

---------

Co-authored-by: Tomás Warynyca <[email protected]>
  • Loading branch information
Skyenought and tomaswarynyca authored Jun 26, 2023
1 parent 5967d36 commit fefc533
Show file tree
Hide file tree
Showing 20 changed files with 865 additions and 42 deletions.
10 changes: 5 additions & 5 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"encoding/xml"
"errors"
"fmt"
"log"
"net"
"net/http"
"net/http/httputil"
Expand All @@ -24,6 +23,7 @@ import (
"sync"
"time"

"github.com/gofiber/fiber/v2/log"
"github.com/gofiber/fiber/v2/utils"

"github.com/valyala/fasthttp"
Expand Down Expand Up @@ -521,7 +521,7 @@ func New(config ...Config) *App {

if app.config.ETag {
if !IsChild() {
log.Printf("[Warning] Config.ETag is deprecated since v2.0.6, please use 'middleware/etag'.\n")
log.Warn("Config.ETag is deprecated since v2.0.6, please use 'middleware/etag'.")
}
}

Expand Down Expand Up @@ -589,7 +589,7 @@ func (app *App) handleTrustedProxy(ipAddress string) {
if strings.Contains(ipAddress, "/") {
_, ipNet, err := net.ParseCIDR(ipAddress)
if err != nil {
log.Printf("[Warning] IP range %q could not be parsed: %v\n", ipAddress, err)
log.Warnf("IP range %q could not be parsed: %v", ipAddress, err)
} else {
app.config.trustedProxyRanges = append(app.config.trustedProxyRanges, ipNet)
}
Expand Down Expand Up @@ -987,7 +987,7 @@ func (app *App) init() *App {
// Only load templates if a view engine is specified
if app.config.Views != nil {
if err := app.config.Views.Load(); err != nil {
log.Printf("[Warning]: failed to load views: %v\n", err)
log.Warnf("failed to load views: %v", err)
}
}

Expand Down Expand Up @@ -1084,7 +1084,7 @@ func (app *App) serverErrorHandler(fctx *fasthttp.RequestCtx, err error) {
}

if catch := app.ErrorHandler(c, err); catch != nil {
log.Printf("serverErrorHandler: failed to call ErrorHandler: %v\n", catch)
log.Errorf("serverErrorHandler: failed to call ErrorHandler: %v", catch)
_ = c.SendStatus(StatusInternalServerError) //nolint:errcheck // It is fine to ignore the error here
return
}
Expand Down
156 changes: 156 additions & 0 deletions docs/api/log.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
---
id: log
title: Log
description: Fiber's built-in log package
sidebar_position: 8
---
## Log

We can use logs to observe program behavior, diagnose problems, or configure corresponding alarms.
And defining a well structured log can improve search efficiency and facilitate handling of problems.

Fiber provides a default way to print logs in the standard output.
It also provides several global functions, such as `log.Info`, `log.Errorf`, `log.Warnw`, etc.

## Log levels

```go
const (
LevelTrace Level = iota
LevelDebug
LevelInfo
LevelWarn
LevelError
LevelFatal
LevelPanic
)
```

## Custom log

Fiber provides the `AllLogger` interface for adapting the various log libraries.

```go
type CommonLogger interface {
Logger
FormatLogger
WithLogger
}

type AllLogger interface {
CommonLogger
ControlLogger
WithLogger
}
```

## Print log
Note: The method of calling the Fatal level will interrupt the program running after printing the log, please use it with caution.
Directly print logs of different levels, which will be entered into messageKey, the default is msg.

```go
log.Info("Hello, World!")
log.Debug("Are you OK?")
log.Info("42 is the answer to life, the universe, and everything")
log.Warn("We are under attack!")
log.Error("Houston, we have a problem.")
log.Fatal("So Long, and Thanks for All the Fislog.")
log.Panic("The system is down.")
```
Format and print logs of different levels, all methods end with f

```go
log.Debugf("Hello %s", "boy")
log.Infof("%d is the answer to life, the universe, and everything", 233)
log.Warnf("We are under attack %s!", "boss")
log.Errorf("%s, we have a problem.", "Master Shifu")
log.Fatalf("So Long, and Thanks for All the %s.", "banana")
```

Print a message with the key and value, or `KEYVALS UNPAIRED` if the key and value are not a pair.

```go
log.Debugw("", "Hello", "boy")
log.Infow("", "number", 233)
log.Warnw("", "job", "boss")
log.Errorw("", "name", "Master Shifu")
log.Fatalw("", "fruit", "banana")
```

## Global log
If you are in a project and just want to use a simple log function that can be printed at any time in the global, we provide a global log.

```go
import "github.com/gofiber/fiber/v2/log"

log.Info("info")
log.Warn("warn")
```

The above is using the default `log.DefaultLogger` standard output.
You can also find an already implemented adaptation under contrib, or use your own implemented Logger and use `log.SetLogger` to set the global log logger.

```go
import (
"log"
fiberlog "github.com/gofiber/fiber/v2/log"
)

var _ log.AllLogger = (*customLogger)(nil)

type customLogger struct {
stdlog *log.Logger
}

// ...
// inject your custom logger
fiberlog.SetLogger(customLogger)
```

## Set Level
`log.SetLevel` sets the level of logs below which logs will not be output.
The default logger is LevelTrace.

Note that this method is not **concurrent-safe**.

```go
import "github.com/gofiber/fiber/v2/log"

log.SetLevel(log.LevelInfo)
```
## Set output

`log.SetOutput` sets the output destination of the logger. The default logger types the log in the console.

```go
var logger AllLogger = &defaultLogger{
stdlog: log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds),
depth: 4,
}
```

Set the output destination to the file.

```go
// Output to ./test.log file
f, err := os.OpenFile("test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
return
}
log.SetOutput(f)
```
Set the output destination to the console and file.

```go
// Output to ./test.log file
file, _ := os.OpenFile("test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
iw := io.MultiWriter(os.Stdout, file)
log.SetOutput(iw)
```
## Bind context
Set the context, using the following method will return a `CommonLogger` instance bound to the specified context
```go
commonLogger := log.WithContext(ctx)
commonLogger.Info("info")
```

8 changes: 4 additions & 4 deletions helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"fmt"
"hash/crc32"
"io"
"log"
"net"
"os"
"path/filepath"
Expand All @@ -19,6 +18,7 @@ import (
"time"
"unsafe"

"github.com/gofiber/fiber/v2/log"
"github.com/gofiber/fiber/v2/utils"

"github.com/valyala/bytebufferpool"
Expand Down Expand Up @@ -75,7 +75,7 @@ func readContent(rf io.ReaderFrom, name string) (int64, error) {
}
defer func() {
if err = f.Close(); err != nil {
log.Printf("Error closing file: %s\n", err)
log.Errorf("Error closing file: %s", err)
}
}()
if n, err := rf.ReadFrom(f); err != nil {
Expand Down Expand Up @@ -192,7 +192,7 @@ func setETag(c *Ctx, weak bool) { //nolint: revive // Accepting a bool param is
if clientEtag[2:] == etag || clientEtag[2:] == etag[2:] {
// W/1 == 1 || W/1 == W/1
if err := c.SendStatus(StatusNotModified); err != nil {
log.Printf("setETag: failed to SendStatus: %v\n", err)
log.Errorf("setETag: failed to SendStatus: %v", err)
}
c.fasthttp.ResetBody()
return
Expand All @@ -204,7 +204,7 @@ func setETag(c *Ctx, weak bool) { //nolint: revive // Accepting a bool param is
if strings.Contains(clientEtag, etag) {
// 1 == 1
if err := c.SendStatus(StatusNotModified); err != nil {
log.Printf("setETag: failed to SendStatus: %v\n", err)
log.Errorf("setETag: failed to SendStatus: %v", err)
}
c.fasthttp.ResetBody()
return
Expand Down
6 changes: 3 additions & 3 deletions hooks.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package fiber

import (
"log"
"github.com/gofiber/fiber/v2/log"
)

// OnRouteHandler Handlers define a function to create hooks for Fiber.
Expand Down Expand Up @@ -194,15 +194,15 @@ func (h *Hooks) executeOnListenHooks(listenData ListenData) error {
func (h *Hooks) executeOnShutdownHooks() {
for _, v := range h.onShutdown {
if err := v(); err != nil {
log.Printf("failed to call shutdown hook: %v\n", err)
log.Errorf("failed to call shutdown hook: %v", err)
}
}
}

func (h *Hooks) executeOnForkHooks(pid int) {
for _, v := range h.onFork {
if err := v(pid); err != nil {
log.Printf("failed to call fork hook: %v\n", err)
log.Errorf("failed to call fork hook: %v", err)
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions internal/template/html/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import (
"fmt"
"html/template"
"io"
"log"
"net/http"
"os"
"path/filepath"
"strings"
"sync"

"github.com/gofiber/fiber/v2/internal/template/utils"
"github.com/gofiber/fiber/v2/log"
)

// Engine struct
Expand Down Expand Up @@ -113,7 +113,7 @@ func (e *Engine) Debug(enabled bool) *Engine {

// Parse is deprecated, please use Load() instead
func (e *Engine) Parse() error {
log.Println("[Warning] Parse() is deprecated, please use Load() instead.")
log.Warn("Parse() is deprecated, please use Load() instead.")
return e.Load()
}

Expand Down Expand Up @@ -170,7 +170,7 @@ func (e *Engine) Load() error {
}
// Debugging
if e.debug {
log.Printf("views: parsed template: %s\n", name)
log.Infof("views: parsed template: %s", name)
}
return err
}
Expand Down
4 changes: 2 additions & 2 deletions listen.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"crypto/x509"
"errors"
"fmt"
"log"
"net"
"os"
"path/filepath"
Expand All @@ -20,6 +19,7 @@ import (
"strings"
"text/tabwriter"

"github.com/gofiber/fiber/v2/log"
"github.com/mattn/go-colorable"
"github.com/mattn/go-isatty"
"github.com/mattn/go-runewidth"
Expand Down Expand Up @@ -49,7 +49,7 @@ func (app *App) Listener(ln net.Listener) error {

// Prefork is not supported for custom listeners
if app.config.Prefork {
log.Printf("[Warning] Prefork isn't supported for custom listeners.\n")
log.Warn("Prefork isn't supported for custom listeners.")
}

// Start listening
Expand Down
Loading

1 comment on commit fefc533

@ReneWerner87
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.

Benchmark suite Current: fefc533 Previous: 5967d36 Ratio
Benchmark_TrimLeft/fiber 12.49 ns/op 0 B/op 0 allocs/op 3.632 ns/op 0 B/op 0 allocs/op 3.44

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.