Top Related Projects
CNCF Jaeger, a Distributed Tracing Platform
OpenTelemetry Collector
Grafana Tempo is a high volume, minimal dependency distributed tracing backend.
Quick Overview
Uptrace/bun is an open-source distributed tracing system and application performance monitoring (APM) tool. It's designed to help developers monitor, troubleshoot, and optimize their applications by providing insights into system performance and behavior.
Pros
- Easy to set up and integrate with existing applications
- Supports multiple programming languages and frameworks
- Provides detailed performance metrics and visualizations
- Offers both self-hosted and cloud-based options
Cons
- Relatively new project, may have fewer features compared to more established APM tools
- Documentation could be more comprehensive
- Limited community support compared to larger, more popular APM solutions
Code Examples
Here are a few examples of how to use Uptrace with different programming languages:
- Go example (using OpenTelemetry):
import (
"go.opentelemetry.io/otel"
"github.com/uptrace/uptrace-go/uptrace"
)
func main() {
uptrace.ConfigureOpenTelemetry(
uptrace.WithDSN("https://<token>@api.uptrace.dev/<project_id>"),
)
defer uptrace.Shutdown()
tracer := otel.Tracer("my-app")
ctx, span := tracer.Start(context.Background(), "main")
defer span.End()
// Your application code here
}
- Python example:
from opentelemetry import trace
from uptrace import configure_opentelemetry
configure_opentelemetry(
dsn="https://<token>@api.uptrace.dev/<project_id>",
service_name="myapp",
service_version="1.0.0",
)
tracer = trace.get_tracer("my-app")
with tracer.start_as_current_span("main"):
# Your application code here
- Node.js example:
const { NodeTracerProvider } = require('@opentelemetry/node');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { UptracePropagator, UptraceBatchSpanProcessor } = require('@uptrace/uptrace-node');
const provider = new NodeTracerProvider();
provider.register({
propagator: new UptracePropagator(),
});
registerInstrumentations({
instrumentations: getNodeAutoInstrumentations(),
});
const uptrace = new UptraceBatchSpanProcessor({
dsn: 'https://<token>@api.uptrace.dev/<project_id>',
});
provider.addSpanProcessor(uptrace);
// Your application code here
Getting Started
To get started with Uptrace:
- Sign up for an Uptrace account at https://uptrace.dev/
- Create a new project and obtain your DSN (Data Source Name)
- Install the Uptrace library for your programming language (e.g.,
pip install uptracefor Python) - Configure Uptrace in your application using the provided DSN
- Instrument your code with OpenTelemetry traces and metrics
- Deploy your application and start monitoring its performance in the Uptrace dashboard
For more detailed instructions and language-specific guides, refer to the official Uptrace documentation.
Competitor Comparisons
CNCF Jaeger, a Distributed Tracing Platform
Pros of Jaeger
- More mature and widely adopted in the industry
- Supports multiple storage backends (Cassandra, Elasticsearch, etc.)
- Offers a rich set of features for distributed tracing
Cons of Jaeger
- Can be complex to set up and configure
- Requires more resources to run effectively
- May have a steeper learning curve for beginners
Code Comparison
Jaeger (Go):
tracer, closer, err := cfg.NewTracer(
config.Logger(jaeger.StdLogger),
)
defer closer.Close()
Bun (JavaScript):
const tracer = new BunTracer({
serviceName: 'my-service',
url: 'http://localhost:14318/v1/traces'
});
Additional Notes
Bun is a more lightweight and easy-to-use alternative to Jaeger, focusing on simplicity and developer experience. It's designed to work well with modern JavaScript and TypeScript applications, making it a good choice for teams already using these technologies.
Jaeger, on the other hand, offers a more comprehensive solution for distributed tracing across various languages and frameworks. It's better suited for large-scale, complex systems where advanced features and flexibility are required.
OpenTelemetry Collector
Pros of OpenTelemetry Collector
- Widely adopted and supported by the OpenTelemetry community
- Offers a more comprehensive set of features for telemetry data collection and processing
- Highly extensible with a plugin architecture for custom receivers, processors, and exporters
Cons of OpenTelemetry Collector
- More complex setup and configuration compared to Bun
- Potentially higher resource usage due to its comprehensive feature set
- Steeper learning curve for newcomers to observability and telemetry
Code Comparison
OpenTelemetry Collector configuration (YAML):
receivers:
otlp:
protocols:
grpc:
processors:
batch:
exporters:
prometheus:
endpoint: "0.0.0.0:8889"
Bun configuration (JavaScript):
import { BunTracer } from "bun";
const tracer = new BunTracer({
serviceName: "my-service",
endpoint: "http://localhost:14268/api/traces"
});
The OpenTelemetry Collector configuration demonstrates its flexibility in defining receivers, processors, and exporters. In contrast, Bun's configuration is more straightforward and focused on tracing setup. While the OpenTelemetry Collector offers more customization options, Bun provides a simpler approach for quick integration into JavaScript/TypeScript projects.
Grafana Tempo is a high volume, minimal dependency distributed tracing backend.
Pros of Tempo
- More mature and widely adopted project with a larger community
- Integrated with Grafana's ecosystem for visualization and querying
- Supports multiple storage backends (S3, GCS, Azure Blob Storage)
Cons of Tempo
- Higher resource requirements and complexity
- Steeper learning curve for setup and configuration
- Limited to tracing data, while Bun offers a more comprehensive observability solution
Code Comparison
Tempo (configuration example):
tempo:
receivers:
jaeger:
protocols:
thrift_http:
endpoint: 0.0.0.0:14268
Bun (configuration example):
bun.Init(&bun.Config{
DSN: "postgres://user:pass@localhost:5432/db",
TracingEnabled: true,
})
Summary
Tempo is a robust distributed tracing backend with strong integration into the Grafana ecosystem, making it suitable for large-scale deployments. Bun, on the other hand, offers a more lightweight and comprehensive observability solution that includes tracing, metrics, and logging. While Tempo excels in tracing-specific features and scalability, Bun provides a simpler setup and broader observability capabilities in a single package. The choice between the two depends on specific project requirements, existing infrastructure, and the desired level of integration with other tools.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Bun: SQL-first Golang ORM
Lightweight, SQL-first Golang ORM for PostgreSQL, MySQL, MSSQL, SQLite, and Oracle
Bun is a modern ORM that embraces SQL rather than hiding it. Write complex queries in Go with type safety, powerful scanning capabilities, and database-agnostic code that works across multiple SQL databases.
⨠Key Features
- SQL-first approach - Write elegant, readable queries that feel like SQL
- Multi-database support - PostgreSQL, MySQL/MariaDB, MSSQL, SQLite, and Oracle
- Type-safe operations - Leverage Go's static typing for compile-time safety
- Flexible scanning - Query results into structs, maps, scalars, or slices
- Performance optimized - Built on
database/sqlwith minimal overhead - Rich relationships - Define complex table relationships with struct tags
- Production ready - Migrations, fixtures, soft deletes, and OpenTelemetry support
ð Quick Start
go get github.com/uptrace/bun
Basic Example
package main
import (
"context"
"database/sql"
"fmt"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/sqlitedialect"
"github.com/uptrace/bun/driver/sqliteshim"
)
func main() {
ctx := context.Background()
// Open database
sqldb, err := sql.Open(sqliteshim.ShimName, "file::memory:")
if err != nil {
panic(err)
}
// Create Bun instance
db := bun.NewDB(sqldb, sqlitedialect.New())
// Define model
type User struct {
ID int64 `bun:",pk,autoincrement"`
Name string `bun:",notnull"`
}
// Create table
db.NewCreateTable().Model((*User)(nil)).Exec(ctx)
// Insert user
user := &User{Name: "John Doe"}
db.NewInsert().Model(user).Exec(ctx)
// Query user
err = db.NewSelect().Model(user).Where("id = ?", user.ID).Scan(ctx)
fmt.Printf("User: %+v\n", user)
}
ð¯ Why Choose Bun?
Elegant Complex Queries
Write sophisticated queries that remain readable and maintainable:
regionalSales := db.NewSelect().
ColumnExpr("region").
ColumnExpr("SUM(amount) AS total_sales").
TableExpr("orders").
GroupExpr("region")
topRegions := db.NewSelect().
ColumnExpr("region").
TableExpr("regional_sales").
Where("total_sales > (SELECT SUM(total_sales) / 10 FROM regional_sales)")
var results []struct {
Region string `bun:"region"`
Product string `bun:"product"`
ProductUnits int `bun:"product_units"`
ProductSales int `bun:"product_sales"`
}
err := db.NewSelect().
With("regional_sales", regionalSales).
With("top_regions", topRegions).
ColumnExpr("region, product").
ColumnExpr("SUM(quantity) AS product_units").
ColumnExpr("SUM(amount) AS product_sales").
TableExpr("orders").
Where("region IN (SELECT region FROM top_regions)").
GroupExpr("region, product").
Scan(ctx, &results)
Flexible Result Scanning
Scan query results into various Go types:
// Into structs
var users []User
db.NewSelect().Model(&users).Scan(ctx)
// Into maps
var userMaps []map[string]interface{}
db.NewSelect().Table("users").Scan(ctx, &userMaps)
// Into scalars
var count int
db.NewSelect().Table("users").ColumnExpr("COUNT(*)").Scan(ctx, &count)
// Into individual variables
var id int64
var name string
db.NewSelect().Table("users").Column("id", "name").Limit(1).Scan(ctx, &id, &name)
ð Database Support
| Database | Driver | Dialect |
|---|---|---|
| PostgreSQL | github.com/uptrace/bun/driver/pgdriver | pgdialect.New() |
| MySQL/MariaDB | github.com/go-sql-driver/mysql | mysqldialect.New() |
| SQLite | github.com/uptrace/bun/driver/sqliteshim | sqlitedialect.New() |
| SQL Server | github.com/denisenkom/go-mssqldb | mssqldialect.New() |
| Oracle | github.com/sijms/go-ora/v2 | oracledialect.New() |
ð§ Advanced Features
Table Relationships
Define complex relationships with struct tags:
type User struct {
ID int64 `bun:",pk,autoincrement"`
Name string `bun:",notnull"`
Posts []Post `bun:"rel:has-many,join:id=user_id"`
Profile Profile `bun:"rel:has-one,join:id=user_id"`
}
type Post struct {
ID int64 `bun:",pk,autoincrement"`
Title string
UserID int64
User *User `bun:"rel:belongs-to,join:user_id=id"`
}
// Load users with their posts
var users []User
err := db.NewSelect().
Model(&users).
Relation("Posts").
Scan(ctx)
Bulk Operations
Efficient bulk operations for large datasets:
// Bulk insert
users := []User{{Name: "John"}, {Name: "Jane"}, {Name: "Bob"}}
_, err := db.NewInsert().Model(&users).Exec(ctx)
// Bulk update with CTE
_, err = db.NewUpdate().
Model(&users).
Set("updated_at = NOW()").
Where("active = ?", true).
Exec(ctx)
// Bulk delete
_, err = db.NewDelete().
Model((*User)(nil)).
Where("created_at < ?", time.Now().AddDate(-1, 0, 0)).
Exec(ctx)
Migrations
Version your database schema:
import "github.com/uptrace/bun/migrate"
migrations := migrate.NewMigrations()
migrations.MustRegister(func(ctx context.Context, db *bun.DB) error {
_, err := db.NewCreateTable().Model((*User)(nil)).Exec(ctx)
return err
}, func(ctx context.Context, db *bun.DB) error {
_, err := db.NewDropTable().Model((*User)(nil)).Exec(ctx)
return err
})
migrator := migrate.NewMigrator(db, migrations)
err := migrator.Init(ctx)
err = migrator.Up(ctx)
ð Monitoring & Observability
Debug Queries
Enable query logging for development:
import "github.com/uptrace/bun/extra/bundebug"
db.AddQueryHook(bundebug.NewQueryHook(
bundebug.WithVerbose(true),
))
OpenTelemetry Integration
Production-ready observability with distributed tracing:
import "github.com/uptrace/bun/extra/bunotel"
db.AddQueryHook(bunotel.NewQueryHook(
bunotel.WithDBName("myapp"),
))
Monitoring made easy: Bun is brought to you by â uptrace/uptrace. Uptrace is an open-source APM tool that supports distributed tracing, metrics, and logs. You can use it to monitor applications and set up automatic alerts to receive notifications via email, Slack, Telegram, and others.
See OpenTelemetry example which demonstrates how you can use Uptrace to monitor Bun.
ð Documentation & Resources
- Getting Started Guide - Comprehensive tutorial
- API Reference - Complete package documentation
- Examples - Working code samples
- Starter Kit - Production-ready template
- Community Discussions - Get help and share ideas
ð¤ Contributing
We welcome contributions! Please see our Contributing Guide for details on how to get started.
Thanks to all our contributors:
ð Related Projects
- Golang HTTP router - Fast and flexible HTTP router
- Golang msgpack - High-performance MessagePack serialization
Top Related Projects
CNCF Jaeger, a Distributed Tracing Platform
OpenTelemetry Collector
Grafana Tempo is a high volume, minimal dependency distributed tracing backend.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot