OpenTelemetry
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
2.5 KiB

package meter
import (
"context"
"fmt"
"os"
"path/filepath"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
)
func WithServiceName(name string) func(*Option) error {
return func(o *Option) error {
o.serviceName = name
return nil
}
}
func WithAttributes(attrs ...attribute.KeyValue) func(context.Context, *Option) error {
return func(_ context.Context, o *Option) error {
o.attributes = attrs
return nil
}
}
func WithExtraResource(opts ...resource.Option) func(context.Context, *Option) error {
return func(_ context.Context, o *Option) error {
o.extraResource = opts
return nil
}
}
func WithReader(reader metric.Reader) func(context.Context, *Option) error {
return func(_ context.Context, o *Option) error {
o.reader = reader
return nil
}
}
type Option struct {
reader metric.Reader
serviceName string
attributes []attribute.KeyValue
extraResource []resource.Option
}
func newOptions(ctx context.Context, opts ...func(context.Context, *Option) error) (Option, error) {
option := Option{
serviceName: filepath.Base(os.Args[0]),
extraResource: []resource.Option{
resource.WithOS(),
resource.WithProcess(),
resource.WithContainer(),
resource.WithHost(),
},
}
for idx, opt := range opts {
if err := opt(ctx, &option); err != nil {
return option, fmt.Errorf("option[%d]:%w", idx, err)
}
}
return option, nil
}
func New(ctx context.Context, opts ...func(context.Context, *Option) error) (*metric.MeterProvider, error) {
option, err := newOptions(ctx, opts...)
if err != nil {
return nil, fmt.Errorf("configure:%w", err)
}
extraResources, eerr := resource.New(
ctx,
append(
option.extraResource,
resource.WithAttributes(
append(
option.attributes,
semconv.ServiceName(option.serviceName),
)...,
),
)...,
)
if eerr != nil {
return nil, fmt.Errorf("create extra resource: %w", eerr)
}
res, rerr := resource.Merge(
resource.Default(),
extraResources,
)
if rerr != nil {
return nil, fmt.Errorf("merge resource: %w", rerr)
}
provOption := make([]metric.Option, 0, 2)
if option.reader != nil {
provOption = append(provOption, metric.WithReader(option.reader))
}
meterProvider := metric.NewMeterProvider(append(provOption, metric.WithResource(res))...)
otel.SetMeterProvider(meterProvider)
return meterProvider, nil
}