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
116 lines
2.5 KiB
8 months ago
|
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
|
||
|
}
|