Convert Figma logo to code with AI

uptrace logobun

SQL-first Golang ORM

4,469
259
4,469
32

Top Related Projects

22,079

CNCF Jaeger, a Distributed Tracing Platform

OpenTelemetry Collector

4,846

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:

  1. 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
}
  1. 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
  1. 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:

  1. Sign up for an Uptrace account at https://uptrace.dev/
  2. Create a new project and obtain your DSN (Data Source Name)
  3. Install the Uptrace library for your programming language (e.g., pip install uptrace for Python)
  4. Configure Uptrace in your application using the provided DSN
  5. Instrument your code with OpenTelemetry traces and metrics
  6. 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

22,079

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.

4,846

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 Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Bun: SQL-first Golang ORM

build workflow PkgGoDev Documentation Chat Gurubase

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/sql with 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

DatabaseDriverDialect
PostgreSQLgithub.com/uptrace/bun/driver/pgdriverpgdialect.New()
MySQL/MariaDBgithub.com/go-sql-driver/mysqlmysqldialect.New()
SQLitegithub.com/uptrace/bun/driver/sqliteshimsqlitedialect.New()
SQL Servergithub.com/denisenkom/go-mssqldbmssqldialect.New()
Oraclegithub.com/sijms/go-ora/v2oracledialect.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

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details on how to get started.

Thanks to all our contributors:

Contributors

🔗 Related Projects


Star ⭐ this repo if you find Bun useful!
Join our community on Discord • Follow updates on GitHub