v0.1.4 formatter race fix, fiber adapter added, default config changed, docs updated
This commit is contained in:
284
doc/adapters.md
284
doc/adapters.md
@ -349,4 +349,286 @@ func requestLogger(adapter *compat.FastHTTPAdapter) fasthttp.RequestHandler {
|
||||
time.Since(start))
|
||||
}
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
### Simple integration example suite
|
||||
|
||||
Below simple client and server examples can be used to test the basic functionality of the adapters. They are not included in the package to avoid dependency creep.
|
||||
|
||||
|
||||
#### gnet server
|
||||
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/lixenwraith/log"
|
||||
"github.com/lixenwraith/log/compat"
|
||||
"github.com/panjf2000/gnet/v2"
|
||||
)
|
||||
|
||||
type echoServer struct {
|
||||
gnet.BuiltinEventEngine
|
||||
adapter *compat.GnetAdapter
|
||||
}
|
||||
|
||||
func (es *echoServer) OnTraffic(c gnet.Conn) gnet.Action {
|
||||
buf, _ := c.Next(-1)
|
||||
if len(buf) > 0 {
|
||||
es.adapter.Infof("Echo %d bytes", len(buf))
|
||||
c.Write(buf)
|
||||
}
|
||||
return gnet.None
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Minimal logger config
|
||||
logger, err := log.NewBuilder().
|
||||
Directory("./logs_gnet").
|
||||
Format("json").
|
||||
LevelString("info").
|
||||
HeartbeatLevel(0).
|
||||
Build()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := logger.Start(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
adapter, err := compat.NewBuilder().WithLogger(logger).BuildGnet()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
handler := &echoServer{adapter: adapter}
|
||||
|
||||
fmt.Println("Starting gnet server on :9000")
|
||||
fmt.Println("Press Ctrl+C to stop")
|
||||
|
||||
// Signal handling
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
if err := gnet.Run(handler, "tcp://:9000",
|
||||
gnet.WithLogger(adapter),
|
||||
); err != nil {
|
||||
fmt.Printf("gnet error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}()
|
||||
|
||||
<-sigChan
|
||||
fmt.Println("\nShutting down...")
|
||||
logger.Shutdown()
|
||||
}
|
||||
```
|
||||
|
||||
#### fasthttp server
|
||||
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/lixenwraith/log"
|
||||
"github.com/lixenwraith/log/compat"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Minimal logger config
|
||||
logger, err := log.NewBuilder().
|
||||
Directory("./logs_fasthttp").
|
||||
Format("json").
|
||||
LevelString("info").
|
||||
HeartbeatLevel(0).
|
||||
Build()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := logger.Start(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
adapter, err := compat.NewBuilder().WithLogger(logger).BuildFastHTTP()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
server := &fasthttp.Server{
|
||||
Handler: func(ctx *fasthttp.RequestCtx) {
|
||||
adapter.Printf("Request: %s %s", ctx.Method(), ctx.Path())
|
||||
ctx.WriteString("OK")
|
||||
},
|
||||
Logger: adapter,
|
||||
Name: "TestServer",
|
||||
}
|
||||
|
||||
fmt.Println("Starting FastHTTP server on :8080")
|
||||
fmt.Println("Press Ctrl+C to stop")
|
||||
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
if err := server.ListenAndServe(":8080"); err != nil {
|
||||
fmt.Printf("FastHTTP error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}()
|
||||
|
||||
<-sigChan
|
||||
fmt.Println("\nShutting down...")
|
||||
server.Shutdown()
|
||||
logger.Shutdown()
|
||||
}
|
||||
```
|
||||
|
||||
#### Fiber server
|
||||
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/lixenwraith/log"
|
||||
"github.com/lixenwraith/log/compat"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Minimal logger config
|
||||
logger, err := log.NewBuilder().
|
||||
Directory("./logs_fiber").
|
||||
Format("json").
|
||||
LevelString("info").
|
||||
HeartbeatLevel(0).
|
||||
Build()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := logger.Start(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
adapter, err := compat.NewBuilder().WithLogger(logger).BuildFiber()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
app := fiber.New(fiber.Config{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
|
||||
app.Use(func(c *fiber.Ctx) error {
|
||||
adapter.Infow("Request", "method", c.Method(), "path", c.Path())
|
||||
return c.Next()
|
||||
})
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("OK")
|
||||
})
|
||||
|
||||
fmt.Println("Starting Fiber server on :3000")
|
||||
fmt.Println("Press Ctrl+C to stop")
|
||||
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
if err := app.Listen(":3000"); err != nil {
|
||||
fmt.Printf("Fiber error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}()
|
||||
|
||||
<-sigChan
|
||||
fmt.Println("\nShutting down...")
|
||||
app.ShutdownWithTimeout(2 * time.Second)
|
||||
logger.Shutdown()
|
||||
}
|
||||
```
|
||||
|
||||
#### Client
|
||||
|
||||
Client for all adapter servers.
|
||||
|
||||
```bash
|
||||
# Run with:
|
||||
go run client.go -target=gnet
|
||||
go run client.go -target=fasthttp
|
||||
go run client.go -target=fiber
|
||||
```
|
||||
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var target = flag.String("target", "fiber", "Target: gnet|fasthttp|fiber")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
switch *target {
|
||||
case "gnet":
|
||||
conn, err := net.Dial("tcp", "localhost:9000")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
conn.Write([]byte("TEST"))
|
||||
buf := make([]byte, 4)
|
||||
conn.Read(buf)
|
||||
conn.Close()
|
||||
fmt.Println("gnet: received echo")
|
||||
|
||||
case "fasthttp":
|
||||
resp, err := http.Get("http://localhost:8080/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
fmt.Printf("fasthttp: %s\n", body)
|
||||
|
||||
case "fiber":
|
||||
resp, err := http.Get("http://localhost:3000/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
fmt.Printf("fiber: %s\n", body)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,9 @@ Direct struct configuration using the Config struct, or key-value overrides:
|
||||
```go
|
||||
logger := log.NewLogger() // logger instance created with DefaultConfig (using default values)
|
||||
|
||||
logger.Info("info txt log record written to ./log/log.log")
|
||||
// Note: with default config, logs only go to stderr (file output disabled by default)
|
||||
logger.Start() // Required before logging
|
||||
logger.Info("info raw log record written to stderr")
|
||||
|
||||
// Directly change config struct
|
||||
cfg := log.GetConfig()
|
||||
@ -51,7 +53,7 @@ logger.Info("info txt log record written to /var/log/myapp.txt")
|
||||
| `name` | `string` | Base name for log files | `"log"` |
|
||||
| `extension` | `string` | Log file extension (without dot) | `"log"` |
|
||||
| `directory` | `string` | Directory to store log files | `"./log"` |
|
||||
| `format` | `string` | Output format: `"txt"`, `"json"`, or `"raw"` | `"txt"` |
|
||||
| `format` | `string` | Output format: `"txt"`, `"json"`, or `"raw"` | `"raw"` |
|
||||
| `sanitization` | `string` | Sanitization policy: `"raw"`, `"txt"`, `"json"`, or `"shell"` | `"raw"` |
|
||||
| `timestamp_format` | `string` | Custom timestamp format (Go time format) | `time.RFC3339Nano` |
|
||||
| `internal_errors_to_stderr` | `bool` | Write logger's internal errors to stderr | `false` |
|
||||
@ -63,8 +65,8 @@ logger.Info("info txt log record written to /var/log/myapp.txt")
|
||||
| `show_timestamp` | `bool` | Include timestamps in log entries | `true` |
|
||||
| `show_level` | `bool` | Include log level in entries | `true` |
|
||||
| `enable_console` | `bool` | Enable console output (stdout/stderr) | `true` |
|
||||
| `console_target` | `string` | Console target: `"stdout"`, `"stderr"`, or `"split"` | `"stdout"` |
|
||||
| `enable_file` | `bool` | Enable file output (console-only) | `true` |
|
||||
| `console_target` | `string` | Console target: `"stdout"`, `"stderr"`, or `"split"` | `"stderr"` |
|
||||
| `enable_file` | `bool` | Enable file output (console-only) | `false` |
|
||||
|
||||
**Note:** When `console_target="split"`, INFO/DEBUG logs go to stdout while WARN/ERROR logs go to stderr.
|
||||
|
||||
|
||||
@ -33,8 +33,8 @@ func main() {
|
||||
// Create a new logger instance with default configuration
|
||||
logger := log.NewLogger()
|
||||
|
||||
// Apply configuration
|
||||
err := logger.ApplyConfigString("directory=/var/log/myapp")
|
||||
// Apply configuration (enable file output since it's disabled by default)
|
||||
err := logger.ApplyConfigString("directory=/var/log/myapp", "enable_file=true")
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to apply logger config: %w", err))
|
||||
}
|
||||
|
||||
@ -126,7 +126,7 @@ func logWithContext(ctx context.Context, logger *log.Logger, level string, msg s
|
||||
|
||||
## Output Formats
|
||||
|
||||
The logger supports three output formats, each with configurable sanitization. For advanced formatting needs, see [Formatting & Sanitization](formatting.md) for standalone usage of the formatter and sanitizer packages.
|
||||
The logger supports three output formats, each with configurable sanitization. The default format is "raw".
|
||||
|
||||
### Txt Format (Human-Readable)
|
||||
|
||||
|
||||
@ -26,7 +26,8 @@ func main() {
|
||||
LevelString("info"). // Minimum log level
|
||||
Format("json"). // Output format
|
||||
Sanitization("json"). // Sanitization policy
|
||||
BufferSize(2048). // Channel buffer size
|
||||
EnableFile(true). // Enable file output (disabled by default)
|
||||
BufferSize(2048). // Channel buffer size
|
||||
MaxSizeMB(10). // Max file size before rotation
|
||||
HeartbeatLevel(1). // Enable operational monitoring
|
||||
HeartbeatIntervalS(300). // Every 5 minutes
|
||||
|
||||
Reference in New Issue
Block a user