Last active
January 3, 2025 20:07
-
-
Save angristan/9139b26a390a9ae236e5fe711ae58ec7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"database/sql" | |
"fmt" | |
"log" | |
"math/rand" | |
"os" | |
"time" | |
"github.com/getsentry/sentry-go" | |
sentryotel "github.com/getsentry/sentry-go/otel" | |
"github.com/gin-gonic/gin" | |
_ "github.com/lib/pq" | |
"github.com/redis/go-redis/extra/redisotel/v9" | |
"github.com/redis/go-redis/v9" | |
"go.nhat.io/otelsql" | |
"go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin" | |
"go.opentelemetry.io/otel" | |
sdktrace "go.opentelemetry.io/otel/sdk/trace" | |
semconv "go.opentelemetry.io/otel/semconv/v1.4.0" | |
) | |
type User struct { | |
Email string `json:"email"` | |
} | |
type Response struct { | |
Email string `json:"email"` | |
RedisKey string `json:"redis_key"` | |
RedisValue string `json:"redis_value"` | |
} | |
func main() { | |
// Initialize Sentry | |
err := sentry.Init(sentry.ClientOptions{ | |
Dsn: os.Getenv("SENTRY_DSN"), | |
EnableTracing: true, | |
TracesSampleRate: 1.0, | |
Debug: true, | |
}) | |
if err != nil { | |
log.Fatalf("sentry.Init: %s", err) | |
} | |
defer sentry.Flush(2 * time.Second) | |
tp := sdktrace.NewTracerProvider( | |
sdktrace.WithSpanProcessor(sentryotel.NewSentrySpanProcessor()), | |
) | |
otel.SetTracerProvider(tp) | |
otel.SetTextMapPropagator(sentryotel.NewSentryPropagator()) | |
// Instrument PostgreSQL with otelsql | |
driverName, err := otelsql.Register("postgres", | |
otelsql.AllowRoot(), | |
otelsql.TraceQueryWithoutArgs(), | |
otelsql.TraceAll(), | |
otelsql.TraceRowsClose(), | |
otelsql.TraceRowsAffected(), | |
otelsql.WithDatabaseName("my_database"), // Optional. | |
otelsql.WithSystem(semconv.DBSystemPostgreSQL), // Optional. | |
) | |
if err != nil { | |
log.Fatalf("otelsql.Register: %s", err) | |
} | |
// Initialize PostgreSQL connection | |
db, err := sql.Open(driverName, os.Getenv("DATABASE_URL")) | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer db.Close() | |
// Test the database connection | |
err = db.Ping() | |
if err != nil { | |
log.Fatal(err) | |
} | |
// Initialize Redis client with tracing | |
opt, err := redis.ParseURL(os.Getenv("REDIS_URL")) | |
if err != nil { | |
log.Fatal(err) | |
} | |
rdb := redis.NewClient(opt) | |
if err := redisotel.InstrumentTracing(rdb); err != nil { | |
log.Fatalf("Failed to instrument Redis for tracing: %s", err) | |
} | |
defer rdb.Close() | |
// Create a Gin router | |
r := gin.Default() | |
r.Use(otelgin.Middleware("GinRedisPostgresService")) | |
r.GET("/", func(c *gin.Context) { | |
ctx := c.Request.Context() | |
// Generate random key and value | |
randomKey := fmt.Sprintf("key_%d", rand.Int()) | |
randomValue := fmt.Sprintf("value_%d", rand.Int()) | |
// Redis SET with TTL | |
err := rdb.Set(ctx, randomKey, randomValue, 1*time.Hour).Err() | |
if err != nil { | |
sentry.CaptureException(err) | |
c.JSON(500, gin.H{"error": "Redis SET error"}) | |
return | |
} | |
// Redis GET | |
val, err := rdb.Get(ctx, randomKey).Result() | |
if err != nil { | |
sentry.CaptureException(err) | |
c.JSON(500, gin.H{"error": "Redis GET error"}) | |
return | |
} | |
// Query database | |
var user User | |
err = db.QueryRowContext(ctx, "SELECT email FROM users WHERE id = 1 LIMIT 1").Scan(&user.Email) | |
if err != nil { | |
sentry.CaptureException(err) | |
c.JSON(500, gin.H{"error": "Database query error"}) | |
return | |
} | |
// Prepare response | |
response := Response{ | |
Email: user.Email, | |
RedisKey: randomKey, | |
RedisValue: val, | |
} | |
// Send JSON response | |
c.JSON(200, response) | |
}) | |
// Start the Gin server | |
port := os.Getenv("PORT") | |
if port == "" { | |
port = "8080" | |
} | |
log.Printf("Server starting on port %s", port) | |
if err := r.Run(":" + port); err != nil { | |
log.Fatal(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment