feat(telemetry): instrument inference duration and frame age
This commit is contained in:
		@@ -1,8 +1,10 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"flag"
 | 
			
		||||
	"github.com/cyrilix/robocar-base/cli"
 | 
			
		||||
	"github.com/cyrilix/robocar-steering-tflite-edgetpu/pkg/metrics"
 | 
			
		||||
	"github.com/cyrilix/robocar-steering-tflite-edgetpu/pkg/steering"
 | 
			
		||||
	"go.uber.org/zap"
 | 
			
		||||
	"log"
 | 
			
		||||
@@ -59,6 +61,9 @@ func main() {
 | 
			
		||||
	}()
 | 
			
		||||
	zap.ReplaceGlobals(lgr)
 | 
			
		||||
 | 
			
		||||
	cleanup := metrics.Init(context.Background())
 | 
			
		||||
	defer cleanup()
 | 
			
		||||
 | 
			
		||||
	if modelPath == "" {
 | 
			
		||||
		zap.L().Error("model path is mandatory")
 | 
			
		||||
		flag.PrintDefaults()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								go.mod
									
									
									
									
									
								
							@@ -9,15 +9,24 @@ require (
 | 
			
		||||
	github.com/eclipse/paho.mqtt.golang v1.3.5
 | 
			
		||||
	github.com/golang/protobuf v1.5.2
 | 
			
		||||
	github.com/mattn/go-tflite v1.0.2-0.20210524070808-ba19dc99415b
 | 
			
		||||
	go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.25.0
 | 
			
		||||
	go.opentelemetry.io/otel/metric v0.25.0
 | 
			
		||||
	go.opentelemetry.io/otel/sdk/export/metric v0.25.0
 | 
			
		||||
	go.opentelemetry.io/otel/sdk/metric v0.25.0
 | 
			
		||||
	go.uber.org/zap v1.19.1
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/gorilla/websocket v1.4.2 // indirect
 | 
			
		||||
	github.com/mattn/go-pointer v0.0.1 // indirect
 | 
			
		||||
	go.opentelemetry.io/otel v1.2.0 // indirect
 | 
			
		||||
	go.opentelemetry.io/otel/internal/metric v0.25.0 // indirect
 | 
			
		||||
	go.opentelemetry.io/otel/sdk v1.2.0 // indirect
 | 
			
		||||
	go.opentelemetry.io/otel/trace v1.2.0 // indirect
 | 
			
		||||
	go.uber.org/atomic v1.7.0 // indirect
 | 
			
		||||
	go.uber.org/multierr v1.6.0 // indirect
 | 
			
		||||
	golang.org/x/image v0.0.0-20200430140353-33d19683fad8 // indirect
 | 
			
		||||
	golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect
 | 
			
		||||
	golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect
 | 
			
		||||
	google.golang.org/protobuf v1.26.0 // indirect
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								go.sum
									
									
									
									
									
								
							@@ -3,8 +3,9 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX
 | 
			
		||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
 | 
			
		||||
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
 | 
			
		||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
 | 
			
		||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
 | 
			
		||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
 | 
			
		||||
github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFAws=
 | 
			
		||||
github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
 | 
			
		||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
 | 
			
		||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 | 
			
		||||
github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
 | 
			
		||||
@@ -53,8 +54,9 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
 | 
			
		||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
 | 
			
		||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 | 
			
		||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 | 
			
		||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
 | 
			
		||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
			
		||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
 | 
			
		||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
			
		||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 | 
			
		||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 | 
			
		||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
 | 
			
		||||
@@ -112,6 +114,22 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM
 | 
			
		||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
 | 
			
		||||
github.com/vincent-petithory/dataurl v0.0.0-20191104211930-d1553a71de50/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U=
 | 
			
		||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 | 
			
		||||
go.opentelemetry.io/otel v1.2.0 h1:YOQDvxO1FayUcT9MIhJhgMyNO1WqoduiyvQHzGN0kUQ=
 | 
			
		||||
go.opentelemetry.io/otel v1.2.0/go.mod h1:aT17Fk0Z1Nor9e0uisf98LrntPGMnk4frBO9+dkf69I=
 | 
			
		||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.25.0 h1:XyBEWc22bxYllvyeG3bmW0G4esJ8Wi6P2m0e/tIuMsE=
 | 
			
		||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.25.0/go.mod h1:Mn5lMLB4mIMKZ1IR4qCoYspC4lEbfK6pD7bI3SSAMKk=
 | 
			
		||||
go.opentelemetry.io/otel/internal/metric v0.25.0 h1:w/7RXe16WdPylaIXDgcYM6t/q0K5lXgSdZOEbIEyliE=
 | 
			
		||||
go.opentelemetry.io/otel/internal/metric v0.25.0/go.mod h1:Nhuw26QSX7d6n4duoqAFi5KOQR4AuzyMcl5eXOgwxtc=
 | 
			
		||||
go.opentelemetry.io/otel/metric v0.25.0 h1:7cXOnCADUsR3+EOqxPaSKwhEuNu0gz/56dRN1hpIdKw=
 | 
			
		||||
go.opentelemetry.io/otel/metric v0.25.0/go.mod h1:E884FSpQfnJOMMUaq+05IWlJ4rjZpk2s/F1Ju+TEEm8=
 | 
			
		||||
go.opentelemetry.io/otel/sdk v1.2.0 h1:wKN260u4DesJYhyjxDa7LRFkuhH7ncEVKU37LWcyNIo=
 | 
			
		||||
go.opentelemetry.io/otel/sdk v1.2.0/go.mod h1:jNN8QtpvbsKhgaC6V5lHiejMoKD+V8uadoSafgHPx1U=
 | 
			
		||||
go.opentelemetry.io/otel/sdk/export/metric v0.25.0 h1:6UjAFmVB5Fza3K5qUJpYWGrk8QMPIqlSnya5FI46VBY=
 | 
			
		||||
go.opentelemetry.io/otel/sdk/export/metric v0.25.0/go.mod h1:Ej7NOa+WpN49EIcr1HMUYRvxXXCCnQCg2+ovdt2z8Pk=
 | 
			
		||||
go.opentelemetry.io/otel/sdk/metric v0.25.0 h1:J+Ta+4IAA5W9AdWhGQLfciEpavBqqSkBzTDeYvJLFNU=
 | 
			
		||||
go.opentelemetry.io/otel/sdk/metric v0.25.0/go.mod h1:G4xzj4LvC6xDDSsVXpvRVclQCbofGGg4ZU2VKKtDRfg=
 | 
			
		||||
go.opentelemetry.io/otel/trace v1.2.0 h1:Ys3iqbqZhcf28hHzrm5WAquMkDHNZTUkw7KHbuNjej0=
 | 
			
		||||
go.opentelemetry.io/otel/trace v1.2.0/go.mod h1:N5FLswTubnxKxOJHM7XZC074qpeEdLy3CgAVsdMucK0=
 | 
			
		||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
 | 
			
		||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 | 
			
		||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4=
 | 
			
		||||
@@ -157,6 +175,8 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w
 | 
			
		||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 | 
			
		||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										69
									
								
								pkg/metrics/metrics.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								pkg/metrics/metrics.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
package metrics
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	stdout "go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/global"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/unit"
 | 
			
		||||
	controller "go.opentelemetry.io/otel/sdk/metric/controller/basic"
 | 
			
		||||
	processor "go.opentelemetry.io/otel/sdk/metric/processor/basic"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/metric/selector/simple"
 | 
			
		||||
	"go.uber.org/zap"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	FrameAge          metric.Int64Histogram
 | 
			
		||||
	InferenceDuration metric.Int64Histogram
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func initMeter(ctx context.Context) func() {
 | 
			
		||||
	zap.S().Info("init telemetry")
 | 
			
		||||
	exporter, err := stdout.New(
 | 
			
		||||
		stdout.WithPrettyPrint(),
 | 
			
		||||
	)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		zap.S().Panicf("failed to initialize prometheus exporter %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pusher := controller.New(
 | 
			
		||||
		processor.NewFactory(
 | 
			
		||||
			simple.NewWithInexpensiveDistribution(),
 | 
			
		||||
			//simple.NewWithHistogramDistribution(
 | 
			
		||||
			//	histogram.WithExplicitBoundaries(
 | 
			
		||||
			//		[]float64{.005, .5, 1, 2.5, 5, 10, 20, 50, 100},
 | 
			
		||||
			//	),
 | 
			
		||||
			//),
 | 
			
		||||
			exporter,
 | 
			
		||||
		),
 | 
			
		||||
		controller.WithExporter(exporter),
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	if err = pusher.Start(ctx); err != nil {
 | 
			
		||||
		zap.S().Fatalf("starting push controller: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	global.SetMeterProvider(pusher)
 | 
			
		||||
	return func() {
 | 
			
		||||
		if err := pusher.Stop(ctx); err != nil {
 | 
			
		||||
			zap.S().Fatalf("stopping push controller: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Init(ctx context.Context) func() {
 | 
			
		||||
	cleaner := initMeter(ctx)
 | 
			
		||||
 | 
			
		||||
	meter := global.Meter("robocar/rc-steering")
 | 
			
		||||
 | 
			
		||||
	FrameAge = metric.Must(meter).NewInt64Histogram(
 | 
			
		||||
		"robocar.frame_age",
 | 
			
		||||
		metric.WithUnit(unit.Milliseconds),
 | 
			
		||||
		metric.WithDescription("time before frame processing"))
 | 
			
		||||
	InferenceDuration = metric.Must(meter).NewInt64Histogram(
 | 
			
		||||
		"robocar.inference_duration",
 | 
			
		||||
		metric.WithUnit(unit.Milliseconds),
 | 
			
		||||
		metric.WithDescription("tensorflow inference duration"))
 | 
			
		||||
 | 
			
		||||
	return cleaner
 | 
			
		||||
}
 | 
			
		||||
@@ -2,9 +2,11 @@ package steering
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/cyrilix/robocar-base/service"
 | 
			
		||||
	"github.com/cyrilix/robocar-protobuf/go/events"
 | 
			
		||||
	"github.com/cyrilix/robocar-steering-tflite-edgetpu/pkg/metrics"
 | 
			
		||||
	"github.com/disintegration/imaging"
 | 
			
		||||
	mqtt "github.com/eclipse/paho.mqtt.golang"
 | 
			
		||||
	"github.com/golang/protobuf/proto"
 | 
			
		||||
@@ -14,6 +16,7 @@ import (
 | 
			
		||||
	"image"
 | 
			
		||||
	_ "image/jpeg"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func NewPart(client mqtt.Client, modelPath, steeringTopic, cameraTopic string, edgeVerbosity int, imgWidth, imgHeight, horizon int) *Part {
 | 
			
		||||
@@ -130,6 +133,11 @@ func (p *Part) onFrame(_ mqtt.Client, message mqtt.Message) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	now := time.Now().UnixMilli()
 | 
			
		||||
	frameAge := now - msg.Id.CreatedAt.AsTime().UnixMilli()
 | 
			
		||||
	go metrics.FrameAge.Record(context.Background(), frameAge)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	img, _, err := image.Decode(bytes.NewReader(msg.GetFrame()))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		zap.L().Error("unable to decode frame, skip frame", zap.Error(err))
 | 
			
		||||
@@ -137,6 +145,9 @@ func (p *Part) onFrame(_ mqtt.Client, message mqtt.Message) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	steering, confidence, err := p.Value(img)
 | 
			
		||||
	inferenceDuration := time.Now().UnixMilli() - now
 | 
			
		||||
	go metrics.InferenceDuration.Record(context.Background(), inferenceDuration)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		zap.S().Errorw("unable to compute sterring",
 | 
			
		||||
			"frame", msg.GetId().GetId(),
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/go.opentelemetry.io/otel/.gitattributes
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/go.opentelemetry.io/otel/.gitattributes
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
* text=auto eol=lf
 | 
			
		||||
*.{cmd,[cC][mM][dD]} text eol=crlf
 | 
			
		||||
*.{bat,[bB][aA][tT]} text eol=crlf
 | 
			
		||||
							
								
								
									
										21
									
								
								vendor/go.opentelemetry.io/otel/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/go.opentelemetry.io/otel/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
.DS_Store
 | 
			
		||||
Thumbs.db
 | 
			
		||||
 | 
			
		||||
.tools/
 | 
			
		||||
.idea/
 | 
			
		||||
.vscode/
 | 
			
		||||
*.iml
 | 
			
		||||
*.so
 | 
			
		||||
coverage.*
 | 
			
		||||
 | 
			
		||||
gen/
 | 
			
		||||
 | 
			
		||||
/example/fib/fib
 | 
			
		||||
/example/jaeger/jaeger
 | 
			
		||||
/example/namedtracer/namedtracer
 | 
			
		||||
/example/opencensus/opencensus
 | 
			
		||||
/example/passthrough/passthrough
 | 
			
		||||
/example/prometheus/prometheus
 | 
			
		||||
/example/prom-collector/prom-collector
 | 
			
		||||
/example/zipkin/zipkin
 | 
			
		||||
/example/otel-collector/otel-collector
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/go.opentelemetry.io/otel/.gitmodules
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/go.opentelemetry.io/otel/.gitmodules
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
[submodule "opentelemetry-proto"]
 | 
			
		||||
	path = exporters/otlp/internal/opentelemetry-proto
 | 
			
		||||
	url = https://github.com/open-telemetry/opentelemetry-proto
 | 
			
		||||
							
								
								
									
										32
									
								
								vendor/go.opentelemetry.io/otel/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								vendor/go.opentelemetry.io/otel/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
# See https://github.com/golangci/golangci-lint#config-file
 | 
			
		||||
run:
 | 
			
		||||
  issues-exit-code: 1 #Default
 | 
			
		||||
  tests: true #Default
 | 
			
		||||
 | 
			
		||||
linters:
 | 
			
		||||
  enable:
 | 
			
		||||
    - misspell
 | 
			
		||||
    - goimports
 | 
			
		||||
    - revive
 | 
			
		||||
    - gofmt
 | 
			
		||||
 | 
			
		||||
issues:
 | 
			
		||||
  exclude-rules:
 | 
			
		||||
    # helpers in tests often (rightfully) pass a *testing.T as their first argument
 | 
			
		||||
    - path: _test\.go
 | 
			
		||||
      text: "context.Context should be the first parameter of a function"
 | 
			
		||||
      linters:
 | 
			
		||||
        - revive
 | 
			
		||||
    # Yes, they are, but it's okay in a test
 | 
			
		||||
    - path: _test\.go
 | 
			
		||||
      text: "exported func.*returns unexported type.*which can be annoying to use"
 | 
			
		||||
      linters:
 | 
			
		||||
        - revive
 | 
			
		||||
 | 
			
		||||
linters-settings:
 | 
			
		||||
  misspell:
 | 
			
		||||
    locale: US
 | 
			
		||||
    ignore-words:
 | 
			
		||||
      - cancelled
 | 
			
		||||
  goimports:
 | 
			
		||||
    local-prefixes: go.opentelemetry.io
 | 
			
		||||
							
								
								
									
										16
									
								
								vendor/go.opentelemetry.io/otel/.markdown-link.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/go.opentelemetry.io/otel/.markdown-link.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
{
 | 
			
		||||
    "ignorePatterns": [
 | 
			
		||||
        {
 | 
			
		||||
            "pattern": "^http(s)?://localhost"
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    "replacementPatterns": [
 | 
			
		||||
        {
 | 
			
		||||
            "pattern": "^/registry",
 | 
			
		||||
            "replacement": "https://opentelemetry.io/registry"
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    "retryOn429": true,
 | 
			
		||||
    "retryCount": 5,
 | 
			
		||||
    "fallbackRetryDelay": "30s"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								vendor/go.opentelemetry.io/otel/.markdownlint.yaml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/go.opentelemetry.io/otel/.markdownlint.yaml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
# Default state for all rules
 | 
			
		||||
default: true
 | 
			
		||||
 | 
			
		||||
# ul-style
 | 
			
		||||
MD004: false
 | 
			
		||||
 | 
			
		||||
# hard-tabs
 | 
			
		||||
MD010: false
 | 
			
		||||
 | 
			
		||||
# line-length
 | 
			
		||||
MD013: false
 | 
			
		||||
 | 
			
		||||
# no-duplicate-header
 | 
			
		||||
MD024:
 | 
			
		||||
  siblings_only: true
 | 
			
		||||
 | 
			
		||||
#single-title
 | 
			
		||||
MD025: false
 | 
			
		||||
 | 
			
		||||
# ol-prefix
 | 
			
		||||
MD029:
 | 
			
		||||
  style: ordered
 | 
			
		||||
 | 
			
		||||
# no-inline-html
 | 
			
		||||
MD033: false
 | 
			
		||||
 | 
			
		||||
# fenced-code-language
 | 
			
		||||
MD040: false
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1638
									
								
								vendor/go.opentelemetry.io/otel/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1638
									
								
								vendor/go.opentelemetry.io/otel/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										17
									
								
								vendor/go.opentelemetry.io/otel/CODEOWNERS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								vendor/go.opentelemetry.io/otel/CODEOWNERS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
#####################################################
 | 
			
		||||
#
 | 
			
		||||
# List of approvers for this repository
 | 
			
		||||
#
 | 
			
		||||
#####################################################
 | 
			
		||||
#
 | 
			
		||||
# Learn about membership in OpenTelemetry community:
 | 
			
		||||
#  https://github.com/open-telemetry/community/blob/main/community-membership.md
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# Learn about CODEOWNERS file format:
 | 
			
		||||
#  https://help.github.com/en/articles/about-code-owners
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
* @jmacd @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @paivagustavo @MadVikingGod @pellared
 | 
			
		||||
 | 
			
		||||
CODEOWNERS @MrAlias @Aneurysm9
 | 
			
		||||
							
								
								
									
										495
									
								
								vendor/go.opentelemetry.io/otel/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										495
									
								
								vendor/go.opentelemetry.io/otel/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,495 @@
 | 
			
		||||
# Contributing to opentelemetry-go
 | 
			
		||||
 | 
			
		||||
The Go special interest group (SIG) meets regularly. See the
 | 
			
		||||
OpenTelemetry
 | 
			
		||||
[community](https://github.com/open-telemetry/community#golang-sdk)
 | 
			
		||||
repo for information on this and other language SIGs.
 | 
			
		||||
 | 
			
		||||
See the [public meeting
 | 
			
		||||
notes](https://docs.google.com/document/d/1A63zSWX0x2CyCK_LoNhmQC4rqhLpYXJzXbEPDUQ2n6w/edit#heading=h.9tngw7jdwd6b)
 | 
			
		||||
for a summary description of past meetings. To request edit access,
 | 
			
		||||
join the meeting or get in touch on
 | 
			
		||||
[Slack](https://cloud-native.slack.com/archives/C01NPAXACKT).
 | 
			
		||||
 | 
			
		||||
## Development
 | 
			
		||||
 | 
			
		||||
You can view and edit the source code by cloning this repository:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
git clone https://github.com/open-telemetry/opentelemetry-go.git
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Run `make test` to run the tests instead of `go test`.
 | 
			
		||||
 | 
			
		||||
There are some generated files checked into the repo. To make sure
 | 
			
		||||
that the generated files are up-to-date, run `make` (or `make
 | 
			
		||||
precommit` - the `precommit` target is the default).
 | 
			
		||||
 | 
			
		||||
The `precommit` target also fixes the formatting of the code and
 | 
			
		||||
checks the status of the go module files.
 | 
			
		||||
 | 
			
		||||
If after running `make precommit` the output of `git status` contains
 | 
			
		||||
`nothing to commit, working tree clean` then it means that everything
 | 
			
		||||
is up-to-date and properly formatted.
 | 
			
		||||
 | 
			
		||||
## Pull Requests
 | 
			
		||||
 | 
			
		||||
### How to Send Pull Requests
 | 
			
		||||
 | 
			
		||||
Everyone is welcome to contribute code to `opentelemetry-go` via
 | 
			
		||||
GitHub pull requests (PRs).
 | 
			
		||||
 | 
			
		||||
To create a new PR, fork the project in GitHub and clone the upstream
 | 
			
		||||
repo:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
go get -d go.opentelemetry.io/otel
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
(This may print some warning about "build constraints exclude all Go
 | 
			
		||||
files", just ignore it.)
 | 
			
		||||
 | 
			
		||||
This will put the project in `${GOPATH}/src/go.opentelemetry.io/otel`. You
 | 
			
		||||
can alternatively use `git` directly with:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
git clone https://github.com/open-telemetry/opentelemetry-go
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
(Note that `git clone` is *not* using the `go.opentelemetry.io/otel` name -
 | 
			
		||||
that name is a kind of a redirector to GitHub that `go get` can
 | 
			
		||||
understand, but `git` does not.)
 | 
			
		||||
 | 
			
		||||
This would put the project in the `opentelemetry-go` directory in
 | 
			
		||||
current working directory.
 | 
			
		||||
 | 
			
		||||
Enter the newly created directory and add your fork as a new remote:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
git remote add <YOUR_FORK> git@github.com:<YOUR_GITHUB_USERNAME>/opentelemetry-go
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Check out a new branch, make modifications, run linters and tests, update
 | 
			
		||||
`CHANGELOG.md`, and push the branch to your fork:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
git checkout -b <YOUR_BRANCH_NAME>
 | 
			
		||||
# edit files
 | 
			
		||||
# update changelog
 | 
			
		||||
make precommit
 | 
			
		||||
git add -p
 | 
			
		||||
git commit
 | 
			
		||||
git push <YOUR_FORK> <YOUR_BRANCH_NAME>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Open a pull request against the main `opentelemetry-go` repo. Be sure to add the pull
 | 
			
		||||
request ID to the entry you added to `CHANGELOG.md`.
 | 
			
		||||
 | 
			
		||||
### How to Receive Comments
 | 
			
		||||
 | 
			
		||||
* If the PR is not ready for review, please put `[WIP]` in the title,
 | 
			
		||||
  tag it as `work-in-progress`, or mark it as
 | 
			
		||||
  [`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/).
 | 
			
		||||
* Make sure CLA is signed and CI is clear.
 | 
			
		||||
 | 
			
		||||
### How to Get PRs Merged
 | 
			
		||||
 | 
			
		||||
A PR is considered to be **ready to merge** when:
 | 
			
		||||
 | 
			
		||||
* It has received two approvals from Collaborators/Maintainers (at
 | 
			
		||||
  different companies). This is not enforced through technical means
 | 
			
		||||
  and a PR may be **ready to merge** with a single approval if the change
 | 
			
		||||
  and its approach have been discussed and consensus reached.
 | 
			
		||||
* Feedback has been addressed.
 | 
			
		||||
* Any substantive changes to your PR will require that you clear any prior
 | 
			
		||||
  Approval reviews, this includes changes resulting from other feedback. Unless
 | 
			
		||||
  the approver explicitly stated that their approval will persist across
 | 
			
		||||
  changes it should be assumed that the PR needs their review again. Other
 | 
			
		||||
  project members (e.g. approvers, maintainers) can help with this if there are
 | 
			
		||||
  any questions or if you forget to clear reviews.
 | 
			
		||||
* It has been open for review for at least one working day. This gives
 | 
			
		||||
  people reasonable time to review.
 | 
			
		||||
* Trivial changes (typo, cosmetic, doc, etc.) do not have to wait for
 | 
			
		||||
  one day and may be merged with a single Maintainer's approval.
 | 
			
		||||
* `CHANGELOG.md` has been updated to reflect what has been
 | 
			
		||||
  added, changed, removed, or fixed.
 | 
			
		||||
* `README.md` has been updated if necessary.
 | 
			
		||||
* Urgent fix can take exception as long as it has been actively
 | 
			
		||||
  communicated.
 | 
			
		||||
 | 
			
		||||
Any Maintainer can merge the PR once it is **ready to merge**.
 | 
			
		||||
 | 
			
		||||
## Design Choices
 | 
			
		||||
 | 
			
		||||
As with other OpenTelemetry clients, opentelemetry-go follows the
 | 
			
		||||
[opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification).
 | 
			
		||||
 | 
			
		||||
It's especially valuable to read through the [library
 | 
			
		||||
guidelines](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/library-guidelines.md).
 | 
			
		||||
 | 
			
		||||
### Focus on Capabilities, Not Structure Compliance
 | 
			
		||||
 | 
			
		||||
OpenTelemetry is an evolving specification, one where the desires and
 | 
			
		||||
use cases are clear, but the method to satisfy those uses cases are
 | 
			
		||||
not.
 | 
			
		||||
 | 
			
		||||
As such, Contributions should provide functionality and behavior that
 | 
			
		||||
conforms to the specification, but the interface and structure is
 | 
			
		||||
flexible.
 | 
			
		||||
 | 
			
		||||
It is preferable to have contributions follow the idioms of the
 | 
			
		||||
language rather than conform to specific API names or argument
 | 
			
		||||
patterns in the spec.
 | 
			
		||||
 | 
			
		||||
For a deeper discussion, see
 | 
			
		||||
[this](https://github.com/open-telemetry/opentelemetry-specification/issues/165).
 | 
			
		||||
 | 
			
		||||
## Documentation
 | 
			
		||||
 | 
			
		||||
Each non-example Go Module should have its own `README.md` containing:
 | 
			
		||||
 | 
			
		||||
- A pkg.go.dev badge which can be generated [here](https://pkg.go.dev/badge/).
 | 
			
		||||
- Brief description.
 | 
			
		||||
- Installation instructions (and requirements if applicable).
 | 
			
		||||
- Hyperlink to an example. Depending on the component the example can be:
 | 
			
		||||
  - An `example_test.go` like [here](exporters/stdout/stdouttrace/example_test.go).
 | 
			
		||||
  - A sample Go application with its own `README.md`, like [here](example/zipkin).
 | 
			
		||||
- Additional documentation sections such us:
 | 
			
		||||
  - Configuration,
 | 
			
		||||
  - Contributing,
 | 
			
		||||
  - References.
 | 
			
		||||
 | 
			
		||||
[Here](exporters/jaeger/README.md) is an example of a concise `README.md`.
 | 
			
		||||
 | 
			
		||||
Moreover, it should be possible to navigate to any `README.md` from the
 | 
			
		||||
root `README.md`.
 | 
			
		||||
 | 
			
		||||
## Style Guide
 | 
			
		||||
 | 
			
		||||
One of the primary goals of this project is that it is actually used by
 | 
			
		||||
developers. With this goal in mind the project strives to build
 | 
			
		||||
user-friendly and idiomatic Go code adhering to the Go community's best
 | 
			
		||||
practices.
 | 
			
		||||
 | 
			
		||||
For a non-comprehensive but foundational overview of these best practices
 | 
			
		||||
the [Effective Go](https://golang.org/doc/effective_go.html) documentation
 | 
			
		||||
is an excellent starting place.
 | 
			
		||||
 | 
			
		||||
As a convenience for developers building this project the `make precommit`
 | 
			
		||||
will format, lint, validate, and in some cases fix the changes you plan to
 | 
			
		||||
submit. This check will need to pass for your changes to be able to be
 | 
			
		||||
merged.
 | 
			
		||||
 | 
			
		||||
In addition to idiomatic Go, the project has adopted certain standards for
 | 
			
		||||
implementations of common patterns. These standards should be followed as a
 | 
			
		||||
default, and if they are not followed documentation needs to be included as
 | 
			
		||||
to the reasons why.
 | 
			
		||||
 | 
			
		||||
### Configuration
 | 
			
		||||
 | 
			
		||||
When creating an instantiation function for a complex `type T struct`, it is
 | 
			
		||||
useful to allow variable number of options to be applied. However, the strong
 | 
			
		||||
type system of Go restricts the function design options. There are a few ways
 | 
			
		||||
to solve this problem, but we have landed on the following design.
 | 
			
		||||
 | 
			
		||||
#### `config`
 | 
			
		||||
 | 
			
		||||
Configuration should be held in a `struct` named `config`, or prefixed with
 | 
			
		||||
specific type name this Configuration applies to if there are multiple
 | 
			
		||||
`config` in the package. This type must contain configuration options.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// config contains configuration options for a thing.
 | 
			
		||||
type config struct {
 | 
			
		||||
	// options ...
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In general the `config` type will not need to be used externally to the
 | 
			
		||||
package and should be unexported. If, however, it is expected that the user
 | 
			
		||||
will likely want to build custom options for the configuration, the `config`
 | 
			
		||||
should be exported. Please, include in the documentation for the `config`
 | 
			
		||||
how the user can extend the configuration.
 | 
			
		||||
 | 
			
		||||
It is important that internal `config` are not shared across package boundaries.
 | 
			
		||||
Meaning a `config` from one package should not be directly used by another. The
 | 
			
		||||
one exception is the API packages.  The configs from the base API, eg.
 | 
			
		||||
`go.opentelemetry.io/otel/trace.TracerConfig` and
 | 
			
		||||
`go.opentelemetry.io/otel/metric.InstrumentConfig`, are intended to be consumed
 | 
			
		||||
by the SDK therefor it is expected that these are exported.
 | 
			
		||||
 | 
			
		||||
When a config is exported we want to maintain forward and backward
 | 
			
		||||
compatibility, to achieve this no fields should be exported but should
 | 
			
		||||
instead be accessed by methods.
 | 
			
		||||
 | 
			
		||||
Optionally, it is common to include a `newConfig` function (with the same
 | 
			
		||||
naming scheme). This function wraps any defaults setting and looping over
 | 
			
		||||
all options to create a configured `config`.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// newConfig returns an appropriately configured config.
 | 
			
		||||
func newConfig([]Option) config {
 | 
			
		||||
	// Set default values for config.
 | 
			
		||||
	config := config{/* […] */}
 | 
			
		||||
	for _, option := range options {
 | 
			
		||||
		option.apply(&config)
 | 
			
		||||
	}
 | 
			
		||||
	// Preform any validation here.
 | 
			
		||||
	return config
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If validation of the `config` options is also preformed this can return an
 | 
			
		||||
error as well that is expected to be handled by the instantiation function
 | 
			
		||||
or propagated to the user.
 | 
			
		||||
 | 
			
		||||
Given the design goal of not having the user need to work with the `config`,
 | 
			
		||||
the `newConfig` function should also be unexported.
 | 
			
		||||
 | 
			
		||||
#### `Option`
 | 
			
		||||
 | 
			
		||||
To set the value of the options a `config` contains, a corresponding
 | 
			
		||||
`Option` interface type should be used.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Option interface {
 | 
			
		||||
	apply(*config)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Having `apply` unexported makes sure that it will not be used externally.
 | 
			
		||||
Moreover, the interface becomes sealed so the user cannot easily implement
 | 
			
		||||
the interface on its own.
 | 
			
		||||
 | 
			
		||||
The name of the interface should be prefixed in the same way the
 | 
			
		||||
corresponding `config` is (if at all).
 | 
			
		||||
 | 
			
		||||
#### Options
 | 
			
		||||
 | 
			
		||||
All user configurable options for a `config` must have a related unexported
 | 
			
		||||
implementation of the `Option` interface and an exported configuration
 | 
			
		||||
function that wraps this implementation.
 | 
			
		||||
 | 
			
		||||
The wrapping function name should be prefixed with `With*` (or in the
 | 
			
		||||
special case of a boolean options `Without*`) and should have the following
 | 
			
		||||
function signature.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
func With*(…) Option { … }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### `bool` Options
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type defaultFalseOption bool
 | 
			
		||||
 | 
			
		||||
func (o defaultFalseOption) apply(c *config) {
 | 
			
		||||
	c.Bool = bool(o)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithOption sets a T to have an option included.
 | 
			
		||||
func WithOption() Option {
 | 
			
		||||
	return defaultFalseOption(true)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type defaultTrueOption bool
 | 
			
		||||
 | 
			
		||||
func (o defaultTrueOption) apply(c *config) {
 | 
			
		||||
	c.Bool = bool(o)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithoutOption sets a T to have Bool option excluded.
 | 
			
		||||
func WithoutOption() Option {
 | 
			
		||||
	return defaultTrueOption(false)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### Declared Type Options
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type myTypeOption struct {
 | 
			
		||||
	MyType MyType
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o myTypeOption) apply(c *config) {
 | 
			
		||||
	c.MyType = o.MyType
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithMyType sets T to have include MyType.
 | 
			
		||||
func WithMyType(t MyType) Option {
 | 
			
		||||
	return myTypeOption{t}
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### Functional Options
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type optionFunc func(*config)
 | 
			
		||||
 | 
			
		||||
func (fn optionFunc) apply(c *config) {
 | 
			
		||||
	fn(c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithMyType sets t as MyType.
 | 
			
		||||
func WithMyType(t MyType) Option {
 | 
			
		||||
	return optionFunc(func(c *config) {
 | 
			
		||||
		c.MyType = t
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Instantiation
 | 
			
		||||
 | 
			
		||||
Using this configuration pattern to configure instantiation with a `NewT`
 | 
			
		||||
function.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
func NewT(options ...Option) T {…}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Any required parameters can be declared before the variadic `options`.
 | 
			
		||||
 | 
			
		||||
#### Dealing with Overlap
 | 
			
		||||
 | 
			
		||||
Sometimes there are multiple complex `struct` that share common
 | 
			
		||||
configuration and also have distinct configuration. To avoid repeated
 | 
			
		||||
portions of `config`s, a common `config` can be used with the union of
 | 
			
		||||
options being handled with the `Option` interface.
 | 
			
		||||
 | 
			
		||||
For example.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// config holds options for all animals.
 | 
			
		||||
type config struct {
 | 
			
		||||
	Weight      float64
 | 
			
		||||
	Color       string
 | 
			
		||||
	MaxAltitude float64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DogOption apply Dog specific options.
 | 
			
		||||
type DogOption interface {
 | 
			
		||||
	applyDog(*config)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BirdOption apply Bird specific options.
 | 
			
		||||
type BirdOption interface {
 | 
			
		||||
	applyBird(*config)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Option apply options for all animals.
 | 
			
		||||
type Option interface {
 | 
			
		||||
	BirdOption
 | 
			
		||||
	DogOption
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type weightOption float64
 | 
			
		||||
func (o weightOption) applyDog(c *config)  { c.Weight = float64(o) }
 | 
			
		||||
func (o weightOption) applyBird(c *config) { c.Weight = float64(o) }
 | 
			
		||||
func WithWeight(w float64) Option          { return weightOption(w) }
 | 
			
		||||
 | 
			
		||||
type furColorOption string
 | 
			
		||||
func (o furColorOption) applyDog(c *config) { c.Color = string(o) }
 | 
			
		||||
func WithFurColor(c string) DogOption       { return furColorOption(c) }
 | 
			
		||||
 | 
			
		||||
type maxAltitudeOption float64
 | 
			
		||||
func (o maxAltitudeOption) applyBird(c *config) { c.MaxAltitude = float64(o) }
 | 
			
		||||
func WithMaxAltitude(a float64) BirdOption      { return maxAltitudeOption(a) }
 | 
			
		||||
 | 
			
		||||
func NewDog(name string, o ...DogOption) Dog    {…}
 | 
			
		||||
func NewBird(name string, o ...BirdOption) Bird {…}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Interfaces
 | 
			
		||||
 | 
			
		||||
To allow other developers to better comprehend the code, it is important
 | 
			
		||||
to ensure it is sufficiently documented. One simple measure that contributes
 | 
			
		||||
to this aim is self-documenting by naming method parameters. Therefore,
 | 
			
		||||
where appropriate, methods of every exported interface type should have
 | 
			
		||||
their parameters appropriately named.
 | 
			
		||||
 | 
			
		||||
#### Interface Stability
 | 
			
		||||
 | 
			
		||||
All exported stable interfaces that include the following warning in their
 | 
			
		||||
doumentation are allowed to be extended with additional methods.
 | 
			
		||||
 | 
			
		||||
> Warning: methods may be added to this interface in minor releases.
 | 
			
		||||
 | 
			
		||||
Otherwise, stable interfaces MUST NOT be modified.
 | 
			
		||||
 | 
			
		||||
If new functionality is needed for an interface that cannot be changed it MUST
 | 
			
		||||
be added by including an additional interface. That added interface can be a
 | 
			
		||||
simple interface for the specific functionality that you want to add or it can
 | 
			
		||||
be a super-set of the original interface. For example, if you wanted to a
 | 
			
		||||
`Close` method to the `Exporter` interface:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Exporter interface {
 | 
			
		||||
	Export()
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
A new interface, `Closer`, can be added:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Closer interface {
 | 
			
		||||
	Close()
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Code that is passed the `Exporter` interface can now check to see if the passed
 | 
			
		||||
value also satisfies the new interface. E.g.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
func caller(e Exporter) {
 | 
			
		||||
	/* ... */
 | 
			
		||||
	if c, ok := e.(Closer); ok {
 | 
			
		||||
		c.Close()
 | 
			
		||||
	}
 | 
			
		||||
	/* ... */
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Alternatively, a new type that is the super-set of an `Exporter` can be created.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type ClosingExporter struct {
 | 
			
		||||
	Exporter
 | 
			
		||||
	Close()
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This new type can be used similar to the simple interface above in that a
 | 
			
		||||
passed `Exporter` type can be asserted to satisfy the `ClosingExporter` type
 | 
			
		||||
and the `Close` method called.
 | 
			
		||||
 | 
			
		||||
This super-set approach can be useful if there is explicit behavior that needs
 | 
			
		||||
to be coupled with the original type and passed as a unified type to a new
 | 
			
		||||
function, but, because of this coupling, it also limits the applicability of
 | 
			
		||||
the added functionality. If there exist other interfaces where this
 | 
			
		||||
functionality should be added, each one will need their own super-set
 | 
			
		||||
interfaces and will duplicate the pattern. For this reason, the simple targeted
 | 
			
		||||
interface that defines the specific functionality should be preferred.
 | 
			
		||||
 | 
			
		||||
## Approvers and Maintainers
 | 
			
		||||
 | 
			
		||||
Approvers:
 | 
			
		||||
 | 
			
		||||
- [Evan Torrie](https://github.com/evantorrie), Verizon Media
 | 
			
		||||
- [Josh MacDonald](https://github.com/jmacd), LightStep
 | 
			
		||||
- [Sam Xie](https://github.com/XSAM)
 | 
			
		||||
- [David Ashpole](https://github.com/dashpole), Google
 | 
			
		||||
- [Gustavo Silva Paiva](https://github.com/paivagustavo), LightStep
 | 
			
		||||
- [Aaron Clawson](https://github.com/MadVikingGod)
 | 
			
		||||
- [Robert Pająk](https://github.com/pellared), Splunk
 | 
			
		||||
 | 
			
		||||
Maintainers:
 | 
			
		||||
 | 
			
		||||
- [Anthony Mirabella](https://github.com/Aneurysm9), AWS
 | 
			
		||||
- [Tyler Yahn](https://github.com/MrAlias), Splunk
 | 
			
		||||
 | 
			
		||||
### Become an Approver or a Maintainer
 | 
			
		||||
 | 
			
		||||
See the [community membership document in OpenTelemetry community
 | 
			
		||||
repo](https://github.com/open-telemetry/community/blob/main/community-membership.md).
 | 
			
		||||
							
								
								
									
										201
									
								
								vendor/go.opentelemetry.io/otel/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								vendor/go.opentelemetry.io/otel/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
							
								
								
									
										207
									
								
								vendor/go.opentelemetry.io/otel/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								vendor/go.opentelemetry.io/otel/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,207 @@
 | 
			
		||||
# Copyright The OpenTelemetry Authors
 | 
			
		||||
#
 | 
			
		||||
# Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
# you may not use this file except in compliance with the License.
 | 
			
		||||
# You may obtain a copy of the License at
 | 
			
		||||
#
 | 
			
		||||
#     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
#
 | 
			
		||||
# Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
# distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
# See the License for the specific language governing permissions and
 | 
			
		||||
# limitations under the License.
 | 
			
		||||
 | 
			
		||||
EXAMPLES := $(shell ./get_main_pkgs.sh ./example)
 | 
			
		||||
TOOLS_MOD_DIR := ./internal/tools
 | 
			
		||||
 | 
			
		||||
# All source code and documents. Used in spell check.
 | 
			
		||||
ALL_DOCS := $(shell find . -name '*.md' -type f | sort)
 | 
			
		||||
# All directories with go.mod files related to opentelemetry library. Used for building, testing and linting.
 | 
			
		||||
ALL_GO_MOD_DIRS := $(filter-out $(TOOLS_MOD_DIR), $(shell find . -type f -name 'go.mod' -exec dirname {} \; | egrep -v '^./example' | sort)) $(shell find ./example -type f -name 'go.mod' -exec dirname {} \; | sort)
 | 
			
		||||
ALL_COVERAGE_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | egrep -v '^./example|^$(TOOLS_MOD_DIR)' | sort)
 | 
			
		||||
 | 
			
		||||
GO = go
 | 
			
		||||
TIMEOUT = 60
 | 
			
		||||
 | 
			
		||||
.DEFAULT_GOAL := precommit
 | 
			
		||||
 | 
			
		||||
.PHONY: precommit ci
 | 
			
		||||
precommit: dependabot-check license-check lint build examples test-default
 | 
			
		||||
ci: precommit check-clean-work-tree test-coverage
 | 
			
		||||
 | 
			
		||||
# Tools
 | 
			
		||||
 | 
			
		||||
TOOLS = $(CURDIR)/.tools
 | 
			
		||||
 | 
			
		||||
$(TOOLS):
 | 
			
		||||
	@mkdir -p $@
 | 
			
		||||
$(TOOLS)/%: | $(TOOLS)
 | 
			
		||||
	cd $(TOOLS_MOD_DIR) && \
 | 
			
		||||
	$(GO) build -o $@ $(PACKAGE)
 | 
			
		||||
 | 
			
		||||
MULTIMOD = $(TOOLS)/multimod
 | 
			
		||||
$(TOOLS)/multimod: PACKAGE=go.opentelemetry.io/build-tools/multimod
 | 
			
		||||
 | 
			
		||||
SEMCONVGEN = $(TOOLS)/semconvgen
 | 
			
		||||
$(TOOLS)/semconvgen: PACKAGE=go.opentelemetry.io/build-tools/semconvgen
 | 
			
		||||
 | 
			
		||||
CROSSLINK = $(TOOLS)/crosslink
 | 
			
		||||
$(TOOLS)/crosslink: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/crosslink
 | 
			
		||||
 | 
			
		||||
GOLANGCI_LINT = $(TOOLS)/golangci-lint
 | 
			
		||||
$(TOOLS)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/cmd/golangci-lint
 | 
			
		||||
 | 
			
		||||
MISSPELL = $(TOOLS)/misspell
 | 
			
		||||
$(TOOLS)/misspell: PACKAGE=github.com/client9/misspell/cmd/misspell
 | 
			
		||||
 | 
			
		||||
GOCOVMERGE = $(TOOLS)/gocovmerge
 | 
			
		||||
$(TOOLS)/gocovmerge: PACKAGE=github.com/wadey/gocovmerge
 | 
			
		||||
 | 
			
		||||
STRINGER = $(TOOLS)/stringer
 | 
			
		||||
$(TOOLS)/stringer: PACKAGE=golang.org/x/tools/cmd/stringer
 | 
			
		||||
 | 
			
		||||
PORTO = $(TOOLS)/porto
 | 
			
		||||
$(TOOLS)/porto: PACKAGE=github.com/jcchavezs/porto/cmd/porto
 | 
			
		||||
 | 
			
		||||
GOJQ = $(TOOLS)/gojq
 | 
			
		||||
$(TOOLS)/gojq: PACKAGE=github.com/itchyny/gojq/cmd/gojq
 | 
			
		||||
 | 
			
		||||
.PHONY: tools
 | 
			
		||||
tools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(GOJQ) $(SEMCONVGEN) $(MULTIMOD)
 | 
			
		||||
 | 
			
		||||
# Build
 | 
			
		||||
 | 
			
		||||
.PHONY: examples generate build
 | 
			
		||||
examples:
 | 
			
		||||
	@set -e; for dir in $(EXAMPLES); do \
 | 
			
		||||
	  echo "$(GO) build $${dir}/..."; \
 | 
			
		||||
	  (cd "$${dir}" && \
 | 
			
		||||
	   $(GO) build .); \
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
generate: $(STRINGER) $(PORTO)
 | 
			
		||||
	set -e; for dir in $(ALL_GO_MOD_DIRS); do \
 | 
			
		||||
	  echo "$(GO) generate $${dir}/..."; \
 | 
			
		||||
	  (cd "$${dir}" && \
 | 
			
		||||
	    PATH="$(TOOLS):$${PATH}" $(GO) generate ./... && \
 | 
			
		||||
		$(PORTO) -w .); \
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
build: generate
 | 
			
		||||
	# Build all package code including testing code.
 | 
			
		||||
	set -e; for dir in $(ALL_GO_MOD_DIRS); do \
 | 
			
		||||
	  echo "$(GO) build $${dir}/..."; \
 | 
			
		||||
	  (cd "$${dir}" && \
 | 
			
		||||
	    $(GO) build ./... && \
 | 
			
		||||
		$(GO) list ./... \
 | 
			
		||||
		  | grep -v third_party \
 | 
			
		||||
		  | xargs $(GO) test -vet=off -run xxxxxMatchNothingxxxxx >/dev/null); \
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
# Tests
 | 
			
		||||
 | 
			
		||||
TEST_TARGETS := test-default test-bench test-short test-verbose test-race
 | 
			
		||||
.PHONY: $(TEST_TARGETS) test
 | 
			
		||||
test-default: ARGS=-v -race
 | 
			
		||||
test-bench:   ARGS=-run=xxxxxMatchNothingxxxxx -test.benchtime=1ms -bench=.
 | 
			
		||||
test-short:   ARGS=-short
 | 
			
		||||
test-verbose: ARGS=-v
 | 
			
		||||
test-race:    ARGS=-race
 | 
			
		||||
$(TEST_TARGETS): test
 | 
			
		||||
test:
 | 
			
		||||
	@set -e; for dir in $(ALL_GO_MOD_DIRS); do \
 | 
			
		||||
	  echo "$(GO) test -timeout $(TIMEOUT)s $(ARGS) $${dir}/..."; \
 | 
			
		||||
	  (cd "$${dir}" && \
 | 
			
		||||
	    $(GO) list ./... \
 | 
			
		||||
		  | grep -v third_party \
 | 
			
		||||
		  | xargs $(GO) test -timeout $(TIMEOUT)s $(ARGS)); \
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
COVERAGE_MODE    = atomic
 | 
			
		||||
COVERAGE_PROFILE = coverage.out
 | 
			
		||||
.PHONY: test-coverage
 | 
			
		||||
test-coverage: | $(GOCOVMERGE)
 | 
			
		||||
	@set -e; \
 | 
			
		||||
	printf "" > coverage.txt; \
 | 
			
		||||
	for dir in $(ALL_COVERAGE_MOD_DIRS); do \
 | 
			
		||||
	  echo "$(GO) test -coverpkg=go.opentelemetry.io/otel/... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" $${dir}/..."; \
 | 
			
		||||
	  (cd "$${dir}" && \
 | 
			
		||||
	    $(GO) list ./... \
 | 
			
		||||
	    | grep -v third_party \
 | 
			
		||||
	    | xargs $(GO) test -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" && \
 | 
			
		||||
	  $(GO) tool cover -html=coverage.out -o coverage.html); \
 | 
			
		||||
	done; \
 | 
			
		||||
	$(GOCOVMERGE) $$(find . -name coverage.out) > coverage.txt
 | 
			
		||||
 | 
			
		||||
.PHONY: lint
 | 
			
		||||
lint: misspell lint-modules | $(GOLANGCI_LINT)
 | 
			
		||||
	set -e; for dir in $(ALL_GO_MOD_DIRS); do \
 | 
			
		||||
	  echo "golangci-lint in $${dir}"; \
 | 
			
		||||
	  (cd "$${dir}" && \
 | 
			
		||||
	    $(GOLANGCI_LINT) run --fix && \
 | 
			
		||||
	    $(GOLANGCI_LINT) run); \
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
.PHONY: vanity-import-check
 | 
			
		||||
vanity-import-check: | $(PORTO)
 | 
			
		||||
	$(PORTO) --include-internal -l .
 | 
			
		||||
 | 
			
		||||
.PHONY: misspell
 | 
			
		||||
misspell: | $(MISSPELL)
 | 
			
		||||
	$(MISSPELL) -w $(ALL_DOCS)
 | 
			
		||||
 | 
			
		||||
.PHONY: lint-modules
 | 
			
		||||
lint-modules: | $(CROSSLINK)
 | 
			
		||||
	set -e; for dir in $(ALL_GO_MOD_DIRS) $(TOOLS_MOD_DIR); do \
 | 
			
		||||
	  echo "$(GO) mod tidy in $${dir}"; \
 | 
			
		||||
	  (cd "$${dir}" && \
 | 
			
		||||
	    $(GO) mod tidy); \
 | 
			
		||||
	done
 | 
			
		||||
	echo "cross-linking all go modules"
 | 
			
		||||
	$(CROSSLINK)
 | 
			
		||||
 | 
			
		||||
.PHONY: license-check
 | 
			
		||||
license-check:
 | 
			
		||||
	@licRes=$$(for f in $$(find . -type f \( -iname '*.go' -o -iname '*.sh' \) ! -path '**/third_party/*') ; do \
 | 
			
		||||
	           awk '/Copyright The OpenTelemetry Authors|generated|GENERATED/ && NR<=3 { found=1; next } END { if (!found) print FILENAME }' $$f; \
 | 
			
		||||
	   done); \
 | 
			
		||||
	   if [ -n "$${licRes}" ]; then \
 | 
			
		||||
	           echo "license header checking failed:"; echo "$${licRes}"; \
 | 
			
		||||
	           exit 1; \
 | 
			
		||||
	   fi
 | 
			
		||||
 | 
			
		||||
.PHONY: dependabot-check
 | 
			
		||||
dependabot-check:
 | 
			
		||||
	@result=$$( \
 | 
			
		||||
		for f in $$( find . -type f -name go.mod -exec dirname {} \; | sed 's/^.//' ); \
 | 
			
		||||
			do grep -q "directory: \+$$f" .github/dependabot.yml \
 | 
			
		||||
			|| echo "$$f"; \
 | 
			
		||||
		done; \
 | 
			
		||||
	); \
 | 
			
		||||
	if [ -n "$$result" ]; then \
 | 
			
		||||
		echo "missing go.mod dependabot check:"; echo "$$result"; \
 | 
			
		||||
		echo "new modules need to be added to the .github/dependabot.yml file"; \
 | 
			
		||||
		exit 1; \
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
.PHONY: check-clean-work-tree
 | 
			
		||||
check-clean-work-tree:
 | 
			
		||||
	@if ! git diff --quiet; then \
 | 
			
		||||
	  echo; \
 | 
			
		||||
	  echo 'Working tree is not clean, did you forget to run "make precommit"?'; \
 | 
			
		||||
	  echo; \
 | 
			
		||||
	  git status; \
 | 
			
		||||
	  exit 1; \
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
.PHONY: prerelease
 | 
			
		||||
prerelease: | $(MULTIMOD)
 | 
			
		||||
	@[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 )
 | 
			
		||||
	$(MULTIMOD) verify && $(MULTIMOD) prerelease -m ${MODSET}
 | 
			
		||||
 | 
			
		||||
COMMIT ?= "HEAD"
 | 
			
		||||
.PHONY: add-tags
 | 
			
		||||
add-tags: | $(MULTIMOD)
 | 
			
		||||
	@[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 )
 | 
			
		||||
	$(MULTIMOD) verify && $(MULTIMOD) tag -m ${MODSET} -c ${COMMIT}
 | 
			
		||||
							
								
								
									
										100
									
								
								vendor/go.opentelemetry.io/otel/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								vendor/go.opentelemetry.io/otel/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
			
		||||
# OpenTelemetry-Go
 | 
			
		||||
 | 
			
		||||
[](https://github.com/open-telemetry/opentelemetry-go/actions?query=workflow%3Aci+branch%3Amain)
 | 
			
		||||
[](https://app.codecov.io/gh/open-telemetry/opentelemetry-go?branch=main)
 | 
			
		||||
[](https://pkg.go.dev/go.opentelemetry.io/otel)
 | 
			
		||||
[](https://goreportcard.com/report/go.opentelemetry.io/otel)
 | 
			
		||||
[](https://cloud-native.slack.com/archives/C01NPAXACKT)
 | 
			
		||||
 | 
			
		||||
OpenTelemetry-Go is the [Go](https://golang.org/) implementation of [OpenTelemetry](https://opentelemetry.io/).
 | 
			
		||||
It provides a set of APIs to directly measure performance and behavior of your software and send this data to observability platforms.
 | 
			
		||||
 | 
			
		||||
## Project Status
 | 
			
		||||
 | 
			
		||||
| Signal  | Status     | Project |
 | 
			
		||||
| ------- | ---------- | ------- |
 | 
			
		||||
| Traces  | Stable     | N/A     |
 | 
			
		||||
| Metrics | Alpha      | N/A     |
 | 
			
		||||
| Logs    | Frozen [1] | N/A     |
 | 
			
		||||
 | 
			
		||||
- [1]: The Logs signal development is halted for this project while we develop both Traces and Metrics.
 | 
			
		||||
   No Logs Pull Requests are currently being accepted.
 | 
			
		||||
 | 
			
		||||
Progress and status specific to this repository is tracked in our local
 | 
			
		||||
[project boards](https://github.com/open-telemetry/opentelemetry-go/projects)
 | 
			
		||||
and
 | 
			
		||||
[milestones](https://github.com/open-telemetry/opentelemetry-go/milestones).
 | 
			
		||||
 | 
			
		||||
Project versioning information and stability guarantees can be found in the
 | 
			
		||||
[versioning documentation](./VERSIONING.md).
 | 
			
		||||
 | 
			
		||||
### Compatibility
 | 
			
		||||
 | 
			
		||||
This project is tested on the following systems.
 | 
			
		||||
 | 
			
		||||
| OS      | Go Version | Architecture |
 | 
			
		||||
| ------- | ---------- | ------------ |
 | 
			
		||||
| Ubuntu  | 1.17       | amd64        |
 | 
			
		||||
| Ubuntu  | 1.16       | amd64        |
 | 
			
		||||
| Ubuntu  | 1.15       | amd64        |
 | 
			
		||||
| Ubuntu  | 1.17       | 386          |
 | 
			
		||||
| Ubuntu  | 1.16       | 386          |
 | 
			
		||||
| Ubuntu  | 1.15       | 386          |
 | 
			
		||||
| MacOS   | 1.17       | amd64        |
 | 
			
		||||
| MacOS   | 1.16       | amd64        |
 | 
			
		||||
| MacOS   | 1.15       | amd64        |
 | 
			
		||||
| Windows | 1.17       | amd64        |
 | 
			
		||||
| Windows | 1.16       | amd64        |
 | 
			
		||||
| Windows | 1.15       | amd64        |
 | 
			
		||||
| Windows | 1.17       | 386          |
 | 
			
		||||
| Windows | 1.16       | 386          |
 | 
			
		||||
| Windows | 1.15       | 386          |
 | 
			
		||||
 | 
			
		||||
While this project should work for other systems, no compatibility guarantees
 | 
			
		||||
are made for those systems currently.
 | 
			
		||||
 | 
			
		||||
## Getting Started
 | 
			
		||||
 | 
			
		||||
You can find a getting started guide on [opentelemetry.io](https://opentelemetry.io/docs/go/getting-started/).
 | 
			
		||||
 | 
			
		||||
OpenTelemetry's goal is to provide a single set of APIs to capture distributed
 | 
			
		||||
traces and metrics from your application and send them to an observability
 | 
			
		||||
platform. This project allows you to do just that for applications written in
 | 
			
		||||
Go. There are two steps to this process: instrument your application, and
 | 
			
		||||
configure an exporter.
 | 
			
		||||
 | 
			
		||||
### Instrumentation
 | 
			
		||||
 | 
			
		||||
To start capturing distributed traces and metric events from your application
 | 
			
		||||
it first needs to be instrumented. The easiest way to do this is by using an
 | 
			
		||||
instrumentation library for your code. Be sure to check out [the officially
 | 
			
		||||
supported instrumentation
 | 
			
		||||
libraries](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/instrumentation).
 | 
			
		||||
 | 
			
		||||
If you need to extend the telemetry an instrumentation library provides or want
 | 
			
		||||
to build your own instrumentation for your application directly you will need
 | 
			
		||||
to use the
 | 
			
		||||
[go.opentelemetry.io/otel/api](https://pkg.go.dev/go.opentelemetry.io/otel/api)
 | 
			
		||||
package. The included [examples](./example/) are a good way to see some
 | 
			
		||||
practical uses of this process.
 | 
			
		||||
 | 
			
		||||
### Export
 | 
			
		||||
 | 
			
		||||
Now that your application is instrumented to collect telemetry, it needs an
 | 
			
		||||
export pipeline to send that telemetry to an observability platform.
 | 
			
		||||
 | 
			
		||||
All officially supported exporters for the OpenTelemetry project are contained in the [exporters directory](./exporters).
 | 
			
		||||
 | 
			
		||||
| Exporter                              | Metrics | Traces |
 | 
			
		||||
| :-----------------------------------: | :-----: | :----: |
 | 
			
		||||
| [Jaeger](./exporters/jaeger/)         |         | ✓      |
 | 
			
		||||
| [OTLP](./exporters/otlp/)             | ✓       | ✓      |
 | 
			
		||||
| [Prometheus](./exporters/prometheus/) | ✓       |        |
 | 
			
		||||
| [stdout](./exporters/stdout/)         | ✓       | ✓      |
 | 
			
		||||
| [Zipkin](./exporters/zipkin/)         |         | ✓      |
 | 
			
		||||
 | 
			
		||||
Additionally, OpenTelemetry community supported exporters can be found in the [contrib repository](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/exporters).
 | 
			
		||||
 | 
			
		||||
## Contributing
 | 
			
		||||
 | 
			
		||||
See the [contributing documentation](CONTRIBUTING.md).
 | 
			
		||||
							
								
								
									
										133
									
								
								vendor/go.opentelemetry.io/otel/RELEASING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								vendor/go.opentelemetry.io/otel/RELEASING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,133 @@
 | 
			
		||||
# Release Process
 | 
			
		||||
 | 
			
		||||
## Semantic Convention Generation
 | 
			
		||||
 | 
			
		||||
If a new version of the OpenTelemetry Specification has been released it will be necessary to generate a new
 | 
			
		||||
semantic convention package from the YAML definitions in the specification repository. There is a `semconvgen` utility
 | 
			
		||||
installed by `make tools` that can be used to generate the a package with the name matching the specification
 | 
			
		||||
version number under the `semconv` package. This will ideally be done soon after the specification release is
 | 
			
		||||
tagged. Make sure that the specification repo contains a checkout of the the latest tagged release so that the
 | 
			
		||||
generated files match the released semantic conventions.
 | 
			
		||||
 | 
			
		||||
There are currently two categories of semantic conventions that must be generated, `resource` and `trace`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
.tools/semconvgen -i /path/to/specification/repo/semantic_conventions/resource -t semconv/template.j2
 | 
			
		||||
.tools/semconvgen -i /path/to/specification/repo/semantic_conventions/trace -t semconv/template.j2
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Using default values for all options other than `input` will result in using the `template.j2` template to
 | 
			
		||||
generate `resource.go` and `trace.go` in `/path/to/otelgo/repo/semconv/<version>`.
 | 
			
		||||
 | 
			
		||||
There are several ancillary files that are not generated and should be copied into the new package from the
 | 
			
		||||
prior package, with updates made as appropriate to canonical import path statements and constant values.
 | 
			
		||||
These files include:
 | 
			
		||||
 | 
			
		||||
* doc.go
 | 
			
		||||
* exception.go
 | 
			
		||||
* http(_test)?.go
 | 
			
		||||
* schema.go
 | 
			
		||||
 | 
			
		||||
Uses of the previous schema version in this repository should be updated to use the newly generated version.
 | 
			
		||||
No tooling for this exists at present, so use find/replace in your editor of choice or craft a `grep | sed`
 | 
			
		||||
pipeline if you like living on the edge.
 | 
			
		||||
 | 
			
		||||
## Pre-Release
 | 
			
		||||
 | 
			
		||||
First, decide which module sets will be released and update their versions
 | 
			
		||||
in `versions.yaml`.  Commit this change to a new branch.
 | 
			
		||||
 | 
			
		||||
Update go.mod for submodules to depend on the new release which will happen in the next step.
 | 
			
		||||
 | 
			
		||||
1. Run the `prerelease` make target. It creates a branch
 | 
			
		||||
    `prerelease_<module set>_<new tag>` that will contain all release changes.
 | 
			
		||||
 | 
			
		||||
    ```
 | 
			
		||||
    make prerelease MODSET=<module set>
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
2. Verify the changes.
 | 
			
		||||
 | 
			
		||||
    ```
 | 
			
		||||
    git diff ...prerelease_<module set>_<new tag>
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
    This should have changed the version for all modules to be `<new tag>`.
 | 
			
		||||
    If these changes look correct, merge them into your pre-release branch:
 | 
			
		||||
 | 
			
		||||
    ```go
 | 
			
		||||
    git merge prerelease_<module set>_<new tag>
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
3. Update the [Changelog](./CHANGELOG.md).
 | 
			
		||||
   - Make sure all relevant changes for this release are included and are in language that non-contributors to the project can understand.
 | 
			
		||||
       To verify this, you can look directly at the commits since the `<last tag>`.
 | 
			
		||||
 | 
			
		||||
       ```
 | 
			
		||||
       git --no-pager log --pretty=oneline "<last tag>..HEAD"
 | 
			
		||||
       ```
 | 
			
		||||
 | 
			
		||||
   - Move all the `Unreleased` changes into a new section following the title scheme (`[<new tag>] - <date of release>`).
 | 
			
		||||
   - Update all the appropriate links at the bottom.
 | 
			
		||||
 | 
			
		||||
4. Push the changes to upstream and create a Pull Request on GitHub.
 | 
			
		||||
    Be sure to include the curated changes from the [Changelog](./CHANGELOG.md) in the description.
 | 
			
		||||
 | 
			
		||||
## Tag
 | 
			
		||||
 | 
			
		||||
Once the Pull Request with all the version changes has been approved and merged it is time to tag the merged commit.
 | 
			
		||||
 | 
			
		||||
***IMPORTANT***: It is critical you use the same tag that you used in the Pre-Release step!
 | 
			
		||||
Failure to do so will leave things in a broken state. As long as you do not
 | 
			
		||||
change `versions.yaml` between pre-release and this step, things should be fine.
 | 
			
		||||
 | 
			
		||||
***IMPORTANT***: [There is currently no way to remove an incorrectly tagged version of a Go module](https://github.com/golang/go/issues/34189).
 | 
			
		||||
It is critical you make sure the version you push upstream is correct.
 | 
			
		||||
[Failure to do so will lead to minor emergencies and tough to work around](https://github.com/open-telemetry/opentelemetry-go/issues/331).
 | 
			
		||||
 | 
			
		||||
1. For each module set that will be released, run the `add-tags` make target
 | 
			
		||||
    using the `<commit-hash>` of the commit on the main branch for the merged Pull Request.
 | 
			
		||||
 | 
			
		||||
    ```
 | 
			
		||||
    make add-tags MODSET=<module set> COMMIT=<commit hash>
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
    It should only be necessary to provide an explicit `COMMIT` value if the
 | 
			
		||||
    current `HEAD` of your working directory is not the correct commit.
 | 
			
		||||
 | 
			
		||||
2. Push tags to the upstream remote (not your fork: `github.com/open-telemetry/opentelemetry-go.git`).
 | 
			
		||||
    Make sure you push all sub-modules as well.
 | 
			
		||||
 | 
			
		||||
    ```
 | 
			
		||||
    git push upstream <new tag>
 | 
			
		||||
    git push upstream <submodules-path/new tag>
 | 
			
		||||
    ...
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
## Release
 | 
			
		||||
 | 
			
		||||
Finally create a Release for the new `<new tag>` on GitHub.
 | 
			
		||||
The release body should include all the release notes from the Changelog for this release.
 | 
			
		||||
Additionally, the `tag.sh` script generates commit logs since last release which can be used to supplement the release notes.
 | 
			
		||||
 | 
			
		||||
## Verify Examples
 | 
			
		||||
 | 
			
		||||
After releasing verify that examples build outside of the repository.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
./verify_examples.sh
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The script copies examples into a different directory removes any `replace` declarations in `go.mod` and builds them.
 | 
			
		||||
This ensures they build with the published release, not the local copy.
 | 
			
		||||
 | 
			
		||||
## Post-Release
 | 
			
		||||
 | 
			
		||||
### Contrib Repository
 | 
			
		||||
 | 
			
		||||
Once verified be sure to [make a release for the `contrib` repository](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/RELEASING.md) that uses this release.
 | 
			
		||||
 | 
			
		||||
### Website Documentation
 | 
			
		||||
 | 
			
		||||
Update [the documentation](./website_docs) for [the OpenTelemetry website](https://opentelemetry.io/docs/go/).
 | 
			
		||||
Importantly, bump any package versions referenced to be the latest one you just released and ensure all code examples still compile and are accurate.
 | 
			
		||||
							
								
								
									
										224
									
								
								vendor/go.opentelemetry.io/otel/VERSIONING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								vendor/go.opentelemetry.io/otel/VERSIONING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,224 @@
 | 
			
		||||
# Versioning
 | 
			
		||||
 | 
			
		||||
This document describes the versioning policy for this repository. This policy
 | 
			
		||||
is designed so the following goals can be achieved.
 | 
			
		||||
 | 
			
		||||
**Users are provided a codebase of value that is stable and secure.**
 | 
			
		||||
 | 
			
		||||
## Policy
 | 
			
		||||
 | 
			
		||||
* Versioning of this project will be idiomatic of a Go project using [Go
 | 
			
		||||
  modules](https://github.com/golang/go/wiki/Modules).
 | 
			
		||||
  * [Semantic import
 | 
			
		||||
    versioning](https://github.com/golang/go/wiki/Modules#semantic-import-versioning)
 | 
			
		||||
    will be used.
 | 
			
		||||
    * Versions will comply with [semver
 | 
			
		||||
      2.0](https://semver.org/spec/v2.0.0.html) with the following exceptions.
 | 
			
		||||
      * New methods may be added to exported API interfaces. All exported
 | 
			
		||||
        interfaces that fall within this exception will include the following
 | 
			
		||||
        paragraph in their public documentation.
 | 
			
		||||
 | 
			
		||||
        > Warning: methods may be added to this interface in minor releases.
 | 
			
		||||
 | 
			
		||||
    * If a module is version `v2` or higher, the major version of the module
 | 
			
		||||
      must be included as a `/vN` at the end of the module paths used in
 | 
			
		||||
      `go.mod` files (e.g., `module go.opentelemetry.io/otel/v2`, `require
 | 
			
		||||
      go.opentelemetry.io/otel/v2 v2.0.1`) and in the package import path
 | 
			
		||||
      (e.g., `import "go.opentelemetry.io/otel/v2/trace"`). This includes the
 | 
			
		||||
      paths used in `go get` commands (e.g., `go get
 | 
			
		||||
      go.opentelemetry.io/otel/v2@v2.0.1`.  Note there is both a `/v2` and a
 | 
			
		||||
      `@v2.0.1` in that example. One way to think about it is that the module
 | 
			
		||||
      name now includes the `/v2`, so include `/v2` whenever you are using the
 | 
			
		||||
      module name).
 | 
			
		||||
    * If a module is version `v0` or `v1`, do not include the major version in
 | 
			
		||||
      either the module path or the import path.
 | 
			
		||||
  * Modules will be used to encapsulate signals and components.
 | 
			
		||||
    * Experimental modules still under active development will be versioned at
 | 
			
		||||
      `v0` to imply the stability guarantee defined by
 | 
			
		||||
      [semver](https://semver.org/spec/v2.0.0.html#spec-item-4).
 | 
			
		||||
 | 
			
		||||
      > Major version zero (0.y.z) is for initial development. Anything MAY
 | 
			
		||||
      > change at any time. The public API SHOULD NOT be considered stable.
 | 
			
		||||
 | 
			
		||||
    * Mature modules for which we guarantee a stable public API will be versioned
 | 
			
		||||
      with a major version greater than `v0`.
 | 
			
		||||
      * The decision to make a module stable will be made on a case-by-case
 | 
			
		||||
        basis by the maintainers of this project.
 | 
			
		||||
    * Experimental modules will start their versioning at `v0.0.0` and will
 | 
			
		||||
      increment their minor version when backwards incompatible changes are
 | 
			
		||||
      released and increment their patch version when backwards compatible
 | 
			
		||||
      changes are released.
 | 
			
		||||
    * All stable modules that use the same major version number will use the
 | 
			
		||||
      same entire version number.
 | 
			
		||||
      * Stable modules may be released with an incremented minor or patch
 | 
			
		||||
        version even though that module has not been changed, but rather so
 | 
			
		||||
        that it will remain at the same version as other stable modules that
 | 
			
		||||
        did undergo change.
 | 
			
		||||
      * When an experimental module becomes stable a new stable module version
 | 
			
		||||
        will be released and will include this now stable module. The new
 | 
			
		||||
        stable module version will be an increment of the minor version number
 | 
			
		||||
        and will be applied to all existing stable modules as well as the newly
 | 
			
		||||
        stable module being released.
 | 
			
		||||
* Versioning of the associated [contrib
 | 
			
		||||
  repository](https://github.com/open-telemetry/opentelemetry-go-contrib) of
 | 
			
		||||
  this project will be idiomatic of a Go project using [Go
 | 
			
		||||
  modules](https://github.com/golang/go/wiki/Modules).
 | 
			
		||||
  * [Semantic import
 | 
			
		||||
    versioning](https://github.com/golang/go/wiki/Modules#semantic-import-versioning)
 | 
			
		||||
    will be used.
 | 
			
		||||
    * Versions will comply with [semver 2.0](https://semver.org/spec/v2.0.0.html).
 | 
			
		||||
    * If a module is version `v2` or higher, the
 | 
			
		||||
      major version of the module must be included as a `/vN` at the end of the
 | 
			
		||||
      module paths used in `go.mod` files (e.g., `module
 | 
			
		||||
      go.opentelemetry.io/contrib/instrumentation/host/v2`, `require
 | 
			
		||||
      go.opentelemetry.io/contrib/instrumentation/host/v2 v2.0.1`) and in the
 | 
			
		||||
      package import path (e.g., `import
 | 
			
		||||
      "go.opentelemetry.io/contrib/instrumentation/host/v2"`). This includes
 | 
			
		||||
      the paths used in `go get` commands (e.g., `go get
 | 
			
		||||
      go.opentelemetry.io/contrib/instrumentation/host/v2@v2.0.1`.  Note there
 | 
			
		||||
      is both a `/v2` and a `@v2.0.1` in that example. One way to think about
 | 
			
		||||
      it is that the module name now includes the `/v2`, so include `/v2`
 | 
			
		||||
      whenever you are using the module name).
 | 
			
		||||
    * If a module is version `v0` or `v1`, do not include the major version
 | 
			
		||||
      in either the module path or the import path.
 | 
			
		||||
  * In addition to public APIs, telemetry produced by stable instrumentation
 | 
			
		||||
    will remain stable and backwards compatible. This is to avoid breaking
 | 
			
		||||
    alerts and dashboard.
 | 
			
		||||
  * Modules will be used to encapsulate instrumentation, detectors, exporters,
 | 
			
		||||
    propagators, and any other independent sets of related components.
 | 
			
		||||
    * Experimental modules still under active development will be versioned at
 | 
			
		||||
      `v0` to imply the stability guarantee defined by
 | 
			
		||||
      [semver](https://semver.org/spec/v2.0.0.html#spec-item-4).
 | 
			
		||||
 | 
			
		||||
      > Major version zero (0.y.z) is for initial development. Anything MAY
 | 
			
		||||
      > change at any time. The public API SHOULD NOT be considered stable.
 | 
			
		||||
 | 
			
		||||
    * Mature modules for which we guarantee a stable public API and telemetry will
 | 
			
		||||
      be versioned with a major version greater than `v0`.
 | 
			
		||||
    * Experimental modules will start their versioning at `v0.0.0` and will
 | 
			
		||||
      increment their minor version when backwards incompatible changes are
 | 
			
		||||
      released and increment their patch version when backwards compatible
 | 
			
		||||
      changes are released.
 | 
			
		||||
    * Stable contrib modules cannot depend on experimental modules from this
 | 
			
		||||
      project.
 | 
			
		||||
    * All stable contrib modules of the same major version with this project
 | 
			
		||||
      will use the same entire version as this project.
 | 
			
		||||
      * Stable modules may be released with an incremented minor or patch
 | 
			
		||||
        version even though that module's code has not been changed. Instead
 | 
			
		||||
        the only change that will have been included is to have updated that
 | 
			
		||||
        modules dependency on this project's stable APIs.
 | 
			
		||||
      * When an experimental module in contrib becomes stable a new stable
 | 
			
		||||
        module version will be released and will include this now stable
 | 
			
		||||
        module. The new stable module version will be an increment of the minor
 | 
			
		||||
        version number and will be applied to all existing stable contrib
 | 
			
		||||
        modules, this project's modules, and the newly stable module being
 | 
			
		||||
        released.
 | 
			
		||||
  * Contrib modules will be kept up to date with this project's releases.
 | 
			
		||||
    * Due to the dependency contrib modules will implicitly have on this
 | 
			
		||||
      project's modules the release of stable contrib modules to match the
 | 
			
		||||
      released version number will be staggered after this project's release.
 | 
			
		||||
      There is no explicit time guarantee for how long after this projects
 | 
			
		||||
      release the contrib release will be. Effort should be made to keep them
 | 
			
		||||
      as close in time as possible.
 | 
			
		||||
    * No additional stable release in this project can be made until the
 | 
			
		||||
      contrib repository has a matching stable release.
 | 
			
		||||
    * No release can be made in the contrib repository after this project's
 | 
			
		||||
      stable release except for a stable release of the contrib repository.
 | 
			
		||||
* GitHub releases will be made for all releases.
 | 
			
		||||
* Go modules will be made available at Go package mirrors.
 | 
			
		||||
 | 
			
		||||
## Example Versioning Lifecycle
 | 
			
		||||
 | 
			
		||||
To better understand the implementation of the above policy the following
 | 
			
		||||
example is provided. This project is simplified to include only the following
 | 
			
		||||
modules and their versions:
 | 
			
		||||
 | 
			
		||||
* `otel`: `v0.14.0`
 | 
			
		||||
* `otel/trace`: `v0.14.0`
 | 
			
		||||
* `otel/metric`: `v0.14.0`
 | 
			
		||||
* `otel/baggage`: `v0.14.0`
 | 
			
		||||
* `otel/sdk/trace`: `v0.14.0`
 | 
			
		||||
* `otel/sdk/metric`: `v0.14.0`
 | 
			
		||||
 | 
			
		||||
These modules have been developed to a point where the `otel/trace`,
 | 
			
		||||
`otel/baggage`, and `otel/sdk/trace` modules have reached a point that they
 | 
			
		||||
should be considered for a stable release. The `otel/metric` and
 | 
			
		||||
`otel/sdk/metric` are still under active development and the `otel` module
 | 
			
		||||
depends on both `otel/trace` and `otel/metric`.
 | 
			
		||||
 | 
			
		||||
The `otel` package is refactored to remove its dependencies on `otel/metric` so
 | 
			
		||||
it can be released as stable as well. With that done the following release
 | 
			
		||||
candidates are made:
 | 
			
		||||
 | 
			
		||||
* `otel`: `v1.0.0-RC1`
 | 
			
		||||
* `otel/trace`: `v1.0.0-RC1`
 | 
			
		||||
* `otel/baggage`: `v1.0.0-RC1`
 | 
			
		||||
* `otel/sdk/trace`: `v1.0.0-RC1`
 | 
			
		||||
 | 
			
		||||
The `otel/metric` and `otel/sdk/metric` modules remain at `v0.14.0`.
 | 
			
		||||
 | 
			
		||||
A few minor issues are discovered in the `otel/trace` package. These issues are
 | 
			
		||||
resolved with some minor, but backwards incompatible, changes and are released
 | 
			
		||||
as a second release candidate:
 | 
			
		||||
 | 
			
		||||
* `otel`: `v1.0.0-RC2`
 | 
			
		||||
* `otel/trace`: `v1.0.0-RC2`
 | 
			
		||||
* `otel/baggage`: `v1.0.0-RC2`
 | 
			
		||||
* `otel/sdk/trace`: `v1.0.0-RC2`
 | 
			
		||||
 | 
			
		||||
Notice that all module version numbers are incremented to adhere to our
 | 
			
		||||
versioning policy.
 | 
			
		||||
 | 
			
		||||
After these release candidates have been evaluated to satisfaction, they are
 | 
			
		||||
released as version `v1.0.0`.
 | 
			
		||||
 | 
			
		||||
* `otel`: `v1.0.0`
 | 
			
		||||
* `otel/trace`: `v1.0.0`
 | 
			
		||||
* `otel/baggage`: `v1.0.0`
 | 
			
		||||
* `otel/sdk/trace`: `v1.0.0`
 | 
			
		||||
 | 
			
		||||
Since both the `go` utility and the Go module system support [the semantic
 | 
			
		||||
versioning definition of
 | 
			
		||||
precedence](https://semver.org/spec/v2.0.0.html#spec-item-11), this release
 | 
			
		||||
will correctly be interpreted as the successor to the previous release
 | 
			
		||||
candidates.
 | 
			
		||||
 | 
			
		||||
Active development of this project continues. The `otel/metric` module now has
 | 
			
		||||
backwards incompatible changes to its API that need to be released and the
 | 
			
		||||
`otel/baggage` module has a minor bug fix that needs to be released. The
 | 
			
		||||
following release is made:
 | 
			
		||||
 | 
			
		||||
* `otel`: `v1.0.1`
 | 
			
		||||
* `otel/trace`: `v1.0.1`
 | 
			
		||||
* `otel/metric`: `v0.15.0`
 | 
			
		||||
* `otel/baggage`: `v1.0.1`
 | 
			
		||||
* `otel/sdk/trace`: `v1.0.1`
 | 
			
		||||
* `otel/sdk/metric`: `v0.15.0`
 | 
			
		||||
 | 
			
		||||
Notice that, again, all stable module versions are incremented in unison and
 | 
			
		||||
the `otel/sdk/metric` package, which depends on the `otel/metric` package, also
 | 
			
		||||
bumped its version. This bump of the `otel/sdk/metric` package makes sense
 | 
			
		||||
given their coupling, though it is not explicitly required by our versioning
 | 
			
		||||
policy.
 | 
			
		||||
 | 
			
		||||
As we progress, the `otel/metric` and `otel/sdk/metric` packages have reached a
 | 
			
		||||
point where they should be evaluated for stability. The `otel` module is
 | 
			
		||||
reintegrated with the `otel/metric` package and the following release is made:
 | 
			
		||||
 | 
			
		||||
* `otel`: `v1.1.0-RC1`
 | 
			
		||||
* `otel/trace`: `v1.1.0-RC1`
 | 
			
		||||
* `otel/metric`: `v1.1.0-RC1`
 | 
			
		||||
* `otel/baggage`: `v1.1.0-RC1`
 | 
			
		||||
* `otel/sdk/trace`: `v1.1.0-RC1`
 | 
			
		||||
* `otel/sdk/metric`: `v1.1.0-RC1`
 | 
			
		||||
 | 
			
		||||
All the modules are evaluated and determined to a viable stable release. They
 | 
			
		||||
are then released as version `v1.1.0` (the minor version is incremented to
 | 
			
		||||
indicate the addition of new signal).
 | 
			
		||||
 | 
			
		||||
* `otel`: `v1.1.0`
 | 
			
		||||
* `otel/trace`: `v1.1.0`
 | 
			
		||||
* `otel/metric`: `v1.1.0`
 | 
			
		||||
* `otel/baggage`: `v1.1.0`
 | 
			
		||||
* `otel/sdk/trace`: `v1.1.0`
 | 
			
		||||
* `otel/sdk/metric`: `v1.1.0`
 | 
			
		||||
							
								
								
									
										16
									
								
								vendor/go.opentelemetry.io/otel/attribute/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/go.opentelemetry.io/otel/attribute/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
// Package attribute provides key and value attributes.
 | 
			
		||||
package attribute // import "go.opentelemetry.io/otel/attribute"
 | 
			
		||||
							
								
								
									
										150
									
								
								vendor/go.opentelemetry.io/otel/attribute/encoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								vendor/go.opentelemetry.io/otel/attribute/encoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,150 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package attribute // import "go.opentelemetry.io/otel/attribute"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	// Encoder is a mechanism for serializing a label set into a
 | 
			
		||||
	// specific string representation that supports caching, to
 | 
			
		||||
	// avoid repeated serialization. An example could be an
 | 
			
		||||
	// exporter encoding the label set into a wire representation.
 | 
			
		||||
	Encoder interface {
 | 
			
		||||
		// Encode returns the serialized encoding of the label
 | 
			
		||||
		// set using its Iterator.  This result may be cached
 | 
			
		||||
		// by a attribute.Set.
 | 
			
		||||
		Encode(iterator Iterator) string
 | 
			
		||||
 | 
			
		||||
		// ID returns a value that is unique for each class of
 | 
			
		||||
		// label encoder.  Label encoders allocate these using
 | 
			
		||||
		// `NewEncoderID`.
 | 
			
		||||
		ID() EncoderID
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// EncoderID is used to identify distinct Encoder
 | 
			
		||||
	// implementations, for caching encoded results.
 | 
			
		||||
	EncoderID struct {
 | 
			
		||||
		value uint64
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// defaultLabelEncoder uses a sync.Pool of buffers to reduce
 | 
			
		||||
	// the number of allocations used in encoding labels.  This
 | 
			
		||||
	// implementation encodes a comma-separated list of key=value,
 | 
			
		||||
	// with '/'-escaping of '=', ',', and '\'.
 | 
			
		||||
	defaultLabelEncoder struct {
 | 
			
		||||
		// pool is a pool of labelset builders.  The buffers in this
 | 
			
		||||
		// pool grow to a size that most label encodings will not
 | 
			
		||||
		// allocate new memory.
 | 
			
		||||
		pool sync.Pool // *bytes.Buffer
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// escapeChar is used to ensure uniqueness of the label encoding where
 | 
			
		||||
// keys or values contain either '=' or ','.  Since there is no parser
 | 
			
		||||
// needed for this encoding and its only requirement is to be unique,
 | 
			
		||||
// this choice is arbitrary.  Users will see these in some exporters
 | 
			
		||||
// (e.g., stdout), so the backslash ('\') is used as a conventional choice.
 | 
			
		||||
const escapeChar = '\\'
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_ Encoder = &defaultLabelEncoder{}
 | 
			
		||||
 | 
			
		||||
	// encoderIDCounter is for generating IDs for other label
 | 
			
		||||
	// encoders.
 | 
			
		||||
	encoderIDCounter uint64
 | 
			
		||||
 | 
			
		||||
	defaultEncoderOnce     sync.Once
 | 
			
		||||
	defaultEncoderID       = NewEncoderID()
 | 
			
		||||
	defaultEncoderInstance *defaultLabelEncoder
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// NewEncoderID returns a unique label encoder ID. It should be
 | 
			
		||||
// called once per each type of label encoder. Preferably in init() or
 | 
			
		||||
// in var definition.
 | 
			
		||||
func NewEncoderID() EncoderID {
 | 
			
		||||
	return EncoderID{value: atomic.AddUint64(&encoderIDCounter, 1)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DefaultEncoder returns a label encoder that encodes labels
 | 
			
		||||
// in such a way that each escaped label's key is followed by an equal
 | 
			
		||||
// sign and then by an escaped label's value. All key-value pairs are
 | 
			
		||||
// separated by a comma.
 | 
			
		||||
//
 | 
			
		||||
// Escaping is done by prepending a backslash before either a
 | 
			
		||||
// backslash, equal sign or a comma.
 | 
			
		||||
func DefaultEncoder() Encoder {
 | 
			
		||||
	defaultEncoderOnce.Do(func() {
 | 
			
		||||
		defaultEncoderInstance = &defaultLabelEncoder{
 | 
			
		||||
			pool: sync.Pool{
 | 
			
		||||
				New: func() interface{} {
 | 
			
		||||
					return &bytes.Buffer{}
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	return defaultEncoderInstance
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Encode is a part of an implementation of the LabelEncoder
 | 
			
		||||
// interface.
 | 
			
		||||
func (d *defaultLabelEncoder) Encode(iter Iterator) string {
 | 
			
		||||
	buf := d.pool.Get().(*bytes.Buffer)
 | 
			
		||||
	defer d.pool.Put(buf)
 | 
			
		||||
	buf.Reset()
 | 
			
		||||
 | 
			
		||||
	for iter.Next() {
 | 
			
		||||
		i, keyValue := iter.IndexedLabel()
 | 
			
		||||
		if i > 0 {
 | 
			
		||||
			_, _ = buf.WriteRune(',')
 | 
			
		||||
		}
 | 
			
		||||
		copyAndEscape(buf, string(keyValue.Key))
 | 
			
		||||
 | 
			
		||||
		_, _ = buf.WriteRune('=')
 | 
			
		||||
 | 
			
		||||
		if keyValue.Value.Type() == STRING {
 | 
			
		||||
			copyAndEscape(buf, keyValue.Value.AsString())
 | 
			
		||||
		} else {
 | 
			
		||||
			_, _ = buf.WriteString(keyValue.Value.Emit())
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return buf.String()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ID is a part of an implementation of the LabelEncoder interface.
 | 
			
		||||
func (*defaultLabelEncoder) ID() EncoderID {
 | 
			
		||||
	return defaultEncoderID
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// copyAndEscape escapes `=`, `,` and its own escape character (`\`),
 | 
			
		||||
// making the default encoding unique.
 | 
			
		||||
func copyAndEscape(buf *bytes.Buffer, val string) {
 | 
			
		||||
	for _, ch := range val {
 | 
			
		||||
		switch ch {
 | 
			
		||||
		case '=', ',', escapeChar:
 | 
			
		||||
			buf.WriteRune(escapeChar)
 | 
			
		||||
		}
 | 
			
		||||
		buf.WriteRune(ch)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Valid returns true if this encoder ID was allocated by
 | 
			
		||||
// `NewEncoderID`.  Invalid encoder IDs will not be cached.
 | 
			
		||||
func (id EncoderID) Valid() bool {
 | 
			
		||||
	return id.value != 0
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										143
									
								
								vendor/go.opentelemetry.io/otel/attribute/iterator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								vendor/go.opentelemetry.io/otel/attribute/iterator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,143 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package attribute // import "go.opentelemetry.io/otel/attribute"
 | 
			
		||||
 | 
			
		||||
// Iterator allows iterating over the set of labels in order,
 | 
			
		||||
// sorted by key.
 | 
			
		||||
type Iterator struct {
 | 
			
		||||
	storage *Set
 | 
			
		||||
	idx     int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MergeIterator supports iterating over two sets of labels while
 | 
			
		||||
// eliminating duplicate values from the combined set.  The first
 | 
			
		||||
// iterator value takes precedence.
 | 
			
		||||
type MergeIterator struct {
 | 
			
		||||
	one     oneIterator
 | 
			
		||||
	two     oneIterator
 | 
			
		||||
	current KeyValue
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type oneIterator struct {
 | 
			
		||||
	iter  Iterator
 | 
			
		||||
	done  bool
 | 
			
		||||
	label KeyValue
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Next moves the iterator to the next position. Returns false if there
 | 
			
		||||
// are no more labels.
 | 
			
		||||
func (i *Iterator) Next() bool {
 | 
			
		||||
	i.idx++
 | 
			
		||||
	return i.idx < i.Len()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Label returns current KeyValue. Must be called only after Next returns
 | 
			
		||||
// true.
 | 
			
		||||
func (i *Iterator) Label() KeyValue {
 | 
			
		||||
	kv, _ := i.storage.Get(i.idx)
 | 
			
		||||
	return kv
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Attribute is a synonym for Label().
 | 
			
		||||
func (i *Iterator) Attribute() KeyValue {
 | 
			
		||||
	return i.Label()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IndexedLabel returns current index and attribute. Must be called only
 | 
			
		||||
// after Next returns true.
 | 
			
		||||
func (i *Iterator) IndexedLabel() (int, KeyValue) {
 | 
			
		||||
	return i.idx, i.Label()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Len returns a number of labels in the iterator's `*Set`.
 | 
			
		||||
func (i *Iterator) Len() int {
 | 
			
		||||
	return i.storage.Len()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ToSlice is a convenience function that creates a slice of labels
 | 
			
		||||
// from the passed iterator. The iterator is set up to start from the
 | 
			
		||||
// beginning before creating the slice.
 | 
			
		||||
func (i *Iterator) ToSlice() []KeyValue {
 | 
			
		||||
	l := i.Len()
 | 
			
		||||
	if l == 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	i.idx = -1
 | 
			
		||||
	slice := make([]KeyValue, 0, l)
 | 
			
		||||
	for i.Next() {
 | 
			
		||||
		slice = append(slice, i.Label())
 | 
			
		||||
	}
 | 
			
		||||
	return slice
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewMergeIterator returns a MergeIterator for merging two label sets
 | 
			
		||||
// Duplicates are resolved by taking the value from the first set.
 | 
			
		||||
func NewMergeIterator(s1, s2 *Set) MergeIterator {
 | 
			
		||||
	mi := MergeIterator{
 | 
			
		||||
		one: makeOne(s1.Iter()),
 | 
			
		||||
		two: makeOne(s2.Iter()),
 | 
			
		||||
	}
 | 
			
		||||
	return mi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func makeOne(iter Iterator) oneIterator {
 | 
			
		||||
	oi := oneIterator{
 | 
			
		||||
		iter: iter,
 | 
			
		||||
	}
 | 
			
		||||
	oi.advance()
 | 
			
		||||
	return oi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (oi *oneIterator) advance() {
 | 
			
		||||
	if oi.done = !oi.iter.Next(); !oi.done {
 | 
			
		||||
		oi.label = oi.iter.Label()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Next returns true if there is another label available.
 | 
			
		||||
func (m *MergeIterator) Next() bool {
 | 
			
		||||
	if m.one.done && m.two.done {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if m.one.done {
 | 
			
		||||
		m.current = m.two.label
 | 
			
		||||
		m.two.advance()
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	if m.two.done {
 | 
			
		||||
		m.current = m.one.label
 | 
			
		||||
		m.one.advance()
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	if m.one.label.Key == m.two.label.Key {
 | 
			
		||||
		m.current = m.one.label // first iterator label value wins
 | 
			
		||||
		m.one.advance()
 | 
			
		||||
		m.two.advance()
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	if m.one.label.Key < m.two.label.Key {
 | 
			
		||||
		m.current = m.one.label
 | 
			
		||||
		m.one.advance()
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	m.current = m.two.label
 | 
			
		||||
	m.two.advance()
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Label returns the current value after Next() returns true.
 | 
			
		||||
func (m *MergeIterator) Label() KeyValue {
 | 
			
		||||
	return m.current
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										134
									
								
								vendor/go.opentelemetry.io/otel/attribute/key.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								vendor/go.opentelemetry.io/otel/attribute/key.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package attribute // import "go.opentelemetry.io/otel/attribute"
 | 
			
		||||
 | 
			
		||||
// Key represents the key part in key-value pairs. It's a string. The
 | 
			
		||||
// allowed character set in the key depends on the use of the key.
 | 
			
		||||
type Key string
 | 
			
		||||
 | 
			
		||||
// Bool creates a KeyValue instance with a BOOL Value.
 | 
			
		||||
//
 | 
			
		||||
// If creating both a key and value at the same time, use the provided
 | 
			
		||||
// convenience function instead -- Bool(name, value).
 | 
			
		||||
func (k Key) Bool(v bool) KeyValue {
 | 
			
		||||
	return KeyValue{
 | 
			
		||||
		Key:   k,
 | 
			
		||||
		Value: BoolValue(v),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BoolSlice creates a KeyValue instance with a BOOLSLICE Value.
 | 
			
		||||
//
 | 
			
		||||
// If creating both a key and value at the same time, use the provided
 | 
			
		||||
// convenience function instead -- BoolSlice(name, value).
 | 
			
		||||
func (k Key) BoolSlice(v []bool) KeyValue {
 | 
			
		||||
	return KeyValue{
 | 
			
		||||
		Key:   k,
 | 
			
		||||
		Value: BoolSliceValue(v),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int creates a KeyValue instance with an INT64 Value.
 | 
			
		||||
//
 | 
			
		||||
// If creating both a key and value at the same time, use the provided
 | 
			
		||||
// convenience function instead -- Int(name, value).
 | 
			
		||||
func (k Key) Int(v int) KeyValue {
 | 
			
		||||
	return KeyValue{
 | 
			
		||||
		Key:   k,
 | 
			
		||||
		Value: IntValue(v),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IntSlice creates a KeyValue instance with an INT64SLICE Value.
 | 
			
		||||
//
 | 
			
		||||
// If creating both a key and value at the same time, use the provided
 | 
			
		||||
// convenience function instead -- IntSlice(name, value).
 | 
			
		||||
func (k Key) IntSlice(v []int) KeyValue {
 | 
			
		||||
	return KeyValue{
 | 
			
		||||
		Key:   k,
 | 
			
		||||
		Value: IntSliceValue(v),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int64 creates a KeyValue instance with an INT64 Value.
 | 
			
		||||
//
 | 
			
		||||
// If creating both a key and value at the same time, use the provided
 | 
			
		||||
// convenience function instead -- Int64(name, value).
 | 
			
		||||
func (k Key) Int64(v int64) KeyValue {
 | 
			
		||||
	return KeyValue{
 | 
			
		||||
		Key:   k,
 | 
			
		||||
		Value: Int64Value(v),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int64Slice creates a KeyValue instance with an INT64SLICE Value.
 | 
			
		||||
//
 | 
			
		||||
// If creating both a key and value at the same time, use the provided
 | 
			
		||||
// convenience function instead -- Int64Slice(name, value).
 | 
			
		||||
func (k Key) Int64Slice(v []int64) KeyValue {
 | 
			
		||||
	return KeyValue{
 | 
			
		||||
		Key:   k,
 | 
			
		||||
		Value: Int64SliceValue(v),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64 creates a KeyValue instance with a FLOAT64 Value.
 | 
			
		||||
//
 | 
			
		||||
// If creating both a key and value at the same time, use the provided
 | 
			
		||||
// convenience function instead -- Float64(name, value).
 | 
			
		||||
func (k Key) Float64(v float64) KeyValue {
 | 
			
		||||
	return KeyValue{
 | 
			
		||||
		Key:   k,
 | 
			
		||||
		Value: Float64Value(v),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64Slice creates a KeyValue instance with a FLOAT64SLICE Value.
 | 
			
		||||
//
 | 
			
		||||
// If creating both a key and value at the same time, use the provided
 | 
			
		||||
// convenience function instead -- Float64(name, value).
 | 
			
		||||
func (k Key) Float64Slice(v []float64) KeyValue {
 | 
			
		||||
	return KeyValue{
 | 
			
		||||
		Key:   k,
 | 
			
		||||
		Value: Float64SliceValue(v),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String creates a KeyValue instance with a STRING Value.
 | 
			
		||||
//
 | 
			
		||||
// If creating both a key and value at the same time, use the provided
 | 
			
		||||
// convenience function instead -- String(name, value).
 | 
			
		||||
func (k Key) String(v string) KeyValue {
 | 
			
		||||
	return KeyValue{
 | 
			
		||||
		Key:   k,
 | 
			
		||||
		Value: StringValue(v),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StringSlice creates a KeyValue instance with a STRINGSLICE Value.
 | 
			
		||||
//
 | 
			
		||||
// If creating both a key and value at the same time, use the provided
 | 
			
		||||
// convenience function instead -- StringSlice(name, value).
 | 
			
		||||
func (k Key) StringSlice(v []string) KeyValue {
 | 
			
		||||
	return KeyValue{
 | 
			
		||||
		Key:   k,
 | 
			
		||||
		Value: StringSliceValue(v),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Defined returns true for non-empty keys.
 | 
			
		||||
func (k Key) Defined() bool {
 | 
			
		||||
	return len(k) != 0
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								vendor/go.opentelemetry.io/otel/attribute/kv.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								vendor/go.opentelemetry.io/otel/attribute/kv.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package attribute // import "go.opentelemetry.io/otel/attribute"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// KeyValue holds a key and value pair.
 | 
			
		||||
type KeyValue struct {
 | 
			
		||||
	Key   Key
 | 
			
		||||
	Value Value
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Valid returns if kv is a valid OpenTelemetry attribute.
 | 
			
		||||
func (kv KeyValue) Valid() bool {
 | 
			
		||||
	return kv.Key != "" && kv.Value.Type() != INVALID
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Bool creates a KeyValue with a BOOL Value type.
 | 
			
		||||
func Bool(k string, v bool) KeyValue {
 | 
			
		||||
	return Key(k).Bool(v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BoolSlice creates a KeyValue with a BOOLSLICE Value type.
 | 
			
		||||
func BoolSlice(k string, v []bool) KeyValue {
 | 
			
		||||
	return Key(k).BoolSlice(v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int creates a KeyValue with an INT64 Value type.
 | 
			
		||||
func Int(k string, v int) KeyValue {
 | 
			
		||||
	return Key(k).Int(v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IntSlice creates a KeyValue with an INT64SLICE Value type.
 | 
			
		||||
func IntSlice(k string, v []int) KeyValue {
 | 
			
		||||
	return Key(k).IntSlice(v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int64 creates a KeyValue with an INT64 Value type.
 | 
			
		||||
func Int64(k string, v int64) KeyValue {
 | 
			
		||||
	return Key(k).Int64(v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int64Slice creates a KeyValue with an INT64SLICE Value type.
 | 
			
		||||
func Int64Slice(k string, v []int64) KeyValue {
 | 
			
		||||
	return Key(k).Int64Slice(v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64 creates a KeyValue with a FLOAT64 Value type.
 | 
			
		||||
func Float64(k string, v float64) KeyValue {
 | 
			
		||||
	return Key(k).Float64(v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64Slice creates a KeyValue with a FLOAT64SLICE Value type.
 | 
			
		||||
func Float64Slice(k string, v []float64) KeyValue {
 | 
			
		||||
	return Key(k).Float64Slice(v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String creates a KeyValue with a STRING Value type.
 | 
			
		||||
func String(k, v string) KeyValue {
 | 
			
		||||
	return Key(k).String(v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StringSlice creates a KeyValue with a STRINGSLICE Value type.
 | 
			
		||||
func StringSlice(k string, v []string) KeyValue {
 | 
			
		||||
	return Key(k).StringSlice(v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stringer creates a new key-value pair with a passed name and a string
 | 
			
		||||
// value generated by the passed Stringer interface.
 | 
			
		||||
func Stringer(k string, v fmt.Stringer) KeyValue {
 | 
			
		||||
	return Key(k).String(v.String())
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										426
									
								
								vendor/go.opentelemetry.io/otel/attribute/set.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										426
									
								
								vendor/go.opentelemetry.io/otel/attribute/set.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,426 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package attribute // import "go.opentelemetry.io/otel/attribute"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"sort"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	// Set is the representation for a distinct label set.  It
 | 
			
		||||
	// manages an immutable set of labels, with an internal cache
 | 
			
		||||
	// for storing label encodings.
 | 
			
		||||
	//
 | 
			
		||||
	// This type supports the `Equivalent` method of comparison
 | 
			
		||||
	// using values of type `Distinct`.
 | 
			
		||||
	//
 | 
			
		||||
	// This type is used to implement:
 | 
			
		||||
	// 1. Metric labels
 | 
			
		||||
	// 2. Resource sets
 | 
			
		||||
	// 3. Correlation map (TODO)
 | 
			
		||||
	Set struct {
 | 
			
		||||
		equivalent Distinct
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Distinct wraps a variable-size array of `KeyValue`,
 | 
			
		||||
	// constructed with keys in sorted order.  This can be used as
 | 
			
		||||
	// a map key or for equality checking between Sets.
 | 
			
		||||
	Distinct struct {
 | 
			
		||||
		iface interface{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Filter supports removing certain labels from label sets.
 | 
			
		||||
	// When the filter returns true, the label will be kept in
 | 
			
		||||
	// the filtered label set.  When the filter returns false, the
 | 
			
		||||
	// label is excluded from the filtered label set, and the
 | 
			
		||||
	// label instead appears in the `removed` list of excluded labels.
 | 
			
		||||
	Filter func(KeyValue) bool
 | 
			
		||||
 | 
			
		||||
	// Sortable implements `sort.Interface`, used for sorting
 | 
			
		||||
	// `KeyValue`.  This is an exported type to support a
 | 
			
		||||
	// memory optimization.  A pointer to one of these is needed
 | 
			
		||||
	// for the call to `sort.Stable()`, which the caller may
 | 
			
		||||
	// provide in order to avoid an allocation.  See
 | 
			
		||||
	// `NewSetWithSortable()`.
 | 
			
		||||
	Sortable []KeyValue
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// keyValueType is used in `computeDistinctReflect`.
 | 
			
		||||
	keyValueType = reflect.TypeOf(KeyValue{})
 | 
			
		||||
 | 
			
		||||
	// emptySet is returned for empty label sets.
 | 
			
		||||
	emptySet = &Set{
 | 
			
		||||
		equivalent: Distinct{
 | 
			
		||||
			iface: [0]KeyValue{},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// EmptySet returns a reference to a Set with no elements.
 | 
			
		||||
//
 | 
			
		||||
// This is a convenience provided for optimized calling utility.
 | 
			
		||||
func EmptySet() *Set {
 | 
			
		||||
	return emptySet
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// reflect abbreviates `reflect.ValueOf`.
 | 
			
		||||
func (d Distinct) reflect() reflect.Value {
 | 
			
		||||
	return reflect.ValueOf(d.iface)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Valid returns true if this value refers to a valid `*Set`.
 | 
			
		||||
func (d Distinct) Valid() bool {
 | 
			
		||||
	return d.iface != nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Len returns the number of labels in this set.
 | 
			
		||||
func (l *Set) Len() int {
 | 
			
		||||
	if l == nil || !l.equivalent.Valid() {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	return l.equivalent.reflect().Len()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get returns the KeyValue at ordered position `idx` in this set.
 | 
			
		||||
func (l *Set) Get(idx int) (KeyValue, bool) {
 | 
			
		||||
	if l == nil {
 | 
			
		||||
		return KeyValue{}, false
 | 
			
		||||
	}
 | 
			
		||||
	value := l.equivalent.reflect()
 | 
			
		||||
 | 
			
		||||
	if idx >= 0 && idx < value.Len() {
 | 
			
		||||
		// Note: The Go compiler successfully avoids an allocation for
 | 
			
		||||
		// the interface{} conversion here:
 | 
			
		||||
		return value.Index(idx).Interface().(KeyValue), true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return KeyValue{}, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Value returns the value of a specified key in this set.
 | 
			
		||||
func (l *Set) Value(k Key) (Value, bool) {
 | 
			
		||||
	if l == nil {
 | 
			
		||||
		return Value{}, false
 | 
			
		||||
	}
 | 
			
		||||
	rValue := l.equivalent.reflect()
 | 
			
		||||
	vlen := rValue.Len()
 | 
			
		||||
 | 
			
		||||
	idx := sort.Search(vlen, func(idx int) bool {
 | 
			
		||||
		return rValue.Index(idx).Interface().(KeyValue).Key >= k
 | 
			
		||||
	})
 | 
			
		||||
	if idx >= vlen {
 | 
			
		||||
		return Value{}, false
 | 
			
		||||
	}
 | 
			
		||||
	keyValue := rValue.Index(idx).Interface().(KeyValue)
 | 
			
		||||
	if k == keyValue.Key {
 | 
			
		||||
		return keyValue.Value, true
 | 
			
		||||
	}
 | 
			
		||||
	return Value{}, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HasValue tests whether a key is defined in this set.
 | 
			
		||||
func (l *Set) HasValue(k Key) bool {
 | 
			
		||||
	if l == nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	_, ok := l.Value(k)
 | 
			
		||||
	return ok
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Iter returns an iterator for visiting the labels in this set.
 | 
			
		||||
func (l *Set) Iter() Iterator {
 | 
			
		||||
	return Iterator{
 | 
			
		||||
		storage: l,
 | 
			
		||||
		idx:     -1,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ToSlice returns the set of labels belonging to this set, sorted,
 | 
			
		||||
// where keys appear no more than once.
 | 
			
		||||
func (l *Set) ToSlice() []KeyValue {
 | 
			
		||||
	iter := l.Iter()
 | 
			
		||||
	return iter.ToSlice()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Equivalent returns a value that may be used as a map key.  The
 | 
			
		||||
// Distinct type guarantees that the result will equal the equivalent
 | 
			
		||||
// Distinct value of any label set with the same elements as this,
 | 
			
		||||
// where sets are made unique by choosing the last value in the input
 | 
			
		||||
// for any given key.
 | 
			
		||||
func (l *Set) Equivalent() Distinct {
 | 
			
		||||
	if l == nil || !l.equivalent.Valid() {
 | 
			
		||||
		return emptySet.equivalent
 | 
			
		||||
	}
 | 
			
		||||
	return l.equivalent
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Equals returns true if the argument set is equivalent to this set.
 | 
			
		||||
func (l *Set) Equals(o *Set) bool {
 | 
			
		||||
	return l.Equivalent() == o.Equivalent()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Encoded returns the encoded form of this set, according to
 | 
			
		||||
// `encoder`.
 | 
			
		||||
func (l *Set) Encoded(encoder Encoder) string {
 | 
			
		||||
	if l == nil || encoder == nil {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return encoder.Encode(l.Iter())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func empty() Set {
 | 
			
		||||
	return Set{
 | 
			
		||||
		equivalent: emptySet.equivalent,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSet returns a new `Set`.  See the documentation for
 | 
			
		||||
// `NewSetWithSortableFiltered` for more details.
 | 
			
		||||
//
 | 
			
		||||
// Except for empty sets, this method adds an additional allocation
 | 
			
		||||
// compared with calls that include a `*Sortable`.
 | 
			
		||||
func NewSet(kvs ...KeyValue) Set {
 | 
			
		||||
	// Check for empty set.
 | 
			
		||||
	if len(kvs) == 0 {
 | 
			
		||||
		return empty()
 | 
			
		||||
	}
 | 
			
		||||
	s, _ := NewSetWithSortableFiltered(kvs, new(Sortable), nil)
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSetWithSortable returns a new `Set`.  See the documentation for
 | 
			
		||||
// `NewSetWithSortableFiltered` for more details.
 | 
			
		||||
//
 | 
			
		||||
// This call includes a `*Sortable` option as a memory optimization.
 | 
			
		||||
func NewSetWithSortable(kvs []KeyValue, tmp *Sortable) Set {
 | 
			
		||||
	// Check for empty set.
 | 
			
		||||
	if len(kvs) == 0 {
 | 
			
		||||
		return empty()
 | 
			
		||||
	}
 | 
			
		||||
	s, _ := NewSetWithSortableFiltered(kvs, tmp, nil)
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSetWithFiltered returns a new `Set`.  See the documentation for
 | 
			
		||||
// `NewSetWithSortableFiltered` for more details.
 | 
			
		||||
//
 | 
			
		||||
// This call includes a `Filter` to include/exclude label keys from
 | 
			
		||||
// the return value.  Excluded keys are returned as a slice of label
 | 
			
		||||
// values.
 | 
			
		||||
func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
 | 
			
		||||
	// Check for empty set.
 | 
			
		||||
	if len(kvs) == 0 {
 | 
			
		||||
		return empty(), nil
 | 
			
		||||
	}
 | 
			
		||||
	return NewSetWithSortableFiltered(kvs, new(Sortable), filter)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSetWithSortableFiltered returns a new `Set`.
 | 
			
		||||
//
 | 
			
		||||
// Duplicate keys are eliminated by taking the last value.  This
 | 
			
		||||
// re-orders the input slice so that unique last-values are contiguous
 | 
			
		||||
// at the end of the slice.
 | 
			
		||||
//
 | 
			
		||||
// This ensures the following:
 | 
			
		||||
//
 | 
			
		||||
// - Last-value-wins semantics
 | 
			
		||||
// - Caller sees the reordering, but doesn't lose values
 | 
			
		||||
// - Repeated call preserve last-value wins.
 | 
			
		||||
//
 | 
			
		||||
// Note that methods are defined on `*Set`, although this returns `Set`.
 | 
			
		||||
// Callers can avoid memory allocations by:
 | 
			
		||||
//
 | 
			
		||||
// - allocating a `Sortable` for use as a temporary in this method
 | 
			
		||||
// - allocating a `Set` for storing the return value of this
 | 
			
		||||
//   constructor.
 | 
			
		||||
//
 | 
			
		||||
// The result maintains a cache of encoded labels, by attribute.EncoderID.
 | 
			
		||||
// This value should not be copied after its first use.
 | 
			
		||||
//
 | 
			
		||||
// The second `[]KeyValue` return value is a list of labels that were
 | 
			
		||||
// excluded by the Filter (if non-nil).
 | 
			
		||||
func NewSetWithSortableFiltered(kvs []KeyValue, tmp *Sortable, filter Filter) (Set, []KeyValue) {
 | 
			
		||||
	// Check for empty set.
 | 
			
		||||
	if len(kvs) == 0 {
 | 
			
		||||
		return empty(), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*tmp = kvs
 | 
			
		||||
 | 
			
		||||
	// Stable sort so the following de-duplication can implement
 | 
			
		||||
	// last-value-wins semantics.
 | 
			
		||||
	sort.Stable(tmp)
 | 
			
		||||
 | 
			
		||||
	*tmp = nil
 | 
			
		||||
 | 
			
		||||
	position := len(kvs) - 1
 | 
			
		||||
	offset := position - 1
 | 
			
		||||
 | 
			
		||||
	// The requirements stated above require that the stable
 | 
			
		||||
	// result be placed in the end of the input slice, while
 | 
			
		||||
	// overwritten values are swapped to the beginning.
 | 
			
		||||
	//
 | 
			
		||||
	// De-duplicate with last-value-wins semantics.  Preserve
 | 
			
		||||
	// duplicate values at the beginning of the input slice.
 | 
			
		||||
	for ; offset >= 0; offset-- {
 | 
			
		||||
		if kvs[offset].Key == kvs[position].Key {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		position--
 | 
			
		||||
		kvs[offset], kvs[position] = kvs[position], kvs[offset]
 | 
			
		||||
	}
 | 
			
		||||
	if filter != nil {
 | 
			
		||||
		return filterSet(kvs[position:], filter)
 | 
			
		||||
	}
 | 
			
		||||
	return Set{
 | 
			
		||||
		equivalent: computeDistinct(kvs[position:]),
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// filterSet reorders `kvs` so that included keys are contiguous at
 | 
			
		||||
// the end of the slice, while excluded keys precede the included keys.
 | 
			
		||||
func filterSet(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
 | 
			
		||||
	var excluded []KeyValue
 | 
			
		||||
 | 
			
		||||
	// Move labels that do not match the filter so
 | 
			
		||||
	// they're adjacent before calling computeDistinct().
 | 
			
		||||
	distinctPosition := len(kvs)
 | 
			
		||||
 | 
			
		||||
	// Swap indistinct keys forward and distinct keys toward the
 | 
			
		||||
	// end of the slice.
 | 
			
		||||
	offset := len(kvs) - 1
 | 
			
		||||
	for ; offset >= 0; offset-- {
 | 
			
		||||
		if filter(kvs[offset]) {
 | 
			
		||||
			distinctPosition--
 | 
			
		||||
			kvs[offset], kvs[distinctPosition] = kvs[distinctPosition], kvs[offset]
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	excluded = kvs[:distinctPosition]
 | 
			
		||||
 | 
			
		||||
	return Set{
 | 
			
		||||
		equivalent: computeDistinct(kvs[distinctPosition:]),
 | 
			
		||||
	}, excluded
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Filter returns a filtered copy of this `Set`.  See the
 | 
			
		||||
// documentation for `NewSetWithSortableFiltered` for more details.
 | 
			
		||||
func (l *Set) Filter(re Filter) (Set, []KeyValue) {
 | 
			
		||||
	if re == nil {
 | 
			
		||||
		return Set{
 | 
			
		||||
			equivalent: l.equivalent,
 | 
			
		||||
		}, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Note: This could be refactored to avoid the temporary slice
 | 
			
		||||
	// allocation, if it proves to be expensive.
 | 
			
		||||
	return filterSet(l.ToSlice(), re)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// computeDistinct returns a `Distinct` using either the fixed- or
 | 
			
		||||
// reflect-oriented code path, depending on the size of the input.
 | 
			
		||||
// The input slice is assumed to already be sorted and de-duplicated.
 | 
			
		||||
func computeDistinct(kvs []KeyValue) Distinct {
 | 
			
		||||
	iface := computeDistinctFixed(kvs)
 | 
			
		||||
	if iface == nil {
 | 
			
		||||
		iface = computeDistinctReflect(kvs)
 | 
			
		||||
	}
 | 
			
		||||
	return Distinct{
 | 
			
		||||
		iface: iface,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// computeDistinctFixed computes a `Distinct` for small slices.  It
 | 
			
		||||
// returns nil if the input is too large for this code path.
 | 
			
		||||
func computeDistinctFixed(kvs []KeyValue) interface{} {
 | 
			
		||||
	switch len(kvs) {
 | 
			
		||||
	case 1:
 | 
			
		||||
		ptr := new([1]KeyValue)
 | 
			
		||||
		copy((*ptr)[:], kvs)
 | 
			
		||||
		return *ptr
 | 
			
		||||
	case 2:
 | 
			
		||||
		ptr := new([2]KeyValue)
 | 
			
		||||
		copy((*ptr)[:], kvs)
 | 
			
		||||
		return *ptr
 | 
			
		||||
	case 3:
 | 
			
		||||
		ptr := new([3]KeyValue)
 | 
			
		||||
		copy((*ptr)[:], kvs)
 | 
			
		||||
		return *ptr
 | 
			
		||||
	case 4:
 | 
			
		||||
		ptr := new([4]KeyValue)
 | 
			
		||||
		copy((*ptr)[:], kvs)
 | 
			
		||||
		return *ptr
 | 
			
		||||
	case 5:
 | 
			
		||||
		ptr := new([5]KeyValue)
 | 
			
		||||
		copy((*ptr)[:], kvs)
 | 
			
		||||
		return *ptr
 | 
			
		||||
	case 6:
 | 
			
		||||
		ptr := new([6]KeyValue)
 | 
			
		||||
		copy((*ptr)[:], kvs)
 | 
			
		||||
		return *ptr
 | 
			
		||||
	case 7:
 | 
			
		||||
		ptr := new([7]KeyValue)
 | 
			
		||||
		copy((*ptr)[:], kvs)
 | 
			
		||||
		return *ptr
 | 
			
		||||
	case 8:
 | 
			
		||||
		ptr := new([8]KeyValue)
 | 
			
		||||
		copy((*ptr)[:], kvs)
 | 
			
		||||
		return *ptr
 | 
			
		||||
	case 9:
 | 
			
		||||
		ptr := new([9]KeyValue)
 | 
			
		||||
		copy((*ptr)[:], kvs)
 | 
			
		||||
		return *ptr
 | 
			
		||||
	case 10:
 | 
			
		||||
		ptr := new([10]KeyValue)
 | 
			
		||||
		copy((*ptr)[:], kvs)
 | 
			
		||||
		return *ptr
 | 
			
		||||
	default:
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// computeDistinctReflect computes a `Distinct` using reflection,
 | 
			
		||||
// works for any size input.
 | 
			
		||||
func computeDistinctReflect(kvs []KeyValue) interface{} {
 | 
			
		||||
	at := reflect.New(reflect.ArrayOf(len(kvs), keyValueType)).Elem()
 | 
			
		||||
	for i, keyValue := range kvs {
 | 
			
		||||
		*(at.Index(i).Addr().Interface().(*KeyValue)) = keyValue
 | 
			
		||||
	}
 | 
			
		||||
	return at.Interface()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalJSON returns the JSON encoding of the `*Set`.
 | 
			
		||||
func (l *Set) MarshalJSON() ([]byte, error) {
 | 
			
		||||
	return json.Marshal(l.equivalent.iface)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Len implements `sort.Interface`.
 | 
			
		||||
func (l *Sortable) Len() int {
 | 
			
		||||
	return len(*l)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Swap implements `sort.Interface`.
 | 
			
		||||
func (l *Sortable) Swap(i, j int) {
 | 
			
		||||
	(*l)[i], (*l)[j] = (*l)[j], (*l)[i]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Less implements `sort.Interface`.
 | 
			
		||||
func (l *Sortable) Less(i, j int) bool {
 | 
			
		||||
	return (*l)[i].Key < (*l)[j].Key
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								vendor/go.opentelemetry.io/otel/attribute/type_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								vendor/go.opentelemetry.io/otel/attribute/type_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
// Code generated by "stringer -type=Type"; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package attribute
 | 
			
		||||
 | 
			
		||||
import "strconv"
 | 
			
		||||
 | 
			
		||||
func _() {
 | 
			
		||||
	// An "invalid array index" compiler error signifies that the constant values have changed.
 | 
			
		||||
	// Re-run the stringer command to generate them again.
 | 
			
		||||
	var x [1]struct{}
 | 
			
		||||
	_ = x[INVALID-0]
 | 
			
		||||
	_ = x[BOOL-1]
 | 
			
		||||
	_ = x[INT64-2]
 | 
			
		||||
	_ = x[FLOAT64-3]
 | 
			
		||||
	_ = x[STRING-4]
 | 
			
		||||
	_ = x[BOOLSLICE-5]
 | 
			
		||||
	_ = x[INT64SLICE-6]
 | 
			
		||||
	_ = x[FLOAT64SLICE-7]
 | 
			
		||||
	_ = x[STRINGSLICE-8]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const _Type_name = "INVALIDBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICE"
 | 
			
		||||
 | 
			
		||||
var _Type_index = [...]uint8{0, 7, 11, 16, 23, 29, 38, 48, 60, 71}
 | 
			
		||||
 | 
			
		||||
func (i Type) String() string {
 | 
			
		||||
	if i < 0 || i >= Type(len(_Type_index)-1) {
 | 
			
		||||
		return "Type(" + strconv.FormatInt(int64(i), 10) + ")"
 | 
			
		||||
	}
 | 
			
		||||
	return _Type_name[_Type_index[i]:_Type_index[i+1]]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										271
									
								
								vendor/go.opentelemetry.io/otel/attribute/value.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										271
									
								
								vendor/go.opentelemetry.io/otel/attribute/value.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,271 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package attribute // import "go.opentelemetry.io/otel/attribute"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/internal"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//go:generate stringer -type=Type
 | 
			
		||||
 | 
			
		||||
// Type describes the type of the data Value holds.
 | 
			
		||||
type Type int
 | 
			
		||||
 | 
			
		||||
// Value represents the value part in key-value pairs.
 | 
			
		||||
type Value struct {
 | 
			
		||||
	vtype    Type
 | 
			
		||||
	numeric  uint64
 | 
			
		||||
	stringly string
 | 
			
		||||
	slice    interface{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// INVALID is used for a Value with no value set.
 | 
			
		||||
	INVALID Type = iota
 | 
			
		||||
	// BOOL is a boolean Type Value.
 | 
			
		||||
	BOOL
 | 
			
		||||
	// INT64 is a 64-bit signed integral Type Value.
 | 
			
		||||
	INT64
 | 
			
		||||
	// FLOAT64 is a 64-bit floating point Type Value.
 | 
			
		||||
	FLOAT64
 | 
			
		||||
	// STRING is a string Type Value.
 | 
			
		||||
	STRING
 | 
			
		||||
	// BOOLSLICE is a slice of booleans Type Value.
 | 
			
		||||
	BOOLSLICE
 | 
			
		||||
	// INT64SLICE is a slice of 64-bit signed integral numbers Type Value.
 | 
			
		||||
	INT64SLICE
 | 
			
		||||
	// FLOAT64SLICE is a slice of 64-bit floating point numbers Type Value.
 | 
			
		||||
	FLOAT64SLICE
 | 
			
		||||
	// STRINGSLICE is a slice of strings Type Value.
 | 
			
		||||
	STRINGSLICE
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// BoolValue creates a BOOL Value.
 | 
			
		||||
func BoolValue(v bool) Value {
 | 
			
		||||
	return Value{
 | 
			
		||||
		vtype:   BOOL,
 | 
			
		||||
		numeric: internal.BoolToRaw(v),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BoolSliceValue creates a BOOLSLICE Value.
 | 
			
		||||
func BoolSliceValue(v []bool) Value {
 | 
			
		||||
	cp := make([]bool, len(v))
 | 
			
		||||
	copy(cp, v)
 | 
			
		||||
	return Value{
 | 
			
		||||
		vtype: BOOLSLICE,
 | 
			
		||||
		slice: &cp,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IntValue creates an INT64 Value.
 | 
			
		||||
func IntValue(v int) Value {
 | 
			
		||||
	return Int64Value(int64(v))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IntSliceValue creates an INTSLICE Value.
 | 
			
		||||
func IntSliceValue(v []int) Value {
 | 
			
		||||
	cp := make([]int64, 0, len(v))
 | 
			
		||||
	for _, i := range v {
 | 
			
		||||
		cp = append(cp, int64(i))
 | 
			
		||||
	}
 | 
			
		||||
	return Value{
 | 
			
		||||
		vtype: INT64SLICE,
 | 
			
		||||
		slice: &cp,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int64Value creates an INT64 Value.
 | 
			
		||||
func Int64Value(v int64) Value {
 | 
			
		||||
	return Value{
 | 
			
		||||
		vtype:   INT64,
 | 
			
		||||
		numeric: internal.Int64ToRaw(v),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int64SliceValue creates an INT64SLICE Value.
 | 
			
		||||
func Int64SliceValue(v []int64) Value {
 | 
			
		||||
	cp := make([]int64, len(v))
 | 
			
		||||
	copy(cp, v)
 | 
			
		||||
	return Value{
 | 
			
		||||
		vtype: INT64SLICE,
 | 
			
		||||
		slice: &cp,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64Value creates a FLOAT64 Value.
 | 
			
		||||
func Float64Value(v float64) Value {
 | 
			
		||||
	return Value{
 | 
			
		||||
		vtype:   FLOAT64,
 | 
			
		||||
		numeric: internal.Float64ToRaw(v),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64SliceValue creates a FLOAT64SLICE Value.
 | 
			
		||||
func Float64SliceValue(v []float64) Value {
 | 
			
		||||
	cp := make([]float64, len(v))
 | 
			
		||||
	copy(cp, v)
 | 
			
		||||
	return Value{
 | 
			
		||||
		vtype: FLOAT64SLICE,
 | 
			
		||||
		slice: &cp,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StringValue creates a STRING Value.
 | 
			
		||||
func StringValue(v string) Value {
 | 
			
		||||
	return Value{
 | 
			
		||||
		vtype:    STRING,
 | 
			
		||||
		stringly: v,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StringSliceValue creates a STRINGSLICE Value.
 | 
			
		||||
func StringSliceValue(v []string) Value {
 | 
			
		||||
	cp := make([]string, len(v))
 | 
			
		||||
	copy(cp, v)
 | 
			
		||||
	return Value{
 | 
			
		||||
		vtype: STRINGSLICE,
 | 
			
		||||
		slice: &cp,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Type returns a type of the Value.
 | 
			
		||||
func (v Value) Type() Type {
 | 
			
		||||
	return v.vtype
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsBool returns the bool value. Make sure that the Value's type is
 | 
			
		||||
// BOOL.
 | 
			
		||||
func (v Value) AsBool() bool {
 | 
			
		||||
	return internal.RawToBool(v.numeric)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsBoolSlice returns the []bool value. Make sure that the Value's type is
 | 
			
		||||
// BOOLSLICE.
 | 
			
		||||
func (v Value) AsBoolSlice() []bool {
 | 
			
		||||
	if s, ok := v.slice.(*[]bool); ok {
 | 
			
		||||
		return *s
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsInt64 returns the int64 value. Make sure that the Value's type is
 | 
			
		||||
// INT64.
 | 
			
		||||
func (v Value) AsInt64() int64 {
 | 
			
		||||
	return internal.RawToInt64(v.numeric)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsInt64Slice returns the []int64 value. Make sure that the Value's type is
 | 
			
		||||
// INT64SLICE.
 | 
			
		||||
func (v Value) AsInt64Slice() []int64 {
 | 
			
		||||
	if s, ok := v.slice.(*[]int64); ok {
 | 
			
		||||
		return *s
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsFloat64 returns the float64 value. Make sure that the Value's
 | 
			
		||||
// type is FLOAT64.
 | 
			
		||||
func (v Value) AsFloat64() float64 {
 | 
			
		||||
	return internal.RawToFloat64(v.numeric)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsFloat64Slice returns the []float64 value. Make sure that the Value's type is
 | 
			
		||||
// INT64SLICE.
 | 
			
		||||
func (v Value) AsFloat64Slice() []float64 {
 | 
			
		||||
	if s, ok := v.slice.(*[]float64); ok {
 | 
			
		||||
		return *s
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsString returns the string value. Make sure that the Value's type
 | 
			
		||||
// is STRING.
 | 
			
		||||
func (v Value) AsString() string {
 | 
			
		||||
	return v.stringly
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsStringSlice returns the []string value. Make sure that the Value's type is
 | 
			
		||||
// INT64SLICE.
 | 
			
		||||
func (v Value) AsStringSlice() []string {
 | 
			
		||||
	if s, ok := v.slice.(*[]string); ok {
 | 
			
		||||
		return *s
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type unknownValueType struct{}
 | 
			
		||||
 | 
			
		||||
// AsInterface returns Value's data as interface{}.
 | 
			
		||||
func (v Value) AsInterface() interface{} {
 | 
			
		||||
	switch v.Type() {
 | 
			
		||||
	case BOOL:
 | 
			
		||||
		return v.AsBool()
 | 
			
		||||
	case BOOLSLICE:
 | 
			
		||||
		return v.AsBoolSlice()
 | 
			
		||||
	case INT64:
 | 
			
		||||
		return v.AsInt64()
 | 
			
		||||
	case INT64SLICE:
 | 
			
		||||
		return v.AsInt64Slice()
 | 
			
		||||
	case FLOAT64:
 | 
			
		||||
		return v.AsFloat64()
 | 
			
		||||
	case FLOAT64SLICE:
 | 
			
		||||
		return v.AsFloat64Slice()
 | 
			
		||||
	case STRING:
 | 
			
		||||
		return v.stringly
 | 
			
		||||
	case STRINGSLICE:
 | 
			
		||||
		return v.AsStringSlice()
 | 
			
		||||
	}
 | 
			
		||||
	return unknownValueType{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Emit returns a string representation of Value's data.
 | 
			
		||||
func (v Value) Emit() string {
 | 
			
		||||
	switch v.Type() {
 | 
			
		||||
	case BOOLSLICE:
 | 
			
		||||
		return fmt.Sprint(*(v.slice.(*[]bool)))
 | 
			
		||||
	case BOOL:
 | 
			
		||||
		return strconv.FormatBool(v.AsBool())
 | 
			
		||||
	case INT64SLICE:
 | 
			
		||||
		return fmt.Sprint(*(v.slice.(*[]int64)))
 | 
			
		||||
	case INT64:
 | 
			
		||||
		return strconv.FormatInt(v.AsInt64(), 10)
 | 
			
		||||
	case FLOAT64SLICE:
 | 
			
		||||
		return fmt.Sprint(*(v.slice.(*[]float64)))
 | 
			
		||||
	case FLOAT64:
 | 
			
		||||
		return fmt.Sprint(v.AsFloat64())
 | 
			
		||||
	case STRINGSLICE:
 | 
			
		||||
		return fmt.Sprint(*(v.slice.(*[]string)))
 | 
			
		||||
	case STRING:
 | 
			
		||||
		return v.stringly
 | 
			
		||||
	default:
 | 
			
		||||
		return "unknown"
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalJSON returns the JSON encoding of the Value.
 | 
			
		||||
func (v Value) MarshalJSON() ([]byte, error) {
 | 
			
		||||
	var jsonVal struct {
 | 
			
		||||
		Type  string
 | 
			
		||||
		Value interface{}
 | 
			
		||||
	}
 | 
			
		||||
	jsonVal.Type = v.Type().String()
 | 
			
		||||
	jsonVal.Value = v.AsInterface()
 | 
			
		||||
	return json.Marshal(jsonVal)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										509
									
								
								vendor/go.opentelemetry.io/otel/baggage/baggage.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										509
									
								
								vendor/go.opentelemetry.io/otel/baggage/baggage.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,509 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package baggage // import "go.opentelemetry.io/otel/baggage"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/internal/baggage"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	maxMembers               = 180
 | 
			
		||||
	maxBytesPerMembers       = 4096
 | 
			
		||||
	maxBytesPerBaggageString = 8192
 | 
			
		||||
 | 
			
		||||
	listDelimiter     = ","
 | 
			
		||||
	keyValueDelimiter = "="
 | 
			
		||||
	propertyDelimiter = ";"
 | 
			
		||||
 | 
			
		||||
	keyDef      = `([\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5a\x5e-\x7a\x7c\x7e]+)`
 | 
			
		||||
	valueDef    = `([\x21\x23-\x2b\x2d-\x3a\x3c-\x5B\x5D-\x7e]*)`
 | 
			
		||||
	keyValueDef = `\s*` + keyDef + `\s*` + keyValueDelimiter + `\s*` + valueDef + `\s*`
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	keyRe      = regexp.MustCompile(`^` + keyDef + `$`)
 | 
			
		||||
	valueRe    = regexp.MustCompile(`^` + valueDef + `$`)
 | 
			
		||||
	propertyRe = regexp.MustCompile(`^(?:\s*` + keyDef + `\s*|` + keyValueDef + `)$`)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	errInvalidKey      = errors.New("invalid key")
 | 
			
		||||
	errInvalidValue    = errors.New("invalid value")
 | 
			
		||||
	errInvalidProperty = errors.New("invalid baggage list-member property")
 | 
			
		||||
	errInvalidMember   = errors.New("invalid baggage list-member")
 | 
			
		||||
	errMemberNumber    = errors.New("too many list-members in baggage-string")
 | 
			
		||||
	errMemberBytes     = errors.New("list-member too large")
 | 
			
		||||
	errBaggageBytes    = errors.New("baggage-string too large")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Property is an additional metadata entry for a baggage list-member.
 | 
			
		||||
type Property struct {
 | 
			
		||||
	key, value string
 | 
			
		||||
 | 
			
		||||
	// hasValue indicates if a zero-value value means the property does not
 | 
			
		||||
	// have a value or if it was the zero-value.
 | 
			
		||||
	hasValue bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewKeyProperty(key string) (Property, error) {
 | 
			
		||||
	p := Property{}
 | 
			
		||||
	if !keyRe.MatchString(key) {
 | 
			
		||||
		return p, fmt.Errorf("%w: %q", errInvalidKey, key)
 | 
			
		||||
	}
 | 
			
		||||
	p.key = key
 | 
			
		||||
	return p, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewKeyValueProperty(key, value string) (Property, error) {
 | 
			
		||||
	p := Property{}
 | 
			
		||||
	if !keyRe.MatchString(key) {
 | 
			
		||||
		return p, fmt.Errorf("%w: %q", errInvalidKey, key)
 | 
			
		||||
	}
 | 
			
		||||
	if !valueRe.MatchString(value) {
 | 
			
		||||
		return p, fmt.Errorf("%w: %q", errInvalidValue, value)
 | 
			
		||||
	}
 | 
			
		||||
	p.key = key
 | 
			
		||||
	p.value = value
 | 
			
		||||
	p.hasValue = true
 | 
			
		||||
	return p, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseProperty attempts to decode a Property from the passed string. It
 | 
			
		||||
// returns an error if the input is invalid according to the W3C Baggage
 | 
			
		||||
// specification.
 | 
			
		||||
func parseProperty(property string) (Property, error) {
 | 
			
		||||
	p := Property{}
 | 
			
		||||
	if property == "" {
 | 
			
		||||
		return p, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	match := propertyRe.FindStringSubmatch(property)
 | 
			
		||||
	if len(match) != 4 {
 | 
			
		||||
		return p, fmt.Errorf("%w: %q", errInvalidProperty, property)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if match[1] != "" {
 | 
			
		||||
		p.key = match[1]
 | 
			
		||||
	} else {
 | 
			
		||||
		p.key = match[2]
 | 
			
		||||
		p.value = match[3]
 | 
			
		||||
		p.hasValue = true
 | 
			
		||||
	}
 | 
			
		||||
	return p, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// validate ensures p conforms to the W3C Baggage specification, returning an
 | 
			
		||||
// error otherwise.
 | 
			
		||||
func (p Property) validate() error {
 | 
			
		||||
	errFunc := func(err error) error {
 | 
			
		||||
		return fmt.Errorf("invalid property: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !keyRe.MatchString(p.key) {
 | 
			
		||||
		return errFunc(fmt.Errorf("%w: %q", errInvalidKey, p.key))
 | 
			
		||||
	}
 | 
			
		||||
	if p.hasValue && !valueRe.MatchString(p.value) {
 | 
			
		||||
		return errFunc(fmt.Errorf("%w: %q", errInvalidValue, p.value))
 | 
			
		||||
	}
 | 
			
		||||
	if !p.hasValue && p.value != "" {
 | 
			
		||||
		return errFunc(errors.New("inconsistent value"))
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Key returns the Property key.
 | 
			
		||||
func (p Property) Key() string {
 | 
			
		||||
	return p.key
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Value returns the Property value. Additionally a boolean value is returned
 | 
			
		||||
// indicating if the returned value is the empty if the Property has a value
 | 
			
		||||
// that is empty or if the value is not set.
 | 
			
		||||
func (p Property) Value() (string, bool) {
 | 
			
		||||
	return p.value, p.hasValue
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String encodes Property into a string compliant with the W3C Baggage
 | 
			
		||||
// specification.
 | 
			
		||||
func (p Property) String() string {
 | 
			
		||||
	if p.hasValue {
 | 
			
		||||
		return fmt.Sprintf("%s%s%v", p.key, keyValueDelimiter, p.value)
 | 
			
		||||
	}
 | 
			
		||||
	return p.key
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type properties []Property
 | 
			
		||||
 | 
			
		||||
func fromInternalProperties(iProps []baggage.Property) properties {
 | 
			
		||||
	if len(iProps) == 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	props := make(properties, len(iProps))
 | 
			
		||||
	for i, p := range iProps {
 | 
			
		||||
		props[i] = Property{
 | 
			
		||||
			key:      p.Key,
 | 
			
		||||
			value:    p.Value,
 | 
			
		||||
			hasValue: p.HasValue,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return props
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p properties) asInternal() []baggage.Property {
 | 
			
		||||
	if len(p) == 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	iProps := make([]baggage.Property, len(p))
 | 
			
		||||
	for i, prop := range p {
 | 
			
		||||
		iProps[i] = baggage.Property{
 | 
			
		||||
			Key:      prop.key,
 | 
			
		||||
			Value:    prop.value,
 | 
			
		||||
			HasValue: prop.hasValue,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return iProps
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p properties) Copy() properties {
 | 
			
		||||
	if len(p) == 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	props := make(properties, len(p))
 | 
			
		||||
	copy(props, p)
 | 
			
		||||
	return props
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// validate ensures each Property in p conforms to the W3C Baggage
 | 
			
		||||
// specification, returning an error otherwise.
 | 
			
		||||
func (p properties) validate() error {
 | 
			
		||||
	for _, prop := range p {
 | 
			
		||||
		if err := prop.validate(); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String encodes properties into a string compliant with the W3C Baggage
 | 
			
		||||
// specification.
 | 
			
		||||
func (p properties) String() string {
 | 
			
		||||
	props := make([]string, len(p))
 | 
			
		||||
	for i, prop := range p {
 | 
			
		||||
		props[i] = prop.String()
 | 
			
		||||
	}
 | 
			
		||||
	return strings.Join(props, propertyDelimiter)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Member is a list-member of a baggage-string as defined by the W3C Baggage
 | 
			
		||||
// specification.
 | 
			
		||||
type Member struct {
 | 
			
		||||
	key, value string
 | 
			
		||||
	properties properties
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewMember returns a new Member from the passed arguments. An error is
 | 
			
		||||
// returned if the created Member would be invalid according to the W3C
 | 
			
		||||
// Baggage specification.
 | 
			
		||||
func NewMember(key, value string, props ...Property) (Member, error) {
 | 
			
		||||
	m := Member{key: key, value: value, properties: properties(props).Copy()}
 | 
			
		||||
	if err := m.validate(); err != nil {
 | 
			
		||||
		return Member{}, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return m, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseMember attempts to decode a Member from the passed string. It returns
 | 
			
		||||
// an error if the input is invalid according to the W3C Baggage
 | 
			
		||||
// specification.
 | 
			
		||||
func parseMember(member string) (Member, error) {
 | 
			
		||||
	if n := len(member); n > maxBytesPerMembers {
 | 
			
		||||
		return Member{}, fmt.Errorf("%w: %d", errMemberBytes, n)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var (
 | 
			
		||||
		key, value string
 | 
			
		||||
		props      properties
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	parts := strings.SplitN(member, propertyDelimiter, 2)
 | 
			
		||||
	switch len(parts) {
 | 
			
		||||
	case 2:
 | 
			
		||||
		// Parse the member properties.
 | 
			
		||||
		for _, pStr := range strings.Split(parts[1], propertyDelimiter) {
 | 
			
		||||
			p, err := parseProperty(pStr)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return Member{}, err
 | 
			
		||||
			}
 | 
			
		||||
			props = append(props, p)
 | 
			
		||||
		}
 | 
			
		||||
		fallthrough
 | 
			
		||||
	case 1:
 | 
			
		||||
		// Parse the member key/value pair.
 | 
			
		||||
 | 
			
		||||
		// Take into account a value can contain equal signs (=).
 | 
			
		||||
		kv := strings.SplitN(parts[0], keyValueDelimiter, 2)
 | 
			
		||||
		if len(kv) != 2 {
 | 
			
		||||
			return Member{}, fmt.Errorf("%w: %q", errInvalidMember, member)
 | 
			
		||||
		}
 | 
			
		||||
		// "Leading and trailing whitespaces are allowed but MUST be trimmed
 | 
			
		||||
		// when converting the header into a data structure."
 | 
			
		||||
		key, value = strings.TrimSpace(kv[0]), strings.TrimSpace(kv[1])
 | 
			
		||||
		if !keyRe.MatchString(key) {
 | 
			
		||||
			return Member{}, fmt.Errorf("%w: %q", errInvalidKey, key)
 | 
			
		||||
		}
 | 
			
		||||
		if !valueRe.MatchString(value) {
 | 
			
		||||
			return Member{}, fmt.Errorf("%w: %q", errInvalidValue, value)
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		// This should never happen unless a developer has changed the string
 | 
			
		||||
		// splitting somehow. Panic instead of failing silently and allowing
 | 
			
		||||
		// the bug to slip past the CI checks.
 | 
			
		||||
		panic("failed to parse baggage member")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return Member{key: key, value: value, properties: props}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// validate ensures m conforms to the W3C Baggage specification, returning an
 | 
			
		||||
// error otherwise.
 | 
			
		||||
func (m Member) validate() error {
 | 
			
		||||
	if !keyRe.MatchString(m.key) {
 | 
			
		||||
		return fmt.Errorf("%w: %q", errInvalidKey, m.key)
 | 
			
		||||
	}
 | 
			
		||||
	if !valueRe.MatchString(m.value) {
 | 
			
		||||
		return fmt.Errorf("%w: %q", errInvalidValue, m.value)
 | 
			
		||||
	}
 | 
			
		||||
	return m.properties.validate()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Key returns the Member key.
 | 
			
		||||
func (m Member) Key() string { return m.key }
 | 
			
		||||
 | 
			
		||||
// Value returns the Member value.
 | 
			
		||||
func (m Member) Value() string { return m.value }
 | 
			
		||||
 | 
			
		||||
// Properties returns a copy of the Member properties.
 | 
			
		||||
func (m Member) Properties() []Property { return m.properties.Copy() }
 | 
			
		||||
 | 
			
		||||
// String encodes Member into a string compliant with the W3C Baggage
 | 
			
		||||
// specification.
 | 
			
		||||
func (m Member) String() string {
 | 
			
		||||
	// A key is just an ASCII string, but a value is URL encoded UTF-8.
 | 
			
		||||
	s := fmt.Sprintf("%s%s%s", m.key, keyValueDelimiter, url.QueryEscape(m.value))
 | 
			
		||||
	if len(m.properties) > 0 {
 | 
			
		||||
		s = fmt.Sprintf("%s%s%s", s, propertyDelimiter, m.properties.String())
 | 
			
		||||
	}
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Baggage is a list of baggage members representing the baggage-string as
 | 
			
		||||
// defined by the W3C Baggage specification.
 | 
			
		||||
type Baggage struct { //nolint:golint
 | 
			
		||||
	list baggage.List
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// New returns a new valid Baggage. It returns an error if the passed members
 | 
			
		||||
// are invalid according to the W3C Baggage specification or if it results in
 | 
			
		||||
// a Baggage exceeding limits set in that specification.
 | 
			
		||||
func New(members ...Member) (Baggage, error) {
 | 
			
		||||
	if len(members) == 0 {
 | 
			
		||||
		return Baggage{}, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b := make(baggage.List)
 | 
			
		||||
	for _, m := range members {
 | 
			
		||||
		if err := m.validate(); err != nil {
 | 
			
		||||
			return Baggage{}, err
 | 
			
		||||
		}
 | 
			
		||||
		// OpenTelemetry resolves duplicates by last-one-wins.
 | 
			
		||||
		b[m.key] = baggage.Item{
 | 
			
		||||
			Value:      m.value,
 | 
			
		||||
			Properties: m.properties.asInternal(),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check member numbers after deduplicating.
 | 
			
		||||
	if len(b) > maxMembers {
 | 
			
		||||
		return Baggage{}, errMemberNumber
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bag := Baggage{b}
 | 
			
		||||
	if n := len(bag.String()); n > maxBytesPerBaggageString {
 | 
			
		||||
		return Baggage{}, fmt.Errorf("%w: %d", errBaggageBytes, n)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return bag, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Parse attempts to decode a baggage-string from the passed string. It
 | 
			
		||||
// returns an error if the input is invalid according to the W3C Baggage
 | 
			
		||||
// specification.
 | 
			
		||||
//
 | 
			
		||||
// If there are duplicate list-members contained in baggage, the last one
 | 
			
		||||
// defined (reading left-to-right) will be the only one kept. This diverges
 | 
			
		||||
// from the W3C Baggage specification which allows duplicate list-members, but
 | 
			
		||||
// conforms to the OpenTelemetry Baggage specification.
 | 
			
		||||
func Parse(bStr string) (Baggage, error) {
 | 
			
		||||
	if bStr == "" {
 | 
			
		||||
		return Baggage{}, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if n := len(bStr); n > maxBytesPerBaggageString {
 | 
			
		||||
		return Baggage{}, fmt.Errorf("%w: %d", errBaggageBytes, n)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b := make(baggage.List)
 | 
			
		||||
	for _, memberStr := range strings.Split(bStr, listDelimiter) {
 | 
			
		||||
		m, err := parseMember(memberStr)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return Baggage{}, err
 | 
			
		||||
		}
 | 
			
		||||
		// OpenTelemetry resolves duplicates by last-one-wins.
 | 
			
		||||
		b[m.key] = baggage.Item{
 | 
			
		||||
			Value:      m.value,
 | 
			
		||||
			Properties: m.properties.asInternal(),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// OpenTelemetry does not allow for duplicate list-members, but the W3C
 | 
			
		||||
	// specification does. Now that we have deduplicated, ensure the baggage
 | 
			
		||||
	// does not exceed list-member limits.
 | 
			
		||||
	if len(b) > maxMembers {
 | 
			
		||||
		return Baggage{}, errMemberNumber
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return Baggage{b}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Member returns the baggage list-member identified by key.
 | 
			
		||||
//
 | 
			
		||||
// If there is no list-member matching the passed key the returned Member will
 | 
			
		||||
// be a zero-value Member.
 | 
			
		||||
func (b Baggage) Member(key string) Member {
 | 
			
		||||
	v, ok := b.list[key]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		// We do not need to worry about distiguising between the situation
 | 
			
		||||
		// where a zero-valued Member is included in the Baggage because a
 | 
			
		||||
		// zero-valued Member is invalid according to the W3C Baggage
 | 
			
		||||
		// specification (it has an empty key).
 | 
			
		||||
		return Member{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return Member{
 | 
			
		||||
		key:        key,
 | 
			
		||||
		value:      v.Value,
 | 
			
		||||
		properties: fromInternalProperties(v.Properties),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Members returns all the baggage list-members.
 | 
			
		||||
// The order of the returned list-members does not have significance.
 | 
			
		||||
func (b Baggage) Members() []Member {
 | 
			
		||||
	if len(b.list) == 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	members := make([]Member, 0, len(b.list))
 | 
			
		||||
	for k, v := range b.list {
 | 
			
		||||
		members = append(members, Member{
 | 
			
		||||
			key:        k,
 | 
			
		||||
			value:      v.Value,
 | 
			
		||||
			properties: fromInternalProperties(v.Properties),
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	return members
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetMember returns a copy the Baggage with the member included. If the
 | 
			
		||||
// baggage contains a Member with the same key the existing Member is
 | 
			
		||||
// replaced.
 | 
			
		||||
//
 | 
			
		||||
// If member is invalid according to the W3C Baggage specification, an error
 | 
			
		||||
// is returned with the original Baggage.
 | 
			
		||||
func (b Baggage) SetMember(member Member) (Baggage, error) {
 | 
			
		||||
	if err := member.validate(); err != nil {
 | 
			
		||||
		return b, fmt.Errorf("%w: %s", errInvalidMember, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	n := len(b.list)
 | 
			
		||||
	if _, ok := b.list[member.key]; !ok {
 | 
			
		||||
		n++
 | 
			
		||||
	}
 | 
			
		||||
	list := make(baggage.List, n)
 | 
			
		||||
 | 
			
		||||
	for k, v := range b.list {
 | 
			
		||||
		// Do not copy if we are just going to overwrite.
 | 
			
		||||
		if k == member.key {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		list[k] = v
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list[member.key] = baggage.Item{
 | 
			
		||||
		Value:      member.value,
 | 
			
		||||
		Properties: member.properties.asInternal(),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return Baggage{list: list}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteMember returns a copy of the Baggage with the list-member identified
 | 
			
		||||
// by key removed.
 | 
			
		||||
func (b Baggage) DeleteMember(key string) Baggage {
 | 
			
		||||
	n := len(b.list)
 | 
			
		||||
	if _, ok := b.list[key]; ok {
 | 
			
		||||
		n--
 | 
			
		||||
	}
 | 
			
		||||
	list := make(baggage.List, n)
 | 
			
		||||
 | 
			
		||||
	for k, v := range b.list {
 | 
			
		||||
		if k == key {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		list[k] = v
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return Baggage{list: list}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Len returns the number of list-members in the Baggage.
 | 
			
		||||
func (b Baggage) Len() int {
 | 
			
		||||
	return len(b.list)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String encodes Baggage into a string compliant with the W3C Baggage
 | 
			
		||||
// specification. The returned string will be invalid if the Baggage contains
 | 
			
		||||
// any invalid list-members.
 | 
			
		||||
func (b Baggage) String() string {
 | 
			
		||||
	members := make([]string, 0, len(b.list))
 | 
			
		||||
	for k, v := range b.list {
 | 
			
		||||
		members = append(members, Member{
 | 
			
		||||
			key:        k,
 | 
			
		||||
			value:      v.Value,
 | 
			
		||||
			properties: fromInternalProperties(v.Properties),
 | 
			
		||||
		}.String())
 | 
			
		||||
	}
 | 
			
		||||
	return strings.Join(members, listDelimiter)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								vendor/go.opentelemetry.io/otel/baggage/context.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								vendor/go.opentelemetry.io/otel/baggage/context.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package baggage // import "go.opentelemetry.io/otel/baggage"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/internal/baggage"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ContextWithBaggage returns a copy of parent with baggage.
 | 
			
		||||
func ContextWithBaggage(parent context.Context, b Baggage) context.Context {
 | 
			
		||||
	// Delegate so any hooks for the OpenTracing bridge are handled.
 | 
			
		||||
	return baggage.ContextWithList(parent, b.list)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ContextWithoutBaggage returns a copy of parent with no baggage.
 | 
			
		||||
func ContextWithoutBaggage(parent context.Context) context.Context {
 | 
			
		||||
	// Delegate so any hooks for the OpenTracing bridge are handled.
 | 
			
		||||
	return baggage.ContextWithList(parent, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FromContext returns the baggage contained in ctx.
 | 
			
		||||
func FromContext(ctx context.Context) Baggage {
 | 
			
		||||
	// Delegate so any hooks for the OpenTracing bridge are handled.
 | 
			
		||||
	return Baggage{list: baggage.ListFromContext(ctx)}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/go.opentelemetry.io/otel/baggage/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/go.opentelemetry.io/otel/baggage/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Package baggage provides functionality for storing and retrieving
 | 
			
		||||
baggage items in Go context. For propagating the baggage, see the
 | 
			
		||||
go.opentelemetry.io/otel/propagation package.
 | 
			
		||||
*/
 | 
			
		||||
package baggage // import "go.opentelemetry.io/otel/baggage"
 | 
			
		||||
							
								
								
									
										106
									
								
								vendor/go.opentelemetry.io/otel/codes/codes.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								vendor/go.opentelemetry.io/otel/codes/codes.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package codes // import "go.opentelemetry.io/otel/codes"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strconv"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// Unset is the default status code.
 | 
			
		||||
	Unset Code = 0
 | 
			
		||||
	// Error indicates the operation contains an error.
 | 
			
		||||
	Error Code = 1
 | 
			
		||||
	// Ok indicates operation has been validated by an Application developers
 | 
			
		||||
	// or Operator to have completed successfully, or contain no error.
 | 
			
		||||
	Ok Code = 2
 | 
			
		||||
 | 
			
		||||
	maxCode = 3
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Code is an 32-bit representation of a status state.
 | 
			
		||||
type Code uint32
 | 
			
		||||
 | 
			
		||||
var codeToStr = map[Code]string{
 | 
			
		||||
	Unset: "Unset",
 | 
			
		||||
	Error: "Error",
 | 
			
		||||
	Ok:    "Ok",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var strToCode = map[string]Code{
 | 
			
		||||
	`"Unset"`: Unset,
 | 
			
		||||
	`"Error"`: Error,
 | 
			
		||||
	`"Ok"`:    Ok,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String returns the Code as a string.
 | 
			
		||||
func (c Code) String() string {
 | 
			
		||||
	return codeToStr[c]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalJSON unmarshals b into the Code.
 | 
			
		||||
//
 | 
			
		||||
// This is based on the functionality in the gRPC codes package:
 | 
			
		||||
// https://github.com/grpc/grpc-go/blob/bb64fee312b46ebee26be43364a7a966033521b1/codes/codes.go#L218-L244
 | 
			
		||||
func (c *Code) UnmarshalJSON(b []byte) error {
 | 
			
		||||
	// From json.Unmarshaler: By convention, to approximate the behavior of
 | 
			
		||||
	// Unmarshal itself, Unmarshalers implement UnmarshalJSON([]byte("null")) as
 | 
			
		||||
	// a no-op.
 | 
			
		||||
	if string(b) == "null" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	if c == nil {
 | 
			
		||||
		return fmt.Errorf("nil receiver passed to UnmarshalJSON")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var x interface{}
 | 
			
		||||
	if err := json.Unmarshal(b, &x); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	switch x.(type) {
 | 
			
		||||
	case string:
 | 
			
		||||
		if jc, ok := strToCode[string(b)]; ok {
 | 
			
		||||
			*c = jc
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
		return fmt.Errorf("invalid code: %q", string(b))
 | 
			
		||||
	case float64:
 | 
			
		||||
		if ci, err := strconv.ParseUint(string(b), 10, 32); err == nil {
 | 
			
		||||
			if ci >= maxCode {
 | 
			
		||||
				return fmt.Errorf("invalid code: %q", ci)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			*c = Code(ci)
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
		return fmt.Errorf("invalid code: %q", string(b))
 | 
			
		||||
	default:
 | 
			
		||||
		return fmt.Errorf("invalid code: %q", string(b))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalJSON returns c as the JSON encoding of c.
 | 
			
		||||
func (c *Code) MarshalJSON() ([]byte, error) {
 | 
			
		||||
	if c == nil {
 | 
			
		||||
		return []byte("null"), nil
 | 
			
		||||
	}
 | 
			
		||||
	str, ok := codeToStr[*c]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, fmt.Errorf("invalid code: %d", *c)
 | 
			
		||||
	}
 | 
			
		||||
	return []byte(fmt.Sprintf("%q", str)), nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								vendor/go.opentelemetry.io/otel/codes/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/go.opentelemetry.io/otel/codes/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Package codes defines the canonical error codes used by OpenTelemetry.
 | 
			
		||||
 | 
			
		||||
It conforms to [the OpenTelemetry
 | 
			
		||||
specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#statuscanonicalcode).
 | 
			
		||||
*/
 | 
			
		||||
package codes // import "go.opentelemetry.io/otel/codes"
 | 
			
		||||
							
								
								
									
										34
									
								
								vendor/go.opentelemetry.io/otel/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								vendor/go.opentelemetry.io/otel/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Package otel provides global access to the OpenTelemetry API. The subpackages of
 | 
			
		||||
the otel package provide an implementation of the OpenTelemetry API.
 | 
			
		||||
 | 
			
		||||
The provided API is used to instrument code and measure data about that code's
 | 
			
		||||
performance and operation. The measured data, by default, is not processed or
 | 
			
		||||
transmitted anywhere. An implementation of the OpenTelemetry SDK, like the
 | 
			
		||||
default SDK implementation (go.opentelemetry.io/otel/sdk), and associated
 | 
			
		||||
exporters are used to process and transport this data.
 | 
			
		||||
 | 
			
		||||
To read the getting started guide, see https://opentelemetry.io/docs/go/getting-started/.
 | 
			
		||||
 | 
			
		||||
To read more about tracing, see go.opentelemetry.io/otel/trace.
 | 
			
		||||
 | 
			
		||||
To read more about metrics, see go.opentelemetry.io/otel/metric.
 | 
			
		||||
 | 
			
		||||
To read more about propagation, see go.opentelemetry.io/otel/propagation and
 | 
			
		||||
go.opentelemetry.io/otel/baggage.
 | 
			
		||||
*/
 | 
			
		||||
package otel // import "go.opentelemetry.io/otel"
 | 
			
		||||
							
								
								
									
										38
									
								
								vendor/go.opentelemetry.io/otel/error_handler.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								vendor/go.opentelemetry.io/otel/error_handler.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package otel // import "go.opentelemetry.io/otel"
 | 
			
		||||
 | 
			
		||||
// ErrorHandler handles irremediable events.
 | 
			
		||||
type ErrorHandler interface {
 | 
			
		||||
	// DO NOT CHANGE: any modification will not be backwards compatible and
 | 
			
		||||
	// must never be done outside of a new major release.
 | 
			
		||||
 | 
			
		||||
	// Handle handles any error deemed irremediable by an OpenTelemetry
 | 
			
		||||
	// component.
 | 
			
		||||
	Handle(error)
 | 
			
		||||
	// DO NOT CHANGE: any modification will not be backwards compatible and
 | 
			
		||||
	// must never be done outside of a new major release.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ErrorHandlerFunc is a convenience adapter to allow the use of a function
 | 
			
		||||
// as an ErrorHandler.
 | 
			
		||||
type ErrorHandlerFunc func(error)
 | 
			
		||||
 | 
			
		||||
var _ ErrorHandler = ErrorHandlerFunc(nil)
 | 
			
		||||
 | 
			
		||||
// Handle handles the irremediable error by calling the ErrorHandlerFunc itself.
 | 
			
		||||
func (f ErrorHandlerFunc) Handle(err error) {
 | 
			
		||||
	f(err)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										201
									
								
								vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
							
								
								
									
										114
									
								
								vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package stdoutmetric // import "go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	defaultWriter       = os.Stdout
 | 
			
		||||
	defaultPrettyPrint  = false
 | 
			
		||||
	defaultTimestamps   = true
 | 
			
		||||
	defaultLabelEncoder = attribute.DefaultEncoder()
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// config contains options for the STDOUT exporter.
 | 
			
		||||
type config struct {
 | 
			
		||||
	// Writer is the destination.  If not set, os.Stdout is used.
 | 
			
		||||
	Writer io.Writer
 | 
			
		||||
 | 
			
		||||
	// PrettyPrint will encode the output into readable JSON. Default is
 | 
			
		||||
	// false.
 | 
			
		||||
	PrettyPrint bool
 | 
			
		||||
 | 
			
		||||
	// Timestamps specifies if timestamps should be printed. Default is
 | 
			
		||||
	// true.
 | 
			
		||||
	Timestamps bool
 | 
			
		||||
 | 
			
		||||
	// LabelEncoder encodes the labels.
 | 
			
		||||
	LabelEncoder attribute.Encoder
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// newConfig creates a validated Config configured with options.
 | 
			
		||||
func newConfig(options ...Option) (config, error) {
 | 
			
		||||
	cfg := config{
 | 
			
		||||
		Writer:       defaultWriter,
 | 
			
		||||
		PrettyPrint:  defaultPrettyPrint,
 | 
			
		||||
		Timestamps:   defaultTimestamps,
 | 
			
		||||
		LabelEncoder: defaultLabelEncoder,
 | 
			
		||||
	}
 | 
			
		||||
	for _, opt := range options {
 | 
			
		||||
		opt.apply(&cfg)
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	return cfg, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Option sets the value of an option for a Config.
 | 
			
		||||
type Option interface {
 | 
			
		||||
	apply(*config)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithWriter sets the export stream destination.
 | 
			
		||||
func WithWriter(w io.Writer) Option {
 | 
			
		||||
	return writerOption{w}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type writerOption struct {
 | 
			
		||||
	W io.Writer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o writerOption) apply(cfg *config) {
 | 
			
		||||
	cfg.Writer = o.W
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithPrettyPrint sets the export stream format to use JSON.
 | 
			
		||||
func WithPrettyPrint() Option {
 | 
			
		||||
	return prettyPrintOption(true)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type prettyPrintOption bool
 | 
			
		||||
 | 
			
		||||
func (o prettyPrintOption) apply(cfg *config) {
 | 
			
		||||
	cfg.PrettyPrint = bool(o)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithoutTimestamps sets the export stream to not include timestamps.
 | 
			
		||||
func WithoutTimestamps() Option {
 | 
			
		||||
	return timestampsOption(false)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type timestampsOption bool
 | 
			
		||||
 | 
			
		||||
func (o timestampsOption) apply(cfg *config) {
 | 
			
		||||
	cfg.Timestamps = bool(o)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithLabelEncoder sets the label encoder used in export.
 | 
			
		||||
func WithLabelEncoder(enc attribute.Encoder) Option {
 | 
			
		||||
	return labelEncoderOption{enc}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type labelEncoderOption struct {
 | 
			
		||||
	LabelEncoder attribute.Encoder
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o labelEncoderOption) apply(cfg *config) {
 | 
			
		||||
	cfg.LabelEncoder = o.LabelEncoder
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
// Package stdout contains an OpenTelemetry exporter for metric telemetry
 | 
			
		||||
// to be written to an output destination as JSON.
 | 
			
		||||
//
 | 
			
		||||
// This package is currently in a pre-GA phase. Backwards incompatible changes
 | 
			
		||||
// may be introduced in subsequent minor version releases as we work to track
 | 
			
		||||
// the evolving OpenTelemetry specification and user feedback.
 | 
			
		||||
package stdoutmetric // import "go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
 | 
			
		||||
							
								
								
									
										38
									
								
								vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/exporter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/exporter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package stdoutmetric // import "go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/export/metric"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Exporter struct {
 | 
			
		||||
	metricExporter
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_ metric.Exporter = &Exporter{}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// New creates an Exporter with the passed options.
 | 
			
		||||
func New(options ...Option) (*Exporter, error) {
 | 
			
		||||
	cfg, err := newConfig(options...)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &Exporter{
 | 
			
		||||
		metricExporter: metricExporter{cfg},
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										167
									
								
								vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/metric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/metric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,167 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package stdoutmetric // import "go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
	exportmetric "go.opentelemetry.io/otel/sdk/export/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/instrumentation"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/resource"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type metricExporter struct {
 | 
			
		||||
	config config
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ exportmetric.Exporter = &metricExporter{}
 | 
			
		||||
 | 
			
		||||
type line struct {
 | 
			
		||||
	Name      string      `json:"Name"`
 | 
			
		||||
	Min       interface{} `json:"Min,omitempty"`
 | 
			
		||||
	Max       interface{} `json:"Max,omitempty"`
 | 
			
		||||
	Sum       interface{} `json:"Sum,omitempty"`
 | 
			
		||||
	Count     interface{} `json:"Count,omitempty"`
 | 
			
		||||
	LastValue interface{} `json:"Last,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// Note: this is a pointer because omitempty doesn't work when time.IsZero()
 | 
			
		||||
	Timestamp *time.Time `json:"Timestamp,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *metricExporter) TemporalityFor(desc *sdkapi.Descriptor, kind aggregation.Kind) aggregation.Temporality {
 | 
			
		||||
	return aggregation.StatelessTemporalitySelector().TemporalityFor(desc, kind)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *metricExporter) Export(_ context.Context, res *resource.Resource, reader exportmetric.InstrumentationLibraryReader) error {
 | 
			
		||||
	var aggError error
 | 
			
		||||
	var batch []line
 | 
			
		||||
	aggError = reader.ForEach(func(lib instrumentation.Library, mr exportmetric.Reader) error {
 | 
			
		||||
 | 
			
		||||
		var instLabels []attribute.KeyValue
 | 
			
		||||
		if name := lib.Name; name != "" {
 | 
			
		||||
			instLabels = append(instLabels, attribute.String("instrumentation.name", name))
 | 
			
		||||
			if version := lib.Version; version != "" {
 | 
			
		||||
				instLabels = append(instLabels, attribute.String("instrumentation.version", version))
 | 
			
		||||
			}
 | 
			
		||||
			if schema := lib.SchemaURL; schema != "" {
 | 
			
		||||
				instLabels = append(instLabels, attribute.String("instrumentation.schema_url", schema))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		instSet := attribute.NewSet(instLabels...)
 | 
			
		||||
		encodedInstLabels := instSet.Encoded(e.config.LabelEncoder)
 | 
			
		||||
 | 
			
		||||
		return mr.ForEach(e, func(record exportmetric.Record) error {
 | 
			
		||||
			desc := record.Descriptor()
 | 
			
		||||
			agg := record.Aggregation()
 | 
			
		||||
			kind := desc.NumberKind()
 | 
			
		||||
			encodedResource := res.Encoded(e.config.LabelEncoder)
 | 
			
		||||
 | 
			
		||||
			var expose line
 | 
			
		||||
 | 
			
		||||
			if sum, ok := agg.(aggregation.Sum); ok {
 | 
			
		||||
				value, err := sum.Sum()
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
				expose.Sum = value.AsInterface(kind)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if mmsc, ok := agg.(aggregation.MinMaxSumCount); ok {
 | 
			
		||||
				count, err := mmsc.Count()
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
				expose.Count = count
 | 
			
		||||
 | 
			
		||||
				max, err := mmsc.Max()
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
				expose.Max = max.AsInterface(kind)
 | 
			
		||||
 | 
			
		||||
				min, err := mmsc.Min()
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
				expose.Min = min.AsInterface(kind)
 | 
			
		||||
			} else if lv, ok := agg.(aggregation.LastValue); ok {
 | 
			
		||||
				value, timestamp, err := lv.LastValue()
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
				expose.LastValue = value.AsInterface(kind)
 | 
			
		||||
 | 
			
		||||
				if e.config.Timestamps {
 | 
			
		||||
					expose.Timestamp = ×tamp
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var encodedLabels string
 | 
			
		||||
			iter := record.Labels().Iter()
 | 
			
		||||
			if iter.Len() > 0 {
 | 
			
		||||
				encodedLabels = record.Labels().Encoded(e.config.LabelEncoder)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var sb strings.Builder
 | 
			
		||||
 | 
			
		||||
			sb.WriteString(desc.Name())
 | 
			
		||||
 | 
			
		||||
			if len(encodedLabels) > 0 || len(encodedResource) > 0 || len(encodedInstLabels) > 0 {
 | 
			
		||||
				sb.WriteRune('{')
 | 
			
		||||
				sb.WriteString(encodedResource)
 | 
			
		||||
				if len(encodedInstLabels) > 0 && len(encodedResource) > 0 {
 | 
			
		||||
					sb.WriteRune(',')
 | 
			
		||||
				}
 | 
			
		||||
				sb.WriteString(encodedInstLabels)
 | 
			
		||||
				if len(encodedLabels) > 0 && (len(encodedInstLabels) > 0 || len(encodedResource) > 0) {
 | 
			
		||||
					sb.WriteRune(',')
 | 
			
		||||
				}
 | 
			
		||||
				sb.WriteString(encodedLabels)
 | 
			
		||||
				sb.WriteRune('}')
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			expose.Name = sb.String()
 | 
			
		||||
 | 
			
		||||
			batch = append(batch, expose)
 | 
			
		||||
			return nil
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
	if len(batch) == 0 {
 | 
			
		||||
		return aggError
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	data, err := e.marshal(batch)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Fprintln(e.config.Writer, string(data))
 | 
			
		||||
 | 
			
		||||
	return aggError
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// marshal v with appropriate indentation.
 | 
			
		||||
func (e *metricExporter) marshal(v interface{}) ([]byte, error) {
 | 
			
		||||
	if e.config.PrettyPrint {
 | 
			
		||||
		return json.MarshalIndent(v, "", "\t")
 | 
			
		||||
	}
 | 
			
		||||
	return json.Marshal(v)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								vendor/go.opentelemetry.io/otel/get_main_pkgs.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								vendor/go.opentelemetry.io/otel/get_main_pkgs.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Copyright The OpenTelemetry Authors
 | 
			
		||||
#
 | 
			
		||||
# Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
# you may not use this file except in compliance with the License.
 | 
			
		||||
# You may obtain a copy of the License at
 | 
			
		||||
#
 | 
			
		||||
#     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
#
 | 
			
		||||
# Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
# distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
# See the License for the specific language governing permissions and
 | 
			
		||||
# limitations under the License.
 | 
			
		||||
 | 
			
		||||
set -euo pipefail
 | 
			
		||||
 | 
			
		||||
top_dir='.'
 | 
			
		||||
if [[ $# -gt 0 ]]; then
 | 
			
		||||
    top_dir="${1}"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
p=$(pwd)
 | 
			
		||||
mod_dirs=()
 | 
			
		||||
 | 
			
		||||
# Note `mapfile` does not exist in older bash versions:
 | 
			
		||||
# https://stackoverflow.com/questions/41475261/need-alternative-to-readarray-mapfile-for-script-on-older-version-of-bash
 | 
			
		||||
 | 
			
		||||
while IFS= read -r line; do
 | 
			
		||||
    mod_dirs+=("$line")
 | 
			
		||||
done < <(find "${top_dir}" -type f -name 'go.mod' -exec dirname {} \; | sort)
 | 
			
		||||
 | 
			
		||||
for mod_dir in "${mod_dirs[@]}"; do
 | 
			
		||||
    cd "${mod_dir}"
 | 
			
		||||
 | 
			
		||||
    while IFS= read -r line; do
 | 
			
		||||
        echo ".${line#${p}}"
 | 
			
		||||
    done < <(go list --find -f '{{.Name}}|{{.Dir}}' ./... | grep '^main|' | cut -f 2- -d '|')
 | 
			
		||||
    cd "${p}"
 | 
			
		||||
done
 | 
			
		||||
							
								
								
									
										107
									
								
								vendor/go.opentelemetry.io/otel/handler.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								vendor/go.opentelemetry.io/otel/handler.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package otel // import "go.opentelemetry.io/otel"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// globalErrorHandler provides an ErrorHandler that can be used
 | 
			
		||||
	// throughout an OpenTelemetry instrumented project. When a user
 | 
			
		||||
	// specified ErrorHandler is registered (`SetErrorHandler`) all calls to
 | 
			
		||||
	// `Handle` and will be delegated to the registered ErrorHandler.
 | 
			
		||||
	globalErrorHandler = defaultErrorHandler()
 | 
			
		||||
 | 
			
		||||
	// delegateErrorHandlerOnce ensures that a user provided ErrorHandler is
 | 
			
		||||
	// only ever registered once.
 | 
			
		||||
	delegateErrorHandlerOnce sync.Once
 | 
			
		||||
 | 
			
		||||
	// Compile-time check that delegator implements ErrorHandler.
 | 
			
		||||
	_ ErrorHandler = (*delegator)(nil)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type holder struct {
 | 
			
		||||
	eh ErrorHandler
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func defaultErrorHandler() *atomic.Value {
 | 
			
		||||
	v := &atomic.Value{}
 | 
			
		||||
	v.Store(holder{eh: &delegator{l: log.New(os.Stderr, "", log.LstdFlags)}})
 | 
			
		||||
	return v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// delegator logs errors if no delegate is set, otherwise they are delegated.
 | 
			
		||||
type delegator struct {
 | 
			
		||||
	delegate atomic.Value
 | 
			
		||||
 | 
			
		||||
	l *log.Logger
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setDelegate sets the ErrorHandler delegate.
 | 
			
		||||
func (h *delegator) setDelegate(d ErrorHandler) {
 | 
			
		||||
	// It is critical this is guarded with delegateErrorHandlerOnce, if it is
 | 
			
		||||
	// called again with a different concrete type it will panic.
 | 
			
		||||
	h.delegate.Store(d)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Handle logs err if no delegate is set, otherwise it is delegated.
 | 
			
		||||
func (h *delegator) Handle(err error) {
 | 
			
		||||
	if d := h.delegate.Load(); d != nil {
 | 
			
		||||
		d.(ErrorHandler).Handle(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	h.l.Print(err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetErrorHandler returns the global ErrorHandler instance.
 | 
			
		||||
//
 | 
			
		||||
// The default ErrorHandler instance returned will log all errors to STDERR
 | 
			
		||||
// until an override ErrorHandler is set with SetErrorHandler. All
 | 
			
		||||
// ErrorHandler returned prior to this will automatically forward errors to
 | 
			
		||||
// the set instance instead of logging.
 | 
			
		||||
//
 | 
			
		||||
// Subsequent calls to SetErrorHandler after the first will not forward errors
 | 
			
		||||
// to the new ErrorHandler for prior returned instances.
 | 
			
		||||
func GetErrorHandler() ErrorHandler {
 | 
			
		||||
	return globalErrorHandler.Load().(holder).eh
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetErrorHandler sets the global ErrorHandler to h.
 | 
			
		||||
//
 | 
			
		||||
// The first time this is called all ErrorHandler previously returned from
 | 
			
		||||
// GetErrorHandler will send errors to h instead of the default logging
 | 
			
		||||
// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not
 | 
			
		||||
// delegate errors to h.
 | 
			
		||||
func SetErrorHandler(h ErrorHandler) {
 | 
			
		||||
	delegateErrorHandlerOnce.Do(func() {
 | 
			
		||||
		current := GetErrorHandler()
 | 
			
		||||
		if current == h {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if internalHandler, ok := current.(*delegator); ok {
 | 
			
		||||
			internalHandler.setDelegate(h)
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	globalErrorHandler.Store(holder{eh: h})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Handle is a convenience function for ErrorHandler().Handle(err)
 | 
			
		||||
func Handle(err error) {
 | 
			
		||||
	GetErrorHandler().Handle(err)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Package baggage provides base types and functionality to store and retrieve
 | 
			
		||||
baggage in Go context. This package exists because the OpenTracing bridge to
 | 
			
		||||
OpenTelemetry needs to synchronize state whenever baggage for a context is
 | 
			
		||||
modified and that context contains an OpenTracing span. If it were not for
 | 
			
		||||
this need this package would not need to exist and the
 | 
			
		||||
`go.opentelemetry.io/otel/baggage` package would be the singular place where
 | 
			
		||||
W3C baggage is handled.
 | 
			
		||||
*/
 | 
			
		||||
package baggage // import "go.opentelemetry.io/otel/internal/baggage"
 | 
			
		||||
 | 
			
		||||
// List is the collection of baggage members. The W3C allows for duplicates,
 | 
			
		||||
// but OpenTelemetry does not, therefore, this is represented as a map.
 | 
			
		||||
type List map[string]Item
 | 
			
		||||
 | 
			
		||||
// Item is the value and metadata properties part of a list-member.
 | 
			
		||||
type Item struct {
 | 
			
		||||
	Value      string
 | 
			
		||||
	Properties []Property
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Property is a metadata entry for a list-member.
 | 
			
		||||
type Property struct {
 | 
			
		||||
	Key, Value string
 | 
			
		||||
 | 
			
		||||
	// HasValue indicates if a zero-value value means the property does not
 | 
			
		||||
	// have a value or if it was the zero-value.
 | 
			
		||||
	HasValue bool
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										95
									
								
								vendor/go.opentelemetry.io/otel/internal/baggage/context.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								vendor/go.opentelemetry.io/otel/internal/baggage/context.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package baggage // import "go.opentelemetry.io/otel/internal/baggage"
 | 
			
		||||
 | 
			
		||||
import "context"
 | 
			
		||||
 | 
			
		||||
type baggageContextKeyType int
 | 
			
		||||
 | 
			
		||||
const baggageKey baggageContextKeyType = iota
 | 
			
		||||
 | 
			
		||||
// SetHookFunc is a callback called when storing baggage in the context.
 | 
			
		||||
type SetHookFunc func(context.Context, List) context.Context
 | 
			
		||||
 | 
			
		||||
// GetHookFunc is a callback called when getting baggage from the context.
 | 
			
		||||
type GetHookFunc func(context.Context, List) List
 | 
			
		||||
 | 
			
		||||
type baggageState struct {
 | 
			
		||||
	list List
 | 
			
		||||
 | 
			
		||||
	setHook SetHookFunc
 | 
			
		||||
	getHook GetHookFunc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ContextWithSetHook returns a copy of parent with hook configured to be
 | 
			
		||||
// invoked every time ContextWithBaggage is called.
 | 
			
		||||
//
 | 
			
		||||
// Passing nil SetHookFunc creates a context with no set hook to call.
 | 
			
		||||
func ContextWithSetHook(parent context.Context, hook SetHookFunc) context.Context {
 | 
			
		||||
	var s baggageState
 | 
			
		||||
	switch v := parent.Value(baggageKey).(type) {
 | 
			
		||||
	case baggageState:
 | 
			
		||||
		s = v
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.setHook = hook
 | 
			
		||||
	return context.WithValue(parent, baggageKey, s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ContextWithGetHook returns a copy of parent with hook configured to be
 | 
			
		||||
// invoked every time FromContext is called.
 | 
			
		||||
//
 | 
			
		||||
// Passing nil GetHookFunc creates a context with no get hook to call.
 | 
			
		||||
func ContextWithGetHook(parent context.Context, hook GetHookFunc) context.Context {
 | 
			
		||||
	var s baggageState
 | 
			
		||||
	switch v := parent.Value(baggageKey).(type) {
 | 
			
		||||
	case baggageState:
 | 
			
		||||
		s = v
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.getHook = hook
 | 
			
		||||
	return context.WithValue(parent, baggageKey, s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ContextWithList returns a copy of parent with baggage. Passing nil list
 | 
			
		||||
// returns a context without any baggage.
 | 
			
		||||
func ContextWithList(parent context.Context, list List) context.Context {
 | 
			
		||||
	var s baggageState
 | 
			
		||||
	switch v := parent.Value(baggageKey).(type) {
 | 
			
		||||
	case baggageState:
 | 
			
		||||
		s = v
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.list = list
 | 
			
		||||
	ctx := context.WithValue(parent, baggageKey, s)
 | 
			
		||||
	if s.setHook != nil {
 | 
			
		||||
		ctx = s.setHook(ctx, list)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ctx
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ListFromContext returns the baggage contained in ctx.
 | 
			
		||||
func ListFromContext(ctx context.Context) List {
 | 
			
		||||
	switch v := ctx.Value(baggageKey).(type) {
 | 
			
		||||
	case baggageState:
 | 
			
		||||
		if v.getHook != nil {
 | 
			
		||||
			return v.getHook(ctx, v.list)
 | 
			
		||||
		}
 | 
			
		||||
		return v.list
 | 
			
		||||
	default:
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										82
									
								
								vendor/go.opentelemetry.io/otel/internal/global/propagator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								vendor/go.opentelemetry.io/otel/internal/global/propagator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package global // import "go.opentelemetry.io/otel/internal/global"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/propagation"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// textMapPropagator is a default TextMapPropagator that delegates calls to a
 | 
			
		||||
// registered delegate if one is set, otherwise it defaults to delegating the
 | 
			
		||||
// calls to a the default no-op propagation.TextMapPropagator.
 | 
			
		||||
type textMapPropagator struct {
 | 
			
		||||
	mtx      sync.Mutex
 | 
			
		||||
	once     sync.Once
 | 
			
		||||
	delegate propagation.TextMapPropagator
 | 
			
		||||
	noop     propagation.TextMapPropagator
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Compile-time guarantee that textMapPropagator implements the
 | 
			
		||||
// propagation.TextMapPropagator interface.
 | 
			
		||||
var _ propagation.TextMapPropagator = (*textMapPropagator)(nil)
 | 
			
		||||
 | 
			
		||||
func newTextMapPropagator() *textMapPropagator {
 | 
			
		||||
	return &textMapPropagator{
 | 
			
		||||
		noop: propagation.NewCompositeTextMapPropagator(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetDelegate sets a delegate propagation.TextMapPropagator that all calls are
 | 
			
		||||
// forwarded to. Delegation can only be performed once, all subsequent calls
 | 
			
		||||
// perform no delegation.
 | 
			
		||||
func (p *textMapPropagator) SetDelegate(delegate propagation.TextMapPropagator) {
 | 
			
		||||
	if delegate == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.mtx.Lock()
 | 
			
		||||
	p.once.Do(func() { p.delegate = delegate })
 | 
			
		||||
	p.mtx.Unlock()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// effectiveDelegate returns the current delegate of p if one is set,
 | 
			
		||||
// otherwise the default noop TextMapPropagator is returned. This method
 | 
			
		||||
// can be called concurrently.
 | 
			
		||||
func (p *textMapPropagator) effectiveDelegate() propagation.TextMapPropagator {
 | 
			
		||||
	p.mtx.Lock()
 | 
			
		||||
	defer p.mtx.Unlock()
 | 
			
		||||
	if p.delegate != nil {
 | 
			
		||||
		return p.delegate
 | 
			
		||||
	}
 | 
			
		||||
	return p.noop
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Inject set cross-cutting concerns from the Context into the carrier.
 | 
			
		||||
func (p *textMapPropagator) Inject(ctx context.Context, carrier propagation.TextMapCarrier) {
 | 
			
		||||
	p.effectiveDelegate().Inject(ctx, carrier)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Extract reads cross-cutting concerns from the carrier into a Context.
 | 
			
		||||
func (p *textMapPropagator) Extract(ctx context.Context, carrier propagation.TextMapCarrier) context.Context {
 | 
			
		||||
	return p.effectiveDelegate().Extract(ctx, carrier)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fields returns the keys whose values are set with Inject.
 | 
			
		||||
func (p *textMapPropagator) Fields() []string {
 | 
			
		||||
	return p.effectiveDelegate().Fields()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										106
									
								
								vendor/go.opentelemetry.io/otel/internal/global/state.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								vendor/go.opentelemetry.io/otel/internal/global/state.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package global // import "go.opentelemetry.io/otel/internal/global"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sync"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/propagation"
 | 
			
		||||
	"go.opentelemetry.io/otel/trace"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	tracerProviderHolder struct {
 | 
			
		||||
		tp trace.TracerProvider
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	propagatorsHolder struct {
 | 
			
		||||
		tm propagation.TextMapPropagator
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	globalTracer      = defaultTracerValue()
 | 
			
		||||
	globalPropagators = defaultPropagatorsValue()
 | 
			
		||||
 | 
			
		||||
	delegateTraceOnce             sync.Once
 | 
			
		||||
	delegateTextMapPropagatorOnce sync.Once
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TracerProvider is the internal implementation for global.TracerProvider.
 | 
			
		||||
func TracerProvider() trace.TracerProvider {
 | 
			
		||||
	return globalTracer.Load().(tracerProviderHolder).tp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetTracerProvider is the internal implementation for global.SetTracerProvider.
 | 
			
		||||
func SetTracerProvider(tp trace.TracerProvider) {
 | 
			
		||||
	delegateTraceOnce.Do(func() {
 | 
			
		||||
		current := TracerProvider()
 | 
			
		||||
		if current == tp {
 | 
			
		||||
			// Setting the provider to the prior default is nonsense, panic.
 | 
			
		||||
			// Panic is acceptable because we are likely still early in the
 | 
			
		||||
			// process lifetime.
 | 
			
		||||
			panic("invalid TracerProvider, the global instance cannot be reinstalled")
 | 
			
		||||
		} else if def, ok := current.(*tracerProvider); ok {
 | 
			
		||||
			def.setDelegate(tp)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	})
 | 
			
		||||
	globalTracer.Store(tracerProviderHolder{tp: tp})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TextMapPropagator is the internal implementation for global.TextMapPropagator.
 | 
			
		||||
func TextMapPropagator() propagation.TextMapPropagator {
 | 
			
		||||
	return globalPropagators.Load().(propagatorsHolder).tm
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetTextMapPropagator is the internal implementation for global.SetTextMapPropagator.
 | 
			
		||||
func SetTextMapPropagator(p propagation.TextMapPropagator) {
 | 
			
		||||
	// For the textMapPropagator already returned by TextMapPropagator
 | 
			
		||||
	// delegate to p.
 | 
			
		||||
	delegateTextMapPropagatorOnce.Do(func() {
 | 
			
		||||
		if current := TextMapPropagator(); current == p {
 | 
			
		||||
			// Setting the provider to the prior default is nonsense, panic.
 | 
			
		||||
			// Panic is acceptable because we are likely still early in the
 | 
			
		||||
			// process lifetime.
 | 
			
		||||
			panic("invalid TextMapPropagator, the global instance cannot be reinstalled")
 | 
			
		||||
		} else if def, ok := current.(*textMapPropagator); ok {
 | 
			
		||||
			def.SetDelegate(p)
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	// Return p when subsequent calls to TextMapPropagator are made.
 | 
			
		||||
	globalPropagators.Store(propagatorsHolder{tm: p})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func defaultTracerValue() *atomic.Value {
 | 
			
		||||
	v := &atomic.Value{}
 | 
			
		||||
	v.Store(tracerProviderHolder{tp: &tracerProvider{}})
 | 
			
		||||
	return v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func defaultPropagatorsValue() *atomic.Value {
 | 
			
		||||
	v := &atomic.Value{}
 | 
			
		||||
	v.Store(propagatorsHolder{tm: newTextMapPropagator()})
 | 
			
		||||
	return v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResetForTest restores the initial global state, for testing purposes.
 | 
			
		||||
func ResetForTest() {
 | 
			
		||||
	globalTracer = defaultTracerValue()
 | 
			
		||||
	globalPropagators = defaultPropagatorsValue()
 | 
			
		||||
	delegateTraceOnce = sync.Once{}
 | 
			
		||||
	delegateTextMapPropagatorOnce = sync.Once{}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										192
									
								
								vendor/go.opentelemetry.io/otel/internal/global/trace.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								vendor/go.opentelemetry.io/otel/internal/global/trace.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,192 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package global // import "go.opentelemetry.io/otel/internal/global"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
This file contains the forwarding implementation of the TracerProvider used as
 | 
			
		||||
the default global instance. Prior to initialization of an SDK, Tracers
 | 
			
		||||
returned by the global TracerProvider will provide no-op functionality. This
 | 
			
		||||
means that all Span created prior to initialization are no-op Spans.
 | 
			
		||||
 | 
			
		||||
Once an SDK has been initialized, all provided no-op Tracers are swapped for
 | 
			
		||||
Tracers provided by the SDK defined TracerProvider. However, any Span started
 | 
			
		||||
prior to this initialization does not change its behavior. Meaning, the Span
 | 
			
		||||
remains a no-op Span.
 | 
			
		||||
 | 
			
		||||
The implementation to track and swap Tracers locks all new Tracer creation
 | 
			
		||||
until the swap is complete. This assumes that this operation is not
 | 
			
		||||
performance-critical. If that assumption is incorrect, be sure to configure an
 | 
			
		||||
SDK prior to any Tracer creation.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/codes"
 | 
			
		||||
	"go.opentelemetry.io/otel/trace"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// tracerProvider is a placeholder for a configured SDK TracerProvider.
 | 
			
		||||
//
 | 
			
		||||
// All TracerProvider functionality is forwarded to a delegate once
 | 
			
		||||
// configured.
 | 
			
		||||
type tracerProvider struct {
 | 
			
		||||
	mtx      sync.Mutex
 | 
			
		||||
	tracers  map[il]*tracer
 | 
			
		||||
	delegate trace.TracerProvider
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Compile-time guarantee that tracerProvider implements the TracerProvider
 | 
			
		||||
// interface.
 | 
			
		||||
var _ trace.TracerProvider = &tracerProvider{}
 | 
			
		||||
 | 
			
		||||
// setDelegate configures p to delegate all TracerProvider functionality to
 | 
			
		||||
// provider.
 | 
			
		||||
//
 | 
			
		||||
// All Tracers provided prior to this function call are switched out to be
 | 
			
		||||
// Tracers provided by provider.
 | 
			
		||||
//
 | 
			
		||||
// It is guaranteed by the caller that this happens only once.
 | 
			
		||||
func (p *tracerProvider) setDelegate(provider trace.TracerProvider) {
 | 
			
		||||
	p.mtx.Lock()
 | 
			
		||||
	defer p.mtx.Unlock()
 | 
			
		||||
 | 
			
		||||
	p.delegate = provider
 | 
			
		||||
 | 
			
		||||
	if len(p.tracers) == 0 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, t := range p.tracers {
 | 
			
		||||
		t.setDelegate(provider)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.tracers = nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tracer implements TracerProvider.
 | 
			
		||||
func (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer {
 | 
			
		||||
	p.mtx.Lock()
 | 
			
		||||
	defer p.mtx.Unlock()
 | 
			
		||||
 | 
			
		||||
	if p.delegate != nil {
 | 
			
		||||
		return p.delegate.Tracer(name, opts...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// At this moment it is guaranteed that no sdk is installed, save the tracer in the tracers map.
 | 
			
		||||
 | 
			
		||||
	c := trace.NewTracerConfig(opts...)
 | 
			
		||||
	key := il{
 | 
			
		||||
		name:    name,
 | 
			
		||||
		version: c.InstrumentationVersion(),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if p.tracers == nil {
 | 
			
		||||
		p.tracers = make(map[il]*tracer)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if val, ok := p.tracers[key]; ok {
 | 
			
		||||
		return val
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	t := &tracer{name: name, opts: opts, provider: p}
 | 
			
		||||
	p.tracers[key] = t
 | 
			
		||||
	return t
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type il struct {
 | 
			
		||||
	name    string
 | 
			
		||||
	version string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// tracer is a placeholder for a trace.Tracer.
 | 
			
		||||
//
 | 
			
		||||
// All Tracer functionality is forwarded to a delegate once configured.
 | 
			
		||||
// Otherwise, all functionality is forwarded to a NoopTracer.
 | 
			
		||||
type tracer struct {
 | 
			
		||||
	name     string
 | 
			
		||||
	opts     []trace.TracerOption
 | 
			
		||||
	provider *tracerProvider
 | 
			
		||||
 | 
			
		||||
	delegate atomic.Value
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Compile-time guarantee that tracer implements the trace.Tracer interface.
 | 
			
		||||
var _ trace.Tracer = &tracer{}
 | 
			
		||||
 | 
			
		||||
// setDelegate configures t to delegate all Tracer functionality to Tracers
 | 
			
		||||
// created by provider.
 | 
			
		||||
//
 | 
			
		||||
// All subsequent calls to the Tracer methods will be passed to the delegate.
 | 
			
		||||
//
 | 
			
		||||
// It is guaranteed by the caller that this happens only once.
 | 
			
		||||
func (t *tracer) setDelegate(provider trace.TracerProvider) {
 | 
			
		||||
	t.delegate.Store(provider.Tracer(t.name, t.opts...))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Start implements trace.Tracer by forwarding the call to t.delegate if
 | 
			
		||||
// set, otherwise it forwards the call to a NoopTracer.
 | 
			
		||||
func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
 | 
			
		||||
	delegate := t.delegate.Load()
 | 
			
		||||
	if delegate != nil {
 | 
			
		||||
		return delegate.(trace.Tracer).Start(ctx, name, opts...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s := nonRecordingSpan{sc: trace.SpanContextFromContext(ctx), tracer: t}
 | 
			
		||||
	ctx = trace.ContextWithSpan(ctx, s)
 | 
			
		||||
	return ctx, s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// nonRecordingSpan is a minimal implementation of a Span that wraps a
 | 
			
		||||
// SpanContext. It performs no operations other than to return the wrapped
 | 
			
		||||
// SpanContext.
 | 
			
		||||
type nonRecordingSpan struct {
 | 
			
		||||
	sc     trace.SpanContext
 | 
			
		||||
	tracer *tracer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ trace.Span = nonRecordingSpan{}
 | 
			
		||||
 | 
			
		||||
// SpanContext returns the wrapped SpanContext.
 | 
			
		||||
func (s nonRecordingSpan) SpanContext() trace.SpanContext { return s.sc }
 | 
			
		||||
 | 
			
		||||
// IsRecording always returns false.
 | 
			
		||||
func (nonRecordingSpan) IsRecording() bool { return false }
 | 
			
		||||
 | 
			
		||||
// SetStatus does nothing.
 | 
			
		||||
func (nonRecordingSpan) SetStatus(codes.Code, string) {}
 | 
			
		||||
 | 
			
		||||
// SetError does nothing.
 | 
			
		||||
func (nonRecordingSpan) SetError(bool) {}
 | 
			
		||||
 | 
			
		||||
// SetAttributes does nothing.
 | 
			
		||||
func (nonRecordingSpan) SetAttributes(...attribute.KeyValue) {}
 | 
			
		||||
 | 
			
		||||
// End does nothing.
 | 
			
		||||
func (nonRecordingSpan) End(...trace.SpanEndOption) {}
 | 
			
		||||
 | 
			
		||||
// RecordError does nothing.
 | 
			
		||||
func (nonRecordingSpan) RecordError(error, ...trace.EventOption) {}
 | 
			
		||||
 | 
			
		||||
// AddEvent does nothing.
 | 
			
		||||
func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}
 | 
			
		||||
 | 
			
		||||
// SetName does nothing.
 | 
			
		||||
func (nonRecordingSpan) SetName(string) {}
 | 
			
		||||
 | 
			
		||||
func (s nonRecordingSpan) TracerProvider() trace.TracerProvider { return s.tracer.provider }
 | 
			
		||||
							
								
								
									
										201
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
							
								
								
									
										149
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/async.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/async.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,149 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package metric // import "go.opentelemetry.io/otel/internal/metric"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel"
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//nolint:revive // ignoring missing comments for exported error in an internal package
 | 
			
		||||
var ErrInvalidAsyncRunner = errors.New("unknown async runner type")
 | 
			
		||||
 | 
			
		||||
// AsyncCollector is an interface used between the MeterImpl and the
 | 
			
		||||
// AsyncInstrumentState helper below.  This interface is implemented by
 | 
			
		||||
// the SDK to provide support for running observer callbacks.
 | 
			
		||||
type AsyncCollector interface {
 | 
			
		||||
	// CollectAsync passes a batch of observations to the MeterImpl.
 | 
			
		||||
	CollectAsync(labels []attribute.KeyValue, observation ...sdkapi.Observation)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsyncInstrumentState manages an ordered set of asynchronous
 | 
			
		||||
// instruments and the distinct runners, taking into account batch
 | 
			
		||||
// observer callbacks.
 | 
			
		||||
type AsyncInstrumentState struct {
 | 
			
		||||
	lock sync.Mutex
 | 
			
		||||
 | 
			
		||||
	// errorOnce will use the otel.Handler to report an error
 | 
			
		||||
	// once in case of an invalid runner attempting to run.
 | 
			
		||||
	errorOnce sync.Once
 | 
			
		||||
 | 
			
		||||
	// runnerMap keeps the set of runners that will run each
 | 
			
		||||
	// collection interval.  Singletons are entered with a real
 | 
			
		||||
	// instrument each, batch observers are entered with a nil
 | 
			
		||||
	// instrument, ensuring that when a singleton callback is used
 | 
			
		||||
	// repeatedly, it is executed repeatedly in the interval, while
 | 
			
		||||
	// when a batch callback is used repeatedly, it only executes
 | 
			
		||||
	// once per interval.
 | 
			
		||||
	runnerMap map[asyncRunnerPair]struct{}
 | 
			
		||||
 | 
			
		||||
	// runners maintains the set of runners in the order they were
 | 
			
		||||
	// registered.
 | 
			
		||||
	runners []asyncRunnerPair
 | 
			
		||||
 | 
			
		||||
	// instruments maintains the set of instruments in the order
 | 
			
		||||
	// they were registered.
 | 
			
		||||
	instruments []sdkapi.AsyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// asyncRunnerPair is a map entry for Observer callback runners.
 | 
			
		||||
type asyncRunnerPair struct {
 | 
			
		||||
	// runner is used as a map key here.  The API ensures
 | 
			
		||||
	// that all callbacks are pointers for this reason.
 | 
			
		||||
	runner sdkapi.AsyncRunner
 | 
			
		||||
 | 
			
		||||
	// inst refers to a non-nil instrument when `runner` is a
 | 
			
		||||
	// AsyncSingleRunner.
 | 
			
		||||
	inst sdkapi.AsyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewAsyncInstrumentState returns a new *AsyncInstrumentState, for
 | 
			
		||||
// use by MeterImpl to manage running the set of observer callbacks in
 | 
			
		||||
// the correct order.
 | 
			
		||||
func NewAsyncInstrumentState() *AsyncInstrumentState {
 | 
			
		||||
	return &AsyncInstrumentState{
 | 
			
		||||
		runnerMap: map[asyncRunnerPair]struct{}{},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Instruments returns the asynchronous instruments managed by this
 | 
			
		||||
// object, the set that should be checkpointed after observers are
 | 
			
		||||
// run.
 | 
			
		||||
func (a *AsyncInstrumentState) Instruments() []sdkapi.AsyncImpl {
 | 
			
		||||
	a.lock.Lock()
 | 
			
		||||
	defer a.lock.Unlock()
 | 
			
		||||
	return a.instruments
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Register adds a new asynchronous instrument to by managed by this
 | 
			
		||||
// object.  This should be called during NewAsyncInstrument() and
 | 
			
		||||
// assumes that errors (e.g., duplicate registration) have already
 | 
			
		||||
// been checked.
 | 
			
		||||
func (a *AsyncInstrumentState) Register(inst sdkapi.AsyncImpl, runner sdkapi.AsyncRunner) {
 | 
			
		||||
	a.lock.Lock()
 | 
			
		||||
	defer a.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	a.instruments = append(a.instruments, inst)
 | 
			
		||||
 | 
			
		||||
	// asyncRunnerPair reflects this callback in the asyncRunners
 | 
			
		||||
	// list.  If this is a batch runner, the instrument is nil.
 | 
			
		||||
	// If this is a single-Observer runner, the instrument is
 | 
			
		||||
	// included.  This ensures that batch callbacks are called
 | 
			
		||||
	// once and single callbacks are called once per instrument.
 | 
			
		||||
	rp := asyncRunnerPair{
 | 
			
		||||
		runner: runner,
 | 
			
		||||
	}
 | 
			
		||||
	if _, ok := runner.(sdkapi.AsyncSingleRunner); ok {
 | 
			
		||||
		rp.inst = inst
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if _, ok := a.runnerMap[rp]; !ok {
 | 
			
		||||
		a.runnerMap[rp] = struct{}{}
 | 
			
		||||
		a.runners = append(a.runners, rp)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run executes the complete set of observer callbacks.
 | 
			
		||||
func (a *AsyncInstrumentState) Run(ctx context.Context, collector AsyncCollector) {
 | 
			
		||||
	a.lock.Lock()
 | 
			
		||||
	runners := a.runners
 | 
			
		||||
	a.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	for _, rp := range runners {
 | 
			
		||||
		// The runner must be a single or batch runner, no
 | 
			
		||||
		// other implementations are possible because the
 | 
			
		||||
		// interface has un-exported methods.
 | 
			
		||||
 | 
			
		||||
		if singleRunner, ok := rp.runner.(sdkapi.AsyncSingleRunner); ok {
 | 
			
		||||
			singleRunner.Run(ctx, rp.inst, collector.CollectAsync)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if multiRunner, ok := rp.runner.(sdkapi.AsyncBatchRunner); ok {
 | 
			
		||||
			multiRunner.Run(ctx, collector.CollectAsync)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		a.errorOnce.Do(func() {
 | 
			
		||||
			otel.Handle(fmt.Errorf("%w: type %T (reported once)", ErrInvalidAsyncRunner, rp))
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										361
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/global/meter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										361
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/global/meter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,361 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package global // import "go.opentelemetry.io/otel/internal/metric/global"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/internal/metric/registry"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// This file contains the forwarding implementation of MeterProvider used as
 | 
			
		||||
// the default global instance.  Metric events using instruments provided by
 | 
			
		||||
// this implementation are no-ops until the first Meter implementation is set
 | 
			
		||||
// as the global provider.
 | 
			
		||||
//
 | 
			
		||||
// The implementation here uses Mutexes to maintain a list of active Meters in
 | 
			
		||||
// the MeterProvider and Instruments in each Meter, under the assumption that
 | 
			
		||||
// these interfaces are not performance-critical.
 | 
			
		||||
//
 | 
			
		||||
// We have the invariant that setDelegate() will be called before a new
 | 
			
		||||
// MeterProvider implementation is registered as the global provider.  Mutexes
 | 
			
		||||
// in the MeterProvider and Meters ensure that each instrument has a delegate
 | 
			
		||||
// before the global provider is set.
 | 
			
		||||
//
 | 
			
		||||
// Bound instrument operations are implemented by delegating to the
 | 
			
		||||
// instrument after it is registered, with a sync.Once initializer to
 | 
			
		||||
// protect against races with Release().
 | 
			
		||||
//
 | 
			
		||||
// Metric uniqueness checking is implemented by calling the exported
 | 
			
		||||
// methods of the api/metric/registry package.
 | 
			
		||||
 | 
			
		||||
type meterKey struct {
 | 
			
		||||
	InstrumentationName    string
 | 
			
		||||
	InstrumentationVersion string
 | 
			
		||||
	SchemaURL              string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type meterProvider struct {
 | 
			
		||||
	delegate metric.MeterProvider
 | 
			
		||||
 | 
			
		||||
	// lock protects `delegate` and `meters`.
 | 
			
		||||
	lock sync.Mutex
 | 
			
		||||
 | 
			
		||||
	// meters maintains a unique entry for every named Meter
 | 
			
		||||
	// that has been registered through the global instance.
 | 
			
		||||
	meters map[meterKey]*meterEntry
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type meterImpl struct {
 | 
			
		||||
	delegate unsafe.Pointer // (*metric.MeterImpl)
 | 
			
		||||
 | 
			
		||||
	lock       sync.Mutex
 | 
			
		||||
	syncInsts  []*syncImpl
 | 
			
		||||
	asyncInsts []*asyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type meterEntry struct {
 | 
			
		||||
	unique sdkapi.MeterImpl
 | 
			
		||||
	impl   meterImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type instrument struct {
 | 
			
		||||
	descriptor sdkapi.Descriptor
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type syncImpl struct {
 | 
			
		||||
	delegate unsafe.Pointer // (*sdkapi.SyncImpl)
 | 
			
		||||
 | 
			
		||||
	instrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type asyncImpl struct {
 | 
			
		||||
	delegate unsafe.Pointer // (*sdkapi.AsyncImpl)
 | 
			
		||||
 | 
			
		||||
	instrument
 | 
			
		||||
 | 
			
		||||
	runner sdkapi.AsyncRunner
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SyncImpler is implemented by all of the sync metric
 | 
			
		||||
// instruments.
 | 
			
		||||
type SyncImpler interface {
 | 
			
		||||
	SyncImpl() sdkapi.SyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsyncImpler is implemented by all of the async
 | 
			
		||||
// metric instruments.
 | 
			
		||||
type AsyncImpler interface {
 | 
			
		||||
	AsyncImpl() sdkapi.AsyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type syncHandle struct {
 | 
			
		||||
	delegate unsafe.Pointer // (*sdkapi.BoundInstrumentImpl)
 | 
			
		||||
 | 
			
		||||
	inst   *syncImpl
 | 
			
		||||
	labels []attribute.KeyValue
 | 
			
		||||
 | 
			
		||||
	initialize sync.Once
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ metric.MeterProvider = &meterProvider{}
 | 
			
		||||
var _ sdkapi.MeterImpl = &meterImpl{}
 | 
			
		||||
var _ sdkapi.InstrumentImpl = &syncImpl{}
 | 
			
		||||
var _ sdkapi.BoundSyncImpl = &syncHandle{}
 | 
			
		||||
var _ sdkapi.AsyncImpl = &asyncImpl{}
 | 
			
		||||
 | 
			
		||||
func (inst *instrument) Descriptor() sdkapi.Descriptor {
 | 
			
		||||
	return inst.descriptor
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MeterProvider interface and delegation
 | 
			
		||||
 | 
			
		||||
func newMeterProvider() *meterProvider {
 | 
			
		||||
	return &meterProvider{
 | 
			
		||||
		meters: map[meterKey]*meterEntry{},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *meterProvider) setDelegate(provider metric.MeterProvider) {
 | 
			
		||||
	p.lock.Lock()
 | 
			
		||||
	defer p.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	p.delegate = provider
 | 
			
		||||
	for key, entry := range p.meters {
 | 
			
		||||
		entry.impl.setDelegate(key, provider)
 | 
			
		||||
	}
 | 
			
		||||
	p.meters = nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *meterProvider) Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter {
 | 
			
		||||
	p.lock.Lock()
 | 
			
		||||
	defer p.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	if p.delegate != nil {
 | 
			
		||||
		return p.delegate.Meter(instrumentationName, opts...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg := metric.NewMeterConfig(opts...)
 | 
			
		||||
	key := meterKey{
 | 
			
		||||
		InstrumentationName:    instrumentationName,
 | 
			
		||||
		InstrumentationVersion: cfg.InstrumentationVersion(),
 | 
			
		||||
		SchemaURL:              cfg.SchemaURL(),
 | 
			
		||||
	}
 | 
			
		||||
	entry, ok := p.meters[key]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		entry = &meterEntry{}
 | 
			
		||||
		// Note: This code implements its own MeterProvider
 | 
			
		||||
		// name-uniqueness logic because there is
 | 
			
		||||
		// synchronization required at the moment of
 | 
			
		||||
		// delegation.  We use the same instrument-uniqueness
 | 
			
		||||
		// checking the real SDK uses here:
 | 
			
		||||
		entry.unique = registry.NewUniqueInstrumentMeterImpl(&entry.impl)
 | 
			
		||||
		p.meters[key] = entry
 | 
			
		||||
	}
 | 
			
		||||
	return metric.WrapMeterImpl(entry.unique)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Meter interface and delegation
 | 
			
		||||
 | 
			
		||||
func (m *meterImpl) setDelegate(key meterKey, provider metric.MeterProvider) {
 | 
			
		||||
	m.lock.Lock()
 | 
			
		||||
	defer m.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	d := new(sdkapi.MeterImpl)
 | 
			
		||||
	*d = provider.Meter(
 | 
			
		||||
		key.InstrumentationName,
 | 
			
		||||
		metric.WithInstrumentationVersion(key.InstrumentationVersion),
 | 
			
		||||
		metric.WithSchemaURL(key.SchemaURL),
 | 
			
		||||
	).MeterImpl()
 | 
			
		||||
	m.delegate = unsafe.Pointer(d)
 | 
			
		||||
 | 
			
		||||
	for _, inst := range m.syncInsts {
 | 
			
		||||
		inst.setDelegate(*d)
 | 
			
		||||
	}
 | 
			
		||||
	m.syncInsts = nil
 | 
			
		||||
	for _, obs := range m.asyncInsts {
 | 
			
		||||
		obs.setDelegate(*d)
 | 
			
		||||
	}
 | 
			
		||||
	m.asyncInsts = nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *meterImpl) NewSyncInstrument(desc sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
 | 
			
		||||
	m.lock.Lock()
 | 
			
		||||
	defer m.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	if meterPtr := (*sdkapi.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil {
 | 
			
		||||
		return (*meterPtr).NewSyncInstrument(desc)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inst := &syncImpl{
 | 
			
		||||
		instrument: instrument{
 | 
			
		||||
			descriptor: desc,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	m.syncInsts = append(m.syncInsts, inst)
 | 
			
		||||
	return inst, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Synchronous delegation
 | 
			
		||||
 | 
			
		||||
func (inst *syncImpl) setDelegate(d sdkapi.MeterImpl) {
 | 
			
		||||
	implPtr := new(sdkapi.SyncImpl)
 | 
			
		||||
 | 
			
		||||
	var err error
 | 
			
		||||
	*implPtr, err = d.NewSyncInstrument(inst.descriptor)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		// TODO: There is no standard way to deliver this error to the user.
 | 
			
		||||
		// See https://github.com/open-telemetry/opentelemetry-go/issues/514
 | 
			
		||||
		// Note that the default SDK will not generate any errors yet, this is
 | 
			
		||||
		// only for added safety.
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	atomic.StorePointer(&inst.delegate, unsafe.Pointer(implPtr))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (inst *syncImpl) Implementation() interface{} {
 | 
			
		||||
	if implPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil {
 | 
			
		||||
		return (*implPtr).Implementation()
 | 
			
		||||
	}
 | 
			
		||||
	return inst
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (inst *syncImpl) Bind(labels []attribute.KeyValue) sdkapi.BoundSyncImpl {
 | 
			
		||||
	if implPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil {
 | 
			
		||||
		return (*implPtr).Bind(labels)
 | 
			
		||||
	}
 | 
			
		||||
	return &syncHandle{
 | 
			
		||||
		inst:   inst,
 | 
			
		||||
		labels: labels,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bound *syncHandle) Unbind() {
 | 
			
		||||
	bound.initialize.Do(func() {})
 | 
			
		||||
 | 
			
		||||
	implPtr := (*sdkapi.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
 | 
			
		||||
 | 
			
		||||
	if implPtr == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	(*implPtr).Unbind()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Async delegation
 | 
			
		||||
 | 
			
		||||
func (m *meterImpl) NewAsyncInstrument(
 | 
			
		||||
	desc sdkapi.Descriptor,
 | 
			
		||||
	runner sdkapi.AsyncRunner,
 | 
			
		||||
) (sdkapi.AsyncImpl, error) {
 | 
			
		||||
 | 
			
		||||
	m.lock.Lock()
 | 
			
		||||
	defer m.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	if meterPtr := (*sdkapi.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil {
 | 
			
		||||
		return (*meterPtr).NewAsyncInstrument(desc, runner)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inst := &asyncImpl{
 | 
			
		||||
		instrument: instrument{
 | 
			
		||||
			descriptor: desc,
 | 
			
		||||
		},
 | 
			
		||||
		runner: runner,
 | 
			
		||||
	}
 | 
			
		||||
	m.asyncInsts = append(m.asyncInsts, inst)
 | 
			
		||||
	return inst, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (obs *asyncImpl) Implementation() interface{} {
 | 
			
		||||
	if implPtr := (*sdkapi.AsyncImpl)(atomic.LoadPointer(&obs.delegate)); implPtr != nil {
 | 
			
		||||
		return (*implPtr).Implementation()
 | 
			
		||||
	}
 | 
			
		||||
	return obs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (obs *asyncImpl) setDelegate(d sdkapi.MeterImpl) {
 | 
			
		||||
	implPtr := new(sdkapi.AsyncImpl)
 | 
			
		||||
 | 
			
		||||
	var err error
 | 
			
		||||
	*implPtr, err = d.NewAsyncInstrument(obs.descriptor, obs.runner)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		// TODO: There is no standard way to deliver this error to the user.
 | 
			
		||||
		// See https://github.com/open-telemetry/opentelemetry-go/issues/514
 | 
			
		||||
		// Note that the default SDK will not generate any errors yet, this is
 | 
			
		||||
		// only for added safety.
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	atomic.StorePointer(&obs.delegate, unsafe.Pointer(implPtr))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Metric updates
 | 
			
		||||
 | 
			
		||||
func (m *meterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurements ...sdkapi.Measurement) {
 | 
			
		||||
	if delegatePtr := (*sdkapi.MeterImpl)(atomic.LoadPointer(&m.delegate)); delegatePtr != nil {
 | 
			
		||||
		(*delegatePtr).RecordBatch(ctx, labels, measurements...)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (inst *syncImpl) RecordOne(ctx context.Context, number number.Number, labels []attribute.KeyValue) {
 | 
			
		||||
	if instPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&inst.delegate)); instPtr != nil {
 | 
			
		||||
		(*instPtr).RecordOne(ctx, number, labels)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Bound instrument initialization
 | 
			
		||||
 | 
			
		||||
func (bound *syncHandle) RecordOne(ctx context.Context, number number.Number) {
 | 
			
		||||
	instPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&bound.inst.delegate))
 | 
			
		||||
	if instPtr == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var implPtr *sdkapi.BoundSyncImpl
 | 
			
		||||
	bound.initialize.Do(func() {
 | 
			
		||||
		implPtr = new(sdkapi.BoundSyncImpl)
 | 
			
		||||
		*implPtr = (*instPtr).Bind(bound.labels)
 | 
			
		||||
		atomic.StorePointer(&bound.delegate, unsafe.Pointer(implPtr))
 | 
			
		||||
	})
 | 
			
		||||
	if implPtr == nil {
 | 
			
		||||
		implPtr = (*sdkapi.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
 | 
			
		||||
	}
 | 
			
		||||
	// This may still be nil if instrument was created and bound
 | 
			
		||||
	// without a delegate, then the instrument was set to have a
 | 
			
		||||
	// delegate and unbound.
 | 
			
		||||
	if implPtr == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	(*implPtr).RecordOne(ctx, number)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func AtomicFieldOffsets() map[string]uintptr {
 | 
			
		||||
	return map[string]uintptr{
 | 
			
		||||
		"meterProvider.delegate": unsafe.Offsetof(meterProvider{}.delegate),
 | 
			
		||||
		"meterImpl.delegate":     unsafe.Offsetof(meterImpl{}.delegate),
 | 
			
		||||
		"syncImpl.delegate":      unsafe.Offsetof(syncImpl{}.delegate),
 | 
			
		||||
		"asyncImpl.delegate":     unsafe.Offsetof(asyncImpl{}.delegate),
 | 
			
		||||
		"syncHandle.delegate":    unsafe.Offsetof(syncHandle{}.delegate),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/global/metric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/global/metric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package global // import "go.opentelemetry.io/otel/internal/metric/global"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sync"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/metric"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type meterProviderHolder struct {
 | 
			
		||||
	mp metric.MeterProvider
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	globalMeter = defaultMeterValue()
 | 
			
		||||
 | 
			
		||||
	delegateMeterOnce sync.Once
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// MeterProvider is the internal implementation for global.MeterProvider.
 | 
			
		||||
func MeterProvider() metric.MeterProvider {
 | 
			
		||||
	return globalMeter.Load().(meterProviderHolder).mp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetMeterProvider is the internal implementation for global.SetMeterProvider.
 | 
			
		||||
func SetMeterProvider(mp metric.MeterProvider) {
 | 
			
		||||
	delegateMeterOnce.Do(func() {
 | 
			
		||||
		current := MeterProvider()
 | 
			
		||||
 | 
			
		||||
		if current == mp {
 | 
			
		||||
			// Setting the provider to the prior default is nonsense, panic.
 | 
			
		||||
			// Panic is acceptable because we are likely still early in the
 | 
			
		||||
			// process lifetime.
 | 
			
		||||
			panic("invalid MeterProvider, the global instance cannot be reinstalled")
 | 
			
		||||
		} else if def, ok := current.(*meterProvider); ok {
 | 
			
		||||
			def.setDelegate(mp)
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	globalMeter.Store(meterProviderHolder{mp: mp})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func defaultMeterValue() *atomic.Value {
 | 
			
		||||
	v := &atomic.Value{}
 | 
			
		||||
	v.Store(meterProviderHolder{mp: newMeterProvider()})
 | 
			
		||||
	return v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResetForTest restores the initial global state, for testing purposes.
 | 
			
		||||
func ResetForTest() {
 | 
			
		||||
	globalMeter = defaultMeterValue()
 | 
			
		||||
	delegateMeterOnce = sync.Once{}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/registry/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/registry/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Package registry provides a non-standalone implementation of
 | 
			
		||||
MeterProvider that adds uniqueness checking for instrument descriptors
 | 
			
		||||
on top of other MeterProvider it wraps.
 | 
			
		||||
 | 
			
		||||
This package is currently in a pre-GA phase. Backwards incompatible changes
 | 
			
		||||
may be introduced in subsequent minor version releases as we work to track the
 | 
			
		||||
evolving OpenTelemetry specification and user feedback.
 | 
			
		||||
*/
 | 
			
		||||
package registry // import "go.opentelemetry.io/otel/internal/metric/registry"
 | 
			
		||||
							
								
								
									
										139
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/registry/registry.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								vendor/go.opentelemetry.io/otel/internal/metric/registry/registry.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,139 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package registry // import "go.opentelemetry.io/otel/internal/metric/registry"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// UniqueInstrumentMeterImpl implements the metric.MeterImpl interface, adding
 | 
			
		||||
// uniqueness checking for instrument descriptors.
 | 
			
		||||
type UniqueInstrumentMeterImpl struct {
 | 
			
		||||
	lock  sync.Mutex
 | 
			
		||||
	impl  sdkapi.MeterImpl
 | 
			
		||||
	state map[string]sdkapi.InstrumentImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ sdkapi.MeterImpl = (*UniqueInstrumentMeterImpl)(nil)
 | 
			
		||||
 | 
			
		||||
// ErrMetricKindMismatch is the standard error for mismatched metric
 | 
			
		||||
// instrument definitions.
 | 
			
		||||
var ErrMetricKindMismatch = fmt.Errorf(
 | 
			
		||||
	"a metric was already registered by this name with another kind or number type")
 | 
			
		||||
 | 
			
		||||
// NewUniqueInstrumentMeterImpl returns a wrapped metric.MeterImpl
 | 
			
		||||
// with the addition of instrument name uniqueness checking.
 | 
			
		||||
func NewUniqueInstrumentMeterImpl(impl sdkapi.MeterImpl) *UniqueInstrumentMeterImpl {
 | 
			
		||||
	return &UniqueInstrumentMeterImpl{
 | 
			
		||||
		impl:  impl,
 | 
			
		||||
		state: map[string]sdkapi.InstrumentImpl{},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MeterImpl gives the caller access to the underlying MeterImpl
 | 
			
		||||
// used by this UniqueInstrumentMeterImpl.
 | 
			
		||||
func (u *UniqueInstrumentMeterImpl) MeterImpl() sdkapi.MeterImpl {
 | 
			
		||||
	return u.impl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RecordBatch implements sdkapi.MeterImpl.
 | 
			
		||||
func (u *UniqueInstrumentMeterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, ms ...sdkapi.Measurement) {
 | 
			
		||||
	u.impl.RecordBatch(ctx, labels, ms...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewMetricKindMismatchError formats an error that describes a
 | 
			
		||||
// mismatched metric instrument definition.
 | 
			
		||||
func NewMetricKindMismatchError(desc sdkapi.Descriptor) error {
 | 
			
		||||
	return fmt.Errorf("metric %s registered as %s %s: %w",
 | 
			
		||||
		desc.Name(),
 | 
			
		||||
		desc.NumberKind(),
 | 
			
		||||
		desc.InstrumentKind(),
 | 
			
		||||
		ErrMetricKindMismatch)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Compatible determines whether two sdkapi.Descriptors are considered
 | 
			
		||||
// the same for the purpose of uniqueness checking.
 | 
			
		||||
func Compatible(candidate, existing sdkapi.Descriptor) bool {
 | 
			
		||||
	return candidate.InstrumentKind() == existing.InstrumentKind() &&
 | 
			
		||||
		candidate.NumberKind() == existing.NumberKind()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// checkUniqueness returns an ErrMetricKindMismatch error if there is
 | 
			
		||||
// a conflict between a descriptor that was already registered and the
 | 
			
		||||
// `descriptor` argument.  If there is an existing compatible
 | 
			
		||||
// registration, this returns the already-registered instrument.  If
 | 
			
		||||
// there is no conflict and no prior registration, returns (nil, nil).
 | 
			
		||||
func (u *UniqueInstrumentMeterImpl) checkUniqueness(descriptor sdkapi.Descriptor) (sdkapi.InstrumentImpl, error) {
 | 
			
		||||
	impl, ok := u.state[descriptor.Name()]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !Compatible(descriptor, impl.Descriptor()) {
 | 
			
		||||
		return nil, NewMetricKindMismatchError(impl.Descriptor())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return impl, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSyncInstrument implements sdkapi.MeterImpl.
 | 
			
		||||
func (u *UniqueInstrumentMeterImpl) NewSyncInstrument(descriptor sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
 | 
			
		||||
	u.lock.Lock()
 | 
			
		||||
	defer u.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	impl, err := u.checkUniqueness(descriptor)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	} else if impl != nil {
 | 
			
		||||
		return impl.(sdkapi.SyncImpl), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	syncInst, err := u.impl.NewSyncInstrument(descriptor)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	u.state[descriptor.Name()] = syncInst
 | 
			
		||||
	return syncInst, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewAsyncInstrument implements sdkapi.MeterImpl.
 | 
			
		||||
func (u *UniqueInstrumentMeterImpl) NewAsyncInstrument(
 | 
			
		||||
	descriptor sdkapi.Descriptor,
 | 
			
		||||
	runner sdkapi.AsyncRunner,
 | 
			
		||||
) (sdkapi.AsyncImpl, error) {
 | 
			
		||||
	u.lock.Lock()
 | 
			
		||||
	defer u.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	impl, err := u.checkUniqueness(descriptor)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	} else if impl != nil {
 | 
			
		||||
		return impl.(sdkapi.AsyncImpl), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	asyncInst, err := u.impl.NewAsyncInstrument(descriptor, runner)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	u.state[descriptor.Name()] = asyncInst
 | 
			
		||||
	return asyncInst, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								vendor/go.opentelemetry.io/otel/internal/rawhelpers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								vendor/go.opentelemetry.io/otel/internal/rawhelpers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package internal // import "go.opentelemetry.io/otel/internal"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"math"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func BoolToRaw(b bool) uint64 {
 | 
			
		||||
	if b {
 | 
			
		||||
		return 1
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RawToBool(r uint64) bool {
 | 
			
		||||
	return r != 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Int64ToRaw(i int64) uint64 {
 | 
			
		||||
	return uint64(i)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RawToInt64(r uint64) int64 {
 | 
			
		||||
	return int64(r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Float64ToRaw(f float64) uint64 {
 | 
			
		||||
	return math.Float64bits(f)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RawToFloat64(r uint64) float64 {
 | 
			
		||||
	return math.Float64frombits(r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RawPtrToFloat64Ptr(r *uint64) *float64 {
 | 
			
		||||
	return (*float64)(unsafe.Pointer(r))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RawPtrToInt64Ptr(r *uint64) *int64 {
 | 
			
		||||
	return (*int64)(unsafe.Pointer(r))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										201
									
								
								vendor/go.opentelemetry.io/otel/metric/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								vendor/go.opentelemetry.io/otel/metric/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
							
								
								
									
										124
									
								
								vendor/go.opentelemetry.io/otel/metric/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								vendor/go.opentelemetry.io/otel/metric/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,124 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package metric // import "go.opentelemetry.io/otel/metric"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/unit"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// InstrumentConfig contains options for metric instrument descriptors.
 | 
			
		||||
type InstrumentConfig struct {
 | 
			
		||||
	description string
 | 
			
		||||
	unit        unit.Unit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Description describes the instrument in human-readable terms.
 | 
			
		||||
func (cfg InstrumentConfig) Description() string {
 | 
			
		||||
	return cfg.description
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unit describes the measurement unit for a instrument.
 | 
			
		||||
func (cfg InstrumentConfig) Unit() unit.Unit {
 | 
			
		||||
	return cfg.unit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentOption is an interface for applying metric instrument options.
 | 
			
		||||
type InstrumentOption interface {
 | 
			
		||||
	// ApplyMeter is used to set a InstrumentOption value of a
 | 
			
		||||
	// InstrumentConfig.
 | 
			
		||||
	applyInstrument(*InstrumentConfig)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInstrumentConfig creates a new InstrumentConfig
 | 
			
		||||
// and applies all the given options.
 | 
			
		||||
func NewInstrumentConfig(opts ...InstrumentOption) InstrumentConfig {
 | 
			
		||||
	var config InstrumentConfig
 | 
			
		||||
	for _, o := range opts {
 | 
			
		||||
		o.applyInstrument(&config)
 | 
			
		||||
	}
 | 
			
		||||
	return config
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type instrumentOptionFunc func(*InstrumentConfig)
 | 
			
		||||
 | 
			
		||||
func (fn instrumentOptionFunc) applyInstrument(cfg *InstrumentConfig) {
 | 
			
		||||
	fn(cfg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithDescription applies provided description.
 | 
			
		||||
func WithDescription(desc string) InstrumentOption {
 | 
			
		||||
	return instrumentOptionFunc(func(cfg *InstrumentConfig) {
 | 
			
		||||
		cfg.description = desc
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithUnit applies provided unit.
 | 
			
		||||
func WithUnit(unit unit.Unit) InstrumentOption {
 | 
			
		||||
	return instrumentOptionFunc(func(cfg *InstrumentConfig) {
 | 
			
		||||
		cfg.unit = unit
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MeterConfig contains options for Meters.
 | 
			
		||||
type MeterConfig struct {
 | 
			
		||||
	instrumentationVersion string
 | 
			
		||||
	schemaURL              string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentationVersion is the version of the library providing instrumentation.
 | 
			
		||||
func (cfg MeterConfig) InstrumentationVersion() string {
 | 
			
		||||
	return cfg.instrumentationVersion
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SchemaURL is the schema_url of the library providing instrumentation.
 | 
			
		||||
func (cfg MeterConfig) SchemaURL() string {
 | 
			
		||||
	return cfg.schemaURL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MeterOption is an interface for applying Meter options.
 | 
			
		||||
type MeterOption interface {
 | 
			
		||||
	// ApplyMeter is used to set a MeterOption value of a MeterConfig.
 | 
			
		||||
	applyMeter(*MeterConfig)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewMeterConfig creates a new MeterConfig and applies
 | 
			
		||||
// all the given options.
 | 
			
		||||
func NewMeterConfig(opts ...MeterOption) MeterConfig {
 | 
			
		||||
	var config MeterConfig
 | 
			
		||||
	for _, o := range opts {
 | 
			
		||||
		o.applyMeter(&config)
 | 
			
		||||
	}
 | 
			
		||||
	return config
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type meterOptionFunc func(*MeterConfig)
 | 
			
		||||
 | 
			
		||||
func (fn meterOptionFunc) applyMeter(cfg *MeterConfig) {
 | 
			
		||||
	fn(cfg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithInstrumentationVersion sets the instrumentation version.
 | 
			
		||||
func WithInstrumentationVersion(version string) MeterOption {
 | 
			
		||||
	return meterOptionFunc(func(config *MeterConfig) {
 | 
			
		||||
		config.instrumentationVersion = version
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithSchemaURL sets the schema URL.
 | 
			
		||||
func WithSchemaURL(schemaURL string) MeterOption {
 | 
			
		||||
	return meterOptionFunc(func(config *MeterConfig) {
 | 
			
		||||
		config.schemaURL = schemaURL
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										67
									
								
								vendor/go.opentelemetry.io/otel/metric/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								vendor/go.opentelemetry.io/otel/metric/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Package metric provides an implementation of the metrics part of the
 | 
			
		||||
OpenTelemetry API.
 | 
			
		||||
 | 
			
		||||
This package is currently in a pre-GA phase. Backwards incompatible changes
 | 
			
		||||
may be introduced in subsequent minor version releases as we work to track the
 | 
			
		||||
evolving OpenTelemetry specification and user feedback.
 | 
			
		||||
 | 
			
		||||
Measurements can be made about an operation being performed or the state of a
 | 
			
		||||
system in general. These measurements can be crucial to the reliable operation
 | 
			
		||||
of code and provide valuable insights about the inner workings of a system.
 | 
			
		||||
 | 
			
		||||
Measurements are made using instruments provided by this package. The type of
 | 
			
		||||
instrument used will depend on the type of measurement being made and of what
 | 
			
		||||
part of a system is being measured.
 | 
			
		||||
 | 
			
		||||
Instruments are categorized as Synchronous or Asynchronous and independently
 | 
			
		||||
as Adding or Grouping. Synchronous instruments are called by the user with a
 | 
			
		||||
Context. Asynchronous instruments are called by the SDK during collection.
 | 
			
		||||
Adding instruments are semantically intended for capturing a sum. Grouping
 | 
			
		||||
instruments are intended for capturing a distribution.
 | 
			
		||||
 | 
			
		||||
Adding instruments may be monotonic, in which case they are non-decreasing
 | 
			
		||||
and naturally define a rate.
 | 
			
		||||
 | 
			
		||||
The synchronous instrument names are:
 | 
			
		||||
 | 
			
		||||
  Counter:           adding, monotonic
 | 
			
		||||
  UpDownCounter:     adding
 | 
			
		||||
  Histogram:         grouping
 | 
			
		||||
 | 
			
		||||
and the asynchronous instruments are:
 | 
			
		||||
 | 
			
		||||
  CounterObserver:       adding, monotonic
 | 
			
		||||
  UpDownCounterObserver: adding
 | 
			
		||||
  GaugeObserver:         grouping
 | 
			
		||||
 | 
			
		||||
All instruments are provided with support for either float64 or int64 input
 | 
			
		||||
values.
 | 
			
		||||
 | 
			
		||||
An instrument is created using a Meter. Additionally, a Meter is used to
 | 
			
		||||
record batches of synchronous measurements or asynchronous observations. A
 | 
			
		||||
Meter is obtained using a MeterProvider. A Meter, like a Tracer, is unique to
 | 
			
		||||
the instrumentation it instruments and must be named and versioned when
 | 
			
		||||
created with a MeterProvider with the name and version of the instrumentation
 | 
			
		||||
library.
 | 
			
		||||
 | 
			
		||||
Instrumentation should be designed to accept a MeterProvider from which it can
 | 
			
		||||
create its own unique Meter. Alternatively, the registered global
 | 
			
		||||
MeterProvider from the go.opentelemetry.io/otel package can be used as a
 | 
			
		||||
default.
 | 
			
		||||
*/
 | 
			
		||||
package metric // import "go.opentelemetry.io/otel/metric"
 | 
			
		||||
							
								
								
									
										49
									
								
								vendor/go.opentelemetry.io/otel/metric/global/metric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								vendor/go.opentelemetry.io/otel/metric/global/metric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package global // import "go.opentelemetry.io/otel/metric/global"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"go.opentelemetry.io/otel/internal/metric/global"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Meter creates an implementation of the Meter interface from the global
 | 
			
		||||
// MeterProvider. The instrumentationName must be the name of the library
 | 
			
		||||
// providing instrumentation. This name may be the same as the instrumented
 | 
			
		||||
// code only if that code provides built-in instrumentation. If the
 | 
			
		||||
// instrumentationName is empty, then a implementation defined default name
 | 
			
		||||
// will be used instead.
 | 
			
		||||
//
 | 
			
		||||
// This is short for MeterProvider().Meter(name)
 | 
			
		||||
func Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter {
 | 
			
		||||
	return GetMeterProvider().Meter(instrumentationName, opts...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetMeterProvider returns the registered global meter provider.  If
 | 
			
		||||
// none is registered then a default meter provider is returned that
 | 
			
		||||
// forwards the Meter interface to the first registered Meter.
 | 
			
		||||
//
 | 
			
		||||
// Use the meter provider to create a named meter. E.g.
 | 
			
		||||
//     meter := global.MeterProvider().Meter("example.com/foo")
 | 
			
		||||
// or
 | 
			
		||||
//     meter := global.Meter("example.com/foo")
 | 
			
		||||
func GetMeterProvider() metric.MeterProvider {
 | 
			
		||||
	return global.MeterProvider()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetMeterProvider registers `mp` as the global meter provider.
 | 
			
		||||
func SetMeterProvider(mp metric.MeterProvider) {
 | 
			
		||||
	global.SetMeterProvider(mp)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										538
									
								
								vendor/go.opentelemetry.io/otel/metric/metric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										538
									
								
								vendor/go.opentelemetry.io/otel/metric/metric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,538 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package metric // import "go.opentelemetry.io/otel/metric"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// MeterProvider supports named Meter instances.
 | 
			
		||||
type MeterProvider interface {
 | 
			
		||||
	// Meter creates an implementation of the Meter interface.
 | 
			
		||||
	// The instrumentationName must be the name of the library providing
 | 
			
		||||
	// instrumentation. This name may be the same as the instrumented code
 | 
			
		||||
	// only if that code provides built-in instrumentation. If the
 | 
			
		||||
	// instrumentationName is empty, then a implementation defined default
 | 
			
		||||
	// name will be used instead.
 | 
			
		||||
	Meter(instrumentationName string, opts ...MeterOption) Meter
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Meter is the creator of metric instruments.
 | 
			
		||||
//
 | 
			
		||||
// An uninitialized Meter is a no-op implementation.
 | 
			
		||||
type Meter struct {
 | 
			
		||||
	impl sdkapi.MeterImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WrapMeterImpl constructs a `Meter` implementation from a
 | 
			
		||||
// `MeterImpl` implementation.
 | 
			
		||||
func WrapMeterImpl(impl sdkapi.MeterImpl) Meter {
 | 
			
		||||
	return Meter{
 | 
			
		||||
		impl: impl,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Measurement is used for reporting a synchronous batch of metric
 | 
			
		||||
// values. Instances of this type should be created by synchronous
 | 
			
		||||
// instruments (e.g., Int64Counter.Measurement()).
 | 
			
		||||
//
 | 
			
		||||
// Note: This is an alias because it is a first-class member of the
 | 
			
		||||
// API but is also part of the lower-level sdkapi interface.
 | 
			
		||||
type Measurement = sdkapi.Measurement
 | 
			
		||||
 | 
			
		||||
// Observation is used for reporting an asynchronous  batch of metric
 | 
			
		||||
// values. Instances of this type should be created by asynchronous
 | 
			
		||||
// instruments (e.g., Int64GaugeObserver.Observation()).
 | 
			
		||||
//
 | 
			
		||||
// Note: This is an alias because it is a first-class member of the
 | 
			
		||||
// API but is also part of the lower-level sdkapi interface.
 | 
			
		||||
type Observation = sdkapi.Observation
 | 
			
		||||
 | 
			
		||||
// RecordBatch atomically records a batch of measurements.
 | 
			
		||||
func (m Meter) RecordBatch(ctx context.Context, ls []attribute.KeyValue, ms ...Measurement) {
 | 
			
		||||
	if m.impl == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	m.impl.RecordBatch(ctx, ls, ms...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewBatchObserver creates a new BatchObserver that supports
 | 
			
		||||
// making batches of observations for multiple instruments.
 | 
			
		||||
func (m Meter) NewBatchObserver(callback BatchObserverFunc) BatchObserver {
 | 
			
		||||
	return BatchObserver{
 | 
			
		||||
		meter:  m,
 | 
			
		||||
		runner: newBatchAsyncRunner(callback),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64Counter creates a new integer Counter instrument with the
 | 
			
		||||
// given name, customized with options.  May return an error if the
 | 
			
		||||
// name is invalid (e.g., empty) or improperly registered (e.g.,
 | 
			
		||||
// duplicate registration).
 | 
			
		||||
func (m Meter) NewInt64Counter(name string, options ...InstrumentOption) (Int64Counter, error) {
 | 
			
		||||
	return wrapInt64CounterInstrument(
 | 
			
		||||
		m.newSync(name, sdkapi.CounterInstrumentKind, number.Int64Kind, options))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64Counter creates a new floating point Counter with the
 | 
			
		||||
// given name, customized with options.  May return an error if the
 | 
			
		||||
// name is invalid (e.g., empty) or improperly registered (e.g.,
 | 
			
		||||
// duplicate registration).
 | 
			
		||||
func (m Meter) NewFloat64Counter(name string, options ...InstrumentOption) (Float64Counter, error) {
 | 
			
		||||
	return wrapFloat64CounterInstrument(
 | 
			
		||||
		m.newSync(name, sdkapi.CounterInstrumentKind, number.Float64Kind, options))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64UpDownCounter creates a new integer UpDownCounter instrument with the
 | 
			
		||||
// given name, customized with options.  May return an error if the
 | 
			
		||||
// name is invalid (e.g., empty) or improperly registered (e.g.,
 | 
			
		||||
// duplicate registration).
 | 
			
		||||
func (m Meter) NewInt64UpDownCounter(name string, options ...InstrumentOption) (Int64UpDownCounter, error) {
 | 
			
		||||
	return wrapInt64UpDownCounterInstrument(
 | 
			
		||||
		m.newSync(name, sdkapi.UpDownCounterInstrumentKind, number.Int64Kind, options))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64UpDownCounter creates a new floating point UpDownCounter with the
 | 
			
		||||
// given name, customized with options.  May return an error if the
 | 
			
		||||
// name is invalid (e.g., empty) or improperly registered (e.g.,
 | 
			
		||||
// duplicate registration).
 | 
			
		||||
func (m Meter) NewFloat64UpDownCounter(name string, options ...InstrumentOption) (Float64UpDownCounter, error) {
 | 
			
		||||
	return wrapFloat64UpDownCounterInstrument(
 | 
			
		||||
		m.newSync(name, sdkapi.UpDownCounterInstrumentKind, number.Float64Kind, options))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64Histogram creates a new integer Histogram instrument with the
 | 
			
		||||
// given name, customized with options.  May return an error if the
 | 
			
		||||
// name is invalid (e.g., empty) or improperly registered (e.g.,
 | 
			
		||||
// duplicate registration).
 | 
			
		||||
func (m Meter) NewInt64Histogram(name string, opts ...InstrumentOption) (Int64Histogram, error) {
 | 
			
		||||
	return wrapInt64HistogramInstrument(
 | 
			
		||||
		m.newSync(name, sdkapi.HistogramInstrumentKind, number.Int64Kind, opts))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64Histogram creates a new floating point Histogram with the
 | 
			
		||||
// given name, customized with options.  May return an error if the
 | 
			
		||||
// name is invalid (e.g., empty) or improperly registered (e.g.,
 | 
			
		||||
// duplicate registration).
 | 
			
		||||
func (m Meter) NewFloat64Histogram(name string, opts ...InstrumentOption) (Float64Histogram, error) {
 | 
			
		||||
	return wrapFloat64HistogramInstrument(
 | 
			
		||||
		m.newSync(name, sdkapi.HistogramInstrumentKind, number.Float64Kind, opts))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64GaugeObserver creates a new integer GaugeObserver instrument
 | 
			
		||||
// with the given name, running a given callback, and customized with
 | 
			
		||||
// options.  May return an error if the name is invalid (e.g., empty)
 | 
			
		||||
// or improperly registered (e.g., duplicate registration).
 | 
			
		||||
func (m Meter) NewInt64GaugeObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64GaugeObserver, error) {
 | 
			
		||||
	if callback == nil {
 | 
			
		||||
		return wrapInt64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
 | 
			
		||||
	}
 | 
			
		||||
	return wrapInt64GaugeObserverInstrument(
 | 
			
		||||
		m.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Int64Kind, opts,
 | 
			
		||||
			newInt64AsyncRunner(callback)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64GaugeObserver creates a new floating point GaugeObserver with
 | 
			
		||||
// the given name, running a given callback, and customized with
 | 
			
		||||
// options.  May return an error if the name is invalid (e.g., empty)
 | 
			
		||||
// or improperly registered (e.g., duplicate registration).
 | 
			
		||||
func (m Meter) NewFloat64GaugeObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64GaugeObserver, error) {
 | 
			
		||||
	if callback == nil {
 | 
			
		||||
		return wrapFloat64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
 | 
			
		||||
	}
 | 
			
		||||
	return wrapFloat64GaugeObserverInstrument(
 | 
			
		||||
		m.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Float64Kind, opts,
 | 
			
		||||
			newFloat64AsyncRunner(callback)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64CounterObserver creates a new integer CounterObserver instrument
 | 
			
		||||
// with the given name, running a given callback, and customized with
 | 
			
		||||
// options.  May return an error if the name is invalid (e.g., empty)
 | 
			
		||||
// or improperly registered (e.g., duplicate registration).
 | 
			
		||||
func (m Meter) NewInt64CounterObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64CounterObserver, error) {
 | 
			
		||||
	if callback == nil {
 | 
			
		||||
		return wrapInt64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
 | 
			
		||||
	}
 | 
			
		||||
	return wrapInt64CounterObserverInstrument(
 | 
			
		||||
		m.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Int64Kind, opts,
 | 
			
		||||
			newInt64AsyncRunner(callback)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64CounterObserver creates a new floating point CounterObserver with
 | 
			
		||||
// the given name, running a given callback, and customized with
 | 
			
		||||
// options.  May return an error if the name is invalid (e.g., empty)
 | 
			
		||||
// or improperly registered (e.g., duplicate registration).
 | 
			
		||||
func (m Meter) NewFloat64CounterObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64CounterObserver, error) {
 | 
			
		||||
	if callback == nil {
 | 
			
		||||
		return wrapFloat64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
 | 
			
		||||
	}
 | 
			
		||||
	return wrapFloat64CounterObserverInstrument(
 | 
			
		||||
		m.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Float64Kind, opts,
 | 
			
		||||
			newFloat64AsyncRunner(callback)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64UpDownCounterObserver creates a new integer UpDownCounterObserver instrument
 | 
			
		||||
// with the given name, running a given callback, and customized with
 | 
			
		||||
// options.  May return an error if the name is invalid (e.g., empty)
 | 
			
		||||
// or improperly registered (e.g., duplicate registration).
 | 
			
		||||
func (m Meter) NewInt64UpDownCounterObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64UpDownCounterObserver, error) {
 | 
			
		||||
	if callback == nil {
 | 
			
		||||
		return wrapInt64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
 | 
			
		||||
	}
 | 
			
		||||
	return wrapInt64UpDownCounterObserverInstrument(
 | 
			
		||||
		m.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Int64Kind, opts,
 | 
			
		||||
			newInt64AsyncRunner(callback)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64UpDownCounterObserver creates a new floating point UpDownCounterObserver with
 | 
			
		||||
// the given name, running a given callback, and customized with
 | 
			
		||||
// options.  May return an error if the name is invalid (e.g., empty)
 | 
			
		||||
// or improperly registered (e.g., duplicate registration).
 | 
			
		||||
func (m Meter) NewFloat64UpDownCounterObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64UpDownCounterObserver, error) {
 | 
			
		||||
	if callback == nil {
 | 
			
		||||
		return wrapFloat64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
 | 
			
		||||
	}
 | 
			
		||||
	return wrapFloat64UpDownCounterObserverInstrument(
 | 
			
		||||
		m.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Float64Kind, opts,
 | 
			
		||||
			newFloat64AsyncRunner(callback)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64GaugeObserver creates a new integer GaugeObserver instrument
 | 
			
		||||
// with the given name, running in a batch callback, and customized with
 | 
			
		||||
// options.  May return an error if the name is invalid (e.g., empty)
 | 
			
		||||
// or improperly registered (e.g., duplicate registration).
 | 
			
		||||
func (b BatchObserver) NewInt64GaugeObserver(name string, opts ...InstrumentOption) (Int64GaugeObserver, error) {
 | 
			
		||||
	if b.runner == nil {
 | 
			
		||||
		return wrapInt64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
 | 
			
		||||
	}
 | 
			
		||||
	return wrapInt64GaugeObserverInstrument(
 | 
			
		||||
		b.meter.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Int64Kind, opts, b.runner))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64GaugeObserver creates a new floating point GaugeObserver with
 | 
			
		||||
// the given name, running in a batch callback, and customized with
 | 
			
		||||
// options.  May return an error if the name is invalid (e.g., empty)
 | 
			
		||||
// or improperly registered (e.g., duplicate registration).
 | 
			
		||||
func (b BatchObserver) NewFloat64GaugeObserver(name string, opts ...InstrumentOption) (Float64GaugeObserver, error) {
 | 
			
		||||
	if b.runner == nil {
 | 
			
		||||
		return wrapFloat64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
 | 
			
		||||
	}
 | 
			
		||||
	return wrapFloat64GaugeObserverInstrument(
 | 
			
		||||
		b.meter.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Float64Kind, opts,
 | 
			
		||||
			b.runner))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64CounterObserver creates a new integer CounterObserver instrument
 | 
			
		||||
// with the given name, running in a batch callback, and customized with
 | 
			
		||||
// options.  May return an error if the name is invalid (e.g., empty)
 | 
			
		||||
// or improperly registered (e.g., duplicate registration).
 | 
			
		||||
func (b BatchObserver) NewInt64CounterObserver(name string, opts ...InstrumentOption) (Int64CounterObserver, error) {
 | 
			
		||||
	if b.runner == nil {
 | 
			
		||||
		return wrapInt64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
 | 
			
		||||
	}
 | 
			
		||||
	return wrapInt64CounterObserverInstrument(
 | 
			
		||||
		b.meter.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Int64Kind, opts, b.runner))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64CounterObserver creates a new floating point CounterObserver with
 | 
			
		||||
// the given name, running in a batch callback, and customized with
 | 
			
		||||
// options.  May return an error if the name is invalid (e.g., empty)
 | 
			
		||||
// or improperly registered (e.g., duplicate registration).
 | 
			
		||||
func (b BatchObserver) NewFloat64CounterObserver(name string, opts ...InstrumentOption) (Float64CounterObserver, error) {
 | 
			
		||||
	if b.runner == nil {
 | 
			
		||||
		return wrapFloat64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
 | 
			
		||||
	}
 | 
			
		||||
	return wrapFloat64CounterObserverInstrument(
 | 
			
		||||
		b.meter.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Float64Kind, opts,
 | 
			
		||||
			b.runner))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64UpDownCounterObserver creates a new integer UpDownCounterObserver instrument
 | 
			
		||||
// with the given name, running in a batch callback, and customized with
 | 
			
		||||
// options.  May return an error if the name is invalid (e.g., empty)
 | 
			
		||||
// or improperly registered (e.g., duplicate registration).
 | 
			
		||||
func (b BatchObserver) NewInt64UpDownCounterObserver(name string, opts ...InstrumentOption) (Int64UpDownCounterObserver, error) {
 | 
			
		||||
	if b.runner == nil {
 | 
			
		||||
		return wrapInt64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
 | 
			
		||||
	}
 | 
			
		||||
	return wrapInt64UpDownCounterObserverInstrument(
 | 
			
		||||
		b.meter.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Int64Kind, opts, b.runner))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64UpDownCounterObserver creates a new floating point UpDownCounterObserver with
 | 
			
		||||
// the given name, running in a batch callback, and customized with
 | 
			
		||||
// options.  May return an error if the name is invalid (e.g., empty)
 | 
			
		||||
// or improperly registered (e.g., duplicate registration).
 | 
			
		||||
func (b BatchObserver) NewFloat64UpDownCounterObserver(name string, opts ...InstrumentOption) (Float64UpDownCounterObserver, error) {
 | 
			
		||||
	if b.runner == nil {
 | 
			
		||||
		return wrapFloat64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
 | 
			
		||||
	}
 | 
			
		||||
	return wrapFloat64UpDownCounterObserverInstrument(
 | 
			
		||||
		b.meter.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Float64Kind, opts,
 | 
			
		||||
			b.runner))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MeterImpl returns the underlying MeterImpl of this Meter.
 | 
			
		||||
func (m Meter) MeterImpl() sdkapi.MeterImpl {
 | 
			
		||||
	return m.impl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// newAsync constructs one new asynchronous instrument.
 | 
			
		||||
func (m Meter) newAsync(
 | 
			
		||||
	name string,
 | 
			
		||||
	mkind sdkapi.InstrumentKind,
 | 
			
		||||
	nkind number.Kind,
 | 
			
		||||
	opts []InstrumentOption,
 | 
			
		||||
	runner sdkapi.AsyncRunner,
 | 
			
		||||
) (
 | 
			
		||||
	sdkapi.AsyncImpl,
 | 
			
		||||
	error,
 | 
			
		||||
) {
 | 
			
		||||
	if m.impl == nil {
 | 
			
		||||
		return sdkapi.NewNoopAsyncInstrument(), nil
 | 
			
		||||
	}
 | 
			
		||||
	cfg := NewInstrumentConfig(opts...)
 | 
			
		||||
	desc := sdkapi.NewDescriptor(name, mkind, nkind, cfg.description, cfg.unit)
 | 
			
		||||
	return m.impl.NewAsyncInstrument(desc, runner)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// newSync constructs one new synchronous instrument.
 | 
			
		||||
func (m Meter) newSync(
 | 
			
		||||
	name string,
 | 
			
		||||
	metricKind sdkapi.InstrumentKind,
 | 
			
		||||
	numberKind number.Kind,
 | 
			
		||||
	opts []InstrumentOption,
 | 
			
		||||
) (
 | 
			
		||||
	sdkapi.SyncImpl,
 | 
			
		||||
	error,
 | 
			
		||||
) {
 | 
			
		||||
	if m.impl == nil {
 | 
			
		||||
		return sdkapi.NewNoopSyncInstrument(), nil
 | 
			
		||||
	}
 | 
			
		||||
	cfg := NewInstrumentConfig(opts...)
 | 
			
		||||
	desc := sdkapi.NewDescriptor(name, metricKind, numberKind, cfg.description, cfg.unit)
 | 
			
		||||
	return m.impl.NewSyncInstrument(desc)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MeterMust is a wrapper for Meter interfaces that panics when any
 | 
			
		||||
// instrument constructor encounters an error.
 | 
			
		||||
type MeterMust struct {
 | 
			
		||||
	meter Meter
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BatchObserverMust is a wrapper for BatchObserver that panics when
 | 
			
		||||
// any instrument constructor encounters an error.
 | 
			
		||||
type BatchObserverMust struct {
 | 
			
		||||
	batch BatchObserver
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Must constructs a MeterMust implementation from a Meter, allowing
 | 
			
		||||
// the application to panic when any instrument constructor yields an
 | 
			
		||||
// error.
 | 
			
		||||
func Must(meter Meter) MeterMust {
 | 
			
		||||
	return MeterMust{meter: meter}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64Counter calls `Meter.NewInt64Counter` and returns the
 | 
			
		||||
// instrument, panicking if it encounters an error.
 | 
			
		||||
func (mm MeterMust) NewInt64Counter(name string, cos ...InstrumentOption) Int64Counter {
 | 
			
		||||
	if inst, err := mm.meter.NewInt64Counter(name, cos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64Counter calls `Meter.NewFloat64Counter` and returns the
 | 
			
		||||
// instrument, panicking if it encounters an error.
 | 
			
		||||
func (mm MeterMust) NewFloat64Counter(name string, cos ...InstrumentOption) Float64Counter {
 | 
			
		||||
	if inst, err := mm.meter.NewFloat64Counter(name, cos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64UpDownCounter calls `Meter.NewInt64UpDownCounter` and returns the
 | 
			
		||||
// instrument, panicking if it encounters an error.
 | 
			
		||||
func (mm MeterMust) NewInt64UpDownCounter(name string, cos ...InstrumentOption) Int64UpDownCounter {
 | 
			
		||||
	if inst, err := mm.meter.NewInt64UpDownCounter(name, cos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64UpDownCounter calls `Meter.NewFloat64UpDownCounter` and returns the
 | 
			
		||||
// instrument, panicking if it encounters an error.
 | 
			
		||||
func (mm MeterMust) NewFloat64UpDownCounter(name string, cos ...InstrumentOption) Float64UpDownCounter {
 | 
			
		||||
	if inst, err := mm.meter.NewFloat64UpDownCounter(name, cos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64Histogram calls `Meter.NewInt64Histogram` and returns the
 | 
			
		||||
// instrument, panicking if it encounters an error.
 | 
			
		||||
func (mm MeterMust) NewInt64Histogram(name string, mos ...InstrumentOption) Int64Histogram {
 | 
			
		||||
	if inst, err := mm.meter.NewInt64Histogram(name, mos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64Histogram calls `Meter.NewFloat64Histogram` and returns the
 | 
			
		||||
// instrument, panicking if it encounters an error.
 | 
			
		||||
func (mm MeterMust) NewFloat64Histogram(name string, mos ...InstrumentOption) Float64Histogram {
 | 
			
		||||
	if inst, err := mm.meter.NewFloat64Histogram(name, mos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64GaugeObserver calls `Meter.NewInt64GaugeObserver` and
 | 
			
		||||
// returns the instrument, panicking if it encounters an error.
 | 
			
		||||
func (mm MeterMust) NewInt64GaugeObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64GaugeObserver {
 | 
			
		||||
	if inst, err := mm.meter.NewInt64GaugeObserver(name, callback, oos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64GaugeObserver calls `Meter.NewFloat64GaugeObserver` and
 | 
			
		||||
// returns the instrument, panicking if it encounters an error.
 | 
			
		||||
func (mm MeterMust) NewFloat64GaugeObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64GaugeObserver {
 | 
			
		||||
	if inst, err := mm.meter.NewFloat64GaugeObserver(name, callback, oos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64CounterObserver calls `Meter.NewInt64CounterObserver` and
 | 
			
		||||
// returns the instrument, panicking if it encounters an error.
 | 
			
		||||
func (mm MeterMust) NewInt64CounterObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64CounterObserver {
 | 
			
		||||
	if inst, err := mm.meter.NewInt64CounterObserver(name, callback, oos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64CounterObserver calls `Meter.NewFloat64CounterObserver` and
 | 
			
		||||
// returns the instrument, panicking if it encounters an error.
 | 
			
		||||
func (mm MeterMust) NewFloat64CounterObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64CounterObserver {
 | 
			
		||||
	if inst, err := mm.meter.NewFloat64CounterObserver(name, callback, oos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64UpDownCounterObserver calls `Meter.NewInt64UpDownCounterObserver` and
 | 
			
		||||
// returns the instrument, panicking if it encounters an error.
 | 
			
		||||
func (mm MeterMust) NewInt64UpDownCounterObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64UpDownCounterObserver {
 | 
			
		||||
	if inst, err := mm.meter.NewInt64UpDownCounterObserver(name, callback, oos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64UpDownCounterObserver calls `Meter.NewFloat64UpDownCounterObserver` and
 | 
			
		||||
// returns the instrument, panicking if it encounters an error.
 | 
			
		||||
func (mm MeterMust) NewFloat64UpDownCounterObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64UpDownCounterObserver {
 | 
			
		||||
	if inst, err := mm.meter.NewFloat64UpDownCounterObserver(name, callback, oos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewBatchObserver returns a wrapper around BatchObserver that panics
 | 
			
		||||
// when any instrument constructor returns an error.
 | 
			
		||||
func (mm MeterMust) NewBatchObserver(callback BatchObserverFunc) BatchObserverMust {
 | 
			
		||||
	return BatchObserverMust{
 | 
			
		||||
		batch: mm.meter.NewBatchObserver(callback),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64GaugeObserver calls `BatchObserver.NewInt64GaugeObserver` and
 | 
			
		||||
// returns the instrument, panicking if it encounters an error.
 | 
			
		||||
func (bm BatchObserverMust) NewInt64GaugeObserver(name string, oos ...InstrumentOption) Int64GaugeObserver {
 | 
			
		||||
	if inst, err := bm.batch.NewInt64GaugeObserver(name, oos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64GaugeObserver calls `BatchObserver.NewFloat64GaugeObserver` and
 | 
			
		||||
// returns the instrument, panicking if it encounters an error.
 | 
			
		||||
func (bm BatchObserverMust) NewFloat64GaugeObserver(name string, oos ...InstrumentOption) Float64GaugeObserver {
 | 
			
		||||
	if inst, err := bm.batch.NewFloat64GaugeObserver(name, oos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64CounterObserver calls `BatchObserver.NewInt64CounterObserver` and
 | 
			
		||||
// returns the instrument, panicking if it encounters an error.
 | 
			
		||||
func (bm BatchObserverMust) NewInt64CounterObserver(name string, oos ...InstrumentOption) Int64CounterObserver {
 | 
			
		||||
	if inst, err := bm.batch.NewInt64CounterObserver(name, oos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64CounterObserver calls `BatchObserver.NewFloat64CounterObserver` and
 | 
			
		||||
// returns the instrument, panicking if it encounters an error.
 | 
			
		||||
func (bm BatchObserverMust) NewFloat64CounterObserver(name string, oos ...InstrumentOption) Float64CounterObserver {
 | 
			
		||||
	if inst, err := bm.batch.NewFloat64CounterObserver(name, oos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64UpDownCounterObserver calls `BatchObserver.NewInt64UpDownCounterObserver` and
 | 
			
		||||
// returns the instrument, panicking if it encounters an error.
 | 
			
		||||
func (bm BatchObserverMust) NewInt64UpDownCounterObserver(name string, oos ...InstrumentOption) Int64UpDownCounterObserver {
 | 
			
		||||
	if inst, err := bm.batch.NewInt64UpDownCounterObserver(name, oos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64UpDownCounterObserver calls `BatchObserver.NewFloat64UpDownCounterObserver` and
 | 
			
		||||
// returns the instrument, panicking if it encounters an error.
 | 
			
		||||
func (bm BatchObserverMust) NewFloat64UpDownCounterObserver(name string, oos ...InstrumentOption) Float64UpDownCounterObserver {
 | 
			
		||||
	if inst, err := bm.batch.NewFloat64UpDownCounterObserver(name, oos...); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		return inst
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										608
									
								
								vendor/go.opentelemetry.io/otel/metric/metric_instrument.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										608
									
								
								vendor/go.opentelemetry.io/otel/metric/metric_instrument.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,608 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package metric // import "go.opentelemetry.io/otel/metric"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"errors"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ErrSDKReturnedNilImpl is returned when a new `MeterImpl` returns nil.
 | 
			
		||||
var ErrSDKReturnedNilImpl = errors.New("SDK returned a nil implementation")
 | 
			
		||||
 | 
			
		||||
// Int64ObserverFunc is a type of callback that integral
 | 
			
		||||
// observers run.
 | 
			
		||||
type Int64ObserverFunc func(context.Context, Int64ObserverResult)
 | 
			
		||||
 | 
			
		||||
// Float64ObserverFunc is a type of callback that floating point
 | 
			
		||||
// observers run.
 | 
			
		||||
type Float64ObserverFunc func(context.Context, Float64ObserverResult)
 | 
			
		||||
 | 
			
		||||
// BatchObserverFunc is a callback argument for use with any
 | 
			
		||||
// Observer instrument that will be reported as a batch of
 | 
			
		||||
// observations.
 | 
			
		||||
type BatchObserverFunc func(context.Context, BatchObserverResult)
 | 
			
		||||
 | 
			
		||||
// Int64ObserverResult is passed to an observer callback to capture
 | 
			
		||||
// observations for one asynchronous integer metric instrument.
 | 
			
		||||
type Int64ObserverResult struct {
 | 
			
		||||
	instrument sdkapi.AsyncImpl
 | 
			
		||||
	function   func([]attribute.KeyValue, ...Observation)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64ObserverResult is passed to an observer callback to capture
 | 
			
		||||
// observations for one asynchronous floating point metric instrument.
 | 
			
		||||
type Float64ObserverResult struct {
 | 
			
		||||
	instrument sdkapi.AsyncImpl
 | 
			
		||||
	function   func([]attribute.KeyValue, ...Observation)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BatchObserverResult is passed to a batch observer callback to
 | 
			
		||||
// capture observations for multiple asynchronous instruments.
 | 
			
		||||
type BatchObserverResult struct {
 | 
			
		||||
	function func([]attribute.KeyValue, ...Observation)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Observe captures a single integer value from the associated
 | 
			
		||||
// instrument callback, with the given labels.
 | 
			
		||||
func (ir Int64ObserverResult) Observe(value int64, labels ...attribute.KeyValue) {
 | 
			
		||||
	ir.function(labels, sdkapi.NewObservation(ir.instrument, number.NewInt64Number(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Observe captures a single floating point value from the associated
 | 
			
		||||
// instrument callback, with the given labels.
 | 
			
		||||
func (fr Float64ObserverResult) Observe(value float64, labels ...attribute.KeyValue) {
 | 
			
		||||
	fr.function(labels, sdkapi.NewObservation(fr.instrument, number.NewFloat64Number(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Observe captures a multiple observations from the associated batch
 | 
			
		||||
// instrument callback, with the given labels.
 | 
			
		||||
func (br BatchObserverResult) Observe(labels []attribute.KeyValue, obs ...Observation) {
 | 
			
		||||
	br.function(labels, obs...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ sdkapi.AsyncSingleRunner = (*Int64ObserverFunc)(nil)
 | 
			
		||||
var _ sdkapi.AsyncSingleRunner = (*Float64ObserverFunc)(nil)
 | 
			
		||||
var _ sdkapi.AsyncBatchRunner = (*BatchObserverFunc)(nil)
 | 
			
		||||
 | 
			
		||||
// newInt64AsyncRunner returns a single-observer callback for integer Observer instruments.
 | 
			
		||||
func newInt64AsyncRunner(c Int64ObserverFunc) sdkapi.AsyncSingleRunner {
 | 
			
		||||
	return &c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// newFloat64AsyncRunner returns a single-observer callback for floating point Observer instruments.
 | 
			
		||||
func newFloat64AsyncRunner(c Float64ObserverFunc) sdkapi.AsyncSingleRunner {
 | 
			
		||||
	return &c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// newBatchAsyncRunner returns a batch-observer callback use with multiple Observer instruments.
 | 
			
		||||
func newBatchAsyncRunner(c BatchObserverFunc) sdkapi.AsyncBatchRunner {
 | 
			
		||||
	return &c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AnyRunner implements AsyncRunner.
 | 
			
		||||
func (*Int64ObserverFunc) AnyRunner() {}
 | 
			
		||||
 | 
			
		||||
// AnyRunner implements AsyncRunner.
 | 
			
		||||
func (*Float64ObserverFunc) AnyRunner() {}
 | 
			
		||||
 | 
			
		||||
// AnyRunner implements AsyncRunner.
 | 
			
		||||
func (*BatchObserverFunc) AnyRunner() {}
 | 
			
		||||
 | 
			
		||||
// Run implements AsyncSingleRunner.
 | 
			
		||||
func (i *Int64ObserverFunc) Run(ctx context.Context, impl sdkapi.AsyncImpl, function func([]attribute.KeyValue, ...Observation)) {
 | 
			
		||||
	(*i)(ctx, Int64ObserverResult{
 | 
			
		||||
		instrument: impl,
 | 
			
		||||
		function:   function,
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run implements AsyncSingleRunner.
 | 
			
		||||
func (f *Float64ObserverFunc) Run(ctx context.Context, impl sdkapi.AsyncImpl, function func([]attribute.KeyValue, ...Observation)) {
 | 
			
		||||
	(*f)(ctx, Float64ObserverResult{
 | 
			
		||||
		instrument: impl,
 | 
			
		||||
		function:   function,
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run implements AsyncBatchRunner.
 | 
			
		||||
func (b *BatchObserverFunc) Run(ctx context.Context, function func([]attribute.KeyValue, ...Observation)) {
 | 
			
		||||
	(*b)(ctx, BatchObserverResult{
 | 
			
		||||
		function: function,
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// wrapInt64GaugeObserverInstrument converts an AsyncImpl into Int64GaugeObserver.
 | 
			
		||||
func wrapInt64GaugeObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Int64GaugeObserver, error) {
 | 
			
		||||
	common, err := checkNewAsync(asyncInst, err)
 | 
			
		||||
	return Int64GaugeObserver{asyncInstrument: common}, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// wrapFloat64GaugeObserverInstrument converts an AsyncImpl into Float64GaugeObserver.
 | 
			
		||||
func wrapFloat64GaugeObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Float64GaugeObserver, error) {
 | 
			
		||||
	common, err := checkNewAsync(asyncInst, err)
 | 
			
		||||
	return Float64GaugeObserver{asyncInstrument: common}, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// wrapInt64CounterObserverInstrument converts an AsyncImpl into Int64CounterObserver.
 | 
			
		||||
func wrapInt64CounterObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Int64CounterObserver, error) {
 | 
			
		||||
	common, err := checkNewAsync(asyncInst, err)
 | 
			
		||||
	return Int64CounterObserver{asyncInstrument: common}, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// wrapFloat64CounterObserverInstrument converts an AsyncImpl into Float64CounterObserver.
 | 
			
		||||
func wrapFloat64CounterObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Float64CounterObserver, error) {
 | 
			
		||||
	common, err := checkNewAsync(asyncInst, err)
 | 
			
		||||
	return Float64CounterObserver{asyncInstrument: common}, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// wrapInt64UpDownCounterObserverInstrument converts an AsyncImpl into Int64UpDownCounterObserver.
 | 
			
		||||
func wrapInt64UpDownCounterObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Int64UpDownCounterObserver, error) {
 | 
			
		||||
	common, err := checkNewAsync(asyncInst, err)
 | 
			
		||||
	return Int64UpDownCounterObserver{asyncInstrument: common}, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// wrapFloat64UpDownCounterObserverInstrument converts an AsyncImpl into Float64UpDownCounterObserver.
 | 
			
		||||
func wrapFloat64UpDownCounterObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Float64UpDownCounterObserver, error) {
 | 
			
		||||
	common, err := checkNewAsync(asyncInst, err)
 | 
			
		||||
	return Float64UpDownCounterObserver{asyncInstrument: common}, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BatchObserver represents an Observer callback that can report
 | 
			
		||||
// observations for multiple instruments.
 | 
			
		||||
type BatchObserver struct {
 | 
			
		||||
	meter  Meter
 | 
			
		||||
	runner sdkapi.AsyncBatchRunner
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int64GaugeObserver is a metric that captures a set of int64 values at a
 | 
			
		||||
// point in time.
 | 
			
		||||
type Int64GaugeObserver struct {
 | 
			
		||||
	asyncInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64GaugeObserver is a metric that captures a set of float64 values
 | 
			
		||||
// at a point in time.
 | 
			
		||||
type Float64GaugeObserver struct {
 | 
			
		||||
	asyncInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int64CounterObserver is a metric that captures a precomputed sum of
 | 
			
		||||
// int64 values at a point in time.
 | 
			
		||||
type Int64CounterObserver struct {
 | 
			
		||||
	asyncInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64CounterObserver is a metric that captures a precomputed sum of
 | 
			
		||||
// float64 values at a point in time.
 | 
			
		||||
type Float64CounterObserver struct {
 | 
			
		||||
	asyncInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int64UpDownCounterObserver is a metric that captures a precomputed sum of
 | 
			
		||||
// int64 values at a point in time.
 | 
			
		||||
type Int64UpDownCounterObserver struct {
 | 
			
		||||
	asyncInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64UpDownCounterObserver is a metric that captures a precomputed sum of
 | 
			
		||||
// float64 values at a point in time.
 | 
			
		||||
type Float64UpDownCounterObserver struct {
 | 
			
		||||
	asyncInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Observation returns an Observation, a BatchObserverFunc
 | 
			
		||||
// argument, for an asynchronous integer instrument.
 | 
			
		||||
// This returns an implementation-level object for use by the SDK,
 | 
			
		||||
// users should not refer to this.
 | 
			
		||||
func (i Int64GaugeObserver) Observation(v int64) Observation {
 | 
			
		||||
	return sdkapi.NewObservation(i.instrument, number.NewInt64Number(v))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Observation returns an Observation, a BatchObserverFunc
 | 
			
		||||
// argument, for an asynchronous integer instrument.
 | 
			
		||||
// This returns an implementation-level object for use by the SDK,
 | 
			
		||||
// users should not refer to this.
 | 
			
		||||
func (f Float64GaugeObserver) Observation(v float64) Observation {
 | 
			
		||||
	return sdkapi.NewObservation(f.instrument, number.NewFloat64Number(v))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Observation returns an Observation, a BatchObserverFunc
 | 
			
		||||
// argument, for an asynchronous integer instrument.
 | 
			
		||||
// This returns an implementation-level object for use by the SDK,
 | 
			
		||||
// users should not refer to this.
 | 
			
		||||
func (i Int64CounterObserver) Observation(v int64) Observation {
 | 
			
		||||
	return sdkapi.NewObservation(i.instrument, number.NewInt64Number(v))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Observation returns an Observation, a BatchObserverFunc
 | 
			
		||||
// argument, for an asynchronous integer instrument.
 | 
			
		||||
// This returns an implementation-level object for use by the SDK,
 | 
			
		||||
// users should not refer to this.
 | 
			
		||||
func (f Float64CounterObserver) Observation(v float64) Observation {
 | 
			
		||||
	return sdkapi.NewObservation(f.instrument, number.NewFloat64Number(v))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Observation returns an Observation, a BatchObserverFunc
 | 
			
		||||
// argument, for an asynchronous integer instrument.
 | 
			
		||||
// This returns an implementation-level object for use by the SDK,
 | 
			
		||||
// users should not refer to this.
 | 
			
		||||
func (i Int64UpDownCounterObserver) Observation(v int64) Observation {
 | 
			
		||||
	return sdkapi.NewObservation(i.instrument, number.NewInt64Number(v))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Observation returns an Observation, a BatchObserverFunc
 | 
			
		||||
// argument, for an asynchronous integer instrument.
 | 
			
		||||
// This returns an implementation-level object for use by the SDK,
 | 
			
		||||
// users should not refer to this.
 | 
			
		||||
func (f Float64UpDownCounterObserver) Observation(v float64) Observation {
 | 
			
		||||
	return sdkapi.NewObservation(f.instrument, number.NewFloat64Number(v))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// syncInstrument contains a SyncImpl.
 | 
			
		||||
type syncInstrument struct {
 | 
			
		||||
	instrument sdkapi.SyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// syncBoundInstrument contains a BoundSyncImpl.
 | 
			
		||||
type syncBoundInstrument struct {
 | 
			
		||||
	boundInstrument sdkapi.BoundSyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// asyncInstrument contains a AsyncImpl.
 | 
			
		||||
type asyncInstrument struct {
 | 
			
		||||
	instrument sdkapi.AsyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsyncImpl implements AsyncImpl.
 | 
			
		||||
func (a asyncInstrument) AsyncImpl() sdkapi.AsyncImpl {
 | 
			
		||||
	return a.instrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SyncImpl returns the implementation object for synchronous instruments.
 | 
			
		||||
func (s syncInstrument) SyncImpl() sdkapi.SyncImpl {
 | 
			
		||||
	return s.instrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s syncInstrument) bind(labels []attribute.KeyValue) syncBoundInstrument {
 | 
			
		||||
	return newSyncBoundInstrument(s.instrument.Bind(labels))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s syncInstrument) float64Measurement(value float64) Measurement {
 | 
			
		||||
	return sdkapi.NewMeasurement(s.instrument, number.NewFloat64Number(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s syncInstrument) int64Measurement(value int64) Measurement {
 | 
			
		||||
	return sdkapi.NewMeasurement(s.instrument, number.NewInt64Number(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s syncInstrument) directRecord(ctx context.Context, number number.Number, labels []attribute.KeyValue) {
 | 
			
		||||
	s.instrument.RecordOne(ctx, number, labels)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h syncBoundInstrument) directRecord(ctx context.Context, number number.Number) {
 | 
			
		||||
	h.boundInstrument.RecordOne(ctx, number)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unbind calls SyncImpl.Unbind.
 | 
			
		||||
func (h syncBoundInstrument) Unbind() {
 | 
			
		||||
	h.boundInstrument.Unbind()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// checkNewAsync receives an AsyncImpl and potential
 | 
			
		||||
// error, and returns the same types, checking for and ensuring that
 | 
			
		||||
// the returned interface is not nil.
 | 
			
		||||
func checkNewAsync(instrument sdkapi.AsyncImpl, err error) (asyncInstrument, error) {
 | 
			
		||||
	if instrument == nil {
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			err = ErrSDKReturnedNilImpl
 | 
			
		||||
		}
 | 
			
		||||
		instrument = sdkapi.NewNoopAsyncInstrument()
 | 
			
		||||
	}
 | 
			
		||||
	return asyncInstrument{
 | 
			
		||||
		instrument: instrument,
 | 
			
		||||
	}, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// checkNewSync receives an SyncImpl and potential
 | 
			
		||||
// error, and returns the same types, checking for and ensuring that
 | 
			
		||||
// the returned interface is not nil.
 | 
			
		||||
func checkNewSync(instrument sdkapi.SyncImpl, err error) (syncInstrument, error) {
 | 
			
		||||
	if instrument == nil {
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			err = ErrSDKReturnedNilImpl
 | 
			
		||||
		}
 | 
			
		||||
		// Note: an alternate behavior would be to synthesize a new name
 | 
			
		||||
		// or group all duplicately-named instruments of a certain type
 | 
			
		||||
		// together and use a tag for the original name, e.g.,
 | 
			
		||||
		//   name = 'invalid.counter.int64'
 | 
			
		||||
		//   label = 'original-name=duplicate-counter-name'
 | 
			
		||||
		instrument = sdkapi.NewNoopSyncInstrument()
 | 
			
		||||
	}
 | 
			
		||||
	return syncInstrument{
 | 
			
		||||
		instrument: instrument,
 | 
			
		||||
	}, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newSyncBoundInstrument(boundInstrument sdkapi.BoundSyncImpl) syncBoundInstrument {
 | 
			
		||||
	return syncBoundInstrument{
 | 
			
		||||
		boundInstrument: boundInstrument,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// wrapInt64CounterInstrument converts a SyncImpl into Int64Counter.
 | 
			
		||||
func wrapInt64CounterInstrument(syncInst sdkapi.SyncImpl, err error) (Int64Counter, error) {
 | 
			
		||||
	common, err := checkNewSync(syncInst, err)
 | 
			
		||||
	return Int64Counter{syncInstrument: common}, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// wrapFloat64CounterInstrument converts a SyncImpl into Float64Counter.
 | 
			
		||||
func wrapFloat64CounterInstrument(syncInst sdkapi.SyncImpl, err error) (Float64Counter, error) {
 | 
			
		||||
	common, err := checkNewSync(syncInst, err)
 | 
			
		||||
	return Float64Counter{syncInstrument: common}, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// wrapInt64UpDownCounterInstrument converts a SyncImpl into Int64UpDownCounter.
 | 
			
		||||
func wrapInt64UpDownCounterInstrument(syncInst sdkapi.SyncImpl, err error) (Int64UpDownCounter, error) {
 | 
			
		||||
	common, err := checkNewSync(syncInst, err)
 | 
			
		||||
	return Int64UpDownCounter{syncInstrument: common}, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// wrapFloat64UpDownCounterInstrument converts a SyncImpl into Float64UpDownCounter.
 | 
			
		||||
func wrapFloat64UpDownCounterInstrument(syncInst sdkapi.SyncImpl, err error) (Float64UpDownCounter, error) {
 | 
			
		||||
	common, err := checkNewSync(syncInst, err)
 | 
			
		||||
	return Float64UpDownCounter{syncInstrument: common}, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// wrapInt64HistogramInstrument converts a SyncImpl into Int64Histogram.
 | 
			
		||||
func wrapInt64HistogramInstrument(syncInst sdkapi.SyncImpl, err error) (Int64Histogram, error) {
 | 
			
		||||
	common, err := checkNewSync(syncInst, err)
 | 
			
		||||
	return Int64Histogram{syncInstrument: common}, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// wrapFloat64HistogramInstrument converts a SyncImpl into Float64Histogram.
 | 
			
		||||
func wrapFloat64HistogramInstrument(syncInst sdkapi.SyncImpl, err error) (Float64Histogram, error) {
 | 
			
		||||
	common, err := checkNewSync(syncInst, err)
 | 
			
		||||
	return Float64Histogram{syncInstrument: common}, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64Counter is a metric that accumulates float64 values.
 | 
			
		||||
type Float64Counter struct {
 | 
			
		||||
	syncInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int64Counter is a metric that accumulates int64 values.
 | 
			
		||||
type Int64Counter struct {
 | 
			
		||||
	syncInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BoundFloat64Counter is a bound instrument for Float64Counter.
 | 
			
		||||
//
 | 
			
		||||
// It inherits the Unbind function from syncBoundInstrument.
 | 
			
		||||
type BoundFloat64Counter struct {
 | 
			
		||||
	syncBoundInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BoundInt64Counter is a boundInstrument for Int64Counter.
 | 
			
		||||
//
 | 
			
		||||
// It inherits the Unbind function from syncBoundInstrument.
 | 
			
		||||
type BoundInt64Counter struct {
 | 
			
		||||
	syncBoundInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Bind creates a bound instrument for this counter. The labels are
 | 
			
		||||
// associated with values recorded via subsequent calls to Record.
 | 
			
		||||
func (c Float64Counter) Bind(labels ...attribute.KeyValue) (h BoundFloat64Counter) {
 | 
			
		||||
	h.syncBoundInstrument = c.bind(labels)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Bind creates a bound instrument for this counter. The labels are
 | 
			
		||||
// associated with values recorded via subsequent calls to Record.
 | 
			
		||||
func (c Int64Counter) Bind(labels ...attribute.KeyValue) (h BoundInt64Counter) {
 | 
			
		||||
	h.syncBoundInstrument = c.bind(labels)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Measurement creates a Measurement object to use with batch
 | 
			
		||||
// recording.
 | 
			
		||||
func (c Float64Counter) Measurement(value float64) Measurement {
 | 
			
		||||
	return c.float64Measurement(value)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Measurement creates a Measurement object to use with batch
 | 
			
		||||
// recording.
 | 
			
		||||
func (c Int64Counter) Measurement(value int64) Measurement {
 | 
			
		||||
	return c.int64Measurement(value)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add adds the value to the counter's sum. The labels should contain
 | 
			
		||||
// the keys and values to be associated with this value.
 | 
			
		||||
func (c Float64Counter) Add(ctx context.Context, value float64, labels ...attribute.KeyValue) {
 | 
			
		||||
	c.directRecord(ctx, number.NewFloat64Number(value), labels)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add adds the value to the counter's sum. The labels should contain
 | 
			
		||||
// the keys and values to be associated with this value.
 | 
			
		||||
func (c Int64Counter) Add(ctx context.Context, value int64, labels ...attribute.KeyValue) {
 | 
			
		||||
	c.directRecord(ctx, number.NewInt64Number(value), labels)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add adds the value to the counter's sum using the labels
 | 
			
		||||
// previously bound to this counter via Bind()
 | 
			
		||||
func (b BoundFloat64Counter) Add(ctx context.Context, value float64) {
 | 
			
		||||
	b.directRecord(ctx, number.NewFloat64Number(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add adds the value to the counter's sum using the labels
 | 
			
		||||
// previously bound to this counter via Bind()
 | 
			
		||||
func (b BoundInt64Counter) Add(ctx context.Context, value int64) {
 | 
			
		||||
	b.directRecord(ctx, number.NewInt64Number(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64UpDownCounter is a metric instrument that sums floating
 | 
			
		||||
// point values.
 | 
			
		||||
type Float64UpDownCounter struct {
 | 
			
		||||
	syncInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int64UpDownCounter is a metric instrument that sums integer values.
 | 
			
		||||
type Int64UpDownCounter struct {
 | 
			
		||||
	syncInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BoundFloat64UpDownCounter is a bound instrument for Float64UpDownCounter.
 | 
			
		||||
//
 | 
			
		||||
// It inherits the Unbind function from syncBoundInstrument.
 | 
			
		||||
type BoundFloat64UpDownCounter struct {
 | 
			
		||||
	syncBoundInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BoundInt64UpDownCounter is a boundInstrument for Int64UpDownCounter.
 | 
			
		||||
//
 | 
			
		||||
// It inherits the Unbind function from syncBoundInstrument.
 | 
			
		||||
type BoundInt64UpDownCounter struct {
 | 
			
		||||
	syncBoundInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Bind creates a bound instrument for this counter. The labels are
 | 
			
		||||
// associated with values recorded via subsequent calls to Record.
 | 
			
		||||
func (c Float64UpDownCounter) Bind(labels ...attribute.KeyValue) (h BoundFloat64UpDownCounter) {
 | 
			
		||||
	h.syncBoundInstrument = c.bind(labels)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Bind creates a bound instrument for this counter. The labels are
 | 
			
		||||
// associated with values recorded via subsequent calls to Record.
 | 
			
		||||
func (c Int64UpDownCounter) Bind(labels ...attribute.KeyValue) (h BoundInt64UpDownCounter) {
 | 
			
		||||
	h.syncBoundInstrument = c.bind(labels)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Measurement creates a Measurement object to use with batch
 | 
			
		||||
// recording.
 | 
			
		||||
func (c Float64UpDownCounter) Measurement(value float64) Measurement {
 | 
			
		||||
	return c.float64Measurement(value)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Measurement creates a Measurement object to use with batch
 | 
			
		||||
// recording.
 | 
			
		||||
func (c Int64UpDownCounter) Measurement(value int64) Measurement {
 | 
			
		||||
	return c.int64Measurement(value)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add adds the value to the counter's sum. The labels should contain
 | 
			
		||||
// the keys and values to be associated with this value.
 | 
			
		||||
func (c Float64UpDownCounter) Add(ctx context.Context, value float64, labels ...attribute.KeyValue) {
 | 
			
		||||
	c.directRecord(ctx, number.NewFloat64Number(value), labels)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add adds the value to the counter's sum. The labels should contain
 | 
			
		||||
// the keys and values to be associated with this value.
 | 
			
		||||
func (c Int64UpDownCounter) Add(ctx context.Context, value int64, labels ...attribute.KeyValue) {
 | 
			
		||||
	c.directRecord(ctx, number.NewInt64Number(value), labels)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add adds the value to the counter's sum using the labels
 | 
			
		||||
// previously bound to this counter via Bind()
 | 
			
		||||
func (b BoundFloat64UpDownCounter) Add(ctx context.Context, value float64) {
 | 
			
		||||
	b.directRecord(ctx, number.NewFloat64Number(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add adds the value to the counter's sum using the labels
 | 
			
		||||
// previously bound to this counter via Bind()
 | 
			
		||||
func (b BoundInt64UpDownCounter) Add(ctx context.Context, value int64) {
 | 
			
		||||
	b.directRecord(ctx, number.NewInt64Number(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64Histogram is a metric that records float64 values.
 | 
			
		||||
type Float64Histogram struct {
 | 
			
		||||
	syncInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int64Histogram is a metric that records int64 values.
 | 
			
		||||
type Int64Histogram struct {
 | 
			
		||||
	syncInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BoundFloat64Histogram is a bound instrument for Float64Histogram.
 | 
			
		||||
//
 | 
			
		||||
// It inherits the Unbind function from syncBoundInstrument.
 | 
			
		||||
type BoundFloat64Histogram struct {
 | 
			
		||||
	syncBoundInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BoundInt64Histogram is a bound instrument for Int64Histogram.
 | 
			
		||||
//
 | 
			
		||||
// It inherits the Unbind function from syncBoundInstrument.
 | 
			
		||||
type BoundInt64Histogram struct {
 | 
			
		||||
	syncBoundInstrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Bind creates a bound instrument for this Histogram. The labels are
 | 
			
		||||
// associated with values recorded via subsequent calls to Record.
 | 
			
		||||
func (c Float64Histogram) Bind(labels ...attribute.KeyValue) (h BoundFloat64Histogram) {
 | 
			
		||||
	h.syncBoundInstrument = c.bind(labels)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Bind creates a bound instrument for this Histogram. The labels are
 | 
			
		||||
// associated with values recorded via subsequent calls to Record.
 | 
			
		||||
func (c Int64Histogram) Bind(labels ...attribute.KeyValue) (h BoundInt64Histogram) {
 | 
			
		||||
	h.syncBoundInstrument = c.bind(labels)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Measurement creates a Measurement object to use with batch
 | 
			
		||||
// recording.
 | 
			
		||||
func (c Float64Histogram) Measurement(value float64) Measurement {
 | 
			
		||||
	return c.float64Measurement(value)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Measurement creates a Measurement object to use with batch
 | 
			
		||||
// recording.
 | 
			
		||||
func (c Int64Histogram) Measurement(value int64) Measurement {
 | 
			
		||||
	return c.int64Measurement(value)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Record adds a new value to the list of Histogram's records. The
 | 
			
		||||
// labels should contain the keys and values to be associated with
 | 
			
		||||
// this value.
 | 
			
		||||
func (c Float64Histogram) Record(ctx context.Context, value float64, labels ...attribute.KeyValue) {
 | 
			
		||||
	c.directRecord(ctx, number.NewFloat64Number(value), labels)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Record adds a new value to the Histogram's distribution. The
 | 
			
		||||
// labels should contain the keys and values to be associated with
 | 
			
		||||
// this value.
 | 
			
		||||
func (c Int64Histogram) Record(ctx context.Context, value int64, labels ...attribute.KeyValue) {
 | 
			
		||||
	c.directRecord(ctx, number.NewInt64Number(value), labels)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Record adds a new value to the Histogram's distribution using the labels
 | 
			
		||||
// previously bound to the Histogram via Bind().
 | 
			
		||||
func (b BoundFloat64Histogram) Record(ctx context.Context, value float64) {
 | 
			
		||||
	b.directRecord(ctx, number.NewFloat64Number(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Record adds a new value to the Histogram's distribution using the labels
 | 
			
		||||
// previously bound to the Histogram via Bind().
 | 
			
		||||
func (b BoundInt64Histogram) Record(ctx context.Context, value int64) {
 | 
			
		||||
	b.directRecord(ctx, number.NewInt64Number(value))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								vendor/go.opentelemetry.io/otel/metric/noop.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								vendor/go.opentelemetry.io/otel/metric/noop.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package metric // import "go.opentelemetry.io/otel/metric"
 | 
			
		||||
 | 
			
		||||
type noopMeterProvider struct{}
 | 
			
		||||
 | 
			
		||||
// NewNoopMeterProvider returns an implementation of MeterProvider that
 | 
			
		||||
// performs no operations. The Meter and Instrument created from the returned
 | 
			
		||||
// MeterProvider also perform no operations.
 | 
			
		||||
func NewNoopMeterProvider() MeterProvider {
 | 
			
		||||
	return noopMeterProvider{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ MeterProvider = noopMeterProvider{}
 | 
			
		||||
 | 
			
		||||
func (noopMeterProvider) Meter(instrumentationName string, opts ...MeterOption) Meter {
 | 
			
		||||
	return Meter{}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								vendor/go.opentelemetry.io/otel/metric/number/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/go.opentelemetry.io/otel/metric/number/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Package number provides a number abstraction for instruments that
 | 
			
		||||
either support int64 or float64 input values.
 | 
			
		||||
 | 
			
		||||
This package is currently in a pre-GA phase. Backwards incompatible changes
 | 
			
		||||
may be introduced in subsequent minor version releases as we work to track the
 | 
			
		||||
evolving OpenTelemetry specification and user feedback.
 | 
			
		||||
*/
 | 
			
		||||
package number // import "go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
							
								
								
									
										24
									
								
								vendor/go.opentelemetry.io/otel/metric/number/kind_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								vendor/go.opentelemetry.io/otel/metric/number/kind_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
// Code generated by "stringer -type=Kind"; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package number
 | 
			
		||||
 | 
			
		||||
import "strconv"
 | 
			
		||||
 | 
			
		||||
func _() {
 | 
			
		||||
	// An "invalid array index" compiler error signifies that the constant values have changed.
 | 
			
		||||
	// Re-run the stringer command to generate them again.
 | 
			
		||||
	var x [1]struct{}
 | 
			
		||||
	_ = x[Int64Kind-0]
 | 
			
		||||
	_ = x[Float64Kind-1]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const _Kind_name = "Int64KindFloat64Kind"
 | 
			
		||||
 | 
			
		||||
var _Kind_index = [...]uint8{0, 9, 20}
 | 
			
		||||
 | 
			
		||||
func (i Kind) String() string {
 | 
			
		||||
	if i < 0 || i >= Kind(len(_Kind_index)-1) {
 | 
			
		||||
		return "Kind(" + strconv.FormatInt(int64(i), 10) + ")"
 | 
			
		||||
	}
 | 
			
		||||
	return _Kind_name[_Kind_index[i]:_Kind_index[i+1]]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										538
									
								
								vendor/go.opentelemetry.io/otel/metric/number/number.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										538
									
								
								vendor/go.opentelemetry.io/otel/metric/number/number.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,538 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package number // import "go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
 | 
			
		||||
//go:generate stringer -type=Kind
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"math"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/internal"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Kind describes the data type of the Number.
 | 
			
		||||
type Kind int8
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// Int64Kind means that the Number stores int64.
 | 
			
		||||
	Int64Kind Kind = iota
 | 
			
		||||
	// Float64Kind means that the Number stores float64.
 | 
			
		||||
	Float64Kind
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Zero returns a zero value for a given Kind
 | 
			
		||||
func (k Kind) Zero() Number {
 | 
			
		||||
	switch k {
 | 
			
		||||
	case Int64Kind:
 | 
			
		||||
		return NewInt64Number(0)
 | 
			
		||||
	case Float64Kind:
 | 
			
		||||
		return NewFloat64Number(0.)
 | 
			
		||||
	default:
 | 
			
		||||
		return Number(0)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Minimum returns the minimum representable value
 | 
			
		||||
// for a given Kind
 | 
			
		||||
func (k Kind) Minimum() Number {
 | 
			
		||||
	switch k {
 | 
			
		||||
	case Int64Kind:
 | 
			
		||||
		return NewInt64Number(math.MinInt64)
 | 
			
		||||
	case Float64Kind:
 | 
			
		||||
		return NewFloat64Number(-1. * math.MaxFloat64)
 | 
			
		||||
	default:
 | 
			
		||||
		return Number(0)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Maximum returns the maximum representable value
 | 
			
		||||
// for a given Kind
 | 
			
		||||
func (k Kind) Maximum() Number {
 | 
			
		||||
	switch k {
 | 
			
		||||
	case Int64Kind:
 | 
			
		||||
		return NewInt64Number(math.MaxInt64)
 | 
			
		||||
	case Float64Kind:
 | 
			
		||||
		return NewFloat64Number(math.MaxFloat64)
 | 
			
		||||
	default:
 | 
			
		||||
		return Number(0)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Number represents either an integral or a floating point value. It
 | 
			
		||||
// needs to be accompanied with a source of Kind that describes
 | 
			
		||||
// the actual type of the value stored within Number.
 | 
			
		||||
type Number uint64
 | 
			
		||||
 | 
			
		||||
// - constructors
 | 
			
		||||
 | 
			
		||||
// NewNumberFromRaw creates a new Number from a raw value.
 | 
			
		||||
func NewNumberFromRaw(r uint64) Number {
 | 
			
		||||
	return Number(r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInt64Number creates an integral Number.
 | 
			
		||||
func NewInt64Number(i int64) Number {
 | 
			
		||||
	return NewNumberFromRaw(internal.Int64ToRaw(i))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFloat64Number creates a floating point Number.
 | 
			
		||||
func NewFloat64Number(f float64) Number {
 | 
			
		||||
	return NewNumberFromRaw(internal.Float64ToRaw(f))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewNumberSignChange returns a number with the same magnitude and
 | 
			
		||||
// the opposite sign.  `kind` must describe the kind of number in `nn`.
 | 
			
		||||
func NewNumberSignChange(kind Kind, nn Number) Number {
 | 
			
		||||
	switch kind {
 | 
			
		||||
	case Int64Kind:
 | 
			
		||||
		return NewInt64Number(-nn.AsInt64())
 | 
			
		||||
	case Float64Kind:
 | 
			
		||||
		return NewFloat64Number(-nn.AsFloat64())
 | 
			
		||||
	}
 | 
			
		||||
	return nn
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - as x
 | 
			
		||||
 | 
			
		||||
// AsNumber gets the Number.
 | 
			
		||||
func (n *Number) AsNumber() Number {
 | 
			
		||||
	return *n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsRaw gets the uninterpreted raw value. Might be useful for some
 | 
			
		||||
// atomic operations.
 | 
			
		||||
func (n *Number) AsRaw() uint64 {
 | 
			
		||||
	return uint64(*n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsInt64 assumes that the value contains an int64 and returns it as
 | 
			
		||||
// such.
 | 
			
		||||
func (n *Number) AsInt64() int64 {
 | 
			
		||||
	return internal.RawToInt64(n.AsRaw())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsFloat64 assumes that the measurement value contains a float64 and
 | 
			
		||||
// returns it as such.
 | 
			
		||||
func (n *Number) AsFloat64() float64 {
 | 
			
		||||
	return internal.RawToFloat64(n.AsRaw())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - as x atomic
 | 
			
		||||
 | 
			
		||||
// AsNumberAtomic gets the Number atomically.
 | 
			
		||||
func (n *Number) AsNumberAtomic() Number {
 | 
			
		||||
	return NewNumberFromRaw(n.AsRawAtomic())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsRawAtomic gets the uninterpreted raw value atomically. Might be
 | 
			
		||||
// useful for some atomic operations.
 | 
			
		||||
func (n *Number) AsRawAtomic() uint64 {
 | 
			
		||||
	return atomic.LoadUint64(n.AsRawPtr())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsInt64Atomic assumes that the number contains an int64 and returns
 | 
			
		||||
// it as such atomically.
 | 
			
		||||
func (n *Number) AsInt64Atomic() int64 {
 | 
			
		||||
	return atomic.LoadInt64(n.AsInt64Ptr())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsFloat64Atomic assumes that the measurement value contains a
 | 
			
		||||
// float64 and returns it as such atomically.
 | 
			
		||||
func (n *Number) AsFloat64Atomic() float64 {
 | 
			
		||||
	return internal.RawToFloat64(n.AsRawAtomic())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - as x ptr
 | 
			
		||||
 | 
			
		||||
// AsRawPtr gets the pointer to the raw, uninterpreted raw
 | 
			
		||||
// value. Might be useful for some atomic operations.
 | 
			
		||||
func (n *Number) AsRawPtr() *uint64 {
 | 
			
		||||
	return (*uint64)(n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsInt64Ptr assumes that the number contains an int64 and returns a
 | 
			
		||||
// pointer to it.
 | 
			
		||||
func (n *Number) AsInt64Ptr() *int64 {
 | 
			
		||||
	return internal.RawPtrToInt64Ptr(n.AsRawPtr())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsFloat64Ptr assumes that the number contains a float64 and returns a
 | 
			
		||||
// pointer to it.
 | 
			
		||||
func (n *Number) AsFloat64Ptr() *float64 {
 | 
			
		||||
	return internal.RawPtrToFloat64Ptr(n.AsRawPtr())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - coerce
 | 
			
		||||
 | 
			
		||||
// CoerceToInt64 casts the number to int64. May result in
 | 
			
		||||
// data/precision loss.
 | 
			
		||||
func (n *Number) CoerceToInt64(kind Kind) int64 {
 | 
			
		||||
	switch kind {
 | 
			
		||||
	case Int64Kind:
 | 
			
		||||
		return n.AsInt64()
 | 
			
		||||
	case Float64Kind:
 | 
			
		||||
		return int64(n.AsFloat64())
 | 
			
		||||
	default:
 | 
			
		||||
		// you get what you deserve
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CoerceToFloat64 casts the number to float64. May result in
 | 
			
		||||
// data/precision loss.
 | 
			
		||||
func (n *Number) CoerceToFloat64(kind Kind) float64 {
 | 
			
		||||
	switch kind {
 | 
			
		||||
	case Int64Kind:
 | 
			
		||||
		return float64(n.AsInt64())
 | 
			
		||||
	case Float64Kind:
 | 
			
		||||
		return n.AsFloat64()
 | 
			
		||||
	default:
 | 
			
		||||
		// you get what you deserve
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - set
 | 
			
		||||
 | 
			
		||||
// SetNumber sets the number to the passed number. Both should be of
 | 
			
		||||
// the same kind.
 | 
			
		||||
func (n *Number) SetNumber(nn Number) {
 | 
			
		||||
	*n.AsRawPtr() = nn.AsRaw()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetRaw sets the number to the passed raw value. Both number and the
 | 
			
		||||
// raw number should represent the same kind.
 | 
			
		||||
func (n *Number) SetRaw(r uint64) {
 | 
			
		||||
	*n.AsRawPtr() = r
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetInt64 assumes that the number contains an int64 and sets it to
 | 
			
		||||
// the passed value.
 | 
			
		||||
func (n *Number) SetInt64(i int64) {
 | 
			
		||||
	*n.AsInt64Ptr() = i
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetFloat64 assumes that the number contains a float64 and sets it
 | 
			
		||||
// to the passed value.
 | 
			
		||||
func (n *Number) SetFloat64(f float64) {
 | 
			
		||||
	*n.AsFloat64Ptr() = f
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - set atomic
 | 
			
		||||
 | 
			
		||||
// SetNumberAtomic sets the number to the passed number
 | 
			
		||||
// atomically. Both should be of the same kind.
 | 
			
		||||
func (n *Number) SetNumberAtomic(nn Number) {
 | 
			
		||||
	atomic.StoreUint64(n.AsRawPtr(), nn.AsRaw())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetRawAtomic sets the number to the passed raw value
 | 
			
		||||
// atomically. Both number and the raw number should represent the
 | 
			
		||||
// same kind.
 | 
			
		||||
func (n *Number) SetRawAtomic(r uint64) {
 | 
			
		||||
	atomic.StoreUint64(n.AsRawPtr(), r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetInt64Atomic assumes that the number contains an int64 and sets
 | 
			
		||||
// it to the passed value atomically.
 | 
			
		||||
func (n *Number) SetInt64Atomic(i int64) {
 | 
			
		||||
	atomic.StoreInt64(n.AsInt64Ptr(), i)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetFloat64Atomic assumes that the number contains a float64 and
 | 
			
		||||
// sets it to the passed value atomically.
 | 
			
		||||
func (n *Number) SetFloat64Atomic(f float64) {
 | 
			
		||||
	atomic.StoreUint64(n.AsRawPtr(), internal.Float64ToRaw(f))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - swap
 | 
			
		||||
 | 
			
		||||
// SwapNumber sets the number to the passed number and returns the old
 | 
			
		||||
// number. Both this number and the passed number should be of the
 | 
			
		||||
// same kind.
 | 
			
		||||
func (n *Number) SwapNumber(nn Number) Number {
 | 
			
		||||
	old := *n
 | 
			
		||||
	n.SetNumber(nn)
 | 
			
		||||
	return old
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SwapRaw sets the number to the passed raw value and returns the old
 | 
			
		||||
// raw value. Both number and the raw number should represent the same
 | 
			
		||||
// kind.
 | 
			
		||||
func (n *Number) SwapRaw(r uint64) uint64 {
 | 
			
		||||
	old := n.AsRaw()
 | 
			
		||||
	n.SetRaw(r)
 | 
			
		||||
	return old
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SwapInt64 assumes that the number contains an int64, sets it to the
 | 
			
		||||
// passed value and returns the old int64 value.
 | 
			
		||||
func (n *Number) SwapInt64(i int64) int64 {
 | 
			
		||||
	old := n.AsInt64()
 | 
			
		||||
	n.SetInt64(i)
 | 
			
		||||
	return old
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SwapFloat64 assumes that the number contains an float64, sets it to
 | 
			
		||||
// the passed value and returns the old float64 value.
 | 
			
		||||
func (n *Number) SwapFloat64(f float64) float64 {
 | 
			
		||||
	old := n.AsFloat64()
 | 
			
		||||
	n.SetFloat64(f)
 | 
			
		||||
	return old
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - swap atomic
 | 
			
		||||
 | 
			
		||||
// SwapNumberAtomic sets the number to the passed number and returns
 | 
			
		||||
// the old number atomically. Both this number and the passed number
 | 
			
		||||
// should be of the same kind.
 | 
			
		||||
func (n *Number) SwapNumberAtomic(nn Number) Number {
 | 
			
		||||
	return NewNumberFromRaw(atomic.SwapUint64(n.AsRawPtr(), nn.AsRaw()))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SwapRawAtomic sets the number to the passed raw value and returns
 | 
			
		||||
// the old raw value atomically. Both number and the raw number should
 | 
			
		||||
// represent the same kind.
 | 
			
		||||
func (n *Number) SwapRawAtomic(r uint64) uint64 {
 | 
			
		||||
	return atomic.SwapUint64(n.AsRawPtr(), r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SwapInt64Atomic assumes that the number contains an int64, sets it
 | 
			
		||||
// to the passed value and returns the old int64 value atomically.
 | 
			
		||||
func (n *Number) SwapInt64Atomic(i int64) int64 {
 | 
			
		||||
	return atomic.SwapInt64(n.AsInt64Ptr(), i)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SwapFloat64Atomic assumes that the number contains an float64, sets
 | 
			
		||||
// it to the passed value and returns the old float64 value
 | 
			
		||||
// atomically.
 | 
			
		||||
func (n *Number) SwapFloat64Atomic(f float64) float64 {
 | 
			
		||||
	return internal.RawToFloat64(atomic.SwapUint64(n.AsRawPtr(), internal.Float64ToRaw(f)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - add
 | 
			
		||||
 | 
			
		||||
// AddNumber assumes that this and the passed number are of the passed
 | 
			
		||||
// kind and adds the passed number to this number.
 | 
			
		||||
func (n *Number) AddNumber(kind Kind, nn Number) {
 | 
			
		||||
	switch kind {
 | 
			
		||||
	case Int64Kind:
 | 
			
		||||
		n.AddInt64(nn.AsInt64())
 | 
			
		||||
	case Float64Kind:
 | 
			
		||||
		n.AddFloat64(nn.AsFloat64())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddRaw assumes that this number and the passed raw value are of the
 | 
			
		||||
// passed kind and adds the passed raw value to this number.
 | 
			
		||||
func (n *Number) AddRaw(kind Kind, r uint64) {
 | 
			
		||||
	n.AddNumber(kind, NewNumberFromRaw(r))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddInt64 assumes that the number contains an int64 and adds the
 | 
			
		||||
// passed int64 to it.
 | 
			
		||||
func (n *Number) AddInt64(i int64) {
 | 
			
		||||
	*n.AsInt64Ptr() += i
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddFloat64 assumes that the number contains a float64 and adds the
 | 
			
		||||
// passed float64 to it.
 | 
			
		||||
func (n *Number) AddFloat64(f float64) {
 | 
			
		||||
	*n.AsFloat64Ptr() += f
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - add atomic
 | 
			
		||||
 | 
			
		||||
// AddNumberAtomic assumes that this and the passed number are of the
 | 
			
		||||
// passed kind and adds the passed number to this number atomically.
 | 
			
		||||
func (n *Number) AddNumberAtomic(kind Kind, nn Number) {
 | 
			
		||||
	switch kind {
 | 
			
		||||
	case Int64Kind:
 | 
			
		||||
		n.AddInt64Atomic(nn.AsInt64())
 | 
			
		||||
	case Float64Kind:
 | 
			
		||||
		n.AddFloat64Atomic(nn.AsFloat64())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddRawAtomic assumes that this number and the passed raw value are
 | 
			
		||||
// of the passed kind and adds the passed raw value to this number
 | 
			
		||||
// atomically.
 | 
			
		||||
func (n *Number) AddRawAtomic(kind Kind, r uint64) {
 | 
			
		||||
	n.AddNumberAtomic(kind, NewNumberFromRaw(r))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddInt64Atomic assumes that the number contains an int64 and adds
 | 
			
		||||
// the passed int64 to it atomically.
 | 
			
		||||
func (n *Number) AddInt64Atomic(i int64) {
 | 
			
		||||
	atomic.AddInt64(n.AsInt64Ptr(), i)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddFloat64Atomic assumes that the number contains a float64 and
 | 
			
		||||
// adds the passed float64 to it atomically.
 | 
			
		||||
func (n *Number) AddFloat64Atomic(f float64) {
 | 
			
		||||
	for {
 | 
			
		||||
		o := n.AsFloat64Atomic()
 | 
			
		||||
		if n.CompareAndSwapFloat64(o, o+f) {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - compare and swap (atomic only)
 | 
			
		||||
 | 
			
		||||
// CompareAndSwapNumber does the atomic CAS operation on this
 | 
			
		||||
// number. This number and passed old and new numbers should be of the
 | 
			
		||||
// same kind.
 | 
			
		||||
func (n *Number) CompareAndSwapNumber(on, nn Number) bool {
 | 
			
		||||
	return atomic.CompareAndSwapUint64(n.AsRawPtr(), on.AsRaw(), nn.AsRaw())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CompareAndSwapRaw does the atomic CAS operation on this
 | 
			
		||||
// number. This number and passed old and new raw values should be of
 | 
			
		||||
// the same kind.
 | 
			
		||||
func (n *Number) CompareAndSwapRaw(or, nr uint64) bool {
 | 
			
		||||
	return atomic.CompareAndSwapUint64(n.AsRawPtr(), or, nr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CompareAndSwapInt64 assumes that this number contains an int64 and
 | 
			
		||||
// does the atomic CAS operation on it.
 | 
			
		||||
func (n *Number) CompareAndSwapInt64(oi, ni int64) bool {
 | 
			
		||||
	return atomic.CompareAndSwapInt64(n.AsInt64Ptr(), oi, ni)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CompareAndSwapFloat64 assumes that this number contains a float64 and
 | 
			
		||||
// does the atomic CAS operation on it.
 | 
			
		||||
func (n *Number) CompareAndSwapFloat64(of, nf float64) bool {
 | 
			
		||||
	return atomic.CompareAndSwapUint64(n.AsRawPtr(), internal.Float64ToRaw(of), internal.Float64ToRaw(nf))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - compare
 | 
			
		||||
 | 
			
		||||
// CompareNumber compares two Numbers given their kind.  Both numbers
 | 
			
		||||
// should have the same kind.  This returns:
 | 
			
		||||
//    0 if the numbers are equal
 | 
			
		||||
//    -1 if the subject `n` is less than the argument `nn`
 | 
			
		||||
//    +1 if the subject `n` is greater than the argument `nn`
 | 
			
		||||
func (n *Number) CompareNumber(kind Kind, nn Number) int {
 | 
			
		||||
	switch kind {
 | 
			
		||||
	case Int64Kind:
 | 
			
		||||
		return n.CompareInt64(nn.AsInt64())
 | 
			
		||||
	case Float64Kind:
 | 
			
		||||
		return n.CompareFloat64(nn.AsFloat64())
 | 
			
		||||
	default:
 | 
			
		||||
		// you get what you deserve
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CompareRaw compares two numbers, where one is input as a raw
 | 
			
		||||
// uint64, interpreting both values as a `kind` of number.
 | 
			
		||||
func (n *Number) CompareRaw(kind Kind, r uint64) int {
 | 
			
		||||
	return n.CompareNumber(kind, NewNumberFromRaw(r))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CompareInt64 assumes that the Number contains an int64 and performs
 | 
			
		||||
// a comparison between the value and the other value. It returns the
 | 
			
		||||
// typical result of the compare function: -1 if the value is less
 | 
			
		||||
// than the other, 0 if both are equal, 1 if the value is greater than
 | 
			
		||||
// the other.
 | 
			
		||||
func (n *Number) CompareInt64(i int64) int {
 | 
			
		||||
	this := n.AsInt64()
 | 
			
		||||
	if this < i {
 | 
			
		||||
		return -1
 | 
			
		||||
	} else if this > i {
 | 
			
		||||
		return 1
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CompareFloat64 assumes that the Number contains a float64 and
 | 
			
		||||
// performs a comparison between the value and the other value. It
 | 
			
		||||
// returns the typical result of the compare function: -1 if the value
 | 
			
		||||
// is less than the other, 0 if both are equal, 1 if the value is
 | 
			
		||||
// greater than the other.
 | 
			
		||||
//
 | 
			
		||||
// Do not compare NaN values.
 | 
			
		||||
func (n *Number) CompareFloat64(f float64) int {
 | 
			
		||||
	this := n.AsFloat64()
 | 
			
		||||
	if this < f {
 | 
			
		||||
		return -1
 | 
			
		||||
	} else if this > f {
 | 
			
		||||
		return 1
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - relations to zero
 | 
			
		||||
 | 
			
		||||
// IsPositive returns true if the actual value is greater than zero.
 | 
			
		||||
func (n *Number) IsPositive(kind Kind) bool {
 | 
			
		||||
	return n.compareWithZero(kind) > 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsNegative returns true if the actual value is less than zero.
 | 
			
		||||
func (n *Number) IsNegative(kind Kind) bool {
 | 
			
		||||
	return n.compareWithZero(kind) < 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsZero returns true if the actual value is equal to zero.
 | 
			
		||||
func (n *Number) IsZero(kind Kind) bool {
 | 
			
		||||
	return n.compareWithZero(kind) == 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - misc
 | 
			
		||||
 | 
			
		||||
// Emit returns a string representation of the raw value of the
 | 
			
		||||
// Number. A %d is used for integral values, %f for floating point
 | 
			
		||||
// values.
 | 
			
		||||
func (n *Number) Emit(kind Kind) string {
 | 
			
		||||
	switch kind {
 | 
			
		||||
	case Int64Kind:
 | 
			
		||||
		return fmt.Sprintf("%d", n.AsInt64())
 | 
			
		||||
	case Float64Kind:
 | 
			
		||||
		return fmt.Sprintf("%f", n.AsFloat64())
 | 
			
		||||
	default:
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsInterface returns the number as an interface{}, typically used
 | 
			
		||||
// for Kind-correct JSON conversion.
 | 
			
		||||
func (n *Number) AsInterface(kind Kind) interface{} {
 | 
			
		||||
	switch kind {
 | 
			
		||||
	case Int64Kind:
 | 
			
		||||
		return n.AsInt64()
 | 
			
		||||
	case Float64Kind:
 | 
			
		||||
		return n.AsFloat64()
 | 
			
		||||
	default:
 | 
			
		||||
		return math.NaN()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - private stuff
 | 
			
		||||
 | 
			
		||||
func (n *Number) compareWithZero(kind Kind) int {
 | 
			
		||||
	switch kind {
 | 
			
		||||
	case Int64Kind:
 | 
			
		||||
		return n.CompareInt64(0)
 | 
			
		||||
	case Float64Kind:
 | 
			
		||||
		return n.CompareFloat64(0.)
 | 
			
		||||
	default:
 | 
			
		||||
		// you get what you deserve
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										70
									
								
								vendor/go.opentelemetry.io/otel/metric/sdkapi/descriptor.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								vendor/go.opentelemetry.io/otel/metric/sdkapi/descriptor.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package sdkapi // import "go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/unit"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Descriptor contains all the settings that describe an instrument,
 | 
			
		||||
// including its name, metric kind, number kind, and the configurable
 | 
			
		||||
// options.
 | 
			
		||||
type Descriptor struct {
 | 
			
		||||
	name           string
 | 
			
		||||
	instrumentKind InstrumentKind
 | 
			
		||||
	numberKind     number.Kind
 | 
			
		||||
	description    string
 | 
			
		||||
	unit           unit.Unit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewDescriptor returns a Descriptor with the given contents.
 | 
			
		||||
func NewDescriptor(name string, ikind InstrumentKind, nkind number.Kind, description string, unit unit.Unit) Descriptor {
 | 
			
		||||
	return Descriptor{
 | 
			
		||||
		name:           name,
 | 
			
		||||
		instrumentKind: ikind,
 | 
			
		||||
		numberKind:     nkind,
 | 
			
		||||
		description:    description,
 | 
			
		||||
		unit:           unit,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Name returns the metric instrument's name.
 | 
			
		||||
func (d Descriptor) Name() string {
 | 
			
		||||
	return d.name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentKind returns the specific kind of instrument.
 | 
			
		||||
func (d Descriptor) InstrumentKind() InstrumentKind {
 | 
			
		||||
	return d.instrumentKind
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Description provides a human-readable description of the metric
 | 
			
		||||
// instrument.
 | 
			
		||||
func (d Descriptor) Description() string {
 | 
			
		||||
	return d.description
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unit describes the units of the metric instrument.  Unitless
 | 
			
		||||
// metrics return the empty string.
 | 
			
		||||
func (d Descriptor) Unit() unit.Unit {
 | 
			
		||||
	return d.unit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NumberKind returns whether this instrument is declared over int64,
 | 
			
		||||
// float64, or uint64 values.
 | 
			
		||||
func (d Descriptor) NumberKind() number.Kind {
 | 
			
		||||
	return d.numberKind
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										80
									
								
								vendor/go.opentelemetry.io/otel/metric/sdkapi/instrumentkind.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								vendor/go.opentelemetry.io/otel/metric/sdkapi/instrumentkind.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
//go:generate stringer -type=InstrumentKind
 | 
			
		||||
 | 
			
		||||
package sdkapi // import "go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
 | 
			
		||||
// InstrumentKind describes the kind of instrument.
 | 
			
		||||
type InstrumentKind int8
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// HistogramInstrumentKind indicates a Histogram instrument.
 | 
			
		||||
	HistogramInstrumentKind InstrumentKind = iota
 | 
			
		||||
	// GaugeObserverInstrumentKind indicates an GaugeObserver instrument.
 | 
			
		||||
	GaugeObserverInstrumentKind
 | 
			
		||||
 | 
			
		||||
	// CounterInstrumentKind indicates a Counter instrument.
 | 
			
		||||
	CounterInstrumentKind
 | 
			
		||||
	// UpDownCounterInstrumentKind indicates a UpDownCounter instrument.
 | 
			
		||||
	UpDownCounterInstrumentKind
 | 
			
		||||
 | 
			
		||||
	// CounterObserverInstrumentKind indicates a CounterObserver instrument.
 | 
			
		||||
	CounterObserverInstrumentKind
 | 
			
		||||
	// UpDownCounterObserverInstrumentKind indicates a UpDownCounterObserver
 | 
			
		||||
	// instrument.
 | 
			
		||||
	UpDownCounterObserverInstrumentKind
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Synchronous returns whether this is a synchronous kind of instrument.
 | 
			
		||||
func (k InstrumentKind) Synchronous() bool {
 | 
			
		||||
	switch k {
 | 
			
		||||
	case CounterInstrumentKind, UpDownCounterInstrumentKind, HistogramInstrumentKind:
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Asynchronous returns whether this is an asynchronous kind of instrument.
 | 
			
		||||
func (k InstrumentKind) Asynchronous() bool {
 | 
			
		||||
	return !k.Synchronous()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Adding returns whether this kind of instrument adds its inputs (as opposed to Grouping).
 | 
			
		||||
func (k InstrumentKind) Adding() bool {
 | 
			
		||||
	switch k {
 | 
			
		||||
	case CounterInstrumentKind, UpDownCounterInstrumentKind, CounterObserverInstrumentKind, UpDownCounterObserverInstrumentKind:
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Grouping returns whether this kind of instrument groups its inputs (as opposed to Adding).
 | 
			
		||||
func (k InstrumentKind) Grouping() bool {
 | 
			
		||||
	return !k.Adding()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Monotonic returns whether this kind of instrument exposes a non-decreasing sum.
 | 
			
		||||
func (k InstrumentKind) Monotonic() bool {
 | 
			
		||||
	switch k {
 | 
			
		||||
	case CounterInstrumentKind, CounterObserverInstrumentKind:
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PrecomputedSum returns whether this kind of instrument receives precomputed sums.
 | 
			
		||||
func (k InstrumentKind) PrecomputedSum() bool {
 | 
			
		||||
	return k.Adding() && k.Asynchronous()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								vendor/go.opentelemetry.io/otel/metric/sdkapi/instrumentkind_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/go.opentelemetry.io/otel/metric/sdkapi/instrumentkind_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
// Code generated by "stringer -type=InstrumentKind"; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package sdkapi
 | 
			
		||||
 | 
			
		||||
import "strconv"
 | 
			
		||||
 | 
			
		||||
func _() {
 | 
			
		||||
	// An "invalid array index" compiler error signifies that the constant values have changed.
 | 
			
		||||
	// Re-run the stringer command to generate them again.
 | 
			
		||||
	var x [1]struct{}
 | 
			
		||||
	_ = x[HistogramInstrumentKind-0]
 | 
			
		||||
	_ = x[GaugeObserverInstrumentKind-1]
 | 
			
		||||
	_ = x[CounterInstrumentKind-2]
 | 
			
		||||
	_ = x[UpDownCounterInstrumentKind-3]
 | 
			
		||||
	_ = x[CounterObserverInstrumentKind-4]
 | 
			
		||||
	_ = x[UpDownCounterObserverInstrumentKind-5]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const _InstrumentKind_name = "HistogramInstrumentKindGaugeObserverInstrumentKindCounterInstrumentKindUpDownCounterInstrumentKindCounterObserverInstrumentKindUpDownCounterObserverInstrumentKind"
 | 
			
		||||
 | 
			
		||||
var _InstrumentKind_index = [...]uint8{0, 23, 50, 71, 98, 127, 162}
 | 
			
		||||
 | 
			
		||||
func (i InstrumentKind) String() string {
 | 
			
		||||
	if i < 0 || i >= InstrumentKind(len(_InstrumentKind_index)-1) {
 | 
			
		||||
		return "InstrumentKind(" + strconv.FormatInt(int64(i), 10) + ")"
 | 
			
		||||
	}
 | 
			
		||||
	return _InstrumentKind_name[_InstrumentKind_index[i]:_InstrumentKind_index[i+1]]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										64
									
								
								vendor/go.opentelemetry.io/otel/metric/sdkapi/noop.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								vendor/go.opentelemetry.io/otel/metric/sdkapi/noop.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package sdkapi // import "go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type noopInstrument struct{}
 | 
			
		||||
type noopBoundInstrument struct{}
 | 
			
		||||
type noopSyncInstrument struct{ noopInstrument }
 | 
			
		||||
type noopAsyncInstrument struct{ noopInstrument }
 | 
			
		||||
 | 
			
		||||
var _ SyncImpl = noopSyncInstrument{}
 | 
			
		||||
var _ BoundSyncImpl = noopBoundInstrument{}
 | 
			
		||||
var _ AsyncImpl = noopAsyncInstrument{}
 | 
			
		||||
 | 
			
		||||
// NewNoopSyncInstrument returns a No-op implementation of the
 | 
			
		||||
// synchronous instrument interface.
 | 
			
		||||
func NewNoopSyncInstrument() SyncImpl {
 | 
			
		||||
	return noopSyncInstrument{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewNoopAsyncInstrument returns a No-op implementation of the
 | 
			
		||||
// asynchronous instrument interface.
 | 
			
		||||
func NewNoopAsyncInstrument() AsyncImpl {
 | 
			
		||||
	return noopAsyncInstrument{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (noopInstrument) Implementation() interface{} {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (noopInstrument) Descriptor() Descriptor {
 | 
			
		||||
	return Descriptor{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (noopBoundInstrument) RecordOne(context.Context, number.Number) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (noopBoundInstrument) Unbind() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (noopSyncInstrument) Bind([]attribute.KeyValue) BoundSyncImpl {
 | 
			
		||||
	return noopBoundInstrument{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (noopSyncInstrument) RecordOne(context.Context, number.Number, []attribute.KeyValue) {
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										175
									
								
								vendor/go.opentelemetry.io/otel/metric/sdkapi/sdkapi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								vendor/go.opentelemetry.io/otel/metric/sdkapi/sdkapi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,175 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package sdkapi // import "go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// MeterImpl is the interface an SDK must implement to supply a Meter
 | 
			
		||||
// implementation.
 | 
			
		||||
type MeterImpl interface {
 | 
			
		||||
	// RecordBatch atomically records a batch of measurements.
 | 
			
		||||
	RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurement ...Measurement)
 | 
			
		||||
 | 
			
		||||
	// NewSyncInstrument returns a newly constructed
 | 
			
		||||
	// synchronous instrument implementation or an error, should
 | 
			
		||||
	// one occur.
 | 
			
		||||
	NewSyncInstrument(descriptor Descriptor) (SyncImpl, error)
 | 
			
		||||
 | 
			
		||||
	// NewAsyncInstrument returns a newly constructed
 | 
			
		||||
	// asynchronous instrument implementation or an error, should
 | 
			
		||||
	// one occur.
 | 
			
		||||
	NewAsyncInstrument(
 | 
			
		||||
		descriptor Descriptor,
 | 
			
		||||
		runner AsyncRunner,
 | 
			
		||||
	) (AsyncImpl, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentImpl is a common interface for synchronous and
 | 
			
		||||
// asynchronous instruments.
 | 
			
		||||
type InstrumentImpl interface {
 | 
			
		||||
	// Implementation returns the underlying implementation of the
 | 
			
		||||
	// instrument, which allows the implementation to gain access
 | 
			
		||||
	// to its own representation especially from a `Measurement`.
 | 
			
		||||
	Implementation() interface{}
 | 
			
		||||
 | 
			
		||||
	// Descriptor returns a copy of the instrument's Descriptor.
 | 
			
		||||
	Descriptor() Descriptor
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SyncImpl is the implementation-level interface to a generic
 | 
			
		||||
// synchronous instrument (e.g., Histogram and Counter instruments).
 | 
			
		||||
type SyncImpl interface {
 | 
			
		||||
	InstrumentImpl
 | 
			
		||||
 | 
			
		||||
	// Bind creates an implementation-level bound instrument,
 | 
			
		||||
	// binding a label set with this instrument implementation.
 | 
			
		||||
	Bind(labels []attribute.KeyValue) BoundSyncImpl
 | 
			
		||||
 | 
			
		||||
	// RecordOne captures a single synchronous metric event.
 | 
			
		||||
	RecordOne(ctx context.Context, number number.Number, labels []attribute.KeyValue)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BoundSyncImpl is the implementation-level interface to a
 | 
			
		||||
// generic bound synchronous instrument
 | 
			
		||||
type BoundSyncImpl interface {
 | 
			
		||||
 | 
			
		||||
	// RecordOne captures a single synchronous metric event.
 | 
			
		||||
	RecordOne(ctx context.Context, number number.Number)
 | 
			
		||||
 | 
			
		||||
	// Unbind frees the resources associated with this bound instrument. It
 | 
			
		||||
	// does not affect the metric this bound instrument was created through.
 | 
			
		||||
	Unbind()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsyncImpl is an implementation-level interface to an
 | 
			
		||||
// asynchronous instrument (e.g., Observer instruments).
 | 
			
		||||
type AsyncImpl interface {
 | 
			
		||||
	InstrumentImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsyncRunner is expected to convert into an AsyncSingleRunner or an
 | 
			
		||||
// AsyncBatchRunner.  SDKs will encounter an error if the AsyncRunner
 | 
			
		||||
// does not satisfy one of these interfaces.
 | 
			
		||||
type AsyncRunner interface {
 | 
			
		||||
	// AnyRunner() is a non-exported method with no functional use
 | 
			
		||||
	// other than to make this a non-empty interface.
 | 
			
		||||
	AnyRunner()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsyncSingleRunner is an interface implemented by single-observer
 | 
			
		||||
// callbacks.
 | 
			
		||||
type AsyncSingleRunner interface {
 | 
			
		||||
	// Run accepts a single instrument and function for capturing
 | 
			
		||||
	// observations of that instrument.  Each call to the function
 | 
			
		||||
	// receives one captured observation.  (The function accepts
 | 
			
		||||
	// multiple observations so the same implementation can be
 | 
			
		||||
	// used for batch runners.)
 | 
			
		||||
	Run(ctx context.Context, single AsyncImpl, capture func([]attribute.KeyValue, ...Observation))
 | 
			
		||||
 | 
			
		||||
	AsyncRunner
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsyncBatchRunner is an interface implemented by batch-observer
 | 
			
		||||
// callbacks.
 | 
			
		||||
type AsyncBatchRunner interface {
 | 
			
		||||
	// Run accepts a function for capturing observations of
 | 
			
		||||
	// multiple instruments.
 | 
			
		||||
	Run(ctx context.Context, capture func([]attribute.KeyValue, ...Observation))
 | 
			
		||||
 | 
			
		||||
	AsyncRunner
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewMeasurement constructs a single observation, a binding between
 | 
			
		||||
// an asynchronous instrument and a number.
 | 
			
		||||
func NewMeasurement(instrument SyncImpl, number number.Number) Measurement {
 | 
			
		||||
	return Measurement{
 | 
			
		||||
		instrument: instrument,
 | 
			
		||||
		number:     number,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Measurement is a low-level type used with synchronous instruments
 | 
			
		||||
// as a direct interface to the SDK via `RecordBatch`.
 | 
			
		||||
type Measurement struct {
 | 
			
		||||
	// number needs to be aligned for 64-bit atomic operations.
 | 
			
		||||
	number     number.Number
 | 
			
		||||
	instrument SyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SyncImpl returns the instrument that created this measurement.
 | 
			
		||||
// This returns an implementation-level object for use by the SDK,
 | 
			
		||||
// users should not refer to this.
 | 
			
		||||
func (m Measurement) SyncImpl() SyncImpl {
 | 
			
		||||
	return m.instrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Number returns a number recorded in this measurement.
 | 
			
		||||
func (m Measurement) Number() number.Number {
 | 
			
		||||
	return m.number
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewObservation constructs a single observation, a binding between
 | 
			
		||||
// an asynchronous instrument and a number.
 | 
			
		||||
func NewObservation(instrument AsyncImpl, number number.Number) Observation {
 | 
			
		||||
	return Observation{
 | 
			
		||||
		instrument: instrument,
 | 
			
		||||
		number:     number,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Observation is a low-level type used with asynchronous instruments
 | 
			
		||||
// as a direct interface to the SDK via `BatchObserver`.
 | 
			
		||||
type Observation struct {
 | 
			
		||||
	// number needs to be aligned for 64-bit atomic operations.
 | 
			
		||||
	number     number.Number
 | 
			
		||||
	instrument AsyncImpl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsyncImpl returns the instrument that created this observation.
 | 
			
		||||
// This returns an implementation-level object for use by the SDK,
 | 
			
		||||
// users should not refer to this.
 | 
			
		||||
func (m Observation) AsyncImpl() AsyncImpl {
 | 
			
		||||
	return m.instrument
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Number returns a number recorded in this observation.
 | 
			
		||||
func (m Observation) Number() number.Number {
 | 
			
		||||
	return m.number
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/go.opentelemetry.io/otel/metric/unit/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/go.opentelemetry.io/otel/metric/unit/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
// Package unit provides units.
 | 
			
		||||
//
 | 
			
		||||
// This package is currently in a pre-GA phase. Backwards incompatible changes
 | 
			
		||||
// may be introduced in subsequent minor version releases as we work to track
 | 
			
		||||
// the evolving OpenTelemetry specification and user feedback.
 | 
			
		||||
package unit // import "go.opentelemetry.io/otel/metric/unit"
 | 
			
		||||
							
								
								
									
										24
									
								
								vendor/go.opentelemetry.io/otel/metric/unit/unit.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								vendor/go.opentelemetry.io/otel/metric/unit/unit.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package unit // import "go.opentelemetry.io/otel/metric/unit"
 | 
			
		||||
 | 
			
		||||
type Unit string
 | 
			
		||||
 | 
			
		||||
// Units defined by OpenTelemetry.
 | 
			
		||||
const (
 | 
			
		||||
	Dimensionless Unit = "1"
 | 
			
		||||
	Bytes         Unit = "By"
 | 
			
		||||
	Milliseconds  Unit = "ms"
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										95
									
								
								vendor/go.opentelemetry.io/otel/pre_release.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								vendor/go.opentelemetry.io/otel/pre_release.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# Copyright The OpenTelemetry Authors
 | 
			
		||||
#
 | 
			
		||||
# Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
# you may not use this file except in compliance with the License.
 | 
			
		||||
# You may obtain a copy of the License at
 | 
			
		||||
#
 | 
			
		||||
#     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
#
 | 
			
		||||
# Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
# distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
# See the License for the specific language governing permissions and
 | 
			
		||||
# limitations under the License.
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
help()
 | 
			
		||||
{
 | 
			
		||||
   printf "\n"
 | 
			
		||||
   printf "Usage: $0 -t tag\n"
 | 
			
		||||
   printf "\t-t Unreleased tag. Update all go.mod with this tag.\n"
 | 
			
		||||
   exit 1 # Exit script after printing help
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
while getopts "t:" opt
 | 
			
		||||
do
 | 
			
		||||
   case "$opt" in
 | 
			
		||||
      t ) TAG="$OPTARG" ;;
 | 
			
		||||
      ? ) help ;; # Print help
 | 
			
		||||
   esac
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
# Print help in case parameters are empty
 | 
			
		||||
if [ -z "$TAG" ]
 | 
			
		||||
then
 | 
			
		||||
   printf "Tag is missing\n";
 | 
			
		||||
   help
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Validate semver
 | 
			
		||||
SEMVER_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$"
 | 
			
		||||
if [[ "${TAG}" =~ ${SEMVER_REGEX} ]]; then
 | 
			
		||||
	printf "${TAG} is valid semver tag.\n"
 | 
			
		||||
else
 | 
			
		||||
	printf "${TAG} is not a valid semver tag.\n"
 | 
			
		||||
	exit -1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
TAG_FOUND=`git tag --list ${TAG}`
 | 
			
		||||
if [[ ${TAG_FOUND} = ${TAG} ]] ; then
 | 
			
		||||
        printf "Tag ${TAG} already exists\n"
 | 
			
		||||
        exit -1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Get version for version.go
 | 
			
		||||
OTEL_VERSION=$(echo "${TAG}" | grep -o '^v[0-9]\+\.[0-9]\+\.[0-9]\+')
 | 
			
		||||
# Strip leading v
 | 
			
		||||
OTEL_VERSION="${OTEL_VERSION#v}"
 | 
			
		||||
 | 
			
		||||
cd $(dirname $0)
 | 
			
		||||
 | 
			
		||||
if ! git diff --quiet; then \
 | 
			
		||||
	printf "Working tree is not clean, can't proceed with the release process\n"
 | 
			
		||||
	git status
 | 
			
		||||
	git diff
 | 
			
		||||
	exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Update version.go
 | 
			
		||||
cp ./version.go ./version.go.bak
 | 
			
		||||
sed "s/\(return \"\)[0-9]*\.[0-9]*\.[0-9]*\"/\1${OTEL_VERSION}\"/" ./version.go.bak >./version.go
 | 
			
		||||
rm -f ./version.go.bak
 | 
			
		||||
 | 
			
		||||
# Update go.mod
 | 
			
		||||
git checkout -b pre_release_${TAG} main
 | 
			
		||||
PACKAGE_DIRS=$(find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \; | egrep -v 'tools' | sed 's/^\.\///' | sort)
 | 
			
		||||
 | 
			
		||||
for dir in $PACKAGE_DIRS; do
 | 
			
		||||
	cp "${dir}/go.mod" "${dir}/go.mod.bak"
 | 
			
		||||
	sed "s/opentelemetry.io\/otel\([^ ]*\) v[0-9]*\.[0-9]*\.[0-9]/opentelemetry.io\/otel\1 ${TAG}/" "${dir}/go.mod.bak" >"${dir}/go.mod"
 | 
			
		||||
	rm -f "${dir}/go.mod.bak"
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
# Run lint to update go.sum
 | 
			
		||||
make lint
 | 
			
		||||
 | 
			
		||||
# Add changes and commit.
 | 
			
		||||
git add .
 | 
			
		||||
make ci
 | 
			
		||||
git commit -m "Prepare for releasing $TAG"
 | 
			
		||||
 | 
			
		||||
printf "Now run following to verify the changes.\ngit diff main\n"
 | 
			
		||||
printf "\nThen push the changes to upstream\n"
 | 
			
		||||
							
								
								
									
										31
									
								
								vendor/go.opentelemetry.io/otel/propagation.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								vendor/go.opentelemetry.io/otel/propagation.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package otel // import "go.opentelemetry.io/otel"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"go.opentelemetry.io/otel/internal/global"
 | 
			
		||||
	"go.opentelemetry.io/otel/propagation"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetTextMapPropagator returns the global TextMapPropagator. If none has been
 | 
			
		||||
// set, a No-Op TextMapPropagator is returned.
 | 
			
		||||
func GetTextMapPropagator() propagation.TextMapPropagator {
 | 
			
		||||
	return global.TextMapPropagator()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetTextMapPropagator sets propagator as the global TextMapPropagator.
 | 
			
		||||
func SetTextMapPropagator(propagator propagation.TextMapPropagator) {
 | 
			
		||||
	global.SetTextMapPropagator(propagator)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								vendor/go.opentelemetry.io/otel/propagation/baggage.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								vendor/go.opentelemetry.io/otel/propagation/baggage.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package propagation // import "go.opentelemetry.io/otel/propagation"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/baggage"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const baggageHeader = "baggage"
 | 
			
		||||
 | 
			
		||||
// Baggage is a propagator that supports the W3C Baggage format.
 | 
			
		||||
//
 | 
			
		||||
// This propagates user-defined baggage associated with a trace. The complete
 | 
			
		||||
// specification is defined at https://w3c.github.io/baggage/.
 | 
			
		||||
type Baggage struct{}
 | 
			
		||||
 | 
			
		||||
var _ TextMapPropagator = Baggage{}
 | 
			
		||||
 | 
			
		||||
// Inject sets baggage key-values from ctx into the carrier.
 | 
			
		||||
func (b Baggage) Inject(ctx context.Context, carrier TextMapCarrier) {
 | 
			
		||||
	bStr := baggage.FromContext(ctx).String()
 | 
			
		||||
	if bStr != "" {
 | 
			
		||||
		carrier.Set(baggageHeader, bStr)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Extract returns a copy of parent with the baggage from the carrier added.
 | 
			
		||||
func (b Baggage) Extract(parent context.Context, carrier TextMapCarrier) context.Context {
 | 
			
		||||
	bStr := carrier.Get(baggageHeader)
 | 
			
		||||
	if bStr == "" {
 | 
			
		||||
		return parent
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bag, err := baggage.Parse(bStr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return parent
 | 
			
		||||
	}
 | 
			
		||||
	return baggage.ContextWithBaggage(parent, bag)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fields returns the keys who's values are set with Inject.
 | 
			
		||||
func (b Baggage) Fields() []string {
 | 
			
		||||
	return []string{baggageHeader}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								vendor/go.opentelemetry.io/otel/propagation/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								vendor/go.opentelemetry.io/otel/propagation/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Package propagation contains OpenTelemetry context propagators.
 | 
			
		||||
 | 
			
		||||
OpenTelemetry propagators are used to extract and inject context data from and
 | 
			
		||||
into messages exchanged by applications. The propagator supported by this
 | 
			
		||||
package is the W3C Trace Context encoding
 | 
			
		||||
(https://www.w3.org/TR/trace-context/), and W3C Baggage
 | 
			
		||||
(https://w3c.github.io/baggage/).
 | 
			
		||||
*/
 | 
			
		||||
package propagation // import "go.opentelemetry.io/otel/propagation"
 | 
			
		||||
							
								
								
									
										153
									
								
								vendor/go.opentelemetry.io/otel/propagation/propagation.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								vendor/go.opentelemetry.io/otel/propagation/propagation.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,153 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package propagation // import "go.opentelemetry.io/otel/propagation"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TextMapCarrier is the storage medium used by a TextMapPropagator.
 | 
			
		||||
type TextMapCarrier interface {
 | 
			
		||||
	// DO NOT CHANGE: any modification will not be backwards compatible and
 | 
			
		||||
	// must never be done outside of a new major release.
 | 
			
		||||
 | 
			
		||||
	// Get returns the value associated with the passed key.
 | 
			
		||||
	Get(key string) string
 | 
			
		||||
	// DO NOT CHANGE: any modification will not be backwards compatible and
 | 
			
		||||
	// must never be done outside of a new major release.
 | 
			
		||||
 | 
			
		||||
	// Set stores the key-value pair.
 | 
			
		||||
	Set(key string, value string)
 | 
			
		||||
	// DO NOT CHANGE: any modification will not be backwards compatible and
 | 
			
		||||
	// must never be done outside of a new major release.
 | 
			
		||||
 | 
			
		||||
	// Keys lists the keys stored in this carrier.
 | 
			
		||||
	Keys() []string
 | 
			
		||||
	// DO NOT CHANGE: any modification will not be backwards compatible and
 | 
			
		||||
	// must never be done outside of a new major release.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MapCarrier is a TextMapCarrier that uses a map held in memory as a storage
 | 
			
		||||
// medium for propagated key-value pairs.
 | 
			
		||||
type MapCarrier map[string]string
 | 
			
		||||
 | 
			
		||||
// Compile time check that MapCarrier implements the TextMapCarrier.
 | 
			
		||||
var _ TextMapCarrier = MapCarrier{}
 | 
			
		||||
 | 
			
		||||
// Get returns the value associated with the passed key.
 | 
			
		||||
func (c MapCarrier) Get(key string) string {
 | 
			
		||||
	return c[key]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set stores the key-value pair.
 | 
			
		||||
func (c MapCarrier) Set(key, value string) {
 | 
			
		||||
	c[key] = value
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Keys lists the keys stored in this carrier.
 | 
			
		||||
func (c MapCarrier) Keys() []string {
 | 
			
		||||
	keys := make([]string, 0, len(c))
 | 
			
		||||
	for k := range c {
 | 
			
		||||
		keys = append(keys, k)
 | 
			
		||||
	}
 | 
			
		||||
	return keys
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HeaderCarrier adapts http.Header to satisfy the TextMapCarrier interface.
 | 
			
		||||
type HeaderCarrier http.Header
 | 
			
		||||
 | 
			
		||||
// Get returns the value associated with the passed key.
 | 
			
		||||
func (hc HeaderCarrier) Get(key string) string {
 | 
			
		||||
	return http.Header(hc).Get(key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set stores the key-value pair.
 | 
			
		||||
func (hc HeaderCarrier) Set(key string, value string) {
 | 
			
		||||
	http.Header(hc).Set(key, value)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Keys lists the keys stored in this carrier.
 | 
			
		||||
func (hc HeaderCarrier) Keys() []string {
 | 
			
		||||
	keys := make([]string, 0, len(hc))
 | 
			
		||||
	for k := range hc {
 | 
			
		||||
		keys = append(keys, k)
 | 
			
		||||
	}
 | 
			
		||||
	return keys
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TextMapPropagator propagates cross-cutting concerns as key-value text
 | 
			
		||||
// pairs within a carrier that travels in-band across process boundaries.
 | 
			
		||||
type TextMapPropagator interface {
 | 
			
		||||
	// DO NOT CHANGE: any modification will not be backwards compatible and
 | 
			
		||||
	// must never be done outside of a new major release.
 | 
			
		||||
 | 
			
		||||
	// Inject set cross-cutting concerns from the Context into the carrier.
 | 
			
		||||
	Inject(ctx context.Context, carrier TextMapCarrier)
 | 
			
		||||
	// DO NOT CHANGE: any modification will not be backwards compatible and
 | 
			
		||||
	// must never be done outside of a new major release.
 | 
			
		||||
 | 
			
		||||
	// Extract reads cross-cutting concerns from the carrier into a Context.
 | 
			
		||||
	Extract(ctx context.Context, carrier TextMapCarrier) context.Context
 | 
			
		||||
	// DO NOT CHANGE: any modification will not be backwards compatible and
 | 
			
		||||
	// must never be done outside of a new major release.
 | 
			
		||||
 | 
			
		||||
	// Fields returns the keys whose values are set with Inject.
 | 
			
		||||
	Fields() []string
 | 
			
		||||
	// DO NOT CHANGE: any modification will not be backwards compatible and
 | 
			
		||||
	// must never be done outside of a new major release.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type compositeTextMapPropagator []TextMapPropagator
 | 
			
		||||
 | 
			
		||||
func (p compositeTextMapPropagator) Inject(ctx context.Context, carrier TextMapCarrier) {
 | 
			
		||||
	for _, i := range p {
 | 
			
		||||
		i.Inject(ctx, carrier)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p compositeTextMapPropagator) Extract(ctx context.Context, carrier TextMapCarrier) context.Context {
 | 
			
		||||
	for _, i := range p {
 | 
			
		||||
		ctx = i.Extract(ctx, carrier)
 | 
			
		||||
	}
 | 
			
		||||
	return ctx
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p compositeTextMapPropagator) Fields() []string {
 | 
			
		||||
	unique := make(map[string]struct{})
 | 
			
		||||
	for _, i := range p {
 | 
			
		||||
		for _, k := range i.Fields() {
 | 
			
		||||
			unique[k] = struct{}{}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fields := make([]string, 0, len(unique))
 | 
			
		||||
	for k := range unique {
 | 
			
		||||
		fields = append(fields, k)
 | 
			
		||||
	}
 | 
			
		||||
	return fields
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewCompositeTextMapPropagator returns a unified TextMapPropagator from the
 | 
			
		||||
// group of passed TextMapPropagator. This allows different cross-cutting
 | 
			
		||||
// concerns to be propagates in a unified manner.
 | 
			
		||||
//
 | 
			
		||||
// The returned TextMapPropagator will inject and extract cross-cutting
 | 
			
		||||
// concerns in the order the TextMapPropagators were provided. Additionally,
 | 
			
		||||
// the Fields method will return a de-duplicated slice of the keys that are
 | 
			
		||||
// set with the Inject method.
 | 
			
		||||
func NewCompositeTextMapPropagator(p ...TextMapPropagator) TextMapPropagator {
 | 
			
		||||
	return compositeTextMapPropagator(p)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										159
									
								
								vendor/go.opentelemetry.io/otel/propagation/trace_context.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								vendor/go.opentelemetry.io/otel/propagation/trace_context.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,159 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package propagation // import "go.opentelemetry.io/otel/propagation"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"encoding/hex"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"regexp"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/trace"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	supportedVersion  = 0
 | 
			
		||||
	maxVersion        = 254
 | 
			
		||||
	traceparentHeader = "traceparent"
 | 
			
		||||
	tracestateHeader  = "tracestate"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TraceContext is a propagator that supports the W3C Trace Context format
 | 
			
		||||
// (https://www.w3.org/TR/trace-context/)
 | 
			
		||||
//
 | 
			
		||||
// This propagator will propagate the traceparent and tracestate headers to
 | 
			
		||||
// guarantee traces are not broken. It is up to the users of this propagator
 | 
			
		||||
// to choose if they want to participate in a trace by modifying the
 | 
			
		||||
// traceparent header and relevant parts of the tracestate header containing
 | 
			
		||||
// their proprietary information.
 | 
			
		||||
type TraceContext struct{}
 | 
			
		||||
 | 
			
		||||
var _ TextMapPropagator = TraceContext{}
 | 
			
		||||
var traceCtxRegExp = regexp.MustCompile("^(?P<version>[0-9a-f]{2})-(?P<traceID>[a-f0-9]{32})-(?P<spanID>[a-f0-9]{16})-(?P<traceFlags>[a-f0-9]{2})(?:-.*)?$")
 | 
			
		||||
 | 
			
		||||
// Inject set tracecontext from the Context into the carrier.
 | 
			
		||||
func (tc TraceContext) Inject(ctx context.Context, carrier TextMapCarrier) {
 | 
			
		||||
	sc := trace.SpanContextFromContext(ctx)
 | 
			
		||||
	if !sc.IsValid() {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ts := sc.TraceState().String(); ts != "" {
 | 
			
		||||
		carrier.Set(tracestateHeader, ts)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Clear all flags other than the trace-context supported sampling bit.
 | 
			
		||||
	flags := sc.TraceFlags() & trace.FlagsSampled
 | 
			
		||||
 | 
			
		||||
	h := fmt.Sprintf("%.2x-%s-%s-%s",
 | 
			
		||||
		supportedVersion,
 | 
			
		||||
		sc.TraceID(),
 | 
			
		||||
		sc.SpanID(),
 | 
			
		||||
		flags)
 | 
			
		||||
	carrier.Set(traceparentHeader, h)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Extract reads tracecontext from the carrier into a returned Context.
 | 
			
		||||
//
 | 
			
		||||
// The returned Context will be a copy of ctx and contain the extracted
 | 
			
		||||
// tracecontext as the remote SpanContext. If the extracted tracecontext is
 | 
			
		||||
// invalid, the passed ctx will be returned directly instead.
 | 
			
		||||
func (tc TraceContext) Extract(ctx context.Context, carrier TextMapCarrier) context.Context {
 | 
			
		||||
	sc := tc.extract(carrier)
 | 
			
		||||
	if !sc.IsValid() {
 | 
			
		||||
		return ctx
 | 
			
		||||
	}
 | 
			
		||||
	return trace.ContextWithRemoteSpanContext(ctx, sc)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (tc TraceContext) extract(carrier TextMapCarrier) trace.SpanContext {
 | 
			
		||||
	h := carrier.Get(traceparentHeader)
 | 
			
		||||
	if h == "" {
 | 
			
		||||
		return trace.SpanContext{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	matches := traceCtxRegExp.FindStringSubmatch(h)
 | 
			
		||||
 | 
			
		||||
	if len(matches) == 0 {
 | 
			
		||||
		return trace.SpanContext{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(matches) < 5 { // four subgroups plus the overall match
 | 
			
		||||
		return trace.SpanContext{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(matches[1]) != 2 {
 | 
			
		||||
		return trace.SpanContext{}
 | 
			
		||||
	}
 | 
			
		||||
	ver, err := hex.DecodeString(matches[1])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return trace.SpanContext{}
 | 
			
		||||
	}
 | 
			
		||||
	version := int(ver[0])
 | 
			
		||||
	if version > maxVersion {
 | 
			
		||||
		return trace.SpanContext{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if version == 0 && len(matches) != 5 { // four subgroups plus the overall match
 | 
			
		||||
		return trace.SpanContext{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(matches[2]) != 32 {
 | 
			
		||||
		return trace.SpanContext{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var scc trace.SpanContextConfig
 | 
			
		||||
 | 
			
		||||
	scc.TraceID, err = trace.TraceIDFromHex(matches[2][:32])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return trace.SpanContext{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(matches[3]) != 16 {
 | 
			
		||||
		return trace.SpanContext{}
 | 
			
		||||
	}
 | 
			
		||||
	scc.SpanID, err = trace.SpanIDFromHex(matches[3])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return trace.SpanContext{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(matches[4]) != 2 {
 | 
			
		||||
		return trace.SpanContext{}
 | 
			
		||||
	}
 | 
			
		||||
	opts, err := hex.DecodeString(matches[4])
 | 
			
		||||
	if err != nil || len(opts) < 1 || (version == 0 && opts[0] > 2) {
 | 
			
		||||
		return trace.SpanContext{}
 | 
			
		||||
	}
 | 
			
		||||
	// Clear all flags other than the trace-context supported sampling bit.
 | 
			
		||||
	scc.TraceFlags = trace.TraceFlags(opts[0]) & trace.FlagsSampled
 | 
			
		||||
 | 
			
		||||
	// Ignore the error returned here. Failure to parse tracestate MUST NOT
 | 
			
		||||
	// affect the parsing of traceparent according to the W3C tracecontext
 | 
			
		||||
	// specification.
 | 
			
		||||
	scc.TraceState, _ = trace.ParseTraceState(carrier.Get(tracestateHeader))
 | 
			
		||||
	scc.Remote = true
 | 
			
		||||
 | 
			
		||||
	sc := trace.NewSpanContext(scc)
 | 
			
		||||
	if !sc.IsValid() {
 | 
			
		||||
		return trace.SpanContext{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return sc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fields returns the keys who's values are set with Inject.
 | 
			
		||||
func (tc TraceContext) Fields() []string {
 | 
			
		||||
	return []string{traceparentHeader, tracestateHeader}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										201
									
								
								vendor/go.opentelemetry.io/otel/sdk/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								vendor/go.opentelemetry.io/otel/sdk/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
							
								
								
									
										201
									
								
								vendor/go.opentelemetry.io/otel/sdk/export/metric/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								vendor/go.opentelemetry.io/otel/sdk/export/metric/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
							
								
								
									
										156
									
								
								vendor/go.opentelemetry.io/otel/sdk/export/metric/aggregation/aggregation.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								vendor/go.opentelemetry.io/otel/sdk/export/metric/aggregation/aggregation.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,156 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package aggregation // import "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// These interfaces describe the various ways to access state from an
 | 
			
		||||
// Aggregation.
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	// Aggregation is an interface returned by the Aggregator
 | 
			
		||||
	// containing an interval of metric data.
 | 
			
		||||
	Aggregation interface {
 | 
			
		||||
		// Kind returns a short identifying string to identify
 | 
			
		||||
		// the Aggregator that was used to produce the
 | 
			
		||||
		// Aggregation (e.g., "Sum").
 | 
			
		||||
		Kind() Kind
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Sum returns an aggregated sum.
 | 
			
		||||
	Sum interface {
 | 
			
		||||
		Aggregation
 | 
			
		||||
		Sum() (number.Number, error)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Count returns the number of values that were aggregated.
 | 
			
		||||
	Count interface {
 | 
			
		||||
		Aggregation
 | 
			
		||||
		Count() (uint64, error)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Min returns the minimum value over the set of values that were aggregated.
 | 
			
		||||
	Min interface {
 | 
			
		||||
		Aggregation
 | 
			
		||||
		Min() (number.Number, error)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Max returns the maximum value over the set of values that were aggregated.
 | 
			
		||||
	Max interface {
 | 
			
		||||
		Aggregation
 | 
			
		||||
		Max() (number.Number, error)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// LastValue returns the latest value that was aggregated.
 | 
			
		||||
	LastValue interface {
 | 
			
		||||
		Aggregation
 | 
			
		||||
		LastValue() (number.Number, time.Time, error)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Points returns the raw values that were aggregated.
 | 
			
		||||
	Points interface {
 | 
			
		||||
		Aggregation
 | 
			
		||||
 | 
			
		||||
		// Points returns points in the order they were
 | 
			
		||||
		// recorded.  Points are approximately ordered by
 | 
			
		||||
		// timestamp, but this is not guaranteed.
 | 
			
		||||
		Points() ([]Point, error)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Point is a raw data point, consisting of a number and value.
 | 
			
		||||
	Point struct {
 | 
			
		||||
		number.Number
 | 
			
		||||
		time.Time
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Buckets represents histogram buckets boundaries and counts.
 | 
			
		||||
	//
 | 
			
		||||
	// For a Histogram with N defined boundaries, e.g, [x, y, z].
 | 
			
		||||
	// There are N+1 counts: [-inf, x), [x, y), [y, z), [z, +inf]
 | 
			
		||||
	Buckets struct {
 | 
			
		||||
		// Boundaries are floating point numbers, even when
 | 
			
		||||
		// aggregating integers.
 | 
			
		||||
		Boundaries []float64
 | 
			
		||||
 | 
			
		||||
		// Counts holds the count in each bucket.
 | 
			
		||||
		Counts []uint64
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Histogram returns the count of events in pre-determined buckets.
 | 
			
		||||
	Histogram interface {
 | 
			
		||||
		Aggregation
 | 
			
		||||
		Count() (uint64, error)
 | 
			
		||||
		Sum() (number.Number, error)
 | 
			
		||||
		Histogram() (Buckets, error)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// MinMaxSumCount supports the Min, Max, Sum, and Count interfaces.
 | 
			
		||||
	MinMaxSumCount interface {
 | 
			
		||||
		Aggregation
 | 
			
		||||
		Min() (number.Number, error)
 | 
			
		||||
		Max() (number.Number, error)
 | 
			
		||||
		Sum() (number.Number, error)
 | 
			
		||||
		Count() (uint64, error)
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	// Kind is a short name for the Aggregator that produces an
 | 
			
		||||
	// Aggregation, used for descriptive purpose only.  Kind is a
 | 
			
		||||
	// string to allow user-defined Aggregators.
 | 
			
		||||
	//
 | 
			
		||||
	// When deciding how to handle an Aggregation, Exporters are
 | 
			
		||||
	// encouraged to decide based on conversion to the above
 | 
			
		||||
	// interfaces based on strength, not on Kind value, when
 | 
			
		||||
	// deciding how to expose metric data.  This enables
 | 
			
		||||
	// user-supplied Aggregators to replace builtin Aggregators.
 | 
			
		||||
	//
 | 
			
		||||
	// For example, test for a Distribution before testing for a
 | 
			
		||||
	// MinMaxSumCount, test for a Histogram before testing for a
 | 
			
		||||
	// Sum, and so on.
 | 
			
		||||
	Kind string
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Kind description constants.
 | 
			
		||||
const (
 | 
			
		||||
	SumKind            Kind = "Sum"
 | 
			
		||||
	MinMaxSumCountKind Kind = "MinMaxSumCount"
 | 
			
		||||
	HistogramKind      Kind = "Histogram"
 | 
			
		||||
	LastValueKind      Kind = "Lastvalue"
 | 
			
		||||
	ExactKind          Kind = "Exact"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Sentinel errors for Aggregation interface.
 | 
			
		||||
var (
 | 
			
		||||
	ErrNegativeInput    = fmt.Errorf("negative value is out of range for this instrument")
 | 
			
		||||
	ErrNaNInput         = fmt.Errorf("NaN value is an invalid input")
 | 
			
		||||
	ErrInconsistentType = fmt.Errorf("inconsistent aggregator types")
 | 
			
		||||
	ErrNoSubtraction    = fmt.Errorf("aggregator does not subtract")
 | 
			
		||||
 | 
			
		||||
	// ErrNoData is returned when (due to a race with collection)
 | 
			
		||||
	// the Aggregator is check-pointed before the first value is set.
 | 
			
		||||
	// The aggregator should simply be skipped in this case.
 | 
			
		||||
	ErrNoData = fmt.Errorf("no data collected by this aggregator")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// String returns the string value of Kind.
 | 
			
		||||
func (k Kind) String() string {
 | 
			
		||||
	return string(k)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										117
									
								
								vendor/go.opentelemetry.io/otel/sdk/export/metric/aggregation/temporality.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								vendor/go.opentelemetry.io/otel/sdk/export/metric/aggregation/temporality.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,117 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
//go:generate stringer -type=Temporality
 | 
			
		||||
 | 
			
		||||
package aggregation // import "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Temporality indicates the temporal aggregation exported by an exporter.
 | 
			
		||||
// These bits may be OR-d together when multiple exporters are in use.
 | 
			
		||||
type Temporality uint8
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// CumulativeTemporality indicates that an Exporter expects a
 | 
			
		||||
	// Cumulative Aggregation.
 | 
			
		||||
	CumulativeTemporality Temporality = 1
 | 
			
		||||
 | 
			
		||||
	// DeltaTemporality indicates that an Exporter expects a
 | 
			
		||||
	// Delta Aggregation.
 | 
			
		||||
	DeltaTemporality Temporality = 2
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Includes returns if t includes support for other temporality.
 | 
			
		||||
func (t Temporality) Includes(other Temporality) bool {
 | 
			
		||||
	return t&other != 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MemoryRequired returns whether an exporter of this temporality requires
 | 
			
		||||
// memory to export correctly.
 | 
			
		||||
func (t Temporality) MemoryRequired(mkind sdkapi.InstrumentKind) bool {
 | 
			
		||||
	switch mkind {
 | 
			
		||||
	case sdkapi.HistogramInstrumentKind, sdkapi.GaugeObserverInstrumentKind,
 | 
			
		||||
		sdkapi.CounterInstrumentKind, sdkapi.UpDownCounterInstrumentKind:
 | 
			
		||||
		// Delta-oriented instruments:
 | 
			
		||||
		return t.Includes(CumulativeTemporality)
 | 
			
		||||
 | 
			
		||||
	case sdkapi.CounterObserverInstrumentKind, sdkapi.UpDownCounterObserverInstrumentKind:
 | 
			
		||||
		// Cumulative-oriented instruments:
 | 
			
		||||
		return t.Includes(DeltaTemporality)
 | 
			
		||||
	}
 | 
			
		||||
	// Something unexpected is happening--we could panic.  This
 | 
			
		||||
	// will become an error when the exporter tries to access a
 | 
			
		||||
	// checkpoint, presumably, so let it be.
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	constantTemporalitySelector  Temporality
 | 
			
		||||
	statelessTemporalitySelector struct{}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_ TemporalitySelector = constantTemporalitySelector(0)
 | 
			
		||||
	_ TemporalitySelector = statelessTemporalitySelector{}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ConstantTemporalitySelector returns an TemporalitySelector that returns
 | 
			
		||||
// a constant Temporality.
 | 
			
		||||
func ConstantTemporalitySelector(t Temporality) TemporalitySelector {
 | 
			
		||||
	return constantTemporalitySelector(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CumulativeTemporalitySelector returns an TemporalitySelector that
 | 
			
		||||
// always returns CumulativeTemporality.
 | 
			
		||||
func CumulativeTemporalitySelector() TemporalitySelector {
 | 
			
		||||
	return ConstantTemporalitySelector(CumulativeTemporality)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeltaTemporalitySelector returns an TemporalitySelector that
 | 
			
		||||
// always returns DeltaTemporality.
 | 
			
		||||
func DeltaTemporalitySelector() TemporalitySelector {
 | 
			
		||||
	return ConstantTemporalitySelector(DeltaTemporality)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StatelessTemporalitySelector returns an TemporalitySelector that
 | 
			
		||||
// always returns the Temporality that avoids long-term memory
 | 
			
		||||
// requirements.
 | 
			
		||||
func StatelessTemporalitySelector() TemporalitySelector {
 | 
			
		||||
	return statelessTemporalitySelector{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TemporalityFor implements TemporalitySelector.
 | 
			
		||||
func (c constantTemporalitySelector) TemporalityFor(_ *sdkapi.Descriptor, _ Kind) Temporality {
 | 
			
		||||
	return Temporality(c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TemporalityFor implements TemporalitySelector.
 | 
			
		||||
func (s statelessTemporalitySelector) TemporalityFor(desc *sdkapi.Descriptor, kind Kind) Temporality {
 | 
			
		||||
	if kind == SumKind && desc.InstrumentKind().PrecomputedSum() {
 | 
			
		||||
		return CumulativeTemporality
 | 
			
		||||
	}
 | 
			
		||||
	return DeltaTemporality
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TemporalitySelector is a sub-interface of Exporter used to indicate
 | 
			
		||||
// whether the Processor should compute Delta or Cumulative
 | 
			
		||||
// Aggregations.
 | 
			
		||||
type TemporalitySelector interface {
 | 
			
		||||
	// TemporalityFor should return the correct Temporality that
 | 
			
		||||
	// should be used when exporting data for the given metric
 | 
			
		||||
	// instrument and Aggregator kind.
 | 
			
		||||
	TemporalityFor(descriptor *sdkapi.Descriptor, aggregationKind Kind) Temporality
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								vendor/go.opentelemetry.io/otel/sdk/export/metric/aggregation/temporality_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								vendor/go.opentelemetry.io/otel/sdk/export/metric/aggregation/temporality_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
// Code generated by "stringer -type=Temporality"; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package aggregation
 | 
			
		||||
 | 
			
		||||
import "strconv"
 | 
			
		||||
 | 
			
		||||
func _() {
 | 
			
		||||
	// An "invalid array index" compiler error signifies that the constant values have changed.
 | 
			
		||||
	// Re-run the stringer command to generate them again.
 | 
			
		||||
	var x [1]struct{}
 | 
			
		||||
	_ = x[CumulativeTemporality-1]
 | 
			
		||||
	_ = x[DeltaTemporality-2]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const _Temporality_name = "CumulativeTemporalityDeltaTemporality"
 | 
			
		||||
 | 
			
		||||
var _Temporality_index = [...]uint8{0, 21, 37}
 | 
			
		||||
 | 
			
		||||
func (i Temporality) String() string {
 | 
			
		||||
	i -= 1
 | 
			
		||||
	if i >= Temporality(len(_Temporality_index)-1) {
 | 
			
		||||
		return "Temporality(" + strconv.FormatInt(int64(i+1), 10) + ")"
 | 
			
		||||
	}
 | 
			
		||||
	return _Temporality_name[_Temporality_index[i]:_Temporality_index[i+1]]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										354
									
								
								vendor/go.opentelemetry.io/otel/sdk/export/metric/metric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										354
									
								
								vendor/go.opentelemetry.io/otel/sdk/export/metric/metric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,354 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package metric // import "go.opentelemetry.io/otel/sdk/export/metric"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/instrumentation"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/resource"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Processor is responsible for deciding which kind of aggregation to
 | 
			
		||||
// use (via AggregatorSelector), gathering exported results from the
 | 
			
		||||
// SDK during collection, and deciding over which dimensions to group
 | 
			
		||||
// the exported data.
 | 
			
		||||
//
 | 
			
		||||
// The SDK supports binding only one of these interfaces, as it has
 | 
			
		||||
// the sole responsibility of determining which Aggregator to use for
 | 
			
		||||
// each record.
 | 
			
		||||
//
 | 
			
		||||
// The embedded AggregatorSelector interface is called (concurrently)
 | 
			
		||||
// in instrumentation context to select the appropriate Aggregator for
 | 
			
		||||
// an instrument.
 | 
			
		||||
//
 | 
			
		||||
// The `Process` method is called during collection in a
 | 
			
		||||
// single-threaded context from the SDK, after the aggregator is
 | 
			
		||||
// checkpointed, allowing the processor to build the set of metrics
 | 
			
		||||
// currently being exported.
 | 
			
		||||
type Processor interface {
 | 
			
		||||
	// AggregatorSelector is responsible for selecting the
 | 
			
		||||
	// concrete type of Aggregator used for a metric in the SDK.
 | 
			
		||||
	//
 | 
			
		||||
	// This may be a static decision based on fields of the
 | 
			
		||||
	// Descriptor, or it could use an external configuration
 | 
			
		||||
	// source to customize the treatment of each metric
 | 
			
		||||
	// instrument.
 | 
			
		||||
	//
 | 
			
		||||
	// The result from AggregatorSelector.AggregatorFor should be
 | 
			
		||||
	// the same type for a given Descriptor or else nil.  The same
 | 
			
		||||
	// type should be returned for a given descriptor, because
 | 
			
		||||
	// Aggregators only know how to Merge with their own type.  If
 | 
			
		||||
	// the result is nil, the metric instrument will be disabled.
 | 
			
		||||
	//
 | 
			
		||||
	// Note that the SDK only calls AggregatorFor when new records
 | 
			
		||||
	// require an Aggregator. This does not provide a way to
 | 
			
		||||
	// disable metrics with active records.
 | 
			
		||||
	AggregatorSelector
 | 
			
		||||
 | 
			
		||||
	// Process is called by the SDK once per internal record,
 | 
			
		||||
	// passing the export Accumulation (a Descriptor, the corresponding
 | 
			
		||||
	// Labels, and the checkpointed Aggregator). This call has no
 | 
			
		||||
	// Context argument because it is expected to perform only
 | 
			
		||||
	// computation. An SDK is not expected to call exporters from
 | 
			
		||||
	// with Process, use a controller for that (see
 | 
			
		||||
	// ./controllers/{pull,push}.
 | 
			
		||||
	Process(accum Accumulation) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AggregatorSelector supports selecting the kind of Aggregator to
 | 
			
		||||
// use at runtime for a specific metric instrument.
 | 
			
		||||
type AggregatorSelector interface {
 | 
			
		||||
	// AggregatorFor allocates a variable number of aggregators of
 | 
			
		||||
	// a kind suitable for the requested export.  This method
 | 
			
		||||
	// initializes a `...*Aggregator`, to support making a single
 | 
			
		||||
	// allocation.
 | 
			
		||||
	//
 | 
			
		||||
	// When the call returns without initializing the *Aggregator
 | 
			
		||||
	// to a non-nil value, the metric instrument is explicitly
 | 
			
		||||
	// disabled.
 | 
			
		||||
	//
 | 
			
		||||
	// This must return a consistent type to avoid confusion in
 | 
			
		||||
	// later stages of the metrics export process, i.e., when
 | 
			
		||||
	// Merging or Checkpointing aggregators for a specific
 | 
			
		||||
	// instrument.
 | 
			
		||||
	//
 | 
			
		||||
	// Note: This is context-free because the aggregator should
 | 
			
		||||
	// not relate to the incoming context.  This call should not
 | 
			
		||||
	// block.
 | 
			
		||||
	AggregatorFor(descriptor *sdkapi.Descriptor, aggregator ...*Aggregator)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Checkpointer is the interface used by a Controller to coordinate
 | 
			
		||||
// the Processor with Accumulator(s) and Exporter(s).  The
 | 
			
		||||
// StartCollection() and FinishCollection() methods start and finish a
 | 
			
		||||
// collection interval.  Controllers call the Accumulator(s) during
 | 
			
		||||
// collection to process Accumulations.
 | 
			
		||||
type Checkpointer interface {
 | 
			
		||||
	// Processor processes metric data for export.  The Process
 | 
			
		||||
	// method is bracketed by StartCollection and FinishCollection
 | 
			
		||||
	// calls.  The embedded AggregatorSelector can be called at
 | 
			
		||||
	// any time.
 | 
			
		||||
	Processor
 | 
			
		||||
 | 
			
		||||
	// Reader returns the current data set.  This may be
 | 
			
		||||
	// called before and after collection.  The
 | 
			
		||||
	// implementation is required to return the same value
 | 
			
		||||
	// throughout its lifetime, since Reader exposes a
 | 
			
		||||
	// sync.Locker interface.  The caller is responsible for
 | 
			
		||||
	// locking the Reader before initiating collection.
 | 
			
		||||
	Reader() Reader
 | 
			
		||||
 | 
			
		||||
	// StartCollection begins a collection interval.
 | 
			
		||||
	StartCollection()
 | 
			
		||||
 | 
			
		||||
	// FinishCollection ends a collection interval.
 | 
			
		||||
	FinishCollection() error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CheckpointerFactory is an interface for producing configured
 | 
			
		||||
// Checkpointer instances.
 | 
			
		||||
type CheckpointerFactory interface {
 | 
			
		||||
	NewCheckpointer() Checkpointer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Aggregator implements a specific aggregation behavior, e.g., a
 | 
			
		||||
// behavior to track a sequence of updates to an instrument.  Counter
 | 
			
		||||
// instruments commonly use a simple Sum aggregator, but for the
 | 
			
		||||
// distribution instruments (Histogram, GaugeObserver) there are a
 | 
			
		||||
// number of possible aggregators with different cost and accuracy
 | 
			
		||||
// tradeoffs.
 | 
			
		||||
//
 | 
			
		||||
// Note that any Aggregator may be attached to any instrument--this is
 | 
			
		||||
// the result of the OpenTelemetry API/SDK separation.  It is possible
 | 
			
		||||
// to attach a Sum aggregator to a Histogram instrument or a
 | 
			
		||||
// MinMaxSumCount aggregator to a Counter instrument.
 | 
			
		||||
type Aggregator interface {
 | 
			
		||||
	// Aggregation returns an Aggregation interface to access the
 | 
			
		||||
	// current state of this Aggregator.  The caller is
 | 
			
		||||
	// responsible for synchronization and must not call any the
 | 
			
		||||
	// other methods in this interface concurrently while using
 | 
			
		||||
	// the Aggregation.
 | 
			
		||||
	Aggregation() aggregation.Aggregation
 | 
			
		||||
 | 
			
		||||
	// Update receives a new measured value and incorporates it
 | 
			
		||||
	// into the aggregation.  Update() calls may be called
 | 
			
		||||
	// concurrently.
 | 
			
		||||
	//
 | 
			
		||||
	// Descriptor.NumberKind() should be consulted to determine
 | 
			
		||||
	// whether the provided number is an int64 or float64.
 | 
			
		||||
	//
 | 
			
		||||
	// The Context argument comes from user-level code and could be
 | 
			
		||||
	// inspected for a `correlation.Map` or `trace.SpanContext`.
 | 
			
		||||
	Update(ctx context.Context, number number.Number, descriptor *sdkapi.Descriptor) error
 | 
			
		||||
 | 
			
		||||
	// SynchronizedMove is called during collection to finish one
 | 
			
		||||
	// period of aggregation by atomically saving the
 | 
			
		||||
	// currently-updating state into the argument Aggregator AND
 | 
			
		||||
	// resetting the current value to the zero state.
 | 
			
		||||
	//
 | 
			
		||||
	// SynchronizedMove() is called concurrently with Update().  These
 | 
			
		||||
	// two methods must be synchronized with respect to each
 | 
			
		||||
	// other, for correctness.
 | 
			
		||||
	//
 | 
			
		||||
	// After saving a synchronized copy, the Aggregator can be converted
 | 
			
		||||
	// into one or more of the interfaces in the `aggregation` sub-package,
 | 
			
		||||
	// according to kind of Aggregator that was selected.
 | 
			
		||||
	//
 | 
			
		||||
	// This method will return an InconsistentAggregatorError if
 | 
			
		||||
	// this Aggregator cannot be copied into the destination due
 | 
			
		||||
	// to an incompatible type.
 | 
			
		||||
	//
 | 
			
		||||
	// This call has no Context argument because it is expected to
 | 
			
		||||
	// perform only computation.
 | 
			
		||||
	//
 | 
			
		||||
	// When called with a nil `destination`, this Aggregator is reset
 | 
			
		||||
	// and the current value is discarded.
 | 
			
		||||
	SynchronizedMove(destination Aggregator, descriptor *sdkapi.Descriptor) error
 | 
			
		||||
 | 
			
		||||
	// Merge combines the checkpointed state from the argument
 | 
			
		||||
	// Aggregator into this Aggregator.  Merge is not synchronized
 | 
			
		||||
	// with respect to Update or SynchronizedMove.
 | 
			
		||||
	//
 | 
			
		||||
	// The owner of an Aggregator being merged is responsible for
 | 
			
		||||
	// synchronization of both Aggregator states.
 | 
			
		||||
	Merge(aggregator Aggregator, descriptor *sdkapi.Descriptor) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Subtractor is an optional interface implemented by some
 | 
			
		||||
// Aggregators.  An Aggregator must support `Subtract()` in order to
 | 
			
		||||
// be configured for a Precomputed-Sum instrument (CounterObserver,
 | 
			
		||||
// UpDownCounterObserver) using a DeltaExporter.
 | 
			
		||||
type Subtractor interface {
 | 
			
		||||
	// Subtract subtracts the `operand` from this Aggregator and
 | 
			
		||||
	// outputs the value in `result`.
 | 
			
		||||
	Subtract(operand, result Aggregator, descriptor *sdkapi.Descriptor) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Exporter handles presentation of the checkpoint of aggregate
 | 
			
		||||
// metrics.  This is the final stage of a metrics export pipeline,
 | 
			
		||||
// where metric data are formatted for a specific system.
 | 
			
		||||
type Exporter interface {
 | 
			
		||||
	// Export is called immediately after completing a collection
 | 
			
		||||
	// pass in the SDK.
 | 
			
		||||
	//
 | 
			
		||||
	// The Context comes from the controller that initiated
 | 
			
		||||
	// collection.
 | 
			
		||||
	//
 | 
			
		||||
	// The InstrumentationLibraryReader interface refers to the
 | 
			
		||||
	// Processor that just completed collection.
 | 
			
		||||
	Export(ctx context.Context, resource *resource.Resource, reader InstrumentationLibraryReader) error
 | 
			
		||||
 | 
			
		||||
	// TemporalitySelector is an interface used by the Processor
 | 
			
		||||
	// in deciding whether to compute Delta or Cumulative
 | 
			
		||||
	// Aggregations when passing Records to this Exporter.
 | 
			
		||||
	aggregation.TemporalitySelector
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentationLibraryReader is an interface for exporters to iterate
 | 
			
		||||
// over one instrumentation library of metric data at a time.
 | 
			
		||||
type InstrumentationLibraryReader interface {
 | 
			
		||||
	// ForEach calls the passed function once per instrumentation library,
 | 
			
		||||
	// allowing the caller to emit metrics grouped by the library that
 | 
			
		||||
	// produced them.
 | 
			
		||||
	ForEach(readerFunc func(instrumentation.Library, Reader) error) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Reader allows a controller to access a complete checkpoint of
 | 
			
		||||
// aggregated metrics from the Processor for a single library of
 | 
			
		||||
// metric data.  This is passed to the Exporter which may then use
 | 
			
		||||
// ForEach to iterate over the collection of aggregated metrics.
 | 
			
		||||
type Reader interface {
 | 
			
		||||
	// ForEach iterates over aggregated checkpoints for all
 | 
			
		||||
	// metrics that were updated during the last collection
 | 
			
		||||
	// period. Each aggregated checkpoint returned by the
 | 
			
		||||
	// function parameter may return an error.
 | 
			
		||||
	//
 | 
			
		||||
	// The TemporalitySelector argument is used to determine
 | 
			
		||||
	// whether the Record is computed using Delta or Cumulative
 | 
			
		||||
	// aggregation.
 | 
			
		||||
	//
 | 
			
		||||
	// ForEach tolerates ErrNoData silently, as this is
 | 
			
		||||
	// expected from the Meter implementation. Any other kind
 | 
			
		||||
	// of error will immediately halt ForEach and return
 | 
			
		||||
	// the error to the caller.
 | 
			
		||||
	ForEach(tempSelector aggregation.TemporalitySelector, recordFunc func(Record) error) error
 | 
			
		||||
 | 
			
		||||
	// Locker supports locking the checkpoint set.  Collection
 | 
			
		||||
	// into the checkpoint set cannot take place (in case of a
 | 
			
		||||
	// stateful processor) while it is locked.
 | 
			
		||||
	//
 | 
			
		||||
	// The Processor attached to the Accumulator MUST be called
 | 
			
		||||
	// with the lock held.
 | 
			
		||||
	sync.Locker
 | 
			
		||||
 | 
			
		||||
	// RLock acquires a read lock corresponding to this Locker.
 | 
			
		||||
	RLock()
 | 
			
		||||
	// RUnlock releases a read lock corresponding to this Locker.
 | 
			
		||||
	RUnlock()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Metadata contains the common elements for exported metric data that
 | 
			
		||||
// are shared by the Accumulator->Processor and Processor->Exporter
 | 
			
		||||
// steps.
 | 
			
		||||
type Metadata struct {
 | 
			
		||||
	descriptor *sdkapi.Descriptor
 | 
			
		||||
	labels     *attribute.Set
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Accumulation contains the exported data for a single metric instrument
 | 
			
		||||
// and label set, as prepared by an Accumulator for the Processor.
 | 
			
		||||
type Accumulation struct {
 | 
			
		||||
	Metadata
 | 
			
		||||
	aggregator Aggregator
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Record contains the exported data for a single metric instrument
 | 
			
		||||
// and label set, as prepared by the Processor for the Exporter.
 | 
			
		||||
// This includes the effective start and end time for the aggregation.
 | 
			
		||||
type Record struct {
 | 
			
		||||
	Metadata
 | 
			
		||||
	aggregation aggregation.Aggregation
 | 
			
		||||
	start       time.Time
 | 
			
		||||
	end         time.Time
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Descriptor describes the metric instrument being exported.
 | 
			
		||||
func (m Metadata) Descriptor() *sdkapi.Descriptor {
 | 
			
		||||
	return m.descriptor
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Labels describes the labels associated with the instrument and the
 | 
			
		||||
// aggregated data.
 | 
			
		||||
func (m Metadata) Labels() *attribute.Set {
 | 
			
		||||
	return m.labels
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewAccumulation allows Accumulator implementations to construct new
 | 
			
		||||
// Accumulations to send to Processors. The Descriptor, Labels,
 | 
			
		||||
// and Aggregator represent aggregate metric events received over a single
 | 
			
		||||
// collection period.
 | 
			
		||||
func NewAccumulation(descriptor *sdkapi.Descriptor, labels *attribute.Set, aggregator Aggregator) Accumulation {
 | 
			
		||||
	return Accumulation{
 | 
			
		||||
		Metadata: Metadata{
 | 
			
		||||
			descriptor: descriptor,
 | 
			
		||||
			labels:     labels,
 | 
			
		||||
		},
 | 
			
		||||
		aggregator: aggregator,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Aggregator returns the checkpointed aggregator. It is safe to
 | 
			
		||||
// access the checkpointed state without locking.
 | 
			
		||||
func (r Accumulation) Aggregator() Aggregator {
 | 
			
		||||
	return r.aggregator
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewRecord allows Processor implementations to construct export
 | 
			
		||||
// records.  The Descriptor, Labels, and Aggregator represent
 | 
			
		||||
// aggregate metric events received over a single collection period.
 | 
			
		||||
func NewRecord(descriptor *sdkapi.Descriptor, labels *attribute.Set, aggregation aggregation.Aggregation, start, end time.Time) Record {
 | 
			
		||||
	return Record{
 | 
			
		||||
		Metadata: Metadata{
 | 
			
		||||
			descriptor: descriptor,
 | 
			
		||||
			labels:     labels,
 | 
			
		||||
		},
 | 
			
		||||
		aggregation: aggregation,
 | 
			
		||||
		start:       start,
 | 
			
		||||
		end:         end,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Aggregation returns the aggregation, an interface to the record and
 | 
			
		||||
// its aggregator, dependent on the kind of both the input and exporter.
 | 
			
		||||
func (r Record) Aggregation() aggregation.Aggregation {
 | 
			
		||||
	return r.aggregation
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StartTime is the start time of the interval covered by this aggregation.
 | 
			
		||||
func (r Record) StartTime() time.Time {
 | 
			
		||||
	return r.start
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// EndTime is the end time of the interval covered by this aggregation.
 | 
			
		||||
func (r Record) EndTime() time.Time {
 | 
			
		||||
	return r.end
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								vendor/go.opentelemetry.io/otel/sdk/instrumentation/library.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								vendor/go.opentelemetry.io/otel/sdk/instrumentation/library.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Package instrumentation provides an instrumentation library structure to be
 | 
			
		||||
passed to both the OpenTelemetry Tracer and Meter components.
 | 
			
		||||
 | 
			
		||||
For more information see
 | 
			
		||||
[this](https://github.com/open-telemetry/oteps/blob/main/text/0083-component.md).
 | 
			
		||||
*/
 | 
			
		||||
package instrumentation // import "go.opentelemetry.io/otel/sdk/instrumentation"
 | 
			
		||||
 | 
			
		||||
// Library represents the instrumentation library.
 | 
			
		||||
type Library struct {
 | 
			
		||||
	// Name is the name of the instrumentation library. This should be the
 | 
			
		||||
	// Go package name of that library.
 | 
			
		||||
	Name string
 | 
			
		||||
	// Version is the version of the instrumentation library.
 | 
			
		||||
	Version string
 | 
			
		||||
	// SchemaURL of the telemetry emitted by the library.
 | 
			
		||||
	SchemaURL string
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										201
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
							
								
								
									
										52
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/aggregator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/aggregator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package aggregator // import "go.opentelemetry.io/otel/sdk/metric/aggregator"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"math"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
	export "go.opentelemetry.io/otel/sdk/export/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// NewInconsistentAggregatorError formats an error describing an attempt to
 | 
			
		||||
// Checkpoint or Merge different-type aggregators.  The result can be unwrapped as
 | 
			
		||||
// an ErrInconsistentType.
 | 
			
		||||
func NewInconsistentAggregatorError(a1, a2 export.Aggregator) error {
 | 
			
		||||
	return fmt.Errorf("%w: %T and %T", aggregation.ErrInconsistentType, a1, a2)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RangeTest is a common routine for testing for valid input values.
 | 
			
		||||
// This rejects NaN values.  This rejects negative values when the
 | 
			
		||||
// metric instrument does not support negative values, including
 | 
			
		||||
// monotonic counter metrics and absolute Histogram metrics.
 | 
			
		||||
func RangeTest(num number.Number, descriptor *sdkapi.Descriptor) error {
 | 
			
		||||
	numberKind := descriptor.NumberKind()
 | 
			
		||||
 | 
			
		||||
	if numberKind == number.Float64Kind && math.IsNaN(num.AsFloat64()) {
 | 
			
		||||
		return aggregation.ErrNaNInput
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch descriptor.InstrumentKind() {
 | 
			
		||||
	case sdkapi.CounterInstrumentKind, sdkapi.CounterObserverInstrumentKind:
 | 
			
		||||
		if num.IsNegative(numberKind) {
 | 
			
		||||
			return aggregation.ErrNegativeInput
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										130
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/exact/exact.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/exact/exact.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package exact // import "go.opentelemetry.io/otel/sdk/metric/aggregator/exact"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
	export "go.opentelemetry.io/otel/sdk/export/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/metric/aggregator"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	// Aggregator aggregates events that form a distribution, keeping
 | 
			
		||||
	// an array with the exact set of values.
 | 
			
		||||
	Aggregator struct {
 | 
			
		||||
		lock    sync.Mutex
 | 
			
		||||
		samples []aggregation.Point
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _ export.Aggregator = &Aggregator{}
 | 
			
		||||
var _ aggregation.Points = &Aggregator{}
 | 
			
		||||
var _ aggregation.Count = &Aggregator{}
 | 
			
		||||
 | 
			
		||||
// New returns cnt many new exact aggregators, which aggregate recorded
 | 
			
		||||
// measurements by storing them in an array.  This type uses a mutex
 | 
			
		||||
// for Update() and SynchronizedMove() concurrency.
 | 
			
		||||
func New(cnt int) []Aggregator {
 | 
			
		||||
	return make([]Aggregator, cnt)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Aggregation returns an interface for reading the state of this aggregator.
 | 
			
		||||
func (c *Aggregator) Aggregation() aggregation.Aggregation {
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Kind returns aggregation.ExactKind.
 | 
			
		||||
func (c *Aggregator) Kind() aggregation.Kind {
 | 
			
		||||
	return aggregation.ExactKind
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Count returns the number of values in the checkpoint.
 | 
			
		||||
func (c *Aggregator) Count() (uint64, error) {
 | 
			
		||||
	return uint64(len(c.samples)), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Points returns access to the raw data set.
 | 
			
		||||
func (c *Aggregator) Points() ([]aggregation.Point, error) {
 | 
			
		||||
	return c.samples, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SynchronizedMove saves the current state to oa and resets the current state to
 | 
			
		||||
// the empty set, taking a lock to prevent concurrent Update() calls.
 | 
			
		||||
func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *sdkapi.Descriptor) error {
 | 
			
		||||
	o, _ := oa.(*Aggregator)
 | 
			
		||||
 | 
			
		||||
	if oa != nil && o == nil {
 | 
			
		||||
		return aggregator.NewInconsistentAggregatorError(c, oa)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.lock.Lock()
 | 
			
		||||
	defer c.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	if o != nil {
 | 
			
		||||
		o.samples = c.samples
 | 
			
		||||
	}
 | 
			
		||||
	c.samples = nil
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Update adds the recorded measurement to the current data set.
 | 
			
		||||
// Update takes a lock to prevent concurrent Update() and SynchronizedMove()
 | 
			
		||||
// calls.
 | 
			
		||||
func (c *Aggregator) Update(_ context.Context, number number.Number, desc *sdkapi.Descriptor) error {
 | 
			
		||||
	now := time.Now()
 | 
			
		||||
	c.lock.Lock()
 | 
			
		||||
	defer c.lock.Unlock()
 | 
			
		||||
	c.samples = append(c.samples, aggregation.Point{
 | 
			
		||||
		Number: number,
 | 
			
		||||
		Time:   now,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Merge combines two data sets into one.
 | 
			
		||||
func (c *Aggregator) Merge(oa export.Aggregator, desc *sdkapi.Descriptor) error {
 | 
			
		||||
	o, _ := oa.(*Aggregator)
 | 
			
		||||
	if o == nil {
 | 
			
		||||
		return aggregator.NewInconsistentAggregatorError(c, oa)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.samples = combine(c.samples, o.samples)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func combine(a, b []aggregation.Point) []aggregation.Point {
 | 
			
		||||
	result := make([]aggregation.Point, 0, len(a)+len(b))
 | 
			
		||||
 | 
			
		||||
	for len(a) != 0 && len(b) != 0 {
 | 
			
		||||
		if a[0].Time.Before(b[0].Time) {
 | 
			
		||||
			result = append(result, a[0])
 | 
			
		||||
			a = a[1:]
 | 
			
		||||
		} else {
 | 
			
		||||
			result = append(result, b[0])
 | 
			
		||||
			b = b[1:]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	result = append(result, a...)
 | 
			
		||||
	result = append(result, b...)
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										270
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/histogram/histogram.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/histogram/histogram.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,270 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package histogram // import "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
	export "go.opentelemetry.io/otel/sdk/export/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/metric/aggregator"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Note: This code uses a Mutex to govern access to the exclusive
 | 
			
		||||
// aggregator state.  This is in contrast to a lock-free approach
 | 
			
		||||
// (as in the Go prometheus client) that was reverted here:
 | 
			
		||||
// https://github.com/open-telemetry/opentelemetry-go/pull/669
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	// Aggregator observe events and counts them in pre-determined buckets.
 | 
			
		||||
	// It also calculates the sum and count of all events.
 | 
			
		||||
	Aggregator struct {
 | 
			
		||||
		lock       sync.Mutex
 | 
			
		||||
		boundaries []float64
 | 
			
		||||
		kind       number.Kind
 | 
			
		||||
		state      *state
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// config describes how the histogram is aggregated.
 | 
			
		||||
	config struct {
 | 
			
		||||
		// explicitBoundaries support arbitrary bucketing schemes.  This
 | 
			
		||||
		// is the general case.
 | 
			
		||||
		explicitBoundaries []float64
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Option configures a histogram config.
 | 
			
		||||
	Option interface {
 | 
			
		||||
		// apply sets one or more config fields.
 | 
			
		||||
		apply(*config)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// state represents the state of a histogram, consisting of
 | 
			
		||||
	// the sum and counts for all observed values and
 | 
			
		||||
	// the less than equal bucket count for the pre-determined boundaries.
 | 
			
		||||
	state struct {
 | 
			
		||||
		bucketCounts []uint64
 | 
			
		||||
		sum          number.Number
 | 
			
		||||
		count        uint64
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// WithExplicitBoundaries sets the ExplicitBoundaries configuration option of a config.
 | 
			
		||||
func WithExplicitBoundaries(explicitBoundaries []float64) Option {
 | 
			
		||||
	return explicitBoundariesOption{explicitBoundaries}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type explicitBoundariesOption struct {
 | 
			
		||||
	boundaries []float64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o explicitBoundariesOption) apply(config *config) {
 | 
			
		||||
	config.explicitBoundaries = o.boundaries
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// defaultExplicitBoundaries have been copied from prometheus.DefBuckets.
 | 
			
		||||
//
 | 
			
		||||
// Note we anticipate the use of a high-precision histogram sketch as
 | 
			
		||||
// the standard histogram aggregator for OTLP export.
 | 
			
		||||
// (https://github.com/open-telemetry/opentelemetry-specification/issues/982).
 | 
			
		||||
var defaultFloat64ExplicitBoundaries = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}
 | 
			
		||||
 | 
			
		||||
// defaultInt64ExplicitBoundaryMultiplier determines the default
 | 
			
		||||
// integer histogram boundaries.
 | 
			
		||||
const defaultInt64ExplicitBoundaryMultiplier = 1e6
 | 
			
		||||
 | 
			
		||||
// defaultInt64ExplicitBoundaries applies a multiplier to the default
 | 
			
		||||
// float64 boundaries: [ 5K, 10K, 25K, ..., 2.5M, 5M, 10M ]
 | 
			
		||||
var defaultInt64ExplicitBoundaries = func(bounds []float64) (asint []float64) {
 | 
			
		||||
	for _, f := range bounds {
 | 
			
		||||
		asint = append(asint, defaultInt64ExplicitBoundaryMultiplier*f)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}(defaultFloat64ExplicitBoundaries)
 | 
			
		||||
 | 
			
		||||
var _ export.Aggregator = &Aggregator{}
 | 
			
		||||
var _ aggregation.Sum = &Aggregator{}
 | 
			
		||||
var _ aggregation.Count = &Aggregator{}
 | 
			
		||||
var _ aggregation.Histogram = &Aggregator{}
 | 
			
		||||
 | 
			
		||||
// New returns a new aggregator for computing Histograms.
 | 
			
		||||
//
 | 
			
		||||
// A Histogram observe events and counts them in pre-defined buckets.
 | 
			
		||||
// And also provides the total sum and count of all observations.
 | 
			
		||||
//
 | 
			
		||||
// Note that this aggregator maintains each value using independent
 | 
			
		||||
// atomic operations, which introduces the possibility that
 | 
			
		||||
// checkpoints are inconsistent.
 | 
			
		||||
func New(cnt int, desc *sdkapi.Descriptor, opts ...Option) []Aggregator {
 | 
			
		||||
	var cfg config
 | 
			
		||||
 | 
			
		||||
	if desc.NumberKind() == number.Int64Kind {
 | 
			
		||||
		cfg.explicitBoundaries = defaultInt64ExplicitBoundaries
 | 
			
		||||
	} else {
 | 
			
		||||
		cfg.explicitBoundaries = defaultFloat64ExplicitBoundaries
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, opt := range opts {
 | 
			
		||||
		opt.apply(&cfg)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	aggs := make([]Aggregator, cnt)
 | 
			
		||||
 | 
			
		||||
	// Boundaries MUST be ordered otherwise the histogram could not
 | 
			
		||||
	// be properly computed.
 | 
			
		||||
	sortedBoundaries := make([]float64, len(cfg.explicitBoundaries))
 | 
			
		||||
 | 
			
		||||
	copy(sortedBoundaries, cfg.explicitBoundaries)
 | 
			
		||||
	sort.Float64s(sortedBoundaries)
 | 
			
		||||
 | 
			
		||||
	for i := range aggs {
 | 
			
		||||
		aggs[i] = Aggregator{
 | 
			
		||||
			kind:       desc.NumberKind(),
 | 
			
		||||
			boundaries: sortedBoundaries,
 | 
			
		||||
		}
 | 
			
		||||
		aggs[i].state = aggs[i].newState()
 | 
			
		||||
	}
 | 
			
		||||
	return aggs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Aggregation returns an interface for reading the state of this aggregator.
 | 
			
		||||
func (c *Aggregator) Aggregation() aggregation.Aggregation {
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Kind returns aggregation.HistogramKind.
 | 
			
		||||
func (c *Aggregator) Kind() aggregation.Kind {
 | 
			
		||||
	return aggregation.HistogramKind
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sum returns the sum of all values in the checkpoint.
 | 
			
		||||
func (c *Aggregator) Sum() (number.Number, error) {
 | 
			
		||||
	return c.state.sum, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Count returns the number of values in the checkpoint.
 | 
			
		||||
func (c *Aggregator) Count() (uint64, error) {
 | 
			
		||||
	return c.state.count, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Histogram returns the count of events in pre-determined buckets.
 | 
			
		||||
func (c *Aggregator) Histogram() (aggregation.Buckets, error) {
 | 
			
		||||
	return aggregation.Buckets{
 | 
			
		||||
		Boundaries: c.boundaries,
 | 
			
		||||
		Counts:     c.state.bucketCounts,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SynchronizedMove saves the current state into oa and resets the current state to
 | 
			
		||||
// the empty set.  Since no locks are taken, there is a chance that
 | 
			
		||||
// the independent Sum, Count and Bucket Count are not consistent with each
 | 
			
		||||
// other.
 | 
			
		||||
func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *sdkapi.Descriptor) error {
 | 
			
		||||
	o, _ := oa.(*Aggregator)
 | 
			
		||||
 | 
			
		||||
	if oa != nil && o == nil {
 | 
			
		||||
		return aggregator.NewInconsistentAggregatorError(c, oa)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if o != nil {
 | 
			
		||||
		// Swap case: This is the ordinary case for a
 | 
			
		||||
		// synchronous instrument, where the SDK allocates two
 | 
			
		||||
		// Aggregators and lock contention is anticipated.
 | 
			
		||||
		// Reset the target state before swapping it under the
 | 
			
		||||
		// lock below.
 | 
			
		||||
		o.clearState()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.lock.Lock()
 | 
			
		||||
	if o != nil {
 | 
			
		||||
		c.state, o.state = o.state, c.state
 | 
			
		||||
	} else {
 | 
			
		||||
		// No swap case: This is the ordinary case for an
 | 
			
		||||
		// asynchronous instrument, where the SDK allocates a
 | 
			
		||||
		// single Aggregator and there is no anticipated lock
 | 
			
		||||
		// contention.
 | 
			
		||||
		c.clearState()
 | 
			
		||||
	}
 | 
			
		||||
	c.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Aggregator) newState() *state {
 | 
			
		||||
	return &state{
 | 
			
		||||
		bucketCounts: make([]uint64, len(c.boundaries)+1),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Aggregator) clearState() {
 | 
			
		||||
	for i := range c.state.bucketCounts {
 | 
			
		||||
		c.state.bucketCounts[i] = 0
 | 
			
		||||
	}
 | 
			
		||||
	c.state.sum = 0
 | 
			
		||||
	c.state.count = 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Update adds the recorded measurement to the current data set.
 | 
			
		||||
func (c *Aggregator) Update(_ context.Context, number number.Number, desc *sdkapi.Descriptor) error {
 | 
			
		||||
	kind := desc.NumberKind()
 | 
			
		||||
	asFloat := number.CoerceToFloat64(kind)
 | 
			
		||||
 | 
			
		||||
	bucketID := len(c.boundaries)
 | 
			
		||||
	for i, boundary := range c.boundaries {
 | 
			
		||||
		if asFloat < boundary {
 | 
			
		||||
			bucketID = i
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// Note: Binary-search was compared using the benchmarks. The following
 | 
			
		||||
	// code is equivalent to the linear search above:
 | 
			
		||||
	//
 | 
			
		||||
	//     bucketID := sort.Search(len(c.boundaries), func(i int) bool {
 | 
			
		||||
	//         return asFloat < c.boundaries[i]
 | 
			
		||||
	//     })
 | 
			
		||||
	//
 | 
			
		||||
	// The binary search wins for very large boundary sets, but
 | 
			
		||||
	// the linear search performs better up through arrays between
 | 
			
		||||
	// 256 and 512 elements, which is a relatively large histogram, so we
 | 
			
		||||
	// continue to prefer linear search.
 | 
			
		||||
 | 
			
		||||
	c.lock.Lock()
 | 
			
		||||
	defer c.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	c.state.count++
 | 
			
		||||
	c.state.sum.AddNumber(kind, number)
 | 
			
		||||
	c.state.bucketCounts[bucketID]++
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Merge combines two histograms that have the same buckets into a single one.
 | 
			
		||||
func (c *Aggregator) Merge(oa export.Aggregator, desc *sdkapi.Descriptor) error {
 | 
			
		||||
	o, _ := oa.(*Aggregator)
 | 
			
		||||
	if o == nil {
 | 
			
		||||
		return aggregator.NewInconsistentAggregatorError(c, oa)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.state.sum.AddNumber(desc.NumberKind(), o.state.sum)
 | 
			
		||||
	c.state.count += o.state.count
 | 
			
		||||
 | 
			
		||||
	for i := 0; i < len(c.state.bucketCounts); i++ {
 | 
			
		||||
		c.state.bucketCounts[i] += o.state.bucketCounts[i]
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										135
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue/lastvalue.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue/lastvalue.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package lastvalue // import "go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
	"time"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
	export "go.opentelemetry.io/otel/sdk/export/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/metric/aggregator"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
 | 
			
		||||
	// Aggregator aggregates lastValue events.
 | 
			
		||||
	Aggregator struct {
 | 
			
		||||
		// value is an atomic pointer to *lastValueData.  It is never nil.
 | 
			
		||||
		value unsafe.Pointer
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// lastValueData stores the current value of a lastValue along with
 | 
			
		||||
	// a sequence number to determine the winner of a race.
 | 
			
		||||
	lastValueData struct {
 | 
			
		||||
		// value is the int64- or float64-encoded Set() data
 | 
			
		||||
		//
 | 
			
		||||
		// value needs to be aligned for 64-bit atomic operations.
 | 
			
		||||
		value number.Number
 | 
			
		||||
 | 
			
		||||
		// timestamp indicates when this record was submitted.
 | 
			
		||||
		// this can be used to pick a winner when multiple
 | 
			
		||||
		// records contain lastValue data for the same labels due
 | 
			
		||||
		// to races.
 | 
			
		||||
		timestamp time.Time
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _ export.Aggregator = &Aggregator{}
 | 
			
		||||
var _ aggregation.LastValue = &Aggregator{}
 | 
			
		||||
 | 
			
		||||
// An unset lastValue has zero timestamp and zero value.
 | 
			
		||||
var unsetLastValue = &lastValueData{}
 | 
			
		||||
 | 
			
		||||
// New returns a new lastValue aggregator.  This aggregator retains the
 | 
			
		||||
// last value and timestamp that were recorded.
 | 
			
		||||
func New(cnt int) []Aggregator {
 | 
			
		||||
	aggs := make([]Aggregator, cnt)
 | 
			
		||||
	for i := range aggs {
 | 
			
		||||
		aggs[i] = Aggregator{
 | 
			
		||||
			value: unsafe.Pointer(unsetLastValue),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return aggs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Aggregation returns an interface for reading the state of this aggregator.
 | 
			
		||||
func (g *Aggregator) Aggregation() aggregation.Aggregation {
 | 
			
		||||
	return g
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Kind returns aggregation.LastValueKind.
 | 
			
		||||
func (g *Aggregator) Kind() aggregation.Kind {
 | 
			
		||||
	return aggregation.LastValueKind
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LastValue returns the last-recorded lastValue value and the
 | 
			
		||||
// corresponding timestamp.  The error value aggregation.ErrNoData
 | 
			
		||||
// will be returned if (due to a race condition) the checkpoint was
 | 
			
		||||
// computed before the first value was set.
 | 
			
		||||
func (g *Aggregator) LastValue() (number.Number, time.Time, error) {
 | 
			
		||||
	gd := (*lastValueData)(g.value)
 | 
			
		||||
	if gd == unsetLastValue {
 | 
			
		||||
		return 0, time.Time{}, aggregation.ErrNoData
 | 
			
		||||
	}
 | 
			
		||||
	return gd.value.AsNumber(), gd.timestamp, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SynchronizedMove atomically saves the current value.
 | 
			
		||||
func (g *Aggregator) SynchronizedMove(oa export.Aggregator, _ *sdkapi.Descriptor) error {
 | 
			
		||||
	if oa == nil {
 | 
			
		||||
		atomic.StorePointer(&g.value, unsafe.Pointer(unsetLastValue))
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	o, _ := oa.(*Aggregator)
 | 
			
		||||
	if o == nil {
 | 
			
		||||
		return aggregator.NewInconsistentAggregatorError(g, oa)
 | 
			
		||||
	}
 | 
			
		||||
	o.value = atomic.SwapPointer(&g.value, unsafe.Pointer(unsetLastValue))
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Update atomically sets the current "last" value.
 | 
			
		||||
func (g *Aggregator) Update(_ context.Context, number number.Number, desc *sdkapi.Descriptor) error {
 | 
			
		||||
	ngd := &lastValueData{
 | 
			
		||||
		value:     number,
 | 
			
		||||
		timestamp: time.Now(),
 | 
			
		||||
	}
 | 
			
		||||
	atomic.StorePointer(&g.value, unsafe.Pointer(ngd))
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Merge combines state from two aggregators.  The most-recently set
 | 
			
		||||
// value is chosen.
 | 
			
		||||
func (g *Aggregator) Merge(oa export.Aggregator, desc *sdkapi.Descriptor) error {
 | 
			
		||||
	o, _ := oa.(*Aggregator)
 | 
			
		||||
	if o == nil {
 | 
			
		||||
		return aggregator.NewInconsistentAggregatorError(g, oa)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ggd := (*lastValueData)(atomic.LoadPointer(&g.value))
 | 
			
		||||
	ogd := (*lastValueData)(atomic.LoadPointer(&o.value))
 | 
			
		||||
 | 
			
		||||
	if ggd.timestamp.After(ogd.timestamp) {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g.value = unsafe.Pointer(ogd)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										165
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount/mmsc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount/mmsc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package minmaxsumcount // import "go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
	export "go.opentelemetry.io/otel/sdk/export/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/metric/aggregator"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	// Aggregator aggregates events that form a distribution,
 | 
			
		||||
	// keeping only the min, max, sum, and count.
 | 
			
		||||
	Aggregator struct {
 | 
			
		||||
		lock sync.Mutex
 | 
			
		||||
		kind number.Kind
 | 
			
		||||
		state
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	state struct {
 | 
			
		||||
		sum   number.Number
 | 
			
		||||
		min   number.Number
 | 
			
		||||
		max   number.Number
 | 
			
		||||
		count uint64
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _ export.Aggregator = &Aggregator{}
 | 
			
		||||
var _ aggregation.MinMaxSumCount = &Aggregator{}
 | 
			
		||||
 | 
			
		||||
// New returns a new aggregator for computing the min, max, sum, and
 | 
			
		||||
// count.
 | 
			
		||||
//
 | 
			
		||||
// This type uses a mutex for Update() and SynchronizedMove() concurrency.
 | 
			
		||||
func New(cnt int, desc *sdkapi.Descriptor) []Aggregator {
 | 
			
		||||
	kind := desc.NumberKind()
 | 
			
		||||
	aggs := make([]Aggregator, cnt)
 | 
			
		||||
	for i := range aggs {
 | 
			
		||||
		aggs[i] = Aggregator{
 | 
			
		||||
			kind:  kind,
 | 
			
		||||
			state: emptyState(kind),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return aggs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Aggregation returns an interface for reading the state of this aggregator.
 | 
			
		||||
func (c *Aggregator) Aggregation() aggregation.Aggregation {
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Kind returns aggregation.MinMaxSumCountKind.
 | 
			
		||||
func (c *Aggregator) Kind() aggregation.Kind {
 | 
			
		||||
	return aggregation.MinMaxSumCountKind
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sum returns the sum of values in the checkpoint.
 | 
			
		||||
func (c *Aggregator) Sum() (number.Number, error) {
 | 
			
		||||
	return c.sum, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Count returns the number of values in the checkpoint.
 | 
			
		||||
func (c *Aggregator) Count() (uint64, error) {
 | 
			
		||||
	return c.count, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Min returns the minimum value in the checkpoint.
 | 
			
		||||
// The error value aggregation.ErrNoData will be returned
 | 
			
		||||
// if there were no measurements recorded during the checkpoint.
 | 
			
		||||
func (c *Aggregator) Min() (number.Number, error) {
 | 
			
		||||
	if c.count == 0 {
 | 
			
		||||
		return 0, aggregation.ErrNoData
 | 
			
		||||
	}
 | 
			
		||||
	return c.min, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Max returns the maximum value in the checkpoint.
 | 
			
		||||
// The error value aggregation.ErrNoData will be returned
 | 
			
		||||
// if there were no measurements recorded during the checkpoint.
 | 
			
		||||
func (c *Aggregator) Max() (number.Number, error) {
 | 
			
		||||
	if c.count == 0 {
 | 
			
		||||
		return 0, aggregation.ErrNoData
 | 
			
		||||
	}
 | 
			
		||||
	return c.max, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SynchronizedMove saves the current state into oa and resets the current state to
 | 
			
		||||
// the empty set.
 | 
			
		||||
func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *sdkapi.Descriptor) error {
 | 
			
		||||
	o, _ := oa.(*Aggregator)
 | 
			
		||||
 | 
			
		||||
	if oa != nil && o == nil {
 | 
			
		||||
		return aggregator.NewInconsistentAggregatorError(c, oa)
 | 
			
		||||
	}
 | 
			
		||||
	c.lock.Lock()
 | 
			
		||||
	if o != nil {
 | 
			
		||||
		o.state = c.state
 | 
			
		||||
	}
 | 
			
		||||
	c.state = emptyState(c.kind)
 | 
			
		||||
	c.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func emptyState(kind number.Kind) state {
 | 
			
		||||
	return state{
 | 
			
		||||
		count: 0,
 | 
			
		||||
		sum:   0,
 | 
			
		||||
		min:   kind.Maximum(),
 | 
			
		||||
		max:   kind.Minimum(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Update adds the recorded measurement to the current data set.
 | 
			
		||||
func (c *Aggregator) Update(_ context.Context, number number.Number, desc *sdkapi.Descriptor) error {
 | 
			
		||||
	kind := desc.NumberKind()
 | 
			
		||||
 | 
			
		||||
	c.lock.Lock()
 | 
			
		||||
	defer c.lock.Unlock()
 | 
			
		||||
	c.count++
 | 
			
		||||
	c.sum.AddNumber(kind, number)
 | 
			
		||||
	if number.CompareNumber(kind, c.min) < 0 {
 | 
			
		||||
		c.min = number
 | 
			
		||||
	}
 | 
			
		||||
	if number.CompareNumber(kind, c.max) > 0 {
 | 
			
		||||
		c.max = number
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Merge combines two data sets into one.
 | 
			
		||||
func (c *Aggregator) Merge(oa export.Aggregator, desc *sdkapi.Descriptor) error {
 | 
			
		||||
	o, _ := oa.(*Aggregator)
 | 
			
		||||
	if o == nil {
 | 
			
		||||
		return aggregator.NewInconsistentAggregatorError(c, oa)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.count += o.count
 | 
			
		||||
	c.sum.AddNumber(desc.NumberKind(), o.sum)
 | 
			
		||||
 | 
			
		||||
	if c.min.CompareNumber(desc.NumberKind(), o.min) > 0 {
 | 
			
		||||
		c.min.SetNumber(o.min)
 | 
			
		||||
	}
 | 
			
		||||
	if c.max.CompareNumber(desc.NumberKind(), o.max) < 0 {
 | 
			
		||||
		c.max.SetNumber(o.max)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										106
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/sum/sum.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/sum/sum.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package sum // import "go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
	export "go.opentelemetry.io/otel/sdk/export/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/metric/aggregator"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Aggregator aggregates counter events.
 | 
			
		||||
type Aggregator struct {
 | 
			
		||||
	// current holds current increments to this counter record
 | 
			
		||||
	// current needs to be aligned for 64-bit atomic operations.
 | 
			
		||||
	value number.Number
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ export.Aggregator = &Aggregator{}
 | 
			
		||||
var _ export.Subtractor = &Aggregator{}
 | 
			
		||||
var _ aggregation.Sum = &Aggregator{}
 | 
			
		||||
 | 
			
		||||
// New returns a new counter aggregator implemented by atomic
 | 
			
		||||
// operations.  This aggregator implements the aggregation.Sum
 | 
			
		||||
// export interface.
 | 
			
		||||
func New(cnt int) []Aggregator {
 | 
			
		||||
	return make([]Aggregator, cnt)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Aggregation returns an interface for reading the state of this aggregator.
 | 
			
		||||
func (c *Aggregator) Aggregation() aggregation.Aggregation {
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Kind returns aggregation.SumKind.
 | 
			
		||||
func (c *Aggregator) Kind() aggregation.Kind {
 | 
			
		||||
	return aggregation.SumKind
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sum returns the last-checkpointed sum.  This will never return an
 | 
			
		||||
// error.
 | 
			
		||||
func (c *Aggregator) Sum() (number.Number, error) {
 | 
			
		||||
	return c.value, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SynchronizedMove atomically saves the current value into oa and resets the
 | 
			
		||||
// current sum to zero.
 | 
			
		||||
func (c *Aggregator) SynchronizedMove(oa export.Aggregator, _ *sdkapi.Descriptor) error {
 | 
			
		||||
	if oa == nil {
 | 
			
		||||
		c.value.SetRawAtomic(0)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	o, _ := oa.(*Aggregator)
 | 
			
		||||
	if o == nil {
 | 
			
		||||
		return aggregator.NewInconsistentAggregatorError(c, oa)
 | 
			
		||||
	}
 | 
			
		||||
	o.value = c.value.SwapNumberAtomic(number.Number(0))
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Update atomically adds to the current value.
 | 
			
		||||
func (c *Aggregator) Update(_ context.Context, num number.Number, desc *sdkapi.Descriptor) error {
 | 
			
		||||
	c.value.AddNumberAtomic(desc.NumberKind(), num)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Merge combines two counters by adding their sums.
 | 
			
		||||
func (c *Aggregator) Merge(oa export.Aggregator, desc *sdkapi.Descriptor) error {
 | 
			
		||||
	o, _ := oa.(*Aggregator)
 | 
			
		||||
	if o == nil {
 | 
			
		||||
		return aggregator.NewInconsistentAggregatorError(c, oa)
 | 
			
		||||
	}
 | 
			
		||||
	c.value.AddNumber(desc.NumberKind(), o.value)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Aggregator) Subtract(opAgg, resAgg export.Aggregator, descriptor *sdkapi.Descriptor) error {
 | 
			
		||||
	op, _ := opAgg.(*Aggregator)
 | 
			
		||||
	if op == nil {
 | 
			
		||||
		return aggregator.NewInconsistentAggregatorError(c, opAgg)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	res, _ := resAgg.(*Aggregator)
 | 
			
		||||
	if res == nil {
 | 
			
		||||
		return aggregator.NewInconsistentAggregatorError(c, resAgg)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	res.value = c.value
 | 
			
		||||
	res.value.AddNumber(descriptor.NumberKind(), number.NewNumberSignChange(descriptor.NumberKind(), op.value))
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/atomicfields.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/atomicfields.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package metric // import "go.opentelemetry.io/otel/sdk/metric"
 | 
			
		||||
 | 
			
		||||
import "unsafe"
 | 
			
		||||
 | 
			
		||||
func AtomicFieldOffsets() map[string]uintptr {
 | 
			
		||||
	return map[string]uintptr{
 | 
			
		||||
		"record.refMapped.value": unsafe.Offsetof(record{}.refMapped.value),
 | 
			
		||||
		"record.updateCount":     unsafe.Offsetof(record{}.updateCount),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										126
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/controller/basic/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/controller/basic/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,126 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package basic // import "go.opentelemetry.io/otel/sdk/metric/controller/basic"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel"
 | 
			
		||||
	export "go.opentelemetry.io/otel/sdk/export/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/resource"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// config contains configuration for a basic Controller.
 | 
			
		||||
type config struct {
 | 
			
		||||
	// Resource is the OpenTelemetry resource associated with all Meters
 | 
			
		||||
	// created by the Controller.
 | 
			
		||||
	Resource *resource.Resource
 | 
			
		||||
 | 
			
		||||
	// CollectPeriod is the interval between calls to Collect a
 | 
			
		||||
	// checkpoint.
 | 
			
		||||
	//
 | 
			
		||||
	// When pulling metrics and not exporting, this is the minimum
 | 
			
		||||
	// time between calls to Collect.  In a pull-only
 | 
			
		||||
	// configuration, collection is performed on demand; set
 | 
			
		||||
	// CollectPeriod to 0 always recompute the export record set.
 | 
			
		||||
	//
 | 
			
		||||
	// When exporting metrics, this must be > 0.
 | 
			
		||||
	//
 | 
			
		||||
	// Default value is 10s.
 | 
			
		||||
	CollectPeriod time.Duration
 | 
			
		||||
 | 
			
		||||
	// CollectTimeout is the timeout of the Context passed to
 | 
			
		||||
	// Collect() and subsequently to Observer instrument callbacks.
 | 
			
		||||
	//
 | 
			
		||||
	// Default value is 10s.  If zero, no Collect timeout is applied.
 | 
			
		||||
	CollectTimeout time.Duration
 | 
			
		||||
 | 
			
		||||
	// Exporter is used for exporting metric data.
 | 
			
		||||
	//
 | 
			
		||||
	// Note: Exporters such as Prometheus that pull data do not implement
 | 
			
		||||
	// export.Exporter.  These will directly call Collect() and ForEach().
 | 
			
		||||
	Exporter export.Exporter
 | 
			
		||||
 | 
			
		||||
	// PushTimeout is the timeout of the Context when a exporter is configured.
 | 
			
		||||
	//
 | 
			
		||||
	// Default value is 10s.  If zero, no Export timeout is applied.
 | 
			
		||||
	PushTimeout time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Option is the interface that applies the value to a configuration option.
 | 
			
		||||
type Option interface {
 | 
			
		||||
	// apply sets the Option value of a Config.
 | 
			
		||||
	apply(*config)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithResource sets the Resource configuration option of a Config by merging it
 | 
			
		||||
// with the Resource configuration in the environment.
 | 
			
		||||
func WithResource(r *resource.Resource) Option {
 | 
			
		||||
	return resourceOption{r}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type resourceOption struct{ *resource.Resource }
 | 
			
		||||
 | 
			
		||||
func (o resourceOption) apply(cfg *config) {
 | 
			
		||||
	res, err := resource.Merge(cfg.Resource, o.Resource)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		otel.Handle(err)
 | 
			
		||||
	}
 | 
			
		||||
	cfg.Resource = res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithCollectPeriod sets the CollectPeriod configuration option of a Config.
 | 
			
		||||
func WithCollectPeriod(period time.Duration) Option {
 | 
			
		||||
	return collectPeriodOption(period)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type collectPeriodOption time.Duration
 | 
			
		||||
 | 
			
		||||
func (o collectPeriodOption) apply(cfg *config) {
 | 
			
		||||
	cfg.CollectPeriod = time.Duration(o)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithCollectTimeout sets the CollectTimeout configuration option of a Config.
 | 
			
		||||
func WithCollectTimeout(timeout time.Duration) Option {
 | 
			
		||||
	return collectTimeoutOption(timeout)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type collectTimeoutOption time.Duration
 | 
			
		||||
 | 
			
		||||
func (o collectTimeoutOption) apply(cfg *config) {
 | 
			
		||||
	cfg.CollectTimeout = time.Duration(o)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithExporter sets the exporter configuration option of a Config.
 | 
			
		||||
func WithExporter(exporter export.Exporter) Option {
 | 
			
		||||
	return exporterOption{exporter}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type exporterOption struct{ exporter export.Exporter }
 | 
			
		||||
 | 
			
		||||
func (o exporterOption) apply(cfg *config) {
 | 
			
		||||
	cfg.Exporter = o.exporter
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithPushTimeout sets the PushTimeout configuration option of a Config.
 | 
			
		||||
func WithPushTimeout(timeout time.Duration) Option {
 | 
			
		||||
	return pushTimeoutOption(timeout)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type pushTimeoutOption time.Duration
 | 
			
		||||
 | 
			
		||||
func (o pushTimeoutOption) apply(cfg *config) {
 | 
			
		||||
	cfg.PushTimeout = time.Duration(o)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										388
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/controller/basic/controller.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										388
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/controller/basic/controller.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,388 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package basic // import "go.opentelemetry.io/otel/sdk/metric/controller/basic"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel"
 | 
			
		||||
	"go.opentelemetry.io/otel/internal/metric/registry"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric"
 | 
			
		||||
	export "go.opentelemetry.io/otel/sdk/export/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/instrumentation"
 | 
			
		||||
	sdk "go.opentelemetry.io/otel/sdk/metric"
 | 
			
		||||
	controllerTime "go.opentelemetry.io/otel/sdk/metric/controller/time"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/resource"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DefaultPeriod is used for:
 | 
			
		||||
//
 | 
			
		||||
// - the minimum time between calls to Collect()
 | 
			
		||||
// - the timeout for Export()
 | 
			
		||||
// - the timeout for Collect().
 | 
			
		||||
const DefaultPeriod = 10 * time.Second
 | 
			
		||||
 | 
			
		||||
// ErrControllerStarted indicates that a controller was started more
 | 
			
		||||
// than once.
 | 
			
		||||
var ErrControllerStarted = fmt.Errorf("controller already started")
 | 
			
		||||
 | 
			
		||||
// Controller organizes and synchronizes collection of metric data in
 | 
			
		||||
// both "pull" and "push" configurations.  This supports two distinct
 | 
			
		||||
// modes:
 | 
			
		||||
//
 | 
			
		||||
// - Push and Pull: Start() must be called to begin calling the exporter;
 | 
			
		||||
//   Collect() is called periodically by a background thread after starting
 | 
			
		||||
//   the controller.
 | 
			
		||||
// - Pull-Only: Start() is optional in this case, to call Collect periodically.
 | 
			
		||||
//   If Start() is not called, Collect() can be called manually to initiate
 | 
			
		||||
//   collection
 | 
			
		||||
//
 | 
			
		||||
// The controller supports mixing push and pull access to metric data
 | 
			
		||||
// using the export.Reader RWLock interface.  Collection will
 | 
			
		||||
// be blocked by a pull request in the basic controller.
 | 
			
		||||
type Controller struct {
 | 
			
		||||
	// lock protects libraries and synchronizes Start() and Stop().
 | 
			
		||||
	lock sync.Mutex
 | 
			
		||||
	// TODO: libraries is synchronized by lock, but could be
 | 
			
		||||
	// accomplished using a sync.Map.  The SDK specification will
 | 
			
		||||
	// probably require this, as the draft already states that
 | 
			
		||||
	// Stop() and MeterProvider.Meter() should not block each
 | 
			
		||||
	// other.
 | 
			
		||||
	libraries           map[instrumentation.Library]*registry.UniqueInstrumentMeterImpl
 | 
			
		||||
	checkpointerFactory export.CheckpointerFactory
 | 
			
		||||
 | 
			
		||||
	resource *resource.Resource
 | 
			
		||||
	exporter export.Exporter
 | 
			
		||||
	wg       sync.WaitGroup
 | 
			
		||||
	stopCh   chan struct{}
 | 
			
		||||
	clock    controllerTime.Clock
 | 
			
		||||
	ticker   controllerTime.Ticker
 | 
			
		||||
 | 
			
		||||
	collectPeriod  time.Duration
 | 
			
		||||
	collectTimeout time.Duration
 | 
			
		||||
	pushTimeout    time.Duration
 | 
			
		||||
 | 
			
		||||
	// collectedTime is used only in configurations with no
 | 
			
		||||
	// exporter, when ticker != nil.
 | 
			
		||||
	collectedTime time.Time
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ export.InstrumentationLibraryReader = &Controller{}
 | 
			
		||||
var _ metric.MeterProvider = &Controller{}
 | 
			
		||||
 | 
			
		||||
func (c *Controller) Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter {
 | 
			
		||||
	cfg := metric.NewMeterConfig(opts...)
 | 
			
		||||
	library := instrumentation.Library{
 | 
			
		||||
		Name:      instrumentationName,
 | 
			
		||||
		Version:   cfg.InstrumentationVersion(),
 | 
			
		||||
		SchemaURL: cfg.SchemaURL(),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.lock.Lock()
 | 
			
		||||
	defer c.lock.Unlock()
 | 
			
		||||
	m, ok := c.libraries[library]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		checkpointer := c.checkpointerFactory.NewCheckpointer()
 | 
			
		||||
		accumulator := sdk.NewAccumulator(checkpointer)
 | 
			
		||||
		m = registry.NewUniqueInstrumentMeterImpl(&accumulatorCheckpointer{
 | 
			
		||||
			Accumulator:  accumulator,
 | 
			
		||||
			checkpointer: checkpointer,
 | 
			
		||||
			library:      library,
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		c.libraries[library] = m
 | 
			
		||||
	}
 | 
			
		||||
	return metric.WrapMeterImpl(m)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type accumulatorCheckpointer struct {
 | 
			
		||||
	*sdk.Accumulator
 | 
			
		||||
	checkpointer export.Checkpointer
 | 
			
		||||
	library      instrumentation.Library
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// New constructs a Controller using the provided checkpointer factory
 | 
			
		||||
// and options (including optional exporter) to configure a metric
 | 
			
		||||
// export pipeline.
 | 
			
		||||
func New(checkpointerFactory export.CheckpointerFactory, opts ...Option) *Controller {
 | 
			
		||||
	c := &config{
 | 
			
		||||
		CollectPeriod:  DefaultPeriod,
 | 
			
		||||
		CollectTimeout: DefaultPeriod,
 | 
			
		||||
		PushTimeout:    DefaultPeriod,
 | 
			
		||||
	}
 | 
			
		||||
	for _, opt := range opts {
 | 
			
		||||
		opt.apply(c)
 | 
			
		||||
	}
 | 
			
		||||
	if c.Resource == nil {
 | 
			
		||||
		c.Resource = resource.Default()
 | 
			
		||||
	} else {
 | 
			
		||||
		var err error
 | 
			
		||||
		c.Resource, err = resource.Merge(resource.Environment(), c.Resource)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			otel.Handle(err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return &Controller{
 | 
			
		||||
		libraries:           map[instrumentation.Library]*registry.UniqueInstrumentMeterImpl{},
 | 
			
		||||
		checkpointerFactory: checkpointerFactory,
 | 
			
		||||
		exporter:            c.Exporter,
 | 
			
		||||
		resource:            c.Resource,
 | 
			
		||||
		stopCh:              nil,
 | 
			
		||||
		clock:               controllerTime.RealClock{},
 | 
			
		||||
 | 
			
		||||
		collectPeriod:  c.CollectPeriod,
 | 
			
		||||
		collectTimeout: c.CollectTimeout,
 | 
			
		||||
		pushTimeout:    c.PushTimeout,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetClock supports setting a mock clock for testing.  This must be
 | 
			
		||||
// called before Start().
 | 
			
		||||
func (c *Controller) SetClock(clock controllerTime.Clock) {
 | 
			
		||||
	c.lock.Lock()
 | 
			
		||||
	defer c.lock.Unlock()
 | 
			
		||||
	c.clock = clock
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Resource returns the *resource.Resource associated with this
 | 
			
		||||
// controller.
 | 
			
		||||
func (c *Controller) Resource() *resource.Resource {
 | 
			
		||||
	return c.resource
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Start begins a ticker that periodically collects and exports
 | 
			
		||||
// metrics with the configured interval.  This is required for calling
 | 
			
		||||
// a configured Exporter (see WithExporter) and is otherwise optional
 | 
			
		||||
// when only pulling metric data.
 | 
			
		||||
//
 | 
			
		||||
// The passed context is passed to Collect() and subsequently to
 | 
			
		||||
// asynchronous instrument callbacks.  Returns an error when the
 | 
			
		||||
// controller was already started.
 | 
			
		||||
//
 | 
			
		||||
// Note that it is not necessary to Start a controller when only
 | 
			
		||||
// pulling data; use the Collect() and ForEach() methods directly in
 | 
			
		||||
// this case.
 | 
			
		||||
func (c *Controller) Start(ctx context.Context) error {
 | 
			
		||||
	c.lock.Lock()
 | 
			
		||||
	defer c.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	if c.stopCh != nil {
 | 
			
		||||
		return ErrControllerStarted
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.wg.Add(1)
 | 
			
		||||
	c.stopCh = make(chan struct{})
 | 
			
		||||
	c.ticker = c.clock.Ticker(c.collectPeriod)
 | 
			
		||||
	go c.runTicker(ctx, c.stopCh)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stop waits for the background goroutine to return and then collects
 | 
			
		||||
// and exports metrics one last time before returning.  The passed
 | 
			
		||||
// context is passed to the final Collect() and subsequently to the
 | 
			
		||||
// final asynchronous instruments.
 | 
			
		||||
//
 | 
			
		||||
// Note that Stop() will not cancel an ongoing collection or export.
 | 
			
		||||
func (c *Controller) Stop(ctx context.Context) error {
 | 
			
		||||
	if lastCollection := func() bool {
 | 
			
		||||
		c.lock.Lock()
 | 
			
		||||
		defer c.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
		if c.stopCh == nil {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		close(c.stopCh)
 | 
			
		||||
		c.stopCh = nil
 | 
			
		||||
		c.wg.Wait()
 | 
			
		||||
		c.ticker.Stop()
 | 
			
		||||
		c.ticker = nil
 | 
			
		||||
		return true
 | 
			
		||||
	}(); !lastCollection {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return c.collect(ctx)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// runTicker collection on ticker events until the stop channel is closed.
 | 
			
		||||
func (c *Controller) runTicker(ctx context.Context, stopCh chan struct{}) {
 | 
			
		||||
	defer c.wg.Done()
 | 
			
		||||
	for {
 | 
			
		||||
		select {
 | 
			
		||||
		case <-stopCh:
 | 
			
		||||
			return
 | 
			
		||||
		case <-c.ticker.C():
 | 
			
		||||
			if err := c.collect(ctx); err != nil {
 | 
			
		||||
				otel.Handle(err)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// collect computes a checkpoint and optionally exports it.
 | 
			
		||||
func (c *Controller) collect(ctx context.Context) error {
 | 
			
		||||
	if err := c.checkpoint(ctx); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if c.exporter == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Note: this is not subject to collectTimeout.  This blocks the next
 | 
			
		||||
	// collection despite collectTimeout because it holds a lock.
 | 
			
		||||
	return c.export(ctx)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// accumulatorList returns a snapshot of current accumulators
 | 
			
		||||
// registered to this controller.  This briefly locks the controller.
 | 
			
		||||
func (c *Controller) accumulatorList() []*accumulatorCheckpointer {
 | 
			
		||||
	c.lock.Lock()
 | 
			
		||||
	defer c.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	var r []*accumulatorCheckpointer
 | 
			
		||||
	for _, entry := range c.libraries {
 | 
			
		||||
		acc, ok := entry.MeterImpl().(*accumulatorCheckpointer)
 | 
			
		||||
		if ok {
 | 
			
		||||
			r = append(r, acc)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return r
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// checkpoint calls the Accumulator and Checkpointer interfaces to
 | 
			
		||||
// compute the Reader.  This applies the configured collection
 | 
			
		||||
// timeout.  Note that this does not try to cancel a Collect or Export
 | 
			
		||||
// when Stop() is called.
 | 
			
		||||
func (c *Controller) checkpoint(ctx context.Context) error {
 | 
			
		||||
	for _, impl := range c.accumulatorList() {
 | 
			
		||||
		if err := c.checkpointSingleAccumulator(ctx, impl); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// checkpointSingleAccumulator checkpoints a single instrumentation
 | 
			
		||||
// library's accumulator, which involves calling
 | 
			
		||||
// checkpointer.StartCollection, accumulator.Collect, and
 | 
			
		||||
// checkpointer.FinishCollection in sequence.
 | 
			
		||||
func (c *Controller) checkpointSingleAccumulator(ctx context.Context, ac *accumulatorCheckpointer) error {
 | 
			
		||||
	ckpt := ac.checkpointer.Reader()
 | 
			
		||||
	ckpt.Lock()
 | 
			
		||||
	defer ckpt.Unlock()
 | 
			
		||||
 | 
			
		||||
	ac.checkpointer.StartCollection()
 | 
			
		||||
 | 
			
		||||
	if c.collectTimeout > 0 {
 | 
			
		||||
		var cancel context.CancelFunc
 | 
			
		||||
		ctx, cancel = context.WithTimeout(ctx, c.collectTimeout)
 | 
			
		||||
		defer cancel()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_ = ac.Accumulator.Collect(ctx)
 | 
			
		||||
 | 
			
		||||
	var err error
 | 
			
		||||
	select {
 | 
			
		||||
	case <-ctx.Done():
 | 
			
		||||
		err = ctx.Err()
 | 
			
		||||
	default:
 | 
			
		||||
		// The context wasn't done, ok.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Finish the checkpoint whether the accumulator timed out or not.
 | 
			
		||||
	if cerr := ac.checkpointer.FinishCollection(); cerr != nil {
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			err = cerr
 | 
			
		||||
		} else {
 | 
			
		||||
			err = fmt.Errorf("%s: %w", cerr.Error(), err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// export calls the exporter with a read lock on the Reader,
 | 
			
		||||
// applying the configured export timeout.
 | 
			
		||||
func (c *Controller) export(ctx context.Context) error {
 | 
			
		||||
	if c.pushTimeout > 0 {
 | 
			
		||||
		var cancel context.CancelFunc
 | 
			
		||||
		ctx, cancel = context.WithTimeout(ctx, c.pushTimeout)
 | 
			
		||||
		defer cancel()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c.exporter.Export(ctx, c.resource, c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ForEach implements export.InstrumentationLibraryReader.
 | 
			
		||||
func (c *Controller) ForEach(readerFunc func(l instrumentation.Library, r export.Reader) error) error {
 | 
			
		||||
	for _, acPair := range c.accumulatorList() {
 | 
			
		||||
		reader := acPair.checkpointer.Reader()
 | 
			
		||||
		// TODO: We should not fail fast; instead accumulate errors.
 | 
			
		||||
		if err := func() error {
 | 
			
		||||
			reader.RLock()
 | 
			
		||||
			defer reader.RUnlock()
 | 
			
		||||
			return readerFunc(acPair.library, reader)
 | 
			
		||||
		}(); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsRunning returns true if the controller was started via Start(),
 | 
			
		||||
// indicating that the current export.Reader is being kept
 | 
			
		||||
// up-to-date.
 | 
			
		||||
func (c *Controller) IsRunning() bool {
 | 
			
		||||
	c.lock.Lock()
 | 
			
		||||
	defer c.lock.Unlock()
 | 
			
		||||
	return c.ticker != nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Collect requests a collection.  The collection will be skipped if
 | 
			
		||||
// the last collection is aged less than the configured collection
 | 
			
		||||
// period.
 | 
			
		||||
func (c *Controller) Collect(ctx context.Context) error {
 | 
			
		||||
	if c.IsRunning() {
 | 
			
		||||
		// When there's a non-nil ticker, there's a goroutine
 | 
			
		||||
		// computing checkpoints with the collection period.
 | 
			
		||||
		return ErrControllerStarted
 | 
			
		||||
	}
 | 
			
		||||
	if !c.shouldCollect() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c.checkpoint(ctx)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// shouldCollect returns true if the collector should collect now,
 | 
			
		||||
// based on the timestamp, the last collection time, and the
 | 
			
		||||
// configured period.
 | 
			
		||||
func (c *Controller) shouldCollect() bool {
 | 
			
		||||
	c.lock.Lock()
 | 
			
		||||
	defer c.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	if c.collectPeriod == 0 {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	now := c.clock.Now()
 | 
			
		||||
	if now.Sub(c.collectedTime) < c.collectPeriod {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	c.collectedTime = now
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										59
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/controller/time/time.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/controller/time/time.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package time // import "go.opentelemetry.io/otel/sdk/metric/controller/time"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
	lib "time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Several types below are created to match "github.com/benbjohnson/clock"
 | 
			
		||||
// so that it remains a test-only dependency.
 | 
			
		||||
 | 
			
		||||
type Clock interface {
 | 
			
		||||
	Now() lib.Time
 | 
			
		||||
	Ticker(duration lib.Duration) Ticker
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Ticker interface {
 | 
			
		||||
	Stop()
 | 
			
		||||
	C() <-chan lib.Time
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type RealClock struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type RealTicker struct {
 | 
			
		||||
	ticker *lib.Ticker
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ Clock = RealClock{}
 | 
			
		||||
var _ Ticker = RealTicker{}
 | 
			
		||||
 | 
			
		||||
func (RealClock) Now() time.Time {
 | 
			
		||||
	return time.Now()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (RealClock) Ticker(period time.Duration) Ticker {
 | 
			
		||||
	return RealTicker{time.NewTicker(period)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t RealTicker) Stop() {
 | 
			
		||||
	t.ticker.Stop()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t RealTicker) C() <-chan time.Time {
 | 
			
		||||
	return t.ticker.C
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										141
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Package metric implements the OpenTelemetry metric API.
 | 
			
		||||
 | 
			
		||||
This package is currently in a pre-GA phase. Backwards incompatible changes
 | 
			
		||||
may be introduced in subsequent minor version releases as we work to track the
 | 
			
		||||
evolving OpenTelemetry specification and user feedback.
 | 
			
		||||
 | 
			
		||||
The Accumulator type supports configurable metrics export behavior through a
 | 
			
		||||
collection of export interfaces that support various export strategies,
 | 
			
		||||
described below.
 | 
			
		||||
 | 
			
		||||
The OpenTelemetry metric API consists of methods for constructing synchronous
 | 
			
		||||
and asynchronous instruments.  There are two constructors per instrument for
 | 
			
		||||
the two kinds of number (int64, float64).
 | 
			
		||||
 | 
			
		||||
Synchronous instruments are managed by a sync.Map containing a *record
 | 
			
		||||
with the current state for each synchronous instrument.  A bound
 | 
			
		||||
instrument encapsulates a direct pointer to the record, allowing
 | 
			
		||||
bound metric events to bypass a sync.Map lookup.  A lock-free
 | 
			
		||||
algorithm is used to protect against races when adding and removing
 | 
			
		||||
items from the sync.Map.
 | 
			
		||||
 | 
			
		||||
Asynchronous instruments are managed by an internal
 | 
			
		||||
AsyncInstrumentState, which coordinates calling batch and single
 | 
			
		||||
instrument callbacks.
 | 
			
		||||
 | 
			
		||||
Internal Structure
 | 
			
		||||
 | 
			
		||||
Each observer also has its own kind of record stored in the SDK. This
 | 
			
		||||
record contains a set of recorders for every specific label set used in the
 | 
			
		||||
callback.
 | 
			
		||||
 | 
			
		||||
A sync.Map maintains the mapping of current instruments and label sets to
 | 
			
		||||
internal records.  To create a new bound instrument, the SDK consults the Map to
 | 
			
		||||
locate an existing record, otherwise it constructs a new record.  The SDK
 | 
			
		||||
maintains a count of the number of references to each record, ensuring
 | 
			
		||||
that records are not reclaimed from the Map while they are still active
 | 
			
		||||
from the user's perspective.
 | 
			
		||||
 | 
			
		||||
Metric collection is performed via a single-threaded call to Collect that
 | 
			
		||||
sweeps through all records in the SDK, checkpointing their state.  When a
 | 
			
		||||
record is discovered that has no references and has not been updated since
 | 
			
		||||
the prior collection pass, it is removed from the Map.
 | 
			
		||||
 | 
			
		||||
Both synchronous and asynchronous instruments have an associated
 | 
			
		||||
aggregator, which maintains the current state resulting from all metric
 | 
			
		||||
events since its last checkpoint.  Aggregators may be lock-free or they may
 | 
			
		||||
use locking, but they should expect to be called concurrently.  Aggregators
 | 
			
		||||
must be capable of merging with another aggregator of the same type.
 | 
			
		||||
 | 
			
		||||
Export Pipeline
 | 
			
		||||
 | 
			
		||||
While the SDK serves to maintain a current set of records and
 | 
			
		||||
coordinate collection, the behavior of a metrics export pipeline is
 | 
			
		||||
configured through the export types in
 | 
			
		||||
go.opentelemetry.io/otel/sdk/export/metric.  It is important to keep
 | 
			
		||||
in mind the context these interfaces are called from.  There are two
 | 
			
		||||
contexts, instrumentation context, where a user-level goroutine that
 | 
			
		||||
enters the SDK resulting in a new record, and collection context,
 | 
			
		||||
where a system-level thread performs a collection pass through the
 | 
			
		||||
SDK.
 | 
			
		||||
 | 
			
		||||
Descriptor is a struct that describes the metric instrument to the
 | 
			
		||||
export pipeline, containing the name, units, description, metric kind,
 | 
			
		||||
number kind (int64 or float64).  A Descriptor accompanies metric data
 | 
			
		||||
as it passes through the export pipeline.
 | 
			
		||||
 | 
			
		||||
The AggregatorSelector interface supports choosing the method of
 | 
			
		||||
aggregation to apply to a particular instrument, by delegating the
 | 
			
		||||
construction of an Aggregator to this interface.  Given the Descriptor,
 | 
			
		||||
the AggregatorFor method returns an implementation of Aggregator.  If this
 | 
			
		||||
interface returns nil, the metric will be disabled.  The aggregator should
 | 
			
		||||
be matched to the capabilities of the exporter.  Selecting the aggregator
 | 
			
		||||
for Adding instruments is relatively straightforward, but many options
 | 
			
		||||
are available for aggregating distributions from Grouping instruments.
 | 
			
		||||
 | 
			
		||||
Aggregator is an interface which implements a concrete strategy for
 | 
			
		||||
aggregating metric updates.  Several Aggregator implementations are
 | 
			
		||||
provided by the SDK.  Aggregators may be lock-free or use locking,
 | 
			
		||||
depending on their structure and semantics.  Aggregators implement an
 | 
			
		||||
Update method, called in instrumentation context, to receive a single
 | 
			
		||||
metric event.  Aggregators implement a Checkpoint method, called in
 | 
			
		||||
collection context, to save a checkpoint of the current state.
 | 
			
		||||
Aggregators implement a Merge method, also called in collection
 | 
			
		||||
context, that combines state from two aggregators into one.  Each SDK
 | 
			
		||||
record has an associated aggregator.
 | 
			
		||||
 | 
			
		||||
Processor is an interface which sits between the SDK and an exporter.
 | 
			
		||||
The Processor embeds an AggregatorSelector, used by the SDK to assign
 | 
			
		||||
new Aggregators.  The Processor supports a Process() API for submitting
 | 
			
		||||
checkpointed aggregators to the processor, and a Reader() API
 | 
			
		||||
for producing a complete checkpoint for the exporter.  Two default
 | 
			
		||||
Processor implementations are provided, the "defaultkeys" Processor groups
 | 
			
		||||
aggregate metrics by their recommended Descriptor.Keys(), the
 | 
			
		||||
"simple" Processor aggregates metrics at full dimensionality.
 | 
			
		||||
 | 
			
		||||
LabelEncoder is an optional optimization that allows an exporter to
 | 
			
		||||
provide the serialization logic for labels.  This allows avoiding
 | 
			
		||||
duplicate serialization of labels, once as a unique key in the SDK (or
 | 
			
		||||
Processor) and once in the exporter.
 | 
			
		||||
 | 
			
		||||
Reader is an interface between the Processor and the Exporter.
 | 
			
		||||
After completing a collection pass, the Processor.Reader() method
 | 
			
		||||
returns a Reader, which the Exporter uses to iterate over all
 | 
			
		||||
the updated metrics.
 | 
			
		||||
 | 
			
		||||
Record is a struct containing the state of an individual exported
 | 
			
		||||
metric.  This is the result of one collection interface for one
 | 
			
		||||
instrument and one label set.
 | 
			
		||||
 | 
			
		||||
Labels is a struct containing an ordered set of labels, the
 | 
			
		||||
corresponding unique encoding, and the encoder that produced it.
 | 
			
		||||
 | 
			
		||||
Exporter is the final stage of an export pipeline.  It is called with
 | 
			
		||||
a Reader capable of enumerating all the updated metrics.
 | 
			
		||||
 | 
			
		||||
Controller is not an export interface per se, but it orchestrates the
 | 
			
		||||
export pipeline.  For example, a "push" controller will establish a
 | 
			
		||||
periodic timer to regularly collect and export metrics.  A "pull"
 | 
			
		||||
controller will await a pull request before initiating metric
 | 
			
		||||
collection.  Either way, the job of the controller is to call the SDK
 | 
			
		||||
Collect() method, then read the checkpoint, then invoke the exporter.
 | 
			
		||||
Controllers are expected to implement the public metric.MeterProvider
 | 
			
		||||
API, meaning they can be installed as the global Meter provider.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
package metric // import "go.opentelemetry.io/otel/sdk/metric"
 | 
			
		||||
							
								
								
									
										396
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/processor/basic/basic.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										396
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/processor/basic/basic.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,396 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package basic // import "go.opentelemetry.io/otel/sdk/metric/processor/basic"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
	export "go.opentelemetry.io/otel/sdk/export/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	Processor struct {
 | 
			
		||||
		aggregation.TemporalitySelector
 | 
			
		||||
		export.AggregatorSelector
 | 
			
		||||
 | 
			
		||||
		state
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stateKey struct {
 | 
			
		||||
		// TODO: This code is organized to support multiple
 | 
			
		||||
		// accumulators which could theoretically produce the
 | 
			
		||||
		// data for the same instrument, and this code has
 | 
			
		||||
		// logic to combine data properly from multiple
 | 
			
		||||
		// accumulators.  However, the use of
 | 
			
		||||
		// *sdkapi.Descriptor in the stateKey makes such
 | 
			
		||||
		// combination impossible, because each accumulator
 | 
			
		||||
		// allocates its own instruments.  This can be fixed
 | 
			
		||||
		// by using the instrument name and kind instead of
 | 
			
		||||
		// the descriptor pointer.  See
 | 
			
		||||
		// https://github.com/open-telemetry/opentelemetry-go/issues/862.
 | 
			
		||||
		descriptor *sdkapi.Descriptor
 | 
			
		||||
		distinct   attribute.Distinct
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stateValue struct {
 | 
			
		||||
		// labels corresponds to the stateKey.distinct field.
 | 
			
		||||
		labels *attribute.Set
 | 
			
		||||
 | 
			
		||||
		// updated indicates the last sequence number when this value had
 | 
			
		||||
		// Process() called by an accumulator.
 | 
			
		||||
		updated int64
 | 
			
		||||
 | 
			
		||||
		// stateful indicates that a cumulative aggregation is
 | 
			
		||||
		// being maintained, taken from the process start time.
 | 
			
		||||
		stateful bool
 | 
			
		||||
 | 
			
		||||
		// currentOwned indicates that "current" was allocated
 | 
			
		||||
		// by the processor in order to merge results from
 | 
			
		||||
		// multiple Accumulators during a single collection
 | 
			
		||||
		// round, which may happen either because:
 | 
			
		||||
		// (1) multiple Accumulators output the same Accumulation.
 | 
			
		||||
		// (2) one Accumulator is configured with dimensionality reduction.
 | 
			
		||||
		currentOwned bool
 | 
			
		||||
 | 
			
		||||
		// current refers to the output from a single Accumulator
 | 
			
		||||
		// (if !currentOwned) or it refers to an Aggregator
 | 
			
		||||
		// owned by the processor used to accumulate multiple
 | 
			
		||||
		// values in a single collection round.
 | 
			
		||||
		current export.Aggregator
 | 
			
		||||
 | 
			
		||||
		// delta, if non-nil, refers to an Aggregator owned by
 | 
			
		||||
		// the processor used to compute deltas between
 | 
			
		||||
		// precomputed sums.
 | 
			
		||||
		delta export.Aggregator
 | 
			
		||||
 | 
			
		||||
		// cumulative, if non-nil, refers to an Aggregator owned
 | 
			
		||||
		// by the processor used to store the last cumulative
 | 
			
		||||
		// value.
 | 
			
		||||
		cumulative export.Aggregator
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	state struct {
 | 
			
		||||
		config config
 | 
			
		||||
 | 
			
		||||
		// RWMutex implements locking for the `Reader` interface.
 | 
			
		||||
		sync.RWMutex
 | 
			
		||||
		values map[stateKey]*stateValue
 | 
			
		||||
 | 
			
		||||
		// Note: the timestamp logic currently assumes all
 | 
			
		||||
		// exports are deltas.
 | 
			
		||||
 | 
			
		||||
		processStart  time.Time
 | 
			
		||||
		intervalStart time.Time
 | 
			
		||||
		intervalEnd   time.Time
 | 
			
		||||
 | 
			
		||||
		// startedCollection and finishedCollection are the
 | 
			
		||||
		// number of StartCollection() and FinishCollection()
 | 
			
		||||
		// calls, used to ensure that the sequence of starts
 | 
			
		||||
		// and finishes are correctly balanced.
 | 
			
		||||
 | 
			
		||||
		startedCollection  int64
 | 
			
		||||
		finishedCollection int64
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _ export.Processor = &Processor{}
 | 
			
		||||
var _ export.Checkpointer = &Processor{}
 | 
			
		||||
var _ export.Reader = &state{}
 | 
			
		||||
 | 
			
		||||
// ErrInconsistentState is returned when the sequence of collection's starts and finishes are incorrectly balanced.
 | 
			
		||||
var ErrInconsistentState = fmt.Errorf("inconsistent processor state")
 | 
			
		||||
 | 
			
		||||
// ErrInvalidTemporality is returned for unknown metric.Temporality.
 | 
			
		||||
var ErrInvalidTemporality = fmt.Errorf("invalid aggregation temporality")
 | 
			
		||||
 | 
			
		||||
// New returns a basic Processor that is also a Checkpointer using the provided
 | 
			
		||||
// AggregatorSelector to select Aggregators.  The TemporalitySelector
 | 
			
		||||
// is consulted to determine the kind(s) of exporter that will consume
 | 
			
		||||
// data, so that this Processor can prepare to compute Delta or
 | 
			
		||||
// Cumulative Aggregations as needed.
 | 
			
		||||
func New(aselector export.AggregatorSelector, tselector aggregation.TemporalitySelector, opts ...Option) *Processor {
 | 
			
		||||
	return NewFactory(aselector, tselector, opts...).NewCheckpointer().(*Processor)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type factory struct {
 | 
			
		||||
	aselector export.AggregatorSelector
 | 
			
		||||
	tselector aggregation.TemporalitySelector
 | 
			
		||||
	config    config
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewFactory(aselector export.AggregatorSelector, tselector aggregation.TemporalitySelector, opts ...Option) export.CheckpointerFactory {
 | 
			
		||||
	var config config
 | 
			
		||||
	for _, opt := range opts {
 | 
			
		||||
		opt.applyProcessor(&config)
 | 
			
		||||
	}
 | 
			
		||||
	return factory{
 | 
			
		||||
		aselector: aselector,
 | 
			
		||||
		tselector: tselector,
 | 
			
		||||
		config:    config,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ export.CheckpointerFactory = factory{}
 | 
			
		||||
 | 
			
		||||
func (f factory) NewCheckpointer() export.Checkpointer {
 | 
			
		||||
	now := time.Now()
 | 
			
		||||
	p := &Processor{
 | 
			
		||||
		AggregatorSelector:  f.aselector,
 | 
			
		||||
		TemporalitySelector: f.tselector,
 | 
			
		||||
		state: state{
 | 
			
		||||
			values:        map[stateKey]*stateValue{},
 | 
			
		||||
			processStart:  now,
 | 
			
		||||
			intervalStart: now,
 | 
			
		||||
			config:        f.config,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	return p
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Process implements export.Processor.
 | 
			
		||||
func (b *Processor) Process(accum export.Accumulation) error {
 | 
			
		||||
	if b.startedCollection != b.finishedCollection+1 {
 | 
			
		||||
		return ErrInconsistentState
 | 
			
		||||
	}
 | 
			
		||||
	desc := accum.Descriptor()
 | 
			
		||||
	key := stateKey{
 | 
			
		||||
		descriptor: desc,
 | 
			
		||||
		distinct:   accum.Labels().Equivalent(),
 | 
			
		||||
	}
 | 
			
		||||
	agg := accum.Aggregator()
 | 
			
		||||
 | 
			
		||||
	// Check if there is an existing value.
 | 
			
		||||
	value, ok := b.state.values[key]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		stateful := b.TemporalityFor(desc, agg.Aggregation().Kind()).MemoryRequired(desc.InstrumentKind())
 | 
			
		||||
 | 
			
		||||
		newValue := &stateValue{
 | 
			
		||||
			labels:   accum.Labels(),
 | 
			
		||||
			updated:  b.state.finishedCollection,
 | 
			
		||||
			stateful: stateful,
 | 
			
		||||
			current:  agg,
 | 
			
		||||
		}
 | 
			
		||||
		if stateful {
 | 
			
		||||
			if desc.InstrumentKind().PrecomputedSum() {
 | 
			
		||||
				// If we know we need to compute deltas, allocate two aggregators.
 | 
			
		||||
				b.AggregatorFor(desc, &newValue.cumulative, &newValue.delta)
 | 
			
		||||
			} else {
 | 
			
		||||
				// In this case we are certain not to need a delta, only allocate
 | 
			
		||||
				// a cumulative aggregator.
 | 
			
		||||
				b.AggregatorFor(desc, &newValue.cumulative)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		b.state.values[key] = newValue
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Advance the update sequence number.
 | 
			
		||||
	sameCollection := b.state.finishedCollection == value.updated
 | 
			
		||||
	value.updated = b.state.finishedCollection
 | 
			
		||||
 | 
			
		||||
	// At this point in the code, we have located an existing
 | 
			
		||||
	// value for some stateKey.  This can be because:
 | 
			
		||||
	//
 | 
			
		||||
	// (a) stateful aggregation is being used, the entry was
 | 
			
		||||
	// entered during a prior collection, and this is the first
 | 
			
		||||
	// time processing an accumulation for this stateKey in the
 | 
			
		||||
	// current collection.  Since this is the first time
 | 
			
		||||
	// processing an accumulation for this stateKey during this
 | 
			
		||||
	// collection, we don't know yet whether there are multiple
 | 
			
		||||
	// accumulators at work.  If there are multiple accumulators,
 | 
			
		||||
	// they'll hit case (b) the second time through.
 | 
			
		||||
	//
 | 
			
		||||
	// (b) multiple accumulators are being used, whether stateful
 | 
			
		||||
	// or not.
 | 
			
		||||
	//
 | 
			
		||||
	// Case (a) occurs when the instrument and the exporter
 | 
			
		||||
	// require memory to work correctly, either because the
 | 
			
		||||
	// instrument reports a PrecomputedSum to a DeltaExporter or
 | 
			
		||||
	// the reverse, a non-PrecomputedSum instrument with a
 | 
			
		||||
	// CumulativeExporter.  This logic is encapsulated in
 | 
			
		||||
	// Temporality.MemoryRequired(InstrumentKind).
 | 
			
		||||
	//
 | 
			
		||||
	// Case (b) occurs when the variable `sameCollection` is true,
 | 
			
		||||
	// indicating that the stateKey for Accumulation has already
 | 
			
		||||
	// been seen in the same collection.  When this happens, it
 | 
			
		||||
	// implies that multiple Accumulators are being used, or that
 | 
			
		||||
	// a single Accumulator has been configured with a label key
 | 
			
		||||
	// filter.
 | 
			
		||||
 | 
			
		||||
	if !sameCollection {
 | 
			
		||||
		if !value.currentOwned {
 | 
			
		||||
			// This is the first Accumulation we've seen
 | 
			
		||||
			// for this stateKey during this collection.
 | 
			
		||||
			// Just keep a reference to the Accumulator's
 | 
			
		||||
			// Aggregator.  All the other cases copy
 | 
			
		||||
			// Aggregator state.
 | 
			
		||||
			value.current = agg
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
		return agg.SynchronizedMove(value.current, desc)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If the current is not owned, take ownership of a copy
 | 
			
		||||
	// before merging below.
 | 
			
		||||
	if !value.currentOwned {
 | 
			
		||||
		tmp := value.current
 | 
			
		||||
		b.AggregatorSelector.AggregatorFor(desc, &value.current)
 | 
			
		||||
		value.currentOwned = true
 | 
			
		||||
		if err := tmp.SynchronizedMove(value.current, desc); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Combine this Accumulation with the prior Accumulation.
 | 
			
		||||
	return value.current.Merge(agg, desc)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Reader returns the associated Reader.  Use the
 | 
			
		||||
// Reader Locker interface to synchronize access to this
 | 
			
		||||
// object.  The Reader.ForEach() method cannot be called
 | 
			
		||||
// concurrently with Process().
 | 
			
		||||
func (b *Processor) Reader() export.Reader {
 | 
			
		||||
	return &b.state
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StartCollection signals to the Processor one or more Accumulators
 | 
			
		||||
// will begin calling Process() calls during collection.
 | 
			
		||||
func (b *Processor) StartCollection() {
 | 
			
		||||
	if b.startedCollection != 0 {
 | 
			
		||||
		b.intervalStart = b.intervalEnd
 | 
			
		||||
	}
 | 
			
		||||
	b.startedCollection++
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FinishCollection signals to the Processor that a complete
 | 
			
		||||
// collection has finished and that ForEach will be called to access
 | 
			
		||||
// the Reader.
 | 
			
		||||
func (b *Processor) FinishCollection() error {
 | 
			
		||||
	b.intervalEnd = time.Now()
 | 
			
		||||
	if b.startedCollection != b.finishedCollection+1 {
 | 
			
		||||
		return ErrInconsistentState
 | 
			
		||||
	}
 | 
			
		||||
	defer func() { b.finishedCollection++ }()
 | 
			
		||||
 | 
			
		||||
	for key, value := range b.values {
 | 
			
		||||
		mkind := key.descriptor.InstrumentKind()
 | 
			
		||||
		stale := value.updated != b.finishedCollection
 | 
			
		||||
		stateless := !value.stateful
 | 
			
		||||
 | 
			
		||||
		// The following branch updates stateful aggregators.  Skip
 | 
			
		||||
		// these updates if the aggregator is not stateful or if the
 | 
			
		||||
		// aggregator is stale.
 | 
			
		||||
		if stale || stateless {
 | 
			
		||||
			// If this processor does not require memeory,
 | 
			
		||||
			// stale, stateless entries can be removed.
 | 
			
		||||
			// This implies that they were not updated
 | 
			
		||||
			// over the previous full collection interval.
 | 
			
		||||
			if stale && stateless && !b.config.Memory {
 | 
			
		||||
				delete(b.values, key)
 | 
			
		||||
			}
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Update Aggregator state to support exporting either a
 | 
			
		||||
		// delta or a cumulative aggregation.
 | 
			
		||||
		var err error
 | 
			
		||||
		if mkind.PrecomputedSum() {
 | 
			
		||||
			if currentSubtractor, ok := value.current.(export.Subtractor); ok {
 | 
			
		||||
				// This line is equivalent to:
 | 
			
		||||
				// value.delta = currentSubtractor - value.cumulative
 | 
			
		||||
				err = currentSubtractor.Subtract(value.cumulative, value.delta, key.descriptor)
 | 
			
		||||
 | 
			
		||||
				if err == nil {
 | 
			
		||||
					err = value.current.SynchronizedMove(value.cumulative, key.descriptor)
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				err = aggregation.ErrNoSubtraction
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			// This line is equivalent to:
 | 
			
		||||
			// value.cumulative = value.cumulative + value.delta
 | 
			
		||||
			err = value.cumulative.Merge(value.current, key.descriptor)
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ForEach iterates through the Reader, passing an
 | 
			
		||||
// export.Record with the appropriate Cumulative or Delta aggregation
 | 
			
		||||
// to an exporter.
 | 
			
		||||
func (b *state) ForEach(exporter aggregation.TemporalitySelector, f func(export.Record) error) error {
 | 
			
		||||
	if b.startedCollection != b.finishedCollection {
 | 
			
		||||
		return ErrInconsistentState
 | 
			
		||||
	}
 | 
			
		||||
	for key, value := range b.values {
 | 
			
		||||
		mkind := key.descriptor.InstrumentKind()
 | 
			
		||||
 | 
			
		||||
		var agg aggregation.Aggregation
 | 
			
		||||
		var start time.Time
 | 
			
		||||
 | 
			
		||||
		// If the processor does not have Config.Memory and it was not updated
 | 
			
		||||
		// in the prior round, do not visit this value.
 | 
			
		||||
		if !b.config.Memory && value.updated != (b.finishedCollection-1) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		aggTemp := exporter.TemporalityFor(key.descriptor, value.current.Aggregation().Kind())
 | 
			
		||||
		switch aggTemp {
 | 
			
		||||
		case aggregation.CumulativeTemporality:
 | 
			
		||||
			// If stateful, the sum has been computed.  If stateless, the
 | 
			
		||||
			// input was already cumulative.  Either way, use the checkpointed
 | 
			
		||||
			// value:
 | 
			
		||||
			if value.stateful {
 | 
			
		||||
				agg = value.cumulative.Aggregation()
 | 
			
		||||
			} else {
 | 
			
		||||
				agg = value.current.Aggregation()
 | 
			
		||||
			}
 | 
			
		||||
			start = b.processStart
 | 
			
		||||
 | 
			
		||||
		case aggregation.DeltaTemporality:
 | 
			
		||||
			// Precomputed sums are a special case.
 | 
			
		||||
			if mkind.PrecomputedSum() {
 | 
			
		||||
				agg = value.delta.Aggregation()
 | 
			
		||||
			} else {
 | 
			
		||||
				agg = value.current.Aggregation()
 | 
			
		||||
			}
 | 
			
		||||
			start = b.intervalStart
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			return fmt.Errorf("%v: %w", aggTemp, ErrInvalidTemporality)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if err := f(export.NewRecord(
 | 
			
		||||
			key.descriptor,
 | 
			
		||||
			value.labels,
 | 
			
		||||
			agg,
 | 
			
		||||
			start,
 | 
			
		||||
			b.intervalEnd,
 | 
			
		||||
		)); err != nil && !errors.Is(err, aggregation.ErrNoData) {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/processor/basic/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/processor/basic/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package basic // import "go.opentelemetry.io/otel/sdk/metric/processor/basic"
 | 
			
		||||
 | 
			
		||||
// config contains the options for configuring a basic metric processor.
 | 
			
		||||
type config struct {
 | 
			
		||||
	// Memory controls whether the processor remembers metric
 | 
			
		||||
	// instruments and label sets that were previously reported.
 | 
			
		||||
	// When Memory is true, Reader.ForEach() will visit
 | 
			
		||||
	// metrics that were not updated in the most recent interval.
 | 
			
		||||
	Memory bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Option interface {
 | 
			
		||||
	applyProcessor(*config)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithMemory sets the memory behavior of a Processor.  If this is
 | 
			
		||||
// true, the processor will report metric instruments and label sets
 | 
			
		||||
// that were previously reported but not updated in the most recent
 | 
			
		||||
// interval.
 | 
			
		||||
func WithMemory(memory bool) Option {
 | 
			
		||||
	return memoryOption(memory)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type memoryOption bool
 | 
			
		||||
 | 
			
		||||
func (m memoryOption) applyProcessor(cfg *config) {
 | 
			
		||||
	cfg.Memory = bool(m)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										59
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/refcount_mapped.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/refcount_mapped.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package metric // import "go.opentelemetry.io/otel/sdk/metric"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// refcountMapped atomically counts the number of references (usages) of an entry
 | 
			
		||||
// while also keeping a state of mapped/unmapped into a different data structure
 | 
			
		||||
// (an external map or list for example).
 | 
			
		||||
//
 | 
			
		||||
// refcountMapped uses an atomic value where the least significant bit is used to
 | 
			
		||||
// keep the state of mapping ('1' is used for unmapped and '0' is for mapped) and
 | 
			
		||||
// the rest of the bits are used for refcounting.
 | 
			
		||||
type refcountMapped struct {
 | 
			
		||||
	// refcount has to be aligned for 64-bit atomic operations.
 | 
			
		||||
	value int64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ref returns true if the entry is still mapped and increases the
 | 
			
		||||
// reference usages, if unmapped returns false.
 | 
			
		||||
func (rm *refcountMapped) ref() bool {
 | 
			
		||||
	// Check if this entry was marked as unmapped between the moment
 | 
			
		||||
	// we got a reference to it (or will be removed very soon) and here.
 | 
			
		||||
	return atomic.AddInt64(&rm.value, 2)&1 == 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (rm *refcountMapped) unref() {
 | 
			
		||||
	atomic.AddInt64(&rm.value, -2)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// tryUnmap flips the mapped bit to "unmapped" state and returns true if both of the
 | 
			
		||||
// following conditions are true upon entry to this function:
 | 
			
		||||
//  * There are no active references;
 | 
			
		||||
//  * The mapped bit is in "mapped" state.
 | 
			
		||||
// Otherwise no changes are done to mapped bit and false is returned.
 | 
			
		||||
func (rm *refcountMapped) tryUnmap() bool {
 | 
			
		||||
	if atomic.LoadInt64(&rm.value) != 0 {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return atomic.CompareAndSwapInt64(
 | 
			
		||||
		&rm.value,
 | 
			
		||||
		0,
 | 
			
		||||
		1,
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										551
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/sdk.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										551
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/sdk.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,551 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package metric // import "go.opentelemetry.io/otel/sdk/metric"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel"
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	internal "go.opentelemetry.io/otel/internal/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/number"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
	export "go.opentelemetry.io/otel/sdk/export/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/metric/aggregator"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	// Accumulator implements the OpenTelemetry Meter API.  The
 | 
			
		||||
	// Accumulator is bound to a single export.Processor in
 | 
			
		||||
	// `NewAccumulator()`.
 | 
			
		||||
	//
 | 
			
		||||
	// The Accumulator supports a Collect() API to gather and export
 | 
			
		||||
	// current data.  Collect() should be arranged according to
 | 
			
		||||
	// the processor model.  Push-based processors will setup a
 | 
			
		||||
	// timer to call Collect() periodically.  Pull-based processors
 | 
			
		||||
	// will call Collect() when a pull request arrives.
 | 
			
		||||
	Accumulator struct {
 | 
			
		||||
		// current maps `mapkey` to *record.
 | 
			
		||||
		current sync.Map
 | 
			
		||||
 | 
			
		||||
		// asyncInstruments is a set of
 | 
			
		||||
		// `*asyncInstrument` instances
 | 
			
		||||
		asyncLock        sync.Mutex
 | 
			
		||||
		asyncInstruments *internal.AsyncInstrumentState
 | 
			
		||||
 | 
			
		||||
		// currentEpoch is the current epoch number. It is
 | 
			
		||||
		// incremented in `Collect()`.
 | 
			
		||||
		currentEpoch int64
 | 
			
		||||
 | 
			
		||||
		// processor is the configured processor+configuration.
 | 
			
		||||
		processor export.Processor
 | 
			
		||||
 | 
			
		||||
		// collectLock prevents simultaneous calls to Collect().
 | 
			
		||||
		collectLock sync.Mutex
 | 
			
		||||
 | 
			
		||||
		// asyncSortSlice has a single purpose - as a temporary
 | 
			
		||||
		// place for sorting during labels creation to avoid
 | 
			
		||||
		// allocation.  It is cleared after use.
 | 
			
		||||
		asyncSortSlice attribute.Sortable
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	syncInstrument struct {
 | 
			
		||||
		instrument
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// mapkey uniquely describes a metric instrument in terms of
 | 
			
		||||
	// its InstrumentID and the encoded form of its labels.
 | 
			
		||||
	mapkey struct {
 | 
			
		||||
		descriptor *sdkapi.Descriptor
 | 
			
		||||
		ordered    attribute.Distinct
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// record maintains the state of one metric instrument.  Due
 | 
			
		||||
	// the use of lock-free algorithms, there may be more than one
 | 
			
		||||
	// `record` in existence at a time, although at most one can
 | 
			
		||||
	// be referenced from the `Accumulator.current` map.
 | 
			
		||||
	record struct {
 | 
			
		||||
		// refMapped keeps track of refcounts and the mapping state to the
 | 
			
		||||
		// Accumulator.current map.
 | 
			
		||||
		refMapped refcountMapped
 | 
			
		||||
 | 
			
		||||
		// updateCount is incremented on every Update.
 | 
			
		||||
		updateCount int64
 | 
			
		||||
 | 
			
		||||
		// collectedCount is set to updateCount on collection,
 | 
			
		||||
		// supports checking for no updates during a round.
 | 
			
		||||
		collectedCount int64
 | 
			
		||||
 | 
			
		||||
		// storage is the stored label set for this record,
 | 
			
		||||
		// except in cases where a label set is shared due to
 | 
			
		||||
		// batch recording.
 | 
			
		||||
		storage attribute.Set
 | 
			
		||||
 | 
			
		||||
		// labels is the processed label set for this record.
 | 
			
		||||
		// this may refer to the `storage` field in another
 | 
			
		||||
		// record if this label set is shared resulting from
 | 
			
		||||
		// `RecordBatch`.
 | 
			
		||||
		labels *attribute.Set
 | 
			
		||||
 | 
			
		||||
		// sortSlice has a single purpose - as a temporary
 | 
			
		||||
		// place for sorting during labels creation to avoid
 | 
			
		||||
		// allocation.
 | 
			
		||||
		sortSlice attribute.Sortable
 | 
			
		||||
 | 
			
		||||
		// inst is a pointer to the corresponding instrument.
 | 
			
		||||
		inst *syncInstrument
 | 
			
		||||
 | 
			
		||||
		// current implements the actual RecordOne() API,
 | 
			
		||||
		// depending on the type of aggregation.  If nil, the
 | 
			
		||||
		// metric was disabled by the exporter.
 | 
			
		||||
		current    export.Aggregator
 | 
			
		||||
		checkpoint export.Aggregator
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	instrument struct {
 | 
			
		||||
		meter      *Accumulator
 | 
			
		||||
		descriptor sdkapi.Descriptor
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	asyncInstrument struct {
 | 
			
		||||
		instrument
 | 
			
		||||
		// recorders maps ordered labels to the pair of
 | 
			
		||||
		// labelset and recorder
 | 
			
		||||
		recorders map[attribute.Distinct]*labeledRecorder
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	labeledRecorder struct {
 | 
			
		||||
		observedEpoch int64
 | 
			
		||||
		labels        *attribute.Set
 | 
			
		||||
		observed      export.Aggregator
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_ sdkapi.MeterImpl     = &Accumulator{}
 | 
			
		||||
	_ sdkapi.AsyncImpl     = &asyncInstrument{}
 | 
			
		||||
	_ sdkapi.SyncImpl      = &syncInstrument{}
 | 
			
		||||
	_ sdkapi.BoundSyncImpl = &record{}
 | 
			
		||||
 | 
			
		||||
	// ErrUninitializedInstrument is returned when an instrument is used when uninitialized.
 | 
			
		||||
	ErrUninitializedInstrument = fmt.Errorf("use of an uninitialized instrument")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (inst *instrument) Descriptor() sdkapi.Descriptor {
 | 
			
		||||
	return inst.descriptor
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *asyncInstrument) Implementation() interface{} {
 | 
			
		||||
	return a
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *syncInstrument) Implementation() interface{} {
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *asyncInstrument) observe(num number.Number, labels *attribute.Set) {
 | 
			
		||||
	if err := aggregator.RangeTest(num, &a.descriptor); err != nil {
 | 
			
		||||
		otel.Handle(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	recorder := a.getRecorder(labels)
 | 
			
		||||
	if recorder == nil {
 | 
			
		||||
		// The instrument is disabled according to the
 | 
			
		||||
		// AggregatorSelector.
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if err := recorder.Update(context.Background(), num, &a.descriptor); err != nil {
 | 
			
		||||
		otel.Handle(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *asyncInstrument) getRecorder(labels *attribute.Set) export.Aggregator {
 | 
			
		||||
	lrec, ok := a.recorders[labels.Equivalent()]
 | 
			
		||||
	if ok {
 | 
			
		||||
		// Note: SynchronizedMove(nil) can't return an error
 | 
			
		||||
		_ = lrec.observed.SynchronizedMove(nil, &a.descriptor)
 | 
			
		||||
		lrec.observedEpoch = a.meter.currentEpoch
 | 
			
		||||
		a.recorders[labels.Equivalent()] = lrec
 | 
			
		||||
		return lrec.observed
 | 
			
		||||
	}
 | 
			
		||||
	var rec export.Aggregator
 | 
			
		||||
	a.meter.processor.AggregatorFor(&a.descriptor, &rec)
 | 
			
		||||
	if a.recorders == nil {
 | 
			
		||||
		a.recorders = make(map[attribute.Distinct]*labeledRecorder)
 | 
			
		||||
	}
 | 
			
		||||
	// This may store nil recorder in the map, thus disabling the
 | 
			
		||||
	// asyncInstrument for the labelset for good. This is intentional,
 | 
			
		||||
	// but will be revisited later.
 | 
			
		||||
	a.recorders[labels.Equivalent()] = &labeledRecorder{
 | 
			
		||||
		observed:      rec,
 | 
			
		||||
		labels:        labels,
 | 
			
		||||
		observedEpoch: a.meter.currentEpoch,
 | 
			
		||||
	}
 | 
			
		||||
	return rec
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// acquireHandle gets or creates a `*record` corresponding to `kvs`,
 | 
			
		||||
// the input labels.  The second argument `labels` is passed in to
 | 
			
		||||
// support re-use of the orderedLabels computed by a previous
 | 
			
		||||
// measurement in the same batch.   This performs two allocations
 | 
			
		||||
// in the common case.
 | 
			
		||||
func (s *syncInstrument) acquireHandle(kvs []attribute.KeyValue, labelPtr *attribute.Set) *record {
 | 
			
		||||
	var rec *record
 | 
			
		||||
	var equiv attribute.Distinct
 | 
			
		||||
 | 
			
		||||
	if labelPtr == nil {
 | 
			
		||||
		// This memory allocation may not be used, but it's
 | 
			
		||||
		// needed for the `sortSlice` field, to avoid an
 | 
			
		||||
		// allocation while sorting.
 | 
			
		||||
		rec = &record{}
 | 
			
		||||
		rec.storage = attribute.NewSetWithSortable(kvs, &rec.sortSlice)
 | 
			
		||||
		rec.labels = &rec.storage
 | 
			
		||||
		equiv = rec.storage.Equivalent()
 | 
			
		||||
	} else {
 | 
			
		||||
		equiv = labelPtr.Equivalent()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Create lookup key for sync.Map (one allocation, as this
 | 
			
		||||
	// passes through an interface{})
 | 
			
		||||
	mk := mapkey{
 | 
			
		||||
		descriptor: &s.descriptor,
 | 
			
		||||
		ordered:    equiv,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if actual, ok := s.meter.current.Load(mk); ok {
 | 
			
		||||
		// Existing record case.
 | 
			
		||||
		existingRec := actual.(*record)
 | 
			
		||||
		if existingRec.refMapped.ref() {
 | 
			
		||||
			// At this moment it is guaranteed that the entry is in
 | 
			
		||||
			// the map and will not be removed.
 | 
			
		||||
			return existingRec
 | 
			
		||||
		}
 | 
			
		||||
		// This entry is no longer mapped, try to add a new entry.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if rec == nil {
 | 
			
		||||
		rec = &record{}
 | 
			
		||||
		rec.labels = labelPtr
 | 
			
		||||
	}
 | 
			
		||||
	rec.refMapped = refcountMapped{value: 2}
 | 
			
		||||
	rec.inst = s
 | 
			
		||||
 | 
			
		||||
	s.meter.processor.AggregatorFor(&s.descriptor, &rec.current, &rec.checkpoint)
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		// Load/Store: there's a memory allocation to place `mk` into
 | 
			
		||||
		// an interface here.
 | 
			
		||||
		if actual, loaded := s.meter.current.LoadOrStore(mk, rec); loaded {
 | 
			
		||||
			// Existing record case. Cannot change rec here because if fail
 | 
			
		||||
			// will try to add rec again to avoid new allocations.
 | 
			
		||||
			oldRec := actual.(*record)
 | 
			
		||||
			if oldRec.refMapped.ref() {
 | 
			
		||||
				// At this moment it is guaranteed that the entry is in
 | 
			
		||||
				// the map and will not be removed.
 | 
			
		||||
				return oldRec
 | 
			
		||||
			}
 | 
			
		||||
			// This loaded entry is marked as unmapped (so Collect will remove
 | 
			
		||||
			// it from the map immediately), try again - this is a busy waiting
 | 
			
		||||
			// strategy to wait until Collect() removes this entry from the map.
 | 
			
		||||
			//
 | 
			
		||||
			// This can be improved by having a list of "Unmapped" entries for
 | 
			
		||||
			// one time only usages, OR we can make this a blocking path and use
 | 
			
		||||
			// a Mutex that protects the delete operation (delete only if the old
 | 
			
		||||
			// record is associated with the key).
 | 
			
		||||
 | 
			
		||||
			// Let collector get work done to remove the entry from the map.
 | 
			
		||||
			runtime.Gosched()
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		// The new entry was added to the map, good to go.
 | 
			
		||||
		return rec
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// The order of the input array `kvs` may be sorted after the function is called.
 | 
			
		||||
func (s *syncInstrument) Bind(kvs []attribute.KeyValue) sdkapi.BoundSyncImpl {
 | 
			
		||||
	return s.acquireHandle(kvs, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// The order of the input array `kvs` may be sorted after the function is called.
 | 
			
		||||
func (s *syncInstrument) RecordOne(ctx context.Context, num number.Number, kvs []attribute.KeyValue) {
 | 
			
		||||
	h := s.acquireHandle(kvs, nil)
 | 
			
		||||
	defer h.Unbind()
 | 
			
		||||
	h.RecordOne(ctx, num)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewAccumulator constructs a new Accumulator for the given
 | 
			
		||||
// processor.  This Accumulator supports only a single processor.
 | 
			
		||||
//
 | 
			
		||||
// The Accumulator does not start any background process to collect itself
 | 
			
		||||
// periodically, this responsibility lies with the processor, typically,
 | 
			
		||||
// depending on the type of export.  For example, a pull-based
 | 
			
		||||
// processor will call Collect() when it receives a request to scrape
 | 
			
		||||
// current metric values.  A push-based processor should configure its
 | 
			
		||||
// own periodic collection.
 | 
			
		||||
func NewAccumulator(processor export.Processor) *Accumulator {
 | 
			
		||||
	return &Accumulator{
 | 
			
		||||
		processor:        processor,
 | 
			
		||||
		asyncInstruments: internal.NewAsyncInstrumentState(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSyncInstrument implements sdkapi.MetricImpl.
 | 
			
		||||
func (m *Accumulator) NewSyncInstrument(descriptor sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
 | 
			
		||||
	return &syncInstrument{
 | 
			
		||||
		instrument: instrument{
 | 
			
		||||
			descriptor: descriptor,
 | 
			
		||||
			meter:      m,
 | 
			
		||||
		},
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewAsyncInstrument implements sdkapi.MetricImpl.
 | 
			
		||||
func (m *Accumulator) NewAsyncInstrument(descriptor sdkapi.Descriptor, runner sdkapi.AsyncRunner) (sdkapi.AsyncImpl, error) {
 | 
			
		||||
	a := &asyncInstrument{
 | 
			
		||||
		instrument: instrument{
 | 
			
		||||
			descriptor: descriptor,
 | 
			
		||||
			meter:      m,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	m.asyncLock.Lock()
 | 
			
		||||
	defer m.asyncLock.Unlock()
 | 
			
		||||
	m.asyncInstruments.Register(a, runner)
 | 
			
		||||
	return a, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Collect traverses the list of active records and observers and
 | 
			
		||||
// exports data for each active instrument.  Collect() may not be
 | 
			
		||||
// called concurrently.
 | 
			
		||||
//
 | 
			
		||||
// During the collection pass, the export.Processor will receive
 | 
			
		||||
// one Export() call per current aggregation.
 | 
			
		||||
//
 | 
			
		||||
// Returns the number of records that were checkpointed.
 | 
			
		||||
func (m *Accumulator) Collect(ctx context.Context) int {
 | 
			
		||||
	m.collectLock.Lock()
 | 
			
		||||
	defer m.collectLock.Unlock()
 | 
			
		||||
 | 
			
		||||
	checkpointed := m.observeAsyncInstruments(ctx)
 | 
			
		||||
	checkpointed += m.collectSyncInstruments()
 | 
			
		||||
	m.currentEpoch++
 | 
			
		||||
 | 
			
		||||
	return checkpointed
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *Accumulator) collectSyncInstruments() int {
 | 
			
		||||
	checkpointed := 0
 | 
			
		||||
 | 
			
		||||
	m.current.Range(func(key interface{}, value interface{}) bool {
 | 
			
		||||
		// Note: always continue to iterate over the entire
 | 
			
		||||
		// map by returning `true` in this function.
 | 
			
		||||
		inuse := value.(*record)
 | 
			
		||||
 | 
			
		||||
		mods := atomic.LoadInt64(&inuse.updateCount)
 | 
			
		||||
		coll := inuse.collectedCount
 | 
			
		||||
 | 
			
		||||
		if mods != coll {
 | 
			
		||||
			// Updates happened in this interval,
 | 
			
		||||
			// checkpoint and continue.
 | 
			
		||||
			checkpointed += m.checkpointRecord(inuse)
 | 
			
		||||
			inuse.collectedCount = mods
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Having no updates since last collection, try to unmap:
 | 
			
		||||
		if unmapped := inuse.refMapped.tryUnmap(); !unmapped {
 | 
			
		||||
			// The record is referenced by a binding, continue.
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If any other goroutines are now trying to re-insert this
 | 
			
		||||
		// entry in the map, they are busy calling Gosched() awaiting
 | 
			
		||||
		// this deletion:
 | 
			
		||||
		m.current.Delete(inuse.mapkey())
 | 
			
		||||
 | 
			
		||||
		// There's a potential race between `LoadInt64` and
 | 
			
		||||
		// `tryUnmap` in this function.  Since this is the
 | 
			
		||||
		// last we'll see of this record, checkpoint
 | 
			
		||||
		mods = atomic.LoadInt64(&inuse.updateCount)
 | 
			
		||||
		if mods != coll {
 | 
			
		||||
			checkpointed += m.checkpointRecord(inuse)
 | 
			
		||||
		}
 | 
			
		||||
		return true
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return checkpointed
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CollectAsync implements internal.AsyncCollector.
 | 
			
		||||
// The order of the input array `kvs` may be sorted after the function is called.
 | 
			
		||||
func (m *Accumulator) CollectAsync(kv []attribute.KeyValue, obs ...sdkapi.Observation) {
 | 
			
		||||
	labels := attribute.NewSetWithSortable(kv, &m.asyncSortSlice)
 | 
			
		||||
 | 
			
		||||
	for _, ob := range obs {
 | 
			
		||||
		if a := m.fromAsync(ob.AsyncImpl()); a != nil {
 | 
			
		||||
			a.observe(ob.Number(), &labels)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *Accumulator) observeAsyncInstruments(ctx context.Context) int {
 | 
			
		||||
	m.asyncLock.Lock()
 | 
			
		||||
	defer m.asyncLock.Unlock()
 | 
			
		||||
 | 
			
		||||
	asyncCollected := 0
 | 
			
		||||
 | 
			
		||||
	m.asyncInstruments.Run(ctx, m)
 | 
			
		||||
 | 
			
		||||
	for _, inst := range m.asyncInstruments.Instruments() {
 | 
			
		||||
		if a := m.fromAsync(inst); a != nil {
 | 
			
		||||
			asyncCollected += m.checkpointAsync(a)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return asyncCollected
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *Accumulator) checkpointRecord(r *record) int {
 | 
			
		||||
	if r.current == nil {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	err := r.current.SynchronizedMove(r.checkpoint, &r.inst.descriptor)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		otel.Handle(err)
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	a := export.NewAccumulation(&r.inst.descriptor, r.labels, r.checkpoint)
 | 
			
		||||
	err = m.processor.Process(a)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		otel.Handle(err)
 | 
			
		||||
	}
 | 
			
		||||
	return 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *Accumulator) checkpointAsync(a *asyncInstrument) int {
 | 
			
		||||
	if len(a.recorders) == 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	checkpointed := 0
 | 
			
		||||
	for encodedLabels, lrec := range a.recorders {
 | 
			
		||||
		lrec := lrec
 | 
			
		||||
		epochDiff := m.currentEpoch - lrec.observedEpoch
 | 
			
		||||
		if epochDiff == 0 {
 | 
			
		||||
			if lrec.observed != nil {
 | 
			
		||||
				a := export.NewAccumulation(&a.descriptor, lrec.labels, lrec.observed)
 | 
			
		||||
				err := m.processor.Process(a)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					otel.Handle(err)
 | 
			
		||||
				}
 | 
			
		||||
				checkpointed++
 | 
			
		||||
			}
 | 
			
		||||
		} else if epochDiff > 1 {
 | 
			
		||||
			// This is second collection cycle with no
 | 
			
		||||
			// observations for this labelset. Remove the
 | 
			
		||||
			// recorder.
 | 
			
		||||
			delete(a.recorders, encodedLabels)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(a.recorders) == 0 {
 | 
			
		||||
		a.recorders = nil
 | 
			
		||||
	}
 | 
			
		||||
	return checkpointed
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RecordBatch enters a batch of metric events.
 | 
			
		||||
// The order of the input array `kvs` may be sorted after the function is called.
 | 
			
		||||
func (m *Accumulator) RecordBatch(ctx context.Context, kvs []attribute.KeyValue, measurements ...sdkapi.Measurement) {
 | 
			
		||||
	// Labels will be computed the first time acquireHandle is
 | 
			
		||||
	// called.  Subsequent calls to acquireHandle will re-use the
 | 
			
		||||
	// previously computed value instead of recomputing the
 | 
			
		||||
	// ordered labels.
 | 
			
		||||
	var labelsPtr *attribute.Set
 | 
			
		||||
	for i, meas := range measurements {
 | 
			
		||||
		s := m.fromSync(meas.SyncImpl())
 | 
			
		||||
		if s == nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		h := s.acquireHandle(kvs, labelsPtr)
 | 
			
		||||
 | 
			
		||||
		// Re-use labels for the next measurement.
 | 
			
		||||
		if i == 0 {
 | 
			
		||||
			labelsPtr = h.labels
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		defer h.Unbind()
 | 
			
		||||
		h.RecordOne(ctx, meas.Number())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RecordOne implements sdkapi.SyncImpl.
 | 
			
		||||
func (r *record) RecordOne(ctx context.Context, num number.Number) {
 | 
			
		||||
	if r.current == nil {
 | 
			
		||||
		// The instrument is disabled according to the AggregatorSelector.
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if err := aggregator.RangeTest(num, &r.inst.descriptor); err != nil {
 | 
			
		||||
		otel.Handle(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if err := r.current.Update(ctx, num, &r.inst.descriptor); err != nil {
 | 
			
		||||
		otel.Handle(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// Record was modified, inform the Collect() that things need
 | 
			
		||||
	// to be collected while the record is still mapped.
 | 
			
		||||
	atomic.AddInt64(&r.updateCount, 1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unbind implements sdkapi.SyncImpl.
 | 
			
		||||
func (r *record) Unbind() {
 | 
			
		||||
	r.refMapped.unref()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *record) mapkey() mapkey {
 | 
			
		||||
	return mapkey{
 | 
			
		||||
		descriptor: &r.inst.descriptor,
 | 
			
		||||
		ordered:    r.labels.Equivalent(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// fromSync gets a sync implementation object, checking for
 | 
			
		||||
// uninitialized instruments and instruments created by another SDK.
 | 
			
		||||
func (m *Accumulator) fromSync(sync sdkapi.SyncImpl) *syncInstrument {
 | 
			
		||||
	if sync != nil {
 | 
			
		||||
		if inst, ok := sync.Implementation().(*syncInstrument); ok {
 | 
			
		||||
			return inst
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	otel.Handle(ErrUninitializedInstrument)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// fromSync gets an async implementation object, checking for
 | 
			
		||||
// uninitialized instruments and instruments created by another SDK.
 | 
			
		||||
func (m *Accumulator) fromAsync(async sdkapi.AsyncImpl) *asyncInstrument {
 | 
			
		||||
	if async != nil {
 | 
			
		||||
		if inst, ok := async.Implementation().(*asyncInstrument); ok {
 | 
			
		||||
			return inst
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	otel.Handle(ErrUninitializedInstrument)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										120
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/selector/simple/simple.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								vendor/go.opentelemetry.io/otel/sdk/metric/selector/simple/simple.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package simple // import "go.opentelemetry.io/otel/sdk/metric/selector/simple"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"go.opentelemetry.io/otel/metric/sdkapi"
 | 
			
		||||
	export "go.opentelemetry.io/otel/sdk/export/metric"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/metric/aggregator/exact"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount"
 | 
			
		||||
	"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	selectorInexpensive struct{}
 | 
			
		||||
	selectorExact       struct{}
 | 
			
		||||
	selectorHistogram   struct {
 | 
			
		||||
		options []histogram.Option
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_ export.AggregatorSelector = selectorInexpensive{}
 | 
			
		||||
	_ export.AggregatorSelector = selectorExact{}
 | 
			
		||||
	_ export.AggregatorSelector = selectorHistogram{}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// NewWithInexpensiveDistribution returns a simple aggregator selector
 | 
			
		||||
// that uses minmaxsumcount aggregators for `Histogram`
 | 
			
		||||
// instruments.  This selector is faster and uses less memory than the
 | 
			
		||||
// others in this package because minmaxsumcount aggregators maintain
 | 
			
		||||
// the least information about the distribution among these choices.
 | 
			
		||||
func NewWithInexpensiveDistribution() export.AggregatorSelector {
 | 
			
		||||
	return selectorInexpensive{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewWithExactDistribution returns a simple aggregator selector that
 | 
			
		||||
// uses exact aggregators for `Histogram` instruments.  This
 | 
			
		||||
// selector uses more memory than the others in this package because
 | 
			
		||||
// exact aggregators maintain the most information about the
 | 
			
		||||
// distribution among these choices.
 | 
			
		||||
func NewWithExactDistribution() export.AggregatorSelector {
 | 
			
		||||
	return selectorExact{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewWithHistogramDistribution returns a simple aggregator selector
 | 
			
		||||
// that uses histogram aggregators for `Histogram` instruments.
 | 
			
		||||
// This selector is a good default choice for most metric exporters.
 | 
			
		||||
func NewWithHistogramDistribution(options ...histogram.Option) export.AggregatorSelector {
 | 
			
		||||
	return selectorHistogram{options: options}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func sumAggs(aggPtrs []*export.Aggregator) {
 | 
			
		||||
	aggs := sum.New(len(aggPtrs))
 | 
			
		||||
	for i := range aggPtrs {
 | 
			
		||||
		*aggPtrs[i] = &aggs[i]
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func lastValueAggs(aggPtrs []*export.Aggregator) {
 | 
			
		||||
	aggs := lastvalue.New(len(aggPtrs))
 | 
			
		||||
	for i := range aggPtrs {
 | 
			
		||||
		*aggPtrs[i] = &aggs[i]
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (selectorInexpensive) AggregatorFor(descriptor *sdkapi.Descriptor, aggPtrs ...*export.Aggregator) {
 | 
			
		||||
	switch descriptor.InstrumentKind() {
 | 
			
		||||
	case sdkapi.GaugeObserverInstrumentKind:
 | 
			
		||||
		lastValueAggs(aggPtrs)
 | 
			
		||||
	case sdkapi.HistogramInstrumentKind:
 | 
			
		||||
		aggs := minmaxsumcount.New(len(aggPtrs), descriptor)
 | 
			
		||||
		for i := range aggPtrs {
 | 
			
		||||
			*aggPtrs[i] = &aggs[i]
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		sumAggs(aggPtrs)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (selectorExact) AggregatorFor(descriptor *sdkapi.Descriptor, aggPtrs ...*export.Aggregator) {
 | 
			
		||||
	switch descriptor.InstrumentKind() {
 | 
			
		||||
	case sdkapi.GaugeObserverInstrumentKind:
 | 
			
		||||
		lastValueAggs(aggPtrs)
 | 
			
		||||
	case sdkapi.HistogramInstrumentKind:
 | 
			
		||||
		aggs := exact.New(len(aggPtrs))
 | 
			
		||||
		for i := range aggPtrs {
 | 
			
		||||
			*aggPtrs[i] = &aggs[i]
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		sumAggs(aggPtrs)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s selectorHistogram) AggregatorFor(descriptor *sdkapi.Descriptor, aggPtrs ...*export.Aggregator) {
 | 
			
		||||
	switch descriptor.InstrumentKind() {
 | 
			
		||||
	case sdkapi.GaugeObserverInstrumentKind:
 | 
			
		||||
		lastValueAggs(aggPtrs)
 | 
			
		||||
	case sdkapi.HistogramInstrumentKind:
 | 
			
		||||
		aggs := histogram.New(len(aggPtrs), descriptor, s.options...)
 | 
			
		||||
		for i := range aggPtrs {
 | 
			
		||||
			*aggPtrs[i] = &aggs[i]
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		sumAggs(aggPtrs)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user