OpenTelemetry Beego monitoring [otelbeego]
OpenTelemetry Beego instrumentation allows developers to monitor and diagnose issues with their Beego applications, providing valuable insights into application behavior in production.
Quick Setup
| Step | Action | Code/Command |
|---|---|---|
| 1. Install | Install otelbeego package | go get go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego |
| 2. Import | Import otelbeego | import "go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego" |
| 3. Instrument | Create middleware and run with it | mware := otelbeego.NewOTelBeegoMiddleWare("my-service") then beego.RunWithMiddleWares(":8080", mware) |
| 4. Verify | Check your observability backend for traces | Traces collected automatically |
Minimal working example:
import (
"github.com/astaxie/beego"
"go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego"
)
func main() {
mware := otelbeego.NewOTelBeegoMiddleWare("my-service")
beego.Router("/", &MainController{})
beego.RunWithMiddleWares(":8080", mware)
}
This single middleware call automatically captures all incoming HTTP requests, traces request flow, and exports telemetry data to your configured backend.
What is Beego?
Beego is an open-source web framework written in Go that follows the Model-View-Controller (MVC) architectural pattern. It provides a comprehensive set of tools for building web applications and APIs.
Beego's key features include:
- Full MVC architecture with auto-routing
- Built-in ORM for database operations
- Session management and caching
- Logging, configuration, and task scheduling modules
- Hot-reload during development
What is OpenTelemetry?
OpenTelemetry is an open-source observability framework that aims to standardize and simplify the collection, processing, and export of telemetry data from applications and systems.
OpenTelemetry enables developers to instrument their code and collect telemetry data, which can then be exported to various OpenTelemetry backends or observability platforms for analysis and visualization. The OpenTelemetry architecture provides a modular, vendor-neutral approach to observability.
Configuration can be managed through OpenTelemetry environment variables, providing a standardized way to configure exporters, resource attributes, and sampling behavior across environments.
Beego instrumentation
OpenTelemetry Beego instrumentation (otelbeego) provides automatic tracing for your Beego applications. It captures HTTP request details, timing information, and error states without requiring manual instrumentation.
To install otelbeego instrumentation:
go get go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego
Usage
You can instrument Beego by creating an OpenTelemetry middleware and passing it to RunWithMiddleWares:
import (
"github.com/astaxie/beego"
"go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego"
)
func main() {
mware := otelbeego.NewOTelBeegoMiddleWare("my-service")
beego.Router("/api/users", &UserController{})
beego.Router("/api/orders", &OrderController{})
beego.RunWithMiddleWares(":8080", mware)
}
Once instrumented, otelbeego automatically creates spans for each incoming HTTP request, capturing method, route, status code, and timing information.
Middleware options
The otelbeego middleware supports several configuration options:
| Option | Description |
|---|---|
WithTracerProvider | Use a custom TracerProvider instead of the global one |
WithMeterProvider | Use a custom MeterProvider instead of the global one |
WithPropagators | Specify propagators for extracting trace context |
WithFilter | Filter requests (return true to trace, false to skip) |
Filtering health checks
Use the WithFilter option to exclude certain endpoints from tracing:
import (
"net/http"
"github.com/astaxie/beego"
"go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego"
)
mware := otelbeego.NewOTelBeegoMiddleWare("my-service",
otelbeego.WithFilter(func(r *http.Request) bool {
// Return true to trace, false to skip
return r.URL.Path != "/health" && r.URL.Path != "/ready"
}),
)
beego.RunWithMiddleWares(":8080", mware)
Custom tracer provider
For more control over telemetry collection, you can specify a custom provider:
import (
"github.com/astaxie/beego"
"go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego"
"go.opentelemetry.io/otel"
)
mware := otelbeego.NewOTelBeegoMiddleWare("my-service",
otelbeego.WithTracerProvider(otel.GetTracerProvider()),
otelbeego.WithMeterProvider(otel.GetMeterProvider()),
)
beego.RunWithMiddleWares(":8080", mware)
HTTP metrics
The otelbeego middleware automatically collects the following HTTP server metrics:
| Metric | Description |
|---|---|
http.server.request.duration | Duration of HTTP server requests |
http.server.request.body.size | Size of HTTP server request bodies |
http.server.response.body.size | Size of HTTP server response bodies |
These metrics follow the OpenTelemetry semantic conventions for HTTP and include attributes like method, route, and status code.
Instrumenting template rendering
To instrument template rendering, disable autorender and use helpers from otelbeego package:
import (
"github.com/astaxie/beego"
"go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego"
)
func init() {
beego.BConfig.WebConfig.AutoRender = false
}
func (c *MainController) Get() {
// Creates a child span for template rendering
err := otelbeego.Render(&c.Controller)
if err != nil {
c.Abort("500")
}
}
Available render helpers:
- otelbeego.Render - Render template with tracing
- otelbeego.RenderBytes - Render template to bytes with tracing
- otelbeego.RenderString - Render template to string with tracing
Instrumenting outgoing HTTP requests
To trace outgoing HTTP calls from your Beego controllers, use otelhttp to wrap the http.Client transport. This creates client spans that link to the parent server span, giving you end-to-end visibility across service boundaries:
import (
"io"
"net/http"
"github.com/astaxie/beego"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
// Create an instrumented HTTP client for outgoing requests
var httpClient = &http.Client{
Transport: otelhttp.NewTransport(http.DefaultTransport),
}
type ProxyController struct {
beego.Controller
}
func (c *ProxyController) Get() {
ctx := c.Ctx.Request.Context()
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.example.com/data", nil)
if err != nil {
c.Abort("500")
return
}
resp, err := httpClient.Do(req)
if err != nil {
c.Abort("502")
return
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
c.Ctx.Output.Body(body)
}
Creating custom spans
In addition to automatic instrumentation, you can create custom spans to trace specific operations within your controllers:
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
)
var tracer = otel.Tracer("my-service")
func (c *UserController) Get() {
ctx := c.Ctx.Request.Context()
// Create a custom span for database operation
ctx, span := tracer.Start(ctx, "fetch-user-from-database")
defer span.End()
userID := c.Ctx.Input.Param(":id")
span.SetAttributes(attribute.String("user.id", userID))
user, err := db.FindUser(ctx, userID)
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
c.Abort("500")
return
}
span.SetAttributes(attribute.Bool("user.found", user != nil))
c.Data["json"] = user
c.ServeJSON()
}
Error handling
OpenTelemetry Beego instrumentation automatically captures panics and errors. You can also manually record errors in your controllers:
import (
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
)
func (c *OrderController) Post() {
// Get the span from the request context
span := trace.SpanFromContext(c.Ctx.Request.Context())
order, err := processOrder(c.Ctx.Request.Context())
if err != nil {
// Record the error in the span
span.RecordError(err)
span.SetStatus(codes.Error, "order processing failed")
c.Abort("500")
return
}
c.Data["json"] = order
c.ServeJSON()
}
What is Uptrace?
Uptrace is an OpenTelemetry APM that supports distributed tracing, metrics, and logs. You can use it to monitor applications and troubleshoot issues.

Uptrace comes with an intuitive query builder, rich dashboards, alerting rules with notifications, and integrations for most languages and frameworks.
Uptrace can process billions of spans and metrics on a single server and allows you to monitor your applications at 10x lower cost.
In just a few minutes, you can try Uptrace by visiting the cloud demo (no login required) or running it locally with Docker. The source code is available on GitHub.
FAQ
What is otelbeego? The otelbeego package is the official OpenTelemetry instrumentation for the Beego framework. It provides middleware that automatically creates spans for incoming HTTP requests, capturing method, route, status code, and timing information. It also instruments template rendering through dedicated helper functions.
How do I filter health check endpoints? Use the WithFilter option when creating the middleware. Return false for paths like /health or /ready to skip tracing those requests. This reduces noise in your traces and lowers telemetry export costs.
Does otelbeego work with Beego's built-in filters? Yes, otelbeego works alongside Beego's built-in filters and middleware. The OpenTelemetry middleware wraps the entire request lifecycle, so all filters and handlers are captured within the trace. Place otelbeego first to ensure panics are captured before recovery middleware handles them.
What's the performance impact of otelbeego? The performance impact is minimal — typically a few microseconds per request for span creation and context propagation. For high-traffic applications, configure sampling to control the volume of exported spans.
Can I use otelbeego with Beego's namespace routing? Yes, the middleware is applied at the server level via RunWithMiddleWares, so all routes including namespaced routes are automatically instrumented. The http.route attribute in spans reflects the matched route pattern.
How do I instrument Beego's ORM alongside HTTP tracing? Beego's ORM uses database/sql internally. Use otelsql to instrument the database driver, giving you database query spans that nest under your HTTP request spans for end-to-end visibility.
How do I pass context to downstream services? The otelbeego middleware injects trace context into the request. Use c.Ctx.Request.Context() to retrieve it, then pass it to your database clients, HTTP clients, or gRPC calls to propagate tracing across services.
What's next?
With OpenTelemetry Beego instrumentation in place, you can monitor request latency, track error rates, and trace requests across your distributed systems.
Next steps to enhance your observability:
- Add database instrumentation with GORM or database/sql
- Correlate logs with traces using Zap or slog
- Create custom spans using the OpenTelemetry Go Tracing API
- Explore other Go frameworks like Gin or Echo
- Set up the OpenTelemetry Collector for production deployments