Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/quangtung97/otelwrap
OpenTelemetry Go code generation tool
https://github.com/quangtung97/otelwrap
code-generation open-telemetry
Last synced: about 1 month ago
JSON representation
OpenTelemetry Go code generation tool
- Host: GitHub
- URL: https://github.com/quangtung97/otelwrap
- Owner: QuangTung97
- License: mit
- Created: 2021-11-01T04:43:24.000Z (about 3 years ago)
- Default Branch: master
- Last Pushed: 2023-03-29T10:11:26.000Z (over 1 year ago)
- Last Synced: 2024-10-09T20:02:39.379Z (about 1 month ago)
- Topics: code-generation, open-telemetry
- Language: Go
- Homepage:
- Size: 83 KB
- Stars: 7
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
## OtelWrap: code generation tool for Go OpenTelemetry
[![otelwrap](https://github.com/QuangTung97/otelwrap/actions/workflows/go.yml/badge.svg)](https://github.com/QuangTung97/otelwrap/actions/workflows/go.yml)
[![Coverage Status](https://coveralls.io/repos/github/QuangTung97/otelwrap/badge.svg?branch=master)](https://coveralls.io/github/QuangTung97/otelwrap?branch=master)### What is OtelWrap?
**OtelWrap** is a tool that generates a decorator implementation of any interfaces that can be used for instrumentation
with Go OpenTelemetry library. Inspired by https://github.com/matryer/moqSupporting:
* Any interface and any method with **context.Context** as the first parameter.
* Detecting **error** return and set the span's error status accordingly.
* Only tested using **go generate**.
* Interface embedding.### Installing
Using conventional **tools.go** file for pinning version in **go.mod** / **go.sum**.
```go
// +build toolspackage tools
import (
_ "github.com/QuangTung97/otelwrap"
)
```And then download and install the binary with commands:
```shell
$ go mod tidy
$ go install github.com/QuangTung97/otelwrap
```### Usage
```
otelwrap [flags] -source-dir interface [interface2 interface3 ...]
--out string (required)
output file
```Using **go generate**:
```go
package exampleimport "context"
//go:generate otelwrap --out interface_wrappers.go . MyInterface
type MyInterface interface {
Method1(ctx context.Context) error
Method2(ctx context.Context, x int)
Method3()
}
```The run ``go generate ./...`` in your module. The generated file looks like:
```go
// Code generated by otelwrap; DO NOT EDIT.
// github.com/QuangTung97/otelwrappackage example
import (
"context"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
)// MyInterfaceWrapper wraps OpenTelemetry's span
type MyInterfaceWrapper struct {
MyInterface
tracer trace.Tracer
prefix string
}// NewMyInterfaceWrapper creates a wrapper
func NewMyInterfaceWrapper(wrapped MyInterface, tracer trace.Tracer, prefix string) *MyInterfaceWrapper {
return &MyInterfaceWrapper{
MyInterface: wrapped,
tracer: tracer,
prefix: prefix,
}
}// Method1 ...
func (w *MyInterfaceWrapper) Method1(ctx context.Context) (err error) {
ctx, span := w.tracer.Start(ctx, w.prefix+"Method1")
defer span.End()err = w.MyInterface.Method1(ctx)
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
}
return err
}// Method2 ...
func (w *MyInterfaceWrapper) Method2(ctx context.Context, x int) {
ctx, span := w.tracer.Start(ctx, w.prefix+"Method2")
defer span.End()w.MyInterface.Method2(ctx, x)
}
```To use the generated struct, simply wraps the original implementation. The generated code is very easy to read.
```go
package exampleimport "go.opentelemetry.io/otel"
func InitMyInterface() MyInterface {
original := NewMyInterfaceImpl()
return NewMyInterfaceWrapper(original, otel.GetTracerProvider().Tracer("example"), "prefix")
}```
Can also generate for interfaces in other packages:
```go
package exampleimport "path/to/another"
var _ another.Interface1 // not necessary, only for keeping the import statement
//go:generate otelwrap --out interface_wrappers.go . another.Interface1 another.Interface2
```Or generate to another package:
```go
package exampleimport "context"
//go:generate otelwrap --out ../another/interface_wrappers.go . MyInterface
type MyInterface interface {
Method1(ctx context.Context) error
Method2(ctx context.Context, x int)
Method3()
}
```