TraceSight is a Go library that provides a pluggable interface for distributed tracing. Currently, it supports Sentry as its first-class tracing driver, and it can be easily extended to support other tracing backends.
- Central entrypoint:
traceSight.go - Driver interface definition:
internal/drivers/drivers.go - Sentry driver implementation:
The library also includes an integration with the Fiber framework:
- Fiber integration:
integrations/fiberIntegration/fiber.go
Below you will find:
- Features
- Installation
- Usage
- Fiber Integration Example
- Advanced Usage
- Extending TraceSight
- Project Structure
- Driver-based architecture: Easily switch or add new backends (Sentry, etc.).
- Transaction & Span abstraction: Create hierarchical traces (root transaction → child spans).
- Context propagation: Transactions and spans are tied to Go's
context.Context. - User info & HTTP request binding: Attach user data and request/response details to the trace.
- Fiber middleware: Simple drop-in middleware for automatic transaction creation on each request.
go get github.com/sky93/trace-sightTraceSight depends on Sentry Go SDK and optionally Fiber. Make sure they are included in your go.mod.
In order to use the Sentry driver, ensure that Sentry is properly initialized:
import (
"github.com/getsentry/sentry-go"
)
func main() {
err := sentry.Init(sentry.ClientOptions{
Dsn: "YOUR_SENTRY_DSN", // put your DSN here
EnableTracing: true,
TracesSampleRate: 0.1,
})
if err != nil {
panic(err)
}
// ...
}package main
import (
"fmt"
"context"
"github.com/sky93/trace-sight"
)
func main() {
// 1) Initialize Sentry as above.
// 2) Then initialize TraceSight with the Sentry driver:
err := trace.New(trace.SentryDriver)
if err != nil {
panic(fmt.Errorf("failed to initialize TraceSight: %w", err))
}
// Now you can create transactions/spans or use the Fiber middleware integration.
// ...
}// Create a root transaction
tx, err := trace.NewTransaction(context.Background(), "my-operation", "my-description")
if err != nil {
// handle error
}
// Do some work ...
// Create a child span
childSpan := trace.NewSpan(tx.Context(), "child-operation", "child-description")
// Do child work ...
childSpan.End()
// End the root transaction
tx.End()TraceSight provides a middleware for Fiber. This middleware:
- Creates a new transaction for each incoming HTTP request.
- Attaches the transaction to the request context.
- Ends the transaction automatically after the request completes.
You can find the middleware in integrations/fiberIntegration/fiber.go.
import (
"log"
"github.com/gofiber/fiber/v2"
"github.com/sky93/trace-sight"
"github.com/sky93/trace-sight/integrations/fiberIntegration"
"github.com/getsentry/sentry-go"
)
func main() {
// 1) Initialize Sentry
err := sentry.Init(sentry.ClientOptions{
Dsn: "YOUR_SENTRY_DSN",
})
if err != nil {
log.Fatal("Sentry initialization failed: ", err)
}
// 2) Initialize TraceSight with Sentry driver
err = trace.New(trace.SentryDriver)
if err != nil {
log.Fatal("TraceSight initialization failed: ", err)
}
// 3) Set up Fiber
app := fiber.New()
// 4) Use the TraceSight middleware
app.Use(fiberIntegration.TraceSightMiddleware)
// 5) Add routes
app.Get("/", func(c *fiber.Ctx) error {
// Retrieve the current transaction if needed
tx := trace.GetCurrentTransaction(c.UserContext())
if tx != nil {
tx.SetTag("example-tag", "hello-world")
}
return c.SendString("Hello from Fiber with Sentry tracing!")
})
// 6) Start server
log.Fatal(app.Listen(":3000"))
}Note: The middleware will create and end a new transaction for each request. If you want to create child spans inside your handler, you can use
trace.NewSpan(c.UserContext(), "child-span-op", "some description").
You can attach user information to the current transaction so that Sentry can display the user data in the event/timeline:
package main
import "github.com/sky93/trace-sight"
func handler(ctx context.Context) {
tx := trace.GetCurrentTransaction(ctx)
if tx != nil {
userInfo := trace.CreateUser(trace.UserInfo{
ID: "12345",
Email: "user@example.com",
Username: "myusername",
IP: "192.168.1.1",
Name: "John Doe",
})
tx.SetUser(userInfo)
}
// ...
}When using the Fiber middleware, the HTTP request is automatically attached to the transaction. You can also set the response code on the transaction if you want to override or finalize it manually:
tx := trace.GetCurrentTransaction(ctx)
if tx != nil {
// Once you know your response code:
tx.SetResponseCode(200)
}func doSubOperation(ctx context.Context) {
childSpan := trace.NewSpan(ctx, "sub-operation", "Additional details")
defer childSpan.End()
// Perform sub-operation...
// Use childSpan.Context() instead of ctx from now on...
}If you want to add support for another tracing backend (e.g., Jaeger, Zipkin, etc.):
- Create a new driver implementing the
drivers.TraceSightinterface. - Provide concrete types implementing
TransactionandSpan. - Update
traceSight.goto register and initialize your new driver.
TraceSight is designed to be driver-agnostic, so adding new backends should be straightforward.
tracesight/
├── go.mod
├── go.sum
├── integrations
│ └── fiberIntegration
│ └── fiber.go // Fiber middleware
├── internal
│ └── drivers
│ ├── drivers.go // Driver interfaces
│ └── sentry // Sentry driver implementation
│ ├── span.go
│ ├── tracer.go
│ └── transaction.go
└── traceSight.go // Main entry point and orchestrator
traceSight.go: Exports theNew,NewTransaction,NewSpan, and helper functions to interact with the chosen driver.internal/drivers/drivers.go: Defines theTraceSight,Transaction, andSpaninterfaces that each driver must implement.internal/drivers/sentry: Contains the Sentry-based implementation.integrations/fiberIntegration/fiber.go: A sample middleware for Fiber that starts and stops transactions automatically.
Contributions, bug reports, and feature requests are welcome! Feel free to open an issue or submit a pull request.
Enjoy tracing with TraceSight! If you have any questions or issues, please file an issue or reach out @sky93. Contributions are always welcome.