{"id":15137819,"url":"https://github.com/quangtung97/otelwrap","last_synced_at":"2025-07-08T00:34:02.357Z","repository":{"id":57640160,"uuid":"423339738","full_name":"QuangTung97/otelwrap","owner":"QuangTung97","description":"OpenTelemetry Go code generation tool","archived":false,"fork":false,"pushed_at":"2023-03-29T10:11:26.000Z","size":85,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-06T17:22:41.637Z","etag":null,"topics":["code-generation","open-telemetry"],"latest_commit_sha":null,"homepage":"","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/QuangTung97.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":"2021-11-01T04:43:24.000Z","updated_at":"2025-02-14T12:50:21.000Z","dependencies_parsed_at":"2024-06-20T02:53:08.096Z","dependency_job_id":"eced2d44-2b24-4bce-883d-d480288d1f88","html_url":"https://github.com/QuangTung97/otelwrap","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/QuangTung97/otelwrap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuangTung97%2Fotelwrap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuangTung97%2Fotelwrap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuangTung97%2Fotelwrap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuangTung97%2Fotelwrap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/QuangTung97","download_url":"https://codeload.github.com/QuangTung97/otelwrap/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuangTung97%2Fotelwrap/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264169214,"owners_count":23567273,"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":["code-generation","open-telemetry"],"created_at":"2024-09-26T07:02:15.828Z","updated_at":"2025-07-08T00:34:02.292Z","avatar_url":"https://github.com/QuangTung97.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## OtelWrap: code generation tool for Go OpenTelemetry\n\n[![otelwrap](https://github.com/QuangTung97/otelwrap/actions/workflows/go.yml/badge.svg)](https://github.com/QuangTung97/otelwrap/actions/workflows/go.yml)\n[![Coverage Status](https://coveralls.io/repos/github/QuangTung97/otelwrap/badge.svg?branch=master)](https://coveralls.io/github/QuangTung97/otelwrap?branch=master)\n\n### What is OtelWrap?\n\n**OtelWrap** is a tool that generates a decorator implementation of any interfaces that can be used for instrumentation\nwith Go OpenTelemetry library. Inspired by https://github.com/matryer/moq\n\nSupporting:\n\n* Any interface and any method with **context.Context** as the first parameter.\n* Detecting **error** return and set the span's error status accordingly.\n* Only tested using **go generate**.\n* Interface embedding.\n\n### Installing\n\nUsing conventional **tools.go** file for pinning version in **go.mod** / **go.sum**.\n\n```go\n// +build tools\n\npackage tools\n\nimport (\n    _ \"github.com/QuangTung97/otelwrap\"\n)\n```\n\nAnd then download and install the binary with commands:\n\n```shell\n$ go mod tidy\n$ go install github.com/QuangTung97/otelwrap\n```\n\n### Usage\n\n```\notelwrap [flags] -source-dir interface [interface2 interface3 ...]\n    --out string (required)\n        output file\n```\n\nUsing **go generate**:\n\n```go\npackage example\n\nimport \"context\"\n\n//go:generate otelwrap --out interface_wrappers.go . MyInterface\n\ntype MyInterface interface {\n    Method1(ctx context.Context) error\n    Method2(ctx context.Context, x int)\n    Method3()\n}\n```\n\nThe run ``go generate ./...`` in your module. The generated file looks like:\n\n```go\n// Code generated by otelwrap; DO NOT EDIT.\n// github.com/QuangTung97/otelwrap\n\npackage example\n\nimport (\n    \"context\"\n    \"go.opentelemetry.io/otel/codes\"\n    \"go.opentelemetry.io/otel/trace\"\n)\n\n// MyInterfaceWrapper wraps OpenTelemetry's span\ntype MyInterfaceWrapper struct {\n    MyInterface\n    tracer trace.Tracer\n    prefix string\n}\n\n// NewMyInterfaceWrapper creates a wrapper\nfunc NewMyInterfaceWrapper(wrapped MyInterface, tracer trace.Tracer, prefix string) *MyInterfaceWrapper {\n    return \u0026MyInterfaceWrapper{\n        MyInterface: wrapped,\n        tracer:      tracer,\n        prefix:      prefix,\n    }\n}\n\n// Method1 ...\nfunc (w *MyInterfaceWrapper) Method1(ctx context.Context) (err error) {\n    ctx, span := w.tracer.Start(ctx, w.prefix+\"Method1\")\n    defer span.End()\n\n    err = w.MyInterface.Method1(ctx)\n    if err != nil {\n        span.RecordError(err)\n        span.SetStatus(codes.Error, err.Error())\n    }\n    return err\n}\n\n// Method2 ...\nfunc (w *MyInterfaceWrapper) Method2(ctx context.Context, x int) {\n    ctx, span := w.tracer.Start(ctx, w.prefix+\"Method2\")\n    defer span.End()\n\n    w.MyInterface.Method2(ctx, x)\n}\n```\n\nTo use the generated struct, simply wraps the original implementation. The generated code is very easy to read.\n\n```go\npackage example\n\nimport \"go.opentelemetry.io/otel\"\n\nfunc InitMyInterface() MyInterface {\n    original := NewMyInterfaceImpl()\n    return NewMyInterfaceWrapper(original, otel.GetTracerProvider().Tracer(\"example\"), \"prefix\")\n}\n\n\n```\n\nCan also generate for interfaces in other packages:\n\n```go\npackage example\n\nimport \"path/to/another\"\n\nvar _ another.Interface1 // not necessary, only for keeping the import statement\n\n//go:generate otelwrap --out interface_wrappers.go . another.Interface1 another.Interface2\n```\n\nOr generate to another package:\n\n```go\npackage example\n\nimport \"context\"\n\n//go:generate otelwrap --out ../another/interface_wrappers.go . MyInterface\n\ntype MyInterface interface {\n    Method1(ctx context.Context) error\n    Method2(ctx context.Context, x int)\n    Method3()\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquangtung97%2Fotelwrap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquangtung97%2Fotelwrap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquangtung97%2Fotelwrap/lists"}