Skip to content

Commit

Permalink
Merge branch 'main' into zapreflect
Browse files Browse the repository at this point in the history
  • Loading branch information
pellared authored Jun 5, 2024
2 parents cb9ffbc + e8540b2 commit f347d63
Show file tree
Hide file tree
Showing 51 changed files with 979 additions and 385 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Added

- The `go.opentelemetry.io/contrib/config` add support to configure periodic reader interval and timeout. (#5661)
- Add support to configure views when creating MeterProvider using the config package. (#5654)

### Fixed

Expand Down
28 changes: 21 additions & 7 deletions bridges/otelzap/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func WithLoggerProvider(provider log.LoggerProvider) Option {
type Core struct {
logger log.Logger
attr []log.KeyValue
ctx context.Context
}

// Compile-time check *Core implements zapcore.Core.
Expand All @@ -100,6 +101,7 @@ func NewCore(name string, opts ...Option) *Core {
cfg := newConfig(opts)
return &Core{
logger: cfg.logger(name),
ctx: context.Background(),
}
}

Expand All @@ -114,7 +116,11 @@ func (o *Core) Enabled(level zapcore.Level) bool {
func (o *Core) With(fields []zapcore.Field) zapcore.Core {
cloned := o.clone()
if len(fields) > 0 {
cloned.attr = append(cloned.attr, convertField(fields)...)
ctx, attrbuf := convertField(fields)
if ctx != nil {
cloned.ctx = ctx
}
cloned.attr = append(cloned.attr, attrbuf...)
}
return cloned
}
Expand All @@ -123,6 +129,7 @@ func (o *Core) clone() *Core {
return &Core{
logger: o.logger,
attr: slices.Clone(o.attr),
ctx: o.ctx,
}
}

Expand All @@ -148,28 +155,35 @@ func (o *Core) Write(ent zapcore.Entry, fields []zapcore.Field) error {
r.SetBody(log.StringValue(ent.Message))
r.SetSeverity(convertLevel(ent.Level))

// TODO: Handle attributes passed via With (exceptions: context.Context and zap.Namespace).
// TODO: Handle context.Context containing trace context.
// TODO: Handle zap.Namespace.
// TODO: Handle ent.LoggerName.

r.AddAttributes(o.attr...)
if len(fields) > 0 {
r.AddAttributes(convertField(fields)...)
ctx, attrbuf := convertField(fields)
if ctx != nil {
o.ctx = ctx
}
r.AddAttributes(attrbuf...)
}

o.logger.Emit(context.Background(), r)
o.logger.Emit(o.ctx, r)
return nil
}

func convertField(fields []zapcore.Field) []log.KeyValue {
func convertField(fields []zapcore.Field) (context.Context, []log.KeyValue) {
// TODO: Use objectEncoder from a pool instead of newObjectEncoder.
var ctx context.Context
enc := newObjectEncoder(len(fields))
for _, field := range fields {
if ctxFld, ok := field.Interface.(context.Context); ok {
ctx = ctxFld
continue
}
field.AddTo(enc)
}

return enc.kv
return ctx, enc.kv
}

func convertLevel(level zapcore.Level) log.Severity {
Expand Down
3 changes: 3 additions & 0 deletions bridges/otelzap/core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ func TestCore(t *testing.T) {

rec.Reset()

// TODO: Add WriteContext test case.
// TODO: Add WithContext test case.

// test child logger with accumulated fields
t.Run("With", func(t *testing.T) {
testCases := [][]string{{"test1", "value1"}, {"test2", "value2"}}
Expand Down
2 changes: 1 addition & 1 deletion bridges/prometheus/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/common v0.53.0 // indirect
github.com/prometheus/common v0.54.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
go.opentelemetry.io/otel/metric v1.27.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions bridges/prometheus/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQ
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE=
github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8=
github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
Expand Down
8 changes: 4 additions & 4 deletions config/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ require (
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.53.0 // indirect
github.com/prometheus/common v0.54.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect
google.golang.org/grpc v1.64.0 // indirect
Expand Down
16 changes: 8 additions & 8 deletions config/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQ
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE=
github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8=
github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
Expand Down Expand Up @@ -63,12 +63,12 @@ go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IO
go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw=
google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8=
Expand Down
162 changes: 161 additions & 1 deletion config/metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,22 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"

"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
otelprom "go.opentelemetry.io/otel/exporters/prometheus"
"go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/noop"
"go.opentelemetry.io/otel/sdk/instrumentation"
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/resource"
)

var zeroScope instrumentation.Scope

const instrumentKindUndefined = sdkmetric.InstrumentKind(0)

func meterProvider(cfg configOptions, res *resource.Resource) (metric.MeterProvider, shutdownFunc, error) {
if cfg.opentelemetryConfig.MeterProvider == nil {
return noop.NewMeterProvider(), noopShutdown, nil
Expand All @@ -45,6 +51,15 @@ func meterProvider(cfg configOptions, res *resource.Resource) (metric.MeterProvi
errs = append(errs, err)
}
}
for _, vw := range cfg.opentelemetryConfig.MeterProvider.Views {
v, err := view(vw)
if err == nil {
opts = append(opts, sdkmetric.WithView(v))
} else {
errs = append(errs, err)
}
}

if len(errs) > 0 {
return noop.NewMeterProvider(), noopShutdown, errors.Join(errs...)
}
Expand Down Expand Up @@ -156,7 +171,7 @@ func otlpHTTPMetricExporter(ctx context.Context, otlpConfig *OTLPMetric) (sdkmet
}

func otlpGRPCMetricExporter(ctx context.Context, otlpConfig *OTLPMetric) (sdkmetric.Exporter, error) {
opts := []otlpmetricgrpc.Option{}
var opts []otlpmetricgrpc.Option

if len(otlpConfig.Endpoint) > 0 {
u, err := url.ParseRequestURI(otlpConfig.Endpoint)
Expand Down Expand Up @@ -266,3 +281,148 @@ func (rws readerWithServer) Shutdown(ctx context.Context) error {
rws.server.Shutdown(ctx),
)
}

func view(v View) (sdkmetric.View, error) {
if v.Selector == nil {
return nil, errors.New("view: no selector provided")
}

inst, err := instrument(*v.Selector)
if err != nil {
return nil, err
}

return sdkmetric.NewView(inst, stream(v.Stream)), nil
}

func instrument(vs ViewSelector) (sdkmetric.Instrument, error) {
kind, err := instrumentKind(vs.InstrumentType)
if err != nil {
return sdkmetric.Instrument{}, fmt.Errorf("view_selector: %w", err)
}
inst := sdkmetric.Instrument{
Name: strOrEmpty(vs.InstrumentName),
Unit: strOrEmpty(vs.Unit),
Kind: kind,
Scope: instrumentation.Scope{
Name: strOrEmpty(vs.MeterName),
Version: strOrEmpty(vs.MeterVersion),
SchemaURL: strOrEmpty(vs.MeterSchemaUrl),
},
}

if instrumentIsEmpty(inst) {
return sdkmetric.Instrument{}, errors.New("view_selector: empty selector not supporter")
}
return inst, nil
}

func stream(vs *ViewStream) sdkmetric.Stream {
if vs == nil {
return sdkmetric.Stream{}
}

return sdkmetric.Stream{
Name: strOrEmpty(vs.Name),
Description: strOrEmpty(vs.Description),
Aggregation: aggregation(vs.Aggregation),
AttributeFilter: attributeFilter(vs.AttributeKeys),
}
}

func attributeFilter(attributeKeys []string) attribute.Filter {
var attrKeys []attribute.Key
for _, attrStr := range attributeKeys {
attrKeys = append(attrKeys, attribute.Key(attrStr))
}
return attribute.NewAllowKeysFilter(attrKeys...)
}

func aggregation(aggr *ViewStreamAggregation) sdkmetric.Aggregation {
if aggr == nil {
return nil
}

if aggr.Base2ExponentialBucketHistogram != nil {
return sdkmetric.AggregationBase2ExponentialHistogram{
MaxSize: int32(intOrZero(aggr.Base2ExponentialBucketHistogram.MaxSize)),
MaxScale: int32(intOrZero(aggr.Base2ExponentialBucketHistogram.MaxScale)),
// Need to negate because config has the positive action RecordMinMax.
NoMinMax: !boolOrFalse(aggr.Base2ExponentialBucketHistogram.RecordMinMax),
}
}
if aggr.Default != nil {
// TODO: Understand what to set here.
return nil
}
if aggr.Drop != nil {
return sdkmetric.AggregationDrop{}
}
if aggr.ExplicitBucketHistogram != nil {
return sdkmetric.AggregationExplicitBucketHistogram{
Boundaries: aggr.ExplicitBucketHistogram.Boundaries,
// Need to negate because config has the positive action RecordMinMax.
NoMinMax: !boolOrFalse(aggr.ExplicitBucketHistogram.RecordMinMax),
}
}
if aggr.LastValue != nil {
return sdkmetric.AggregationLastValue{}
}
if aggr.Sum != nil {
return sdkmetric.AggregationSum{}
}
return nil
}

func instrumentKind(vsit *ViewSelectorInstrumentType) (sdkmetric.InstrumentKind, error) {
if vsit == nil {
// Equivalent to instrumentKindUndefined.
return instrumentKindUndefined, nil
}

switch *vsit {
case ViewSelectorInstrumentTypeCounter:
return sdkmetric.InstrumentKindCounter, nil
case ViewSelectorInstrumentTypeUpDownCounter:
return sdkmetric.InstrumentKindUpDownCounter, nil
case ViewSelectorInstrumentTypeHistogram:
return sdkmetric.InstrumentKindHistogram, nil
case ViewSelectorInstrumentTypeObservableCounter:
return sdkmetric.InstrumentKindObservableCounter, nil
case ViewSelectorInstrumentTypeObservableUpDownCounter:
return sdkmetric.InstrumentKindObservableUpDownCounter, nil
case ViewSelectorInstrumentTypeObservableGauge:
return sdkmetric.InstrumentKindObservableGauge, nil
}

return instrumentKindUndefined, errors.New("instrument_type: invalid value")
}

func instrumentIsEmpty(i sdkmetric.Instrument) bool {
return i.Name == "" &&
i.Description == "" &&
i.Kind == instrumentKindUndefined &&
i.Unit == "" &&
i.Scope == zeroScope
}

func boolOrFalse(pBool *bool) bool {
if pBool == nil {
return false
}
return *pBool
}

func intOrZero(pInt *int) int {
if pInt == nil {
return 0
}
return *pInt
}

func strOrEmpty(pStr *string) string {
if pStr == nil {
return ""
}
return *pStr
}
Loading

0 comments on commit f347d63

Please sign in to comment.