{"id":23583809,"url":"https://github.com/grahms/gorm-xray","last_synced_at":"2025-05-07T02:27:36.453Z","repository":{"id":268831276,"uuid":"905579116","full_name":"GraHms/gorm-xray","owner":"GraHms","description":"A GORM plugin that seamlessly integrates AWS X-Ray tracing into your Go application, allowing you to monitor and visualize SQL queries in real-time. ","archived":false,"fork":false,"pushed_at":"2024-12-19T06:59:43.000Z","size":14,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-07T01:12:17.624Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GraHms.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-19T05:45:06.000Z","updated_at":"2024-12-19T09:02:47.000Z","dependencies_parsed_at":"2024-12-19T07:31:59.092Z","dependency_job_id":null,"html_url":"https://github.com/GraHms/gorm-xray","commit_stats":null,"previous_names":["grahms/gorm-xray"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GraHms%2Fgorm-xray","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GraHms%2Fgorm-xray/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GraHms%2Fgorm-xray/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GraHms%2Fgorm-xray/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GraHms","download_url":"https://codeload.github.com/GraHms/gorm-xray/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252800912,"owners_count":21806234,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-27T02:17:32.864Z","updated_at":"2025-05-07T02:27:36.429Z","avatar_url":"https://github.com/GraHms.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GORM X-Ray Plugin\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/grahms/gormxray.svg)](https://pkg.go.dev/github.com/grahms/gormxray)\n[![Go Report Card](https://goreportcard.com/badge/github.com/grahms/gormxray)](https://goreportcard.com/report/github.com/grahms/gormxray)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)\n\n**GORM X-Ray Plugin** seamlessly integrates [AWS X-Ray](https://aws.amazon.com/xray/) with [GORM](https://gorm.io/), enabling you to trace and visualize database operations. It automatically creates annotated X-Ray subsegments for SQL queries, providing deep insights into your data layer’s performance, pinpointing bottlenecks, and making it easier to debug issues.\n\n## Features\n\n- **Automatic Tracing:** Hooks into GORM lifecycle events (Create, Query, Update, Delete, Raw, and Row) without manual instrumentation.\n- **Detailed Metadata:** Captures SQL statements, operation types, table names, and affected rows as metadata in each subsegment.\n- **Error Recording:** Automatically marks subsegments with errors if queries fail, aiding in fast root-cause analysis.\n- **Customizable Formatting:** Redact sensitive information or format queries to highlight performance-critical parts.\n- **Lightweight \u0026 Performant:** Minimal overhead, ensuring you can safely use this in production environments.\n\n## Installation\n\n```bash\ngo get github.com/grahms/gormxray\n```\n\nEnsure you have:\n- **Go 1.18+**\n- **GORM v2**\n- **AWS X-Ray SDK for Go** properly configured in your environment.\n\n## Getting Started\n\nBefore using the plugin, set up AWS X-Ray. Typically, you’ll run the X-Ray daemon or utilize an AWS environment (like EC2 or ECS) where X-Ray is already integrated. You should begin a root segment in your request or operation handler, so that all subsequent queries can be traced under it.\n\n### Basic Example\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com/aws/aws-xray-sdk-go/xray\"\n    \"github.com/grahms/gormxray\"\n    \"gorm.io/driver/sqlite\"\n    \"gorm.io/gorm\"\n)\n\nfunc main() {\n    // Begin a root segment for an operation (e.g., handling a request)\n    ctx, rootSeg := xray.BeginSegment(context.Background(), \"UserQueryOperation\")\n    defer rootSeg.Close(nil)\n\n    // Connect to an in-memory SQLite database\n    db, err := gorm.Open(sqlite.Open(\":memory:\"), \u0026gorm.Config{})\n    if err != nil {\n        log.Fatalf(\"failed to connect database: %v\", err)\n    }\n\n    // Integrate the plugin with GORM\n    if err := db.Use(gormxray.NewPlugin()); err != nil {\n        log.Fatalf(\"failed to register xray plugin: %v\", err)\n    }\n\n    // Attach the traced context to all DB operations\n    db = db.WithContext(ctx)\n\n    var val int\n    if err := db.Raw(\"SELECT 42\").Scan(\u0026val).Error; err != nil {\n        log.Printf(\"query error: %v\", err)\n    } else {\n        log.Printf(\"Query returned: %d\", val)\n    }\n\n    // In the X-Ray console, you will see a subsegment for this query under \"UserQueryOperation\"\n}\n```\n\n### Integrating with an API Handler\n\nIf you’re building an API, you often have an incoming request with its own `context.Context`. By using `db.WithContext(ctx)`, each query will be associated with the main segment created for that request, ensuring that your entire request trace is captured end-to-end.\n\n```go\nimport (\n    \"context\"\n    \"log\"\n    \"net/http\"\n\n    \"github.com/aws/aws-xray-sdk-go/xray\"\n    \"github.com/grahms/gormxray\"\n    \"gorm.io/driver/sqlite\"\n    \"gorm.io/gorm\"\n)\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n    // The incoming request context should already have a main X-Ray segment if you’re using xray.Handler\n    ctx := r.Context()\n\n    // Connect to the DB (in production, you'd reuse a persistent connection)\n    db, err := gorm.Open(sqlite.Open(\":memory:\"), \u0026gorm.Config{})\n    if err != nil {\n        http.Error(w, \"failed to connect database\", http.StatusInternalServerError)\n        return\n    }\n\n    // Register the X-Ray plugin\n    if err := db.Use(gormxray.NewPlugin()); err != nil {\n        http.Error(w, \"failed to register xray plugin\", http.StatusInternalServerError)\n        return\n    }\n\n    // Associate the request’s context with DB operations\n    db = db.WithContext(ctx)\n\n    // Each query now appears as a subsegment under the main request segment in X-Ray\n    if err := db.Exec(\"CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)\").Error; err != nil {\n        log.Printf(\"error creating table: %v\", err)\n    }\n\n    if err := db.Exec(\"INSERT INTO users (name) VALUES ('Alice'), ('Bob')\").Error; err != nil {\n        log.Printf(\"error inserting data: %v\", err)\n    }\n\n    var names []string\n    if err := db.Raw(\"SELECT name FROM users\").Scan(\u0026names).Error; err != nil {\n        log.Printf(\"error querying users: %v\", err)\n    } else {\n        log.Printf(\"queried users: %v\", names)\n    }\n\n    w.Write([]byte(\"Data queried successfully\"))\n}\n\nfunc main() {\n    // Wrap your handler with xray.Handler to ensure each request has its own segment\n    http.Handle(\"/\", xray.Handler(xray.NewFixedSegmentNamer(\"MyService\"), http.HandlerFunc(handler)))\n    log.Fatal(http.ListenAndServe(\":8080\", nil))\n}\n```\n\n### Advanced Options\n\nYou can customize the plugin’s behavior with functional options:\n\n- **Exclude Query Variables:** Hide parameter values from metadata.\n- **Query Formatter:** Redact sensitive information or pretty-print SQL queries.\n\n```go\ndb.Use(\n    gormxray.NewPlugin(\n        gormxray.WithExcludeQueryVars(true),\n        gormxray.WithQueryFormatter(func(q string) string {\n            return redactNumbers(q)\n        }),\n    ),\n)\n```\n\nWhere `redactNumbers` might be a function like:\n\n```go\nimport \"regexp\"\n\nfunc redactNumbers(query string) string {\n    return regexp.MustCompile(`\\d+`).ReplaceAllString(query, \"?\")\n}\n```\n\n### Handling Errors\n\nThe plugin automatically marks subsegments with errors for failing queries. Non-critical issues like `sql.ErrNoRows` or `gorm.ErrRecordNotFound` are considered normal and won’t degrade the segment’s status.\n\n## Testing\n\nRun unit tests to ensure correctness and stability:\n\n```bash\ngo test ./...\n```\n\nThese tests verify that:\n- The plugin registers GORM callbacks correctly.\n- Subsegments are created for each query.\n- Errors and non-critical conditions are handled gracefully.\n\n## Troubleshooting\n\n- **No Subsegments in X-Ray Console:** Ensure a main segment is started (e.g., via `xray.BeginSegment`) before running queries. If using HTTP handlers, wrap them with `xray.Handler`.\n- **Missing Metadata:** Confirm that `db.Use(gormxray.NewPlugin())` is called before any queries and that `db.WithContext(ctx)` is applied if you want tracing tied to a specific context.\n- **Performance Concerns:** The overhead is minimal. If you have an extremely high query volume, consider adjusting sampling rules or limiting instrumentation in certain critical paths.\n\n## Contributing\n\nContributions are welcome!\n1. Fork the repository.\n2. Create a feature branch (`git checkout -b feature/my-improvement`).\n3. Implement changes, add tests, and run all tests to ensure stability.\n4. Open a pull request with a clear description of your changes.\n\n## License\n\nThis project is licensed under the [MIT License](./LICENSE).\n\n## Acknowledgements\n\n- Built upon the foundation of [GORM](https://gorm.io/) and [AWS X-Ray SDK for Go](https://github.com/aws/aws-xray-sdk-go).\n- Inspired by developers needing better insight into how database operations impact their service performance.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrahms%2Fgorm-xray","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrahms%2Fgorm-xray","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrahms%2Fgorm-xray/lists"}