Skip to content

Commit 0c4985b

Browse files
authored
feat: add the code for casbin-opentelemetry-logger
1 parent a54bcfb commit 0c4985b

File tree

8 files changed

+1279
-1
lines changed

8 files changed

+1279
-1
lines changed

.github/workflows/ci.yml

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
branches:
9+
- master
10+
11+
jobs:
12+
test:
13+
name: Test
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
strategy:
18+
matrix:
19+
go-version: ['1.23.0']
20+
21+
steps:
22+
- name: Checkout code
23+
uses: actions/checkout@v4
24+
25+
- name: Set up Go
26+
uses: actions/setup-go@v5
27+
with:
28+
go-version: ${{ matrix.go-version }}
29+
30+
- name: Get dependencies
31+
run: go mod download
32+
33+
- name: Run tests
34+
run: go test -v -race -coverprofile=coverage.out -covermode=atomic ./...
35+
36+
- name: Upload coverage to Codecov
37+
uses: codecov/codecov-action@v4
38+
with:
39+
file: ./coverage.out
40+
flags: unittests
41+
name: codecov-umbrella
42+
43+
build:
44+
name: Build
45+
runs-on: ubuntu-latest
46+
permissions:
47+
contents: read
48+
strategy:
49+
matrix:
50+
go-version: ['1.23.0']
51+
52+
steps:
53+
- name: Checkout code
54+
uses: actions/checkout@v4
55+
56+
- name: Set up Go
57+
uses: actions/setup-go@v5
58+
with:
59+
go-version: ${{ matrix.go-version }}
60+
61+
- name: Build
62+
run: go build -v ./...
63+
64+
release:
65+
name: Release
66+
runs-on: ubuntu-latest
67+
permissions:
68+
contents: write
69+
issues: write
70+
pull-requests: write
71+
needs: [test, build]
72+
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
73+
74+
steps:
75+
- name: Checkout code
76+
uses: actions/checkout@v4
77+
with:
78+
fetch-depth: 0
79+
80+
- name: Set up Node.js
81+
uses: actions/setup-node@v4
82+
with:
83+
node-version: 'lts/*'
84+
85+
- name: Install semantic-release
86+
run: |
87+
npm install -g semantic-release@24 \
88+
conventional-changelog-conventionalcommits@8
89+
90+
- name: Release
91+
env:
92+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
93+
run: npx semantic-release

.releaserc.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"branches": ["master"],
3+
"plugins": [
4+
["@semantic-release/commit-analyzer", {
5+
"preset": "conventionalcommits",
6+
"releaseRules": [
7+
{"type": "feat", "release": "minor"},
8+
{"type": "fix", "release": "patch"},
9+
{"type": "perf", "release": "patch"},
10+
{"type": "revert", "release": "patch"},
11+
{"type": "docs", "release": "patch"},
12+
{"type": "chore", "release": false},
13+
{"type": "refactor", "release": "patch"},
14+
{"type": "test", "release": false},
15+
{"type": "build", "release": false},
16+
{"type": "ci", "release": false}
17+
]
18+
}],
19+
["@semantic-release/release-notes-generator", {
20+
"preset": "conventionalcommits",
21+
"presetConfig": {
22+
"types": [
23+
{"type": "feat", "section": "Features"},
24+
{"type": "fix", "section": "Bug Fixes"},
25+
{"type": "perf", "section": "Performance Improvements"},
26+
{"type": "revert", "section": "Reverts"},
27+
{"type": "docs", "section": "Documentation"},
28+
{"type": "refactor", "section": "Code Refactoring"},
29+
{"type": "test", "section": "Tests", "hidden": true},
30+
{"type": "build", "section": "Build System", "hidden": true},
31+
{"type": "ci", "section": "CI", "hidden": true}
32+
]
33+
}
34+
}],
35+
["@semantic-release/github"]
36+
]
37+
}

README.md

Lines changed: 216 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,216 @@
1-
# casbin-opentelemetry-logger
1+
# casbin-opentelemetry-logger
2+
3+
[![Go Report Card](https://goreportcard.com/badge/github.com/casbin/casbin-opentelemetry-logger)](https://goreportcard.com/report/github.com/casbin/casbin-opentelemetry-logger)
4+
[![Go](https://github.com/casbin/casbin-opentelemetry-logger/actions/workflows/ci.yml/badge.svg)](https://github.com/casbin/casbin-opentelemetry-logger/actions/workflows/ci.yml)
5+
[![Coverage Status](https://codecov.io/gh/casbin/casbin-opentelemetry-logger/branch/master/graph/badge.svg)](https://codecov.io/gh/casbin/casbin-opentelemetry-logger)
6+
[![GoDoc](https://godoc.org/github.com/casbin/casbin-opentelemetry-logger?status.svg)](https://godoc.org/github.com/casbin/casbin-opentelemetry-logger)
7+
[![Release](https://img.shields.io/github/release/casbin/casbin-opentelemetry-logger.svg)](https://github.com/casbin/casbin-opentelemetry-logger/releases/latest)
8+
[![Discord](https://img.shields.io/discord/1022748306096537660?logo=discord&label=discord&color=5865F2)](https://discord.gg/S5UjpzGZjN)
9+
10+
An OpenTelemetry logger implementation for [Casbin](https://github.com/casbin/casbin), providing event-driven metrics collection for authorization events.
11+
12+
## Features
13+
14+
- **Event-Driven Logging**: Implements the Casbin Logger interface with support for event-driven logging
15+
- **OpenTelemetry Metrics**: Exports comprehensive metrics using the OpenTelemetry standard
16+
- **Customizable Event Types**: Filter which event types to log
17+
- **Custom Callbacks**: Add custom processing for log entries
18+
- **Context Support**: Support for custom contexts for propagation and cancellation
19+
20+
## Metrics Exported
21+
22+
### Enforce Metrics
23+
- `casbin.enforce.total` - Total number of enforce requests (labeled by `allowed`, `domain`)
24+
- `casbin.enforce.duration` - Duration of enforce requests in seconds (labeled by `allowed`, `domain`)
25+
26+
### Policy Operation Metrics
27+
- `casbin.policy.operations.total` - Total number of policy operations (labeled by `operation`, `success`)
28+
- `casbin.policy.operations.duration` - Duration of policy operations in seconds (labeled by `operation`)
29+
- `casbin.policy.rules.count` - Number of policy rules affected by operations (labeled by `operation`)
30+
31+
## Installation
32+
33+
```bash
34+
go get github.com/casbin/casbin-opentelemetry-logger
35+
```
36+
37+
## Usage
38+
39+
### Basic Usage
40+
41+
```go
42+
package main
43+
44+
import (
45+
"context"
46+
47+
opentelemetrylogger "github.com/casbin/casbin-opentelemetry-logger"
48+
"go.opentelemetry.io/otel"
49+
)
50+
51+
func main() {
52+
// Get a meter from your OpenTelemetry provider
53+
meter := otel.Meter("casbin")
54+
55+
// Create logger
56+
logger, err := opentelemetrylogger.NewOpenTelemetryLogger(meter)
57+
if err != nil {
58+
panic(err)
59+
}
60+
61+
// Use with Casbin
62+
// enforcer.SetLogger(logger)
63+
}
64+
```
65+
66+
### With Custom Context
67+
68+
```go
69+
ctx := context.Background()
70+
logger, err := opentelemetrylogger.NewOpenTelemetryLoggerWithContext(ctx, meter)
71+
if err != nil {
72+
panic(err)
73+
}
74+
```
75+
76+
### Configure Event Types
77+
78+
```go
79+
// Only log specific event types
80+
logger.SetEventTypes([]opentelemetrylogger.EventType{
81+
opentelemetrylogger.EventEnforce,
82+
opentelemetrylogger.EventAddPolicy,
83+
})
84+
```
85+
86+
### Add Custom Callback
87+
88+
```go
89+
// Add custom processing for log entries
90+
logger.SetLogCallback(func(entry *opentelemetrylogger.LogEntry) error {
91+
fmt.Printf("Event: %s, Duration: %v\n", entry.EventType, entry.Duration)
92+
return nil
93+
})
94+
```
95+
96+
## Event Types
97+
98+
The logger supports the following event types:
99+
100+
- `EventEnforce` - Authorization enforcement requests
101+
- `EventAddPolicy` - Policy addition operations
102+
- `EventRemovePolicy` - Policy removal operations
103+
- `EventLoadPolicy` - Policy loading operations
104+
- `EventSavePolicy` - Policy saving operations
105+
106+
## Complete Example with OTLP Exporter
107+
108+
```go
109+
package main
110+
111+
import (
112+
"context"
113+
"log"
114+
"time"
115+
116+
opentelemetrylogger "github.com/casbin/casbin-opentelemetry-logger"
117+
"go.opentelemetry.io/otel"
118+
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
119+
"go.opentelemetry.io/otel/sdk/metric"
120+
"go.opentelemetry.io/otel/sdk/resource"
121+
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
122+
)
123+
124+
func main() {
125+
ctx := context.Background()
126+
127+
// Create OTLP exporter
128+
exporter, err := otlpmetricgrpc.New(ctx,
129+
otlpmetricgrpc.WithEndpoint("localhost:4317"),
130+
otlpmetricgrpc.WithInsecure(),
131+
)
132+
if err != nil {
133+
log.Fatal(err)
134+
}
135+
136+
// Create resource
137+
res, err := resource.New(ctx,
138+
resource.WithAttributes(
139+
semconv.ServiceName("casbin-app"),
140+
),
141+
)
142+
if err != nil {
143+
log.Fatal(err)
144+
}
145+
146+
// Create meter provider
147+
provider := metric.NewMeterProvider(
148+
metric.WithReader(metric.NewPeriodicReader(exporter)),
149+
metric.WithResource(res),
150+
)
151+
otel.SetMeterProvider(provider)
152+
153+
// Create logger
154+
meter := otel.Meter("casbin")
155+
logger, err := opentelemetrylogger.NewOpenTelemetryLogger(meter)
156+
if err != nil {
157+
log.Fatal(err)
158+
}
159+
160+
// Use with Casbin enforcer
161+
// enforcer.SetLogger(logger)
162+
163+
// Shutdown
164+
defer func() {
165+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
166+
defer cancel()
167+
if err := provider.Shutdown(ctx); err != nil {
168+
log.Printf("Error shutting down meter provider: %v", err)
169+
}
170+
}()
171+
}
172+
```
173+
174+
## OpenTelemetry Collector Configuration
175+
176+
To collect metrics from your application, configure the OpenTelemetry Collector:
177+
178+
```yaml
179+
receivers:
180+
otlp:
181+
protocols:
182+
grpc:
183+
endpoint: 0.0.0.0:4317
184+
185+
exporters:
186+
prometheus:
187+
endpoint: "0.0.0.0:8889"
188+
logging:
189+
loglevel: debug
190+
191+
service:
192+
pipelines:
193+
metrics:
194+
receivers: [otlp]
195+
exporters: [prometheus, logging]
196+
```
197+
198+
## Visualization with Prometheus and Grafana
199+
200+
1. **Configure OpenTelemetry Collector** to export metrics to Prometheus (see above)
201+
2. **Configure Prometheus** to scrape the OpenTelemetry Collector endpoint
202+
3. **Import Grafana Dashboard** using similar panels as the Prometheus logger project
203+
204+
## License
205+
206+
This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details.
207+
208+
## Contributing
209+
210+
Contributions are welcome! Please feel free to submit a Pull Request.
211+
212+
## Related Projects
213+
214+
- [Casbin](https://github.com/casbin/casbin) - An authorization library that supports access control models
215+
- [OpenTelemetry](https://opentelemetry.io/) - Observability framework for cloud-native software
216+
- [casbin-prometheus-logger](https://github.com/casbin/casbin-prometheus-logger) - Prometheus logger for Casbin

go.mod

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module github.com/casbin/casbin-opentelemetry-logger
2+
3+
go 1.23.0
4+
5+
require (
6+
go.opentelemetry.io/otel v1.33.0
7+
go.opentelemetry.io/otel/metric v1.33.0
8+
go.opentelemetry.io/otel/sdk/metric v1.33.0
9+
)
10+
11+
require (
12+
github.com/go-logr/logr v1.4.2 // indirect
13+
github.com/go-logr/stdr v1.2.2 // indirect
14+
github.com/google/uuid v1.6.0 // indirect
15+
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
16+
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
17+
go.opentelemetry.io/otel/trace v1.33.0 // indirect
18+
golang.org/x/sys v0.29.0 // indirect
19+
)

0 commit comments

Comments
 (0)