https://github.com/tinh-tinh/tslog
slog for TinhTinh Framework
https://github.com/tinh-tinh/tslog
framework golang slog
Last synced: 13 days ago
JSON representation
slog for TinhTinh Framework
- Host: GitHub
- URL: https://github.com/tinh-tinh/tslog
- Owner: tinh-tinh
- License: mit
- Created: 2026-03-18T14:42:56.000Z (3 months ago)
- Default Branch: master
- Last Pushed: 2026-05-11T15:18:55.000Z (about 1 month ago)
- Last Synced: 2026-05-11T17:17:40.782Z (about 1 month ago)
- Topics: framework, golang, slog
- Language: Go
- Homepage:
- Size: 10.7 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# T-SLOG
[](https://github.com/tinh-tinh/tslog/actions/workflows/go.yml)
[](https://codecov.io/gh/tinh-tinh/tslog)
[](https://pkg.go.dev/github.com/tinh-tinh/tslog)
[](https://goreportcard.com/report/github.com/tinh-tinh/tslog)

**tslog** is a structured logging module for the [Tinh Tinh](https://github.com/tinh-tinh/tinhtinh) framework, built on top of Go's standard [`log/slog`](https://pkg.go.dev/log/slog) package. It integrates `slog` as a first-class provider within the Tinh Tinh dependency injection system and exposes a flexible middleware for HTTP request logging.
---
## Features
- 🔌 **DI-friendly** — Register any `slog.Handler` as a module-level provider using `ForRoot`
- 💉 **Easy injection** — Retrieve the logger anywhere via `Inject(module)`
- 🛣️ **HTTP middleware** — Log every incoming request with a customisable function
- ⏭️ **Skip paths** — Exclude health-check or any other routes from logging
- 🔗 **Context-aware** — Use `slog.Logger.InfoContext` together with request context for trace/request-ID propagation
---
## Requirements
| Dependency | Version |
|---|---|
| Go | ≥ 1.24 |
| `github.com/tinh-tinh/tinhtinh` | v2 |
---
## Installation
```bash
go get github.com/tinh-tinh/tslog
```
---
## Quick Start
### 1. Register the module
Pass any standard `slog.Handler` to `ForRoot`. The logger is registered as a named provider (`TSLOG`) and made available across all imported modules.
```go
package main
import (
"log/slog"
"os"
"github.com/tinh-tinh/tinhtinh/v2/core"
"github.com/tinh-tinh/tslog"
)
func main() {
appModule := func() core.Module {
return core.NewModule(core.NewModuleOptions{
Imports: []core.Modules{
tslog.ForRoot(slog.NewJSONHandler(os.Stdout, nil)),
},
Controllers: []core.Controllers{userController},
})
}
app := core.CreateFactory(appModule)
app.Listen(3000)
}
```
### 2. Inject and use the logger
Inside any controller or service, call `tslog.Inject(module)` to obtain the `*slog.Logger`.
```go
func userController(module core.Module) core.Controller {
ctrl := module.NewController("users")
logger := tslog.Inject(module)
ctrl.Get("", func(ctx core.Ctx) error {
logger.Info("Request processed",
"http", slog.Group("request",
"method", "GET",
"path", "/api/users",
"status", 200,
),
"duration_ms", 42,
)
return ctx.JSON(map[string]any{"ok": true})
})
return ctrl
}
```
---
## HTTP Middleware
### Basic logging middleware
`tslog.Middleware` wraps a user-supplied function (`Fnc`) that receives the request context. Use it to log method, path, latency, or any attribute you need.
```go
loggerMiddleware := tslog.Middleware(tslog.MiddlewareOptions{
Fnc: func(ctx core.Ctx) {
logger := ctx.Ref(tslog.TSLOG).(*slog.Logger)
logger.Info("Incoming request",
slog.Group("http",
slog.Group("request",
"method", ctx.Req().Method,
"path", ctx.Req().URL.Path,
),
),
)
},
})
appModule := func() core.Module {
return core.NewModule(core.NewModuleOptions{
Imports: []core.Modules{tslog.ForRoot(slog.NewJSONHandler(os.Stdout, nil))},
Controllers: []core.Controllers{userController},
Middlewares: []core.Middleware{loggerMiddleware},
})
}
```
### Skipping paths
Supply `SkipPaths` to prevent certain routes (e.g., health-check endpoints) from being logged.
```go
loggerMiddleware := tslog.Middleware(tslog.MiddlewareOptions{
SkipPaths: []string{"/health", "/readyz"},
Fnc: func(ctx core.Ctx) {
logger := ctx.Ref(tslog.TSLOG).(*slog.Logger)
logger.Info("Incoming request",
"method", ctx.Req().Method,
"path", ctx.Req().URL.Path,
)
},
})
```
---
## Context-Aware Logging (Trace / Request ID)
Combine tslog with a custom `slog.Handler` that reads values from the request context to automatically attach trace or request IDs to every log line.
```go
const reqIDKey = "req_id"
// ContextHandler enriches each log record with the request ID stored in ctx.
type ContextHandler struct{ slog.Handler }
func (h ContextHandler) Handle(ctx context.Context, r slog.Record) error {
if reqID, ok := ctx.Value(reqIDKey).(string); ok {
r.AddAttrs(slog.String("req_id", reqID))
}
return h.Handler.Handle(ctx, r)
}
// traceMiddleware assigns a unique request ID and stores it in context.
traceMiddleware := func(ctx core.Ctx) error {
ctx.Set(reqIDKey, rand.Text())
return ctx.Next()
}
// loggerMiddleware logs using the enriched context.
loggerMiddleware := tslog.Middleware(tslog.MiddlewareOptions{
Fnc: func(ctx core.Ctx) {
logger := ctx.Ref(tslog.TSLOG).(*slog.Logger)
logger.InfoContext(ctx.Req().Context(), "API Request")
},
})
appModule := func() core.Module {
base := slog.NewJSONHandler(os.Stdout, nil)
return core.NewModule(core.NewModuleOptions{
Imports: []core.Modules{tslog.ForRoot(ContextHandler{Handler: base})},
Controllers: []core.Controllers{userController},
Middlewares: []core.Middleware{traceMiddleware, loggerMiddleware},
})
}
```
Every log line produced inside a request will now contain a `req_id` field automatically.
---
## API Reference
### `ForRoot(h slog.Handler) core.Modules`
Registers a new `*slog.Logger` (backed by `h`) as the `TSLOG` provider in the module. Call this once in your root module's `Imports`.
### `Inject(module core.Module) *slog.Logger`
Retrieves the `*slog.Logger` registered by `ForRoot`. Returns `nil` if `ForRoot` was not imported.
### `Middleware(options MiddlewareOptions) core.Middleware`
Returns a Tinh Tinh middleware that:
1. Skips execution for any path listed in `SkipPaths`.
2. Calls `Fnc(ctx)` for all other requests.
#### `MiddlewareOptions`
| Field | Type | Description |
|---|---|---|
| `SkipPaths` | `[]string` | URL paths that bypass the middleware |
| `Fnc` | `func(ctx core.Ctx)` | Logging logic executed per request |
### `TSLOG`
A `core.Provide` constant (`"TS_LOG"`) used as the DI token. Use `ctx.Ref(tslog.TSLOG)` inside middleware to retrieve the logger.
---
## Testing
```bash
go test -cover ./...
```
The CI pipeline runs tests against Go **1.24**, **1.25**, and **1.26**, with coverage reports uploaded to [Codecov](https://codecov.io/gh/tinh-tinh/tslog).
---
## License
Distributed under the MIT License. See [LICENSE](LICENSE) for details.