https://github.com/deviantony/drillog
Hierarchical logging for Go
https://github.com/deviantony/drillog
Last synced: 22 days ago
JSON representation
Hierarchical logging for Go
- Host: GitHub
- URL: https://github.com/deviantony/drillog
- Owner: deviantony
- Created: 2025-12-05T08:26:10.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2025-12-06T15:27:13.000Z (2 months ago)
- Last Synced: 2025-12-08T19:56:36.036Z (2 months ago)
- Language: Go
- Size: 66.4 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# drillog
Hierarchical logging for Go. Flat files, tree views.
## The Problem
Modern apps generate thousands of log lines. Concurrent operations interleave. Finding one request's journey through grep is painful.
## The Solution
Keep logs flat (greppable), but add minimal metadata. A viewer reconstructs the hierarchy on demand.
```
Your App → Flat Log File → Tree Viewer
(still works (see the
with grep) hierarchy)
```
## Usage
```go
package main
import (
"context"
"os"
"github.com/deviantony/drillog"
)
func main() {
drillog.SetDefault(drillog.NewTextHandler(os.Stderr, nil))
ctx := context.Background()
ctx, end := drillog.Start(ctx, "main")
defer end()
drillog.Info(ctx, "starting")
processOrder(ctx, 12345)
}
func processOrder(ctx context.Context, orderID int) {
ctx, end := drillog.Start(ctx, "processOrder")
defer end()
drillog.Info(ctx, "loading order", "order_id", orderID)
}
```
**Output:**
```
2025-12-04T10:00:00Z INFO main started span=a1b2c3d4
2025-12-04T10:00:00Z INFO starting span=a1b2c3d4
2025-12-04T10:00:00Z INFO processOrder started span=e5f6a7b8 parent=a1b2c3d4
2025-12-04T10:00:00Z INFO loading order order_id=12345 span=e5f6a7b8 parent=a1b2c3d4
2025-12-04T10:00:00Z INFO processOrder completed duration=1.2ms span=e5f6a7b8 parent=a1b2c3d4
2025-12-04T10:00:00Z INFO main completed duration=2.5ms span=a1b2c3d4
```
**In the viewer:**
```
▼ main [2.5ms]
│ starting
▼ processOrder [1.2ms]
│ loading order order_id=12345
```
## Installation
```bash
go get github.com/deviantony/drillog
```
## API
### Starting Spans
```go
ctx, end := drillog.Start(ctx, "operation name")
defer end()
```
Nested calls automatically capture parent relationships.
### Logging
```go
drillog.Debug(ctx, "message", "key", "value")
drillog.Info(ctx, "message", "key", "value")
drillog.Warn(ctx, "message", "key", "value")
drillog.Error(ctx, "message", "key", "value")
```
Or use standard slog (if handler is configured):
```go
slog.InfoContext(ctx, "message", "key", "value")
```
### Configuration
```go
// Text output (human-readable)
drillog.SetDefault(drillog.NewTextHandler(os.Stderr, nil))
// JSON output
drillog.SetDefault(drillog.NewJSONHandler(os.Stderr, nil))
// Wrap existing handler
drillog.SetDefault(drillog.NewHandler(myHandler, nil))
// Custom ID generator
drillog.SetDefault(drillog.NewTextHandler(os.Stderr, &drillog.HandlerOptions{
IDGenerator: myIDFunc,
}))
```
### Context Utilities
```go
spanID := drillog.SpanID(ctx) // current span ID
parentID := drillog.ParentID(ctx) // parent span ID
```
## Design Principles
- **Zero config works** - defaults to `slog.Default()`
- **Context-first** - no logger objects to pass around
- **Standard library only** - no external dependencies
- **Logs stay flat** - works with grep, tail, existing tools
- **Minimal API** - `Start()` + `defer end()` + log functions
## Viewer
Open `viewer.html` in any browser. Drag and drop your log file. See the tree.
## License
MIT