refactor: use py mongo struct + stdlib log
+ restructure project
This commit is contained in:
		
							
								
								
									
										144
									
								
								cmd/line.go
									
									
									
									
									
								
							
							
						
						
									
										144
									
								
								cmd/line.go
									
									
									
									
									
								
							| @@ -1,101 +1,45 @@ | ||||
| package logmower | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	ms "git.k-space.ee/k-space/logmower-shipper/pkg/mongoStruct" | ||||
| 	prom "github.com/prometheus/client_golang/prometheus" | ||||
| 	"github.com/prometheus/client_golang/prometheus/promauto" | ||||
| 	"go.uber.org/zap" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	promRecordPrefixParsingErr = promauto.NewCounterVec(prom.CounterOpts{ | ||||
| 		Namespace: PrometheusPrefix, | ||||
| 		Subsystem: "record", | ||||
| 		Name:      "parsing_errors", | ||||
| 		Help:      "Errors while parsing log line prefixes", | ||||
| 	}, []string{"filename"}) | ||||
| 	promRecordDroppedTooLarge = promauto.NewCounterVec(prom.CounterOpts{ | ||||
| 		Namespace: PrometheusPrefix, | ||||
| 		// Subsystem: "record", | ||||
| 		Name: "dropped_lines", // "dropped", | ||||
| 		Help: "Records dropped due to being too large", | ||||
| 	}, []string{"filename"}) | ||||
| ) | ||||
| var promRecordDroppedTooLarge = promauto.NewCounterVec(prom.CounterOpts{ | ||||
| 	Namespace: PrometheusPrefix, | ||||
| 	// Subsystem: "record", | ||||
| 	Name: "dropped_lines", // "dropped", | ||||
| 	Help: "Records dropped due to being too large", | ||||
| }, []string{"filename"}) | ||||
|  | ||||
| type ( | ||||
| 	rawLine struct { | ||||
| 		RecordMetadata | ||||
| 		line []byte | ||||
| 	} | ||||
|  | ||||
| 	singleLine struct { | ||||
| 		mLog | ||||
| 		line      []byte | ||||
| 		isPartial bool // P or F | ||||
| 	RawLines <-chan RawLine | ||||
| 	RawLine  struct { | ||||
| 		*file | ||||
| 		Offset int64 | ||||
| 		B      []byte | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| func parseSingleContainerLine(line []byte) (u singleLine, err error) { | ||||
| 	split := bytes.SplitN(line, []byte(" "), 4) | ||||
| 	if len(split) != 4 { | ||||
| 		u.line = line | ||||
| 		return u, fmt.Errorf("expected at least 3 spaces in container log line, got %d", len(split)-1) | ||||
| 	} | ||||
|  | ||||
| 	u.line = split[3] | ||||
|  | ||||
| 	u.StdErr = string(split[1]) == "stderr" // or stdout | ||||
| 	switch string(split[2]) { | ||||
| 	case "P": | ||||
| 		u.isPartial = true | ||||
| 	case "F": | ||||
| 	default: | ||||
| 		return u, fmt.Errorf("partial indicator must be 'P' or 'F', not %q", split[2]) | ||||
| 	} | ||||
|  | ||||
| 	u.ContainerTime, err = time.Parse(time.RFC3339Nano, string(split[0])) | ||||
|  | ||||
| 	return u, err | ||||
| } | ||||
|  | ||||
| func (s *submitter) parseContainerLogLines(unparsed <-chan rawLine, parsed chan<- singleLine) { | ||||
| 	for { | ||||
| 		raw, ok := <-unparsed | ||||
| 		if !ok { | ||||
| 			close(parsed) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		line, err := parseSingleContainerLine(raw.line) | ||||
| 		if err != nil { | ||||
| 			promRecordPrefixParsingErr.WithLabelValues(raw.File).Add(1) | ||||
| 			s.l.Error("parsing container log line", zap.Error(err), zap.String("file", raw.File)) | ||||
| 		} | ||||
|  | ||||
| 		line.mLog.RecordMetadata = raw.RecordMetadata | ||||
| 		parsed <- line | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // assumes all lines are from same file | ||||
| func (s *submitter) parseLines(bufferLimitBytes int, unparsed <-chan rawLine, parsed chan<- mLog) { | ||||
| func (unparsed RawLines) Process(bufferLimitBytes int, parsed chan<- ms.Record) { | ||||
| 	lines := make(chan singleLine) | ||||
| 	go s.parseContainerLogLines(unparsed, lines) | ||||
| 	go unparsed.parse(lines) | ||||
|  | ||||
| 	var wg sync.WaitGroup | ||||
| 	wg.Add(2) | ||||
|  | ||||
| 	stdOut, stdErr := make(chan singleLine), make(chan singleLine) | ||||
| 	go func() { | ||||
| 		s.parseStdChannel(bufferLimitBytes, stdOut, parsed) | ||||
| 		singleLines(stdOut).process(bufferLimitBytes, parsed) | ||||
| 		wg.Done() | ||||
| 	}() | ||||
| 	go func() { | ||||
| 		s.parseStdChannel(bufferLimitBytes, stdErr, parsed) | ||||
| 		singleLines(stdErr).process(bufferLimitBytes, parsed) | ||||
| 		wg.Done() | ||||
| 	}() | ||||
|  | ||||
| @@ -118,58 +62,42 @@ func (s *submitter) parseLines(bufferLimitBytes int, unparsed <-chan rawLine, pa | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // partial is ended with full | ||||
|  | ||||
| func (s *submitter) parseStdChannel(bufferLimitBytes int, lines <-chan singleLine, parsed chan<- mLog) { | ||||
| 	var firstTime time.Time | ||||
| func (lines singleLines) process(bufferLimitBytes int, parsed chan<- ms.Record) { | ||||
| 	var firstMetadata *ms.ParsedMetadata | ||||
| 	var buffer []byte | ||||
|  | ||||
| 	flush := func(last *mLog) { | ||||
| 		parsed <- mLog{ | ||||
| 			RecordMetadata: last.RecordMetadata, | ||||
| 			StdErr:         last.StdErr, | ||||
|  | ||||
| 			ContainerTime: firstTime, | ||||
| 			Content:       parseRecord(buffer), | ||||
| 		} | ||||
| 		buffer = nil | ||||
| 	} | ||||
|  | ||||
| 	for { | ||||
| 		line, ok := <-lines | ||||
| 		if !ok { | ||||
| 			// discard any partial lines without end delimiter (full line) | ||||
| 			// partial line should always be finished with full line | ||||
| 			// discard any partial lines without end (full line) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		if len(buffer) == 0 { | ||||
| 			firstTime = line.ContainerTime | ||||
| 			firstMetadata = &line.ParsedMetadata | ||||
| 		} | ||||
|  | ||||
| 		buffer = append(buffer, line.line...) | ||||
| 		buffer = append(buffer, line.B...) | ||||
|  | ||||
| 		if len(buffer) > bufferLimitBytes { | ||||
| 			promRecordDroppedTooLarge.WithLabelValues(line.metricsName).Add(1) | ||||
| 			log.Printf("dropped record: size in bytes exceeds limit of %d", bufferLimitBytes) | ||||
|  | ||||
| 			buffer = nil | ||||
| 			promRecordDroppedTooLarge.WithLabelValues(line.File).Add(1) | ||||
| 			s.l.Warn("dropped record: too large", zap.Int("cap_bytes", bufferLimitBytes)) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if !line.isPartial { | ||||
| 			flush(&line.mLog) | ||||
| 		if !line.partial { | ||||
| 			parsed <- ms.Record{ | ||||
| 				File:   line.file.File, | ||||
| 				Offset: line.Offset, | ||||
|  | ||||
| 				String:         string(buffer), | ||||
| 				ParsedMetadata: *firstMetadata, | ||||
| 			} | ||||
|  | ||||
| 			buffer = nil | ||||
| 		} | ||||
| 	} | ||||
| 	// TODO: flush last | ||||
| 	// use time of first | ||||
| 	// metadata of last | ||||
| 	// // | ||||
| 	// for { | ||||
| 	// } | ||||
|  | ||||
| 	// promRecordDroppedTooLarge | ||||
| } | ||||
|  | ||||
| func parseRecord(buffer []byte) any { | ||||
| 	// TODO: json parser | ||||
| 	return string(buffer) | ||||
| } | ||||
|   | ||||
							
								
								
									
										75
									
								
								cmd/line_single.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								cmd/line_single.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| package logmower | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"time" | ||||
|  | ||||
| 	ms "git.k-space.ee/k-space/logmower-shipper/pkg/mongoStruct" | ||||
| 	prom "github.com/prometheus/client_golang/prometheus" | ||||
| 	"github.com/prometheus/client_golang/prometheus/promauto" | ||||
| ) | ||||
|  | ||||
| var promRecordPrefixParsingErr = promauto.NewCounterVec(prom.CounterOpts{ | ||||
| 	Namespace: PrometheusPrefix, | ||||
| 	Subsystem: "record", | ||||
| 	Name:      "parsing_errors", | ||||
| 	Help:      "Errors while parsing log line prefixes", | ||||
| }, []string{"filename"}) | ||||
|  | ||||
| func (unparsed RawLines) parse(parsed chan<- singleLine) { | ||||
| 	for { | ||||
| 		raw, ok := <-unparsed | ||||
| 		if !ok { | ||||
| 			close(parsed) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		line := singleLine{RawLine: raw} | ||||
|  | ||||
| 		if err := line.parse(); err != nil { | ||||
| 			promRecordPrefixParsingErr.WithLabelValues(raw.metricsName).Add(1) | ||||
| 			log.Printf("parsing kubernetes log line in %q: %e", raw.File.Path, err) | ||||
| 		} | ||||
|  | ||||
| 		// TODO: should this only be on success? | ||||
| 		parsed <- line | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type ( | ||||
| 	singleLines <-chan singleLine | ||||
| 	singleLine  struct { | ||||
| 		RawLine | ||||
|  | ||||
| 		// populated by parse() | ||||
| 		ms.ParsedMetadata | ||||
| 		partial bool // P or F | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| func (line *singleLine) parse() (err error) { | ||||
| 	split := bytes.SplitN(line.B, []byte(" "), 4) | ||||
| 	if len(split) != 4 { | ||||
| 		return fmt.Errorf("expected at least 3 spaces in , got %d", len(split)-1) | ||||
| 	} | ||||
|  | ||||
| 	line.TimeKubernetes, err = time.Parse(time.RFC3339Nano, string(split[0])) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("invalid time: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	line.StdErr = string(split[1]) == "stderr" // or stdout | ||||
|  | ||||
| 	switch string(split[2]) { | ||||
| 	case "P": | ||||
| 		line.partial = true | ||||
| 	case "F": | ||||
| 	default: | ||||
| 		return fmt.Errorf("partial indicator must be 'P' or 'F', not %q", split[2]) | ||||
| 	} | ||||
|  | ||||
| 	line.B = split[3] | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										32
									
								
								cmd/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								cmd/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| package logmower | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/prometheus/client_golang/prometheus/promhttp" | ||||
| ) | ||||
|  | ||||
| const PrometheusPrefix = "logmower" | ||||
|  | ||||
| // TODO: | ||||
| func main() { | ||||
| 	go func() { | ||||
| 		metricsPort := 2112 | ||||
|  | ||||
| 		log.Printf("serving /metrics on port %d", metricsPort) | ||||
|  | ||||
| 		http.Handle("/metrics", promhttp.Handler()) | ||||
|  | ||||
| 		if err := http.ListenAndServe(fmt.Sprintf(":%d", metricsPort), nil); !errors.Is(err, http.ErrServerClosed) { | ||||
| 			log.Fatalf("serving /metrics: %e", err) | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	if err := App.Run(os.Args); err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										37
									
								
								cmd/mongo.go
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								cmd/mongo.go
									
									
									
									
									
								
							| @@ -2,13 +2,17 @@ package logmower | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"net/url" | ||||
| 	"time" | ||||
|  | ||||
| 	ms "git.k-space.ee/k-space/logmower-shipper/pkg/mongoStruct" | ||||
| 	prom "github.com/prometheus/client_golang/prometheus" | ||||
| 	"github.com/prometheus/client_golang/prometheus/promauto" | ||||
| 	mongoEvent "go.mongodb.org/mongo-driver/event" | ||||
| 	"go.mongodb.org/mongo-driver/mongo" | ||||
| 	mongoOpt "go.mongodb.org/mongo-driver/mongo/options" | ||||
| 	"go.uber.org/zap" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| @@ -36,7 +40,7 @@ var ( | ||||
| 	}, []string{"connection_id", "command_name"}) | ||||
| ) | ||||
|  | ||||
| func mongoMonitoredClientOptions(l *zap.Logger) *mongoOpt.ClientOptions { | ||||
| func mongoMonitoredClientOptions() *mongoOpt.ClientOptions { | ||||
| 	return mongoOpt.Client(). | ||||
| 		SetServerMonitor(&mongoEvent.ServerMonitor{ | ||||
| 			ServerHeartbeatSucceeded: func(ev *mongoEvent.ServerHeartbeatSucceededEvent) { | ||||
| @@ -44,7 +48,7 @@ func mongoMonitoredClientOptions(l *zap.Logger) *mongoOpt.ClientOptions { | ||||
| 			}, | ||||
| 			ServerHeartbeatFailed: func(ev *mongoEvent.ServerHeartbeatFailedEvent) { | ||||
| 				promDbHeartbeat.WithLabelValues(ev.ConnectionID).Observe(0) | ||||
| 				l.Warn("database heartbeat", zap.Error(ev.Failure), zap.String("connection_id", ev.ConnectionID)) | ||||
| 				log.Printf("database heartbeat failed on connection %q: %e", ev.ConnectionID, ev.Failure) | ||||
| 			}, | ||||
| 		}). | ||||
| 		SetMonitor(&mongoEvent.CommandMonitor{ | ||||
| @@ -58,3 +62,30 @@ func mongoMonitoredClientOptions(l *zap.Logger) *mongoOpt.ClientOptions { | ||||
| 			}, | ||||
| 		}) | ||||
| } | ||||
|  | ||||
| func initDatabase(ctx context.Context, uri string) (*mongo.Collection, error) { | ||||
| 	uriParsed, err := url.ParseRequestURI(uri) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("parsing URI for database name: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	uriParsed.Path = uriParsed.Path[1:] // remove leading slash | ||||
| 	if uriParsed.Path == "" { | ||||
| 		return nil, fmt.Errorf("URI must include database name (as database to authenticate against)") | ||||
| 	} | ||||
|  | ||||
| 	dbOpt := mongoMonitoredClientOptions().ApplyURI(uri) | ||||
|  | ||||
| 	dbClient, err := mongo.Connect(mongoTimeoutCtx(ctx)) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("connecting to %q: %w", dbOpt.GetURI(), err) | ||||
| 	} | ||||
|  | ||||
| 	col := dbClient.Database(uriParsed.Path).Collection("logs") | ||||
|  | ||||
| 	if err := ms.InitializeIndexes(mongoTimeoutCtx(ctx), col); err != nil { | ||||
| 		return nil, fmt.Errorf("initializing indexes: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	return col, nil | ||||
| } | ||||
|   | ||||
| @@ -1,120 +0,0 @@ | ||||
| package logmower | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"time" | ||||
|  | ||||
| 	"go.mongodb.org/mongo-driver/bson" | ||||
| 	"go.mongodb.org/mongo-driver/mongo" | ||||
| ) | ||||
|  | ||||
| func initializeIndexes(ctx context.Context, col *mongo.Collection) error { | ||||
| 	ind := col.Indexes() | ||||
|  | ||||
| 	// (does not create duplicates) | ||||
| 	_, err := ind.CreateOne(mongoTimeoutCtx(ctx), mongo.IndexModel{ | ||||
| 		Keys: bson.D{{Key: mLogKeyFileBasename, Value: 1}, {Key: mLogKeyOffset, Value: -1}}, | ||||
| 	}) | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // when editing, also edit everything in this file! | ||||
| type ( | ||||
| 	mLog struct { | ||||
| 		RecordMetadata | ||||
|  | ||||
| 		Content       any | ||||
| 		ContainerTime time.Time | ||||
| 		StdErr        bool | ||||
|  | ||||
| 		// added by toBson() | ||||
| 		ShipTime time.Time | ||||
| 	} | ||||
| 	RecordMetadata struct { | ||||
| 		HostInfo HostInfo | ||||
| 		File     string | ||||
| 		Offset   int64 // byte offset where log entry ends at | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// used outside fromBson and toBson | ||||
| 	mLogKeyHostId = mLogKeyHostInfo + "." + mLogKeyId | ||||
| ) | ||||
|  | ||||
| // Don't use direct strings in bson types. Use the constants as keys. | ||||
| // This ensures keys (and subkeys) are consistent, at least within the package. | ||||
|  | ||||
| const ( | ||||
| 	mLogKeyHostInfo = "host_info" | ||||
| 	mLogKeyId       = "id" | ||||
| 	mLogKeyName     = "name" | ||||
| 	mLogKeyArch     = "arch" | ||||
|  | ||||
| 	mLogKeyFileBasename  = "file" | ||||
| 	mLogKeyOffset        = "offset" | ||||
| 	mLogKeyContent       = "content" | ||||
| 	mLogKeyContainerTime = "container_time" | ||||
| 	mLogKeyStderr        = "stderr" | ||||
| 	mLogKeyShipTime      = "ship_time" | ||||
| ) | ||||
|  | ||||
| // not using marshal, since it is <0.1x performance | ||||
| func (l *mLog) toBson() bson.M { | ||||
| 	return bson.M{ | ||||
| 		mLogKeyHostInfo: bson.M{ | ||||
| 			mLogKeyId:   l.HostInfo.Id, | ||||
| 			mLogKeyName: l.HostInfo.Name, | ||||
| 			mLogKeyArch: l.HostInfo.Arch, | ||||
| 		}, | ||||
| 		mLogKeyFileBasename:  l.File, | ||||
| 		mLogKeyOffset:        l.Offset, | ||||
| 		mLogKeyContent:       l.Content, | ||||
| 		mLogKeyContainerTime: l.ContainerTime, | ||||
| 		mLogKeyStderr:        l.StdErr, | ||||
|  | ||||
| 		mLogKeyShipTime: time.Now(), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // really, mongo should support tagged structs | ||||
| func mLogfromBson(b *bson.Raw) mLog { | ||||
| 	return mLog{ | ||||
| 		RecordMetadata: RecordMetadata{ | ||||
| 			HostInfo: HostInfo{ | ||||
| 				Id:   bsonLookupStringValue(b, mLogKeyHostInfo, mLogKeyId), | ||||
| 				Name: bsonLookupStringValue(b, mLogKeyHostInfo, mLogKeyName), | ||||
| 				Arch: bsonLookupStringValue(b, mLogKeyHostInfo, mLogKeyArch), | ||||
| 			}, | ||||
| 			File:   bsonLookupStringValue(b, mLogKeyFileBasename), | ||||
| 			Offset: bsonLookupInt64(b, mLogKeyOffset), | ||||
| 		}, | ||||
| 		Content:       bsonLookupStringValue(b, mLogKeyContent), | ||||
| 		ContainerTime: bsonLookupTime(b, mLogKeyContainerTime), | ||||
| 		StdErr:        bsonLookupBoolean(b, mLogKeyStderr), | ||||
| 		ShipTime:      bsonLookupTime(b, mLogKeyShipTime), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // default values without ok | ||||
|  | ||||
| func bsonLookupBoolean(b *bson.Raw, key ...string) bool { | ||||
| 	v, _ := b.Lookup(key...).BooleanOK() | ||||
| 	return v | ||||
| } | ||||
|  | ||||
| func bsonLookupStringValue(b *bson.Raw, key ...string) string { | ||||
| 	v, _ := b.Lookup(key...).StringValueOK() | ||||
| 	return v | ||||
| } | ||||
|  | ||||
| func bsonLookupInt64(b *bson.Raw, key ...string) int64 { | ||||
| 	v, _ := b.Lookup(key...).Int64OK() | ||||
| 	return v | ||||
| } | ||||
|  | ||||
| func bsonLookupTime(b *bson.Raw, key ...string) time.Time { | ||||
| 	v, _ := b.Lookup(key...).TimeOK() | ||||
| 	return v | ||||
| } | ||||
| @@ -2,13 +2,14 @@ package logmower | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"path/filepath" | ||||
| 	"log" | ||||
| 	"time" | ||||
|  | ||||
| 	ms "git.k-space.ee/k-space/logmower-shipper/pkg/mongoStruct" | ||||
| 	"github.com/jtagcat/util" | ||||
| 	prom "github.com/prometheus/client_golang/prometheus" | ||||
| 	"github.com/prometheus/client_golang/prometheus/promauto" | ||||
| 	"go.uber.org/zap" | ||||
| 	"go.mongodb.org/mongo-driver/mongo" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| @@ -50,20 +51,20 @@ const ( | ||||
| 	MaxBatchTime  = 5 * time.Second | ||||
| ) | ||||
|  | ||||
| func (s *submitter) sender(name string, sendQueue <-chan mLog) { | ||||
| 	baseName := filepath.Base(name) | ||||
| type queueT <-chan ms.Record | ||||
|  | ||||
| 	batched := make(chan []mLog) | ||||
| func (queue queueT) sender(db *mongo.Collection, metricsFilename string) { | ||||
| 	batched := make(chan []ms.Record) | ||||
|  | ||||
| 	// batcher and queue metrics | ||||
| 	go func() { | ||||
| 		ctx, cancel := context.WithCancel(context.Background()) | ||||
| 		defer cancel() | ||||
|  | ||||
| 		go func() { | ||||
| 			baseName := filepath.Base(name) | ||||
| 			for { | ||||
| 				promShipperQueued.WithLabelValues(baseName).Set(float64( | ||||
| 					len(sendQueue))) | ||||
| 				promShipperQueued.WithLabelValues(metricsFilename).Set(float64( | ||||
| 					len(queue))) | ||||
|  | ||||
| 				timer := time.NewTimer(time.Second) | ||||
| 				select { | ||||
| @@ -74,15 +75,12 @@ func (s *submitter) sender(name string, sendQueue <-chan mLog) { | ||||
| 			} | ||||
| 		}() | ||||
|  | ||||
| 		util.Batch(MaxBatchItems, MaxBatchTime, sendQueue, batched) | ||||
| 		util.Batch(MaxBatchItems, MaxBatchTime, queue, batched) | ||||
| 		// returns when sendQueue is closed | ||||
| 	}() | ||||
|  | ||||
| 	s.Add(1) | ||||
| 	defer s.Done() | ||||
|  | ||||
| 	for { | ||||
| 		promShipperSynced.WithLabelValues(baseName).Set(1) | ||||
| 		promShipperSynced.WithLabelValues(metricsFilename).Set(1) | ||||
|  | ||||
| 		batch, ok := <-batched | ||||
| 		if !ok { | ||||
| @@ -90,21 +88,21 @@ func (s *submitter) sender(name string, sendQueue <-chan mLog) { | ||||
| 		} | ||||
| 		promShipperBatchSizeResult.Observe(float64(len(batch))) | ||||
|  | ||||
| 		promShipperSynced.WithLabelValues(baseName).Set(0) | ||||
| 		promShipperSynced.WithLabelValues(metricsFilename).Set(0) | ||||
|  | ||||
| 		var batchBson []interface{} // mongo does not like typing | ||||
| 		for _, b := range batch { | ||||
| 			batchBson = append(batchBson, b.toBson()) | ||||
| 			batchBson = append(batchBson, b.ToBson()) | ||||
| 		} | ||||
|  | ||||
| 		result, err := s.db.InsertMany(mongoTimeoutCtx(context.Background()), batchBson, nil) | ||||
| 		result, err := db.InsertMany(mongoTimeoutCtx(context.Background()), batchBson, nil) | ||||
| 		if err != nil { | ||||
| 			promShipperDbSendError.WithLabelValues(baseName).Add(1) | ||||
| 			s.l.Error("submission to database", zap.Error(err)) // TODO: add some selective retry here or something | ||||
| 			promShipperDbSendError.WithLabelValues(metricsFilename).Add(1) | ||||
| 			log.Printf("failure in batch submit to database: %e", err) // TODO: add some selective retry here or something, better error handling | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		promShipperDbSent.WithLabelValues(baseName).Add(float64( | ||||
| 		promShipperDbSent.WithLabelValues(metricsFilename).Add(float64( | ||||
| 			len(result.InsertedIDs))) | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -5,18 +5,17 @@ import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	ms "git.k-space.ee/k-space/logmower-shipper/pkg/mongoStruct" | ||||
| 	"github.com/jtagcat/util" | ||||
| 	prom "github.com/prometheus/client_golang/prometheus" | ||||
| 	"github.com/prometheus/client_golang/prometheus/promauto" | ||||
| 	"go.mongodb.org/mongo-driver/bson" | ||||
| 	"go.mongodb.org/mongo-driver/mongo" | ||||
| 	mongoOpt "go.mongodb.org/mongo-driver/mongo/options" | ||||
| 	"go.uber.org/zap" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| ) | ||||
|  | ||||
| @@ -48,49 +47,43 @@ var ( | ||||
| 	}, []string{"filename"}) | ||||
| ) | ||||
|  | ||||
| type ( | ||||
| 	submitter struct { | ||||
| 		l *zap.Logger | ||||
|  | ||||
| 		hostInfo HostInfo | ||||
| 		db       *mongo.Collection | ||||
|  | ||||
| 		sync.WaitGroup | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| const SendQueueLimit = 1024 | ||||
|  | ||||
| // TODO: caller may call duplicate shipFile of same name on file replace; sends might not work properly | ||||
| func (s *submitter) shipFile(ctx context.Context, name string, recordLimitBytes int) { | ||||
| 	baseName := filepath.Base(name) | ||||
| type file struct { | ||||
| 	ms.File | ||||
| 	metricsName string // filepath.Base() | ||||
| } | ||||
|  | ||||
| 	lineChan := make(chan rawLine) | ||||
| // TODO: caller could call duplicate shipFile of same name on file replace: sends might not work properly | ||||
| func (f file) Process(ctx context.Context, db *mongo.Collection, recordLimitBytes int) { | ||||
| 	lineChan := make(chan RawLine) | ||||
| 	defer close(lineChan) | ||||
|  | ||||
| 	sendChan := make(chan mLog, SendQueueLimit) | ||||
| 	dbQueue := make(chan ms.Record, SendQueueLimit) | ||||
| 	go RawLines(lineChan).Process(recordLimitBytes, dbQueue) | ||||
|  | ||||
| 	go s.parseLines(recordLimitBytes, lineChan, sendChan) | ||||
|  | ||||
| 	go s.sender(name, sendChan) | ||||
| 	waitGo := util.GoWg(func() { | ||||
| 		queueT(dbQueue).sender(db, f.metricsName) | ||||
| 	}) | ||||
| 	defer waitGo() | ||||
|  | ||||
| 	// TODO: better way to kill or wait for sendQueue before retrying (or duplicates?) | ||||
| 	_ = wait.ManagedExponentialBackoffWithContext(ctx, defaultBackoff(), func() (done bool, _ error) { | ||||
| 		// | ||||
| 		err := s.shipFileRoutine(ctx, name, lineChan) | ||||
| 		err := f.trySubmit(ctx, db, lineChan) | ||||
| 		if err == nil { | ||||
| 			return true, nil | ||||
| 		} | ||||
|  | ||||
| 		promFileErr.WithLabelValues(baseName).Add(1) | ||||
| 		s.l.Error("shipping file", zap.String("filename", name), zap.Error(err)) | ||||
| 		return false, nil // nil since we want to loop and keep retrying indefinitely | ||||
| 		promFileErr.WithLabelValues(f.metricsName).Add(1) | ||||
| 		log.Printf("processing file %q: %e", f.metricsName, err) | ||||
|  | ||||
| 		// nil: loop and keep retrying indefinitely | ||||
| 		return false, nil | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func (s *submitter) shipFileRoutine(ctx context.Context, name string, sendQueue chan<- rawLine) error { | ||||
| 	baseName := filepath.Base(name) | ||||
|  | ||||
| // use submitter(), don't use directly | ||||
| func (f file) trySubmit(ctx context.Context, db *mongo.Collection, sendQueue chan<- RawLine) error { | ||||
| 	// TODO: better way for respecting ?killing sender for retry | ||||
| 	for { | ||||
| 		if len(sendQueue) == 0 { | ||||
| @@ -100,9 +93,9 @@ func (s *submitter) shipFileRoutine(ctx context.Context, name string, sendQueue | ||||
| 	} | ||||
|  | ||||
| 	// get files with offset | ||||
| 	offsetResult, _ := mongoWithErr(s.db.FindOne(mongoTimeoutCtx(ctx), | ||||
| 		bson.D{{Key: mLogKeyHostId, Value: s.hostInfo.Id}, {Key: mLogKeyFileBasename, Value: baseName}}, | ||||
| 		&mongoOpt.FindOneOptions{Sort: bson.D{{Key: mLogKeyOffset, Value: -1}}}, // sort descending (get largest) | ||||
| 	offsetResult, _ := mongoWithErr(db.FindOne(mongoTimeoutCtx(ctx), | ||||
| 		bson.D{{Key: ms.RecordKeyHostId, Value: f.Host.Id}, {Key: ms.RecordKeyFilePath, Value: f.Path}}, | ||||
| 		&mongoOpt.FindOneOptions{Sort: bson.D{{Key: ms.RecordKeyOffset, Value: -1}}}, // sort descending (get largest) | ||||
| 	)) | ||||
|  | ||||
| 	offsetResultBytes, err := offsetResult.DecodeBytes() | ||||
| @@ -110,9 +103,9 @@ func (s *submitter) shipFileRoutine(ctx context.Context, name string, sendQueue | ||||
| 		return fmt.Errorf("retrieving offset from database: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	log := mLogfromBson(&offsetResultBytes) | ||||
| 	dbOffset := ms.RecordOffsetFromBson(&offsetResultBytes) | ||||
|  | ||||
| 	fi, err := os.Stat(name) | ||||
| 	fi, err := os.Stat(f.Path) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("getting original file size: %w", err) | ||||
| 	} | ||||
| @@ -121,18 +114,15 @@ func (s *submitter) shipFileRoutine(ctx context.Context, name string, sendQueue | ||||
| 	sctx, cancel := context.WithCancel(ctx) | ||||
| 	defer cancel() | ||||
|  | ||||
| 	promFileInitialSeekSkipped.WithLabelValues(baseName).Set(float64(log.Offset)) | ||||
| 	promFileInitialSeekSkipped.WithLabelValues(f.metricsName).Set(float64(dbOffset)) | ||||
|  | ||||
| 	lineChan, errChan, err := util.TailFile(sctx, name, log.Offset, io.SeekStart) | ||||
| 	lineChan, errChan, err := util.TailFile(sctx, f.Path, dbOffset, io.SeekStart) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("tailing file: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	var catchUpped bool // cache | ||||
| 	promFileCatchupDone.WithLabelValues(baseName).Set(0) | ||||
|  | ||||
| 	// TODO: partial line combining | ||||
| 	// TODO: promRecordDroppedTooLarge | ||||
| 	var catchUpped bool | ||||
| 	promFileCatchupDone.WithLabelValues(f.metricsName).Set(0) | ||||
|  | ||||
| 	for { | ||||
| 		select { | ||||
| @@ -144,13 +134,13 @@ func (s *submitter) shipFileRoutine(ctx context.Context, name string, sendQueue | ||||
| 				return nil | ||||
| 			} | ||||
|  | ||||
| 			promFileLineSize.WithLabelValues(baseName).Observe(float64(len(line.Bytes))) | ||||
| 			promFileLineSize.WithLabelValues(f.metricsName).Observe(float64(len(line.Bytes))) | ||||
|  | ||||
| 			if !catchUpped { | ||||
| 				catchUpped = line.EndOffset >= startSize | ||||
|  | ||||
| 				if catchUpped { | ||||
| 					promFileCatchupDone.WithLabelValues(baseName).Set(1) | ||||
| 					promFileCatchupDone.WithLabelValues(f.metricsName).Set(1) | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| @@ -158,14 +148,11 @@ func (s *submitter) shipFileRoutine(ctx context.Context, name string, sendQueue | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			sendQueue <- rawLine{ | ||||
| 				RecordMetadata: RecordMetadata{ | ||||
| 					HostInfo: s.hostInfo, | ||||
| 					File:     baseName, | ||||
| 			sendQueue <- RawLine{ | ||||
| 				file: &f, | ||||
|  | ||||
| 					Offset: line.EndOffset, | ||||
| 				}, | ||||
| 				line: line.Bytes, | ||||
| 				Offset: line.EndOffset, | ||||
| 				B:      line.Bytes, | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										180
									
								
								cmd/watcher.go
									
									
									
									
									
								
							
							
						
						
									
										180
									
								
								cmd/watcher.go
									
									
									
									
									
								
							| @@ -2,34 +2,23 @@ package logmower | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"os/signal" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	ms "git.k-space.ee/k-space/logmower-shipper/pkg/mongoStruct" | ||||
| 	"github.com/fsnotify/fsnotify" | ||||
| 	prom "github.com/prometheus/client_golang/prometheus" | ||||
| 	"github.com/prometheus/client_golang/prometheus/promauto" | ||||
| 	"github.com/prometheus/client_golang/prometheus/promhttp" | ||||
| 	"github.com/urfave/cli/v2" | ||||
| 	"go.elastic.co/ecszap" | ||||
| 	"go.mongodb.org/mongo-driver/mongo" | ||||
| 	"go.uber.org/zap" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	MachineId              = "/etc/machine-id" | ||||
| 	DatabaseCommandTimeout = 10 * time.Second | ||||
| 	PrometheusPrefix       = "logmower" | ||||
| ) | ||||
| const DatabaseCommandTimeout = 10 * time.Second | ||||
|  | ||||
| // wrapper to force copying before use | ||||
| func defaultBackoff() wait.Backoff { | ||||
| @@ -73,16 +62,6 @@ var App = &cli.App{ | ||||
| 	}, | ||||
|  | ||||
| 	Action: func(ctx *cli.Context) error { | ||||
| 		ctx.Context, _ = signal.NotifyContext(ctx.Context, os.Interrupt) // TODO: test | ||||
| 		var wg sync.WaitGroup | ||||
|  | ||||
| 		// init logger, ECS schema | ||||
| 		core := ecszap.NewCore(ecszap.NewDefaultEncoderConfig(), | ||||
| 			os.Stderr, zap.WarnLevel) | ||||
| 		l := zap.New(core, zap.AddCaller()) | ||||
|  | ||||
| 		l.Info("logmower starting", zap.String("version", ctx.App.Version)) | ||||
|  | ||||
| 		var ( | ||||
| 			promWatcherOnline = promauto.NewGauge(prom.GaugeOpts{ | ||||
| 				Namespace: PrometheusPrefix, | ||||
| @@ -115,52 +94,27 @@ var App = &cli.App{ | ||||
| 				Help: "Number of events while watchng (includes initial create events for existing file discovery)", | ||||
| 			}) | ||||
| 		) | ||||
| 		go func() { | ||||
| 			l.Info("/metrics starting", zap.Int("port", 2112)) | ||||
| 			http.Handle("/metrics", promhttp.Handler()) | ||||
|  | ||||
| 			if err := http.ListenAndServe(":2112", nil); !errors.Is(err, http.ErrServerClosed) { | ||||
| 				l.Fatal("failed to serve /metrics", zap.Error(err)) | ||||
| 			} | ||||
| 		}() | ||||
| 		ctx.Context, _ = signal.NotifyContext(ctx.Context, os.Interrupt) // TODO: test | ||||
| 		var wg sync.WaitGroup | ||||
|  | ||||
| 		state := submitter{l: l} | ||||
| 		log.Printf("%s %s starting", ctx.App.Name, ctx.App.Version) | ||||
|  | ||||
| 		dbOpt := mongoMonitoredClientOptions(l).ApplyURI(ctx.String("mongo-uri")) | ||||
|  | ||||
| 		dbClient, err := mongo.Connect(mongoTimeoutCtx(ctx.Context)) | ||||
| 		db, err := initDatabase(ctx.Context, ctx.String("mongo-uri")) | ||||
| 		if err != nil { | ||||
| 			l.Fatal("connecting to database", zap.String("uri", dbOpt.GetURI()), zap.Error(err)) | ||||
| 			return fmt.Errorf("initializing database connection: %w", err) | ||||
| 		} | ||||
|  | ||||
| 		uriParsed, err := url.ParseRequestURI(ctx.String("mongo-uri")) | ||||
| 		if err != nil { | ||||
| 			l.Fatal("parsing URI for mongo database name", zap.Error(err)) | ||||
| 		} | ||||
|  | ||||
| 		uriParsed.Path = uriParsed.Path[1:] // remove leading slash | ||||
| 		if uriParsed.Path == "" { | ||||
| 			l.Fatal("mongo database name must be set in mongo URI") | ||||
| 		} | ||||
|  | ||||
| 		state.db = dbClient.Database(uriParsed.Path).Collection("logs") | ||||
|  | ||||
| 		err = initializeIndexes(ctx.Context, state.db) | ||||
| 		if err != nil { | ||||
| 			l.Fatal("initializing indexes", zap.Error(err)) | ||||
| 		} | ||||
|  | ||||
| 		state.hostInfo, err = getHostInfo(ctx.String("node-name")) | ||||
| 		if err != nil { | ||||
| 			l.Fatal("gathering host info", zap.Error(err)) | ||||
| 		var hostInfo ms.HostInfo | ||||
| 		if err := hostInfo.Populate(ctx.String("node-name")); err != nil { | ||||
| 			return fmt.Errorf("populating host info: %w", err) | ||||
| 		} | ||||
|  | ||||
| 		watcher, err := fsnotify.NewWatcher() | ||||
| 		if err != nil { | ||||
| 			l.Fatal("setting up watcher", zap.Error(err)) | ||||
| 			return fmt.Errorf("initializing log directory watcher: %w", err) | ||||
| 		} | ||||
|  | ||||
| 		logDir := ctx.String("log-directory") | ||||
| 		defer watcher.Close() | ||||
|  | ||||
| 		wg.Add(1) | ||||
| 		go func() { | ||||
| @@ -181,10 +135,10 @@ var App = &cli.App{ | ||||
| 					} | ||||
|  | ||||
| 					// TODO: #1: || if not in filterset | ||||
| 					_, ok = parseLogName(event.Name) | ||||
| 					kubeInfo, ok := ms.ParseLogName(event.Name) | ||||
| 					if !ok { | ||||
| 						promWatcherFilesSkipped.Add(1) | ||||
| 						l.Warn("skipped file with unparsable name", zap.String("name", event.Name)) | ||||
| 						log.Printf("skipped %q: filename not parsable in kubernetes log format", filepath.Base(event.Name)) | ||||
| 						continue | ||||
| 					} | ||||
|  | ||||
| @@ -192,7 +146,16 @@ var App = &cli.App{ | ||||
|  | ||||
| 					wg.Add(1) | ||||
| 					go func() { | ||||
| 						state.shipFile(ctx.Context, event.Name, ctx.Int("max-record-size")) | ||||
| 						file := file{ | ||||
| 							File: ms.File{ | ||||
| 								Host:     &hostInfo, | ||||
| 								KubeInfo: kubeInfo, | ||||
| 								Path:     event.Name, | ||||
| 							}, | ||||
| 							metricsName: filepath.Base(event.Name), | ||||
| 						} | ||||
|  | ||||
| 						file.Process(ctx.Context, db, ctx.Int("max-record-size")) | ||||
| 						wg.Done() | ||||
| 					}() | ||||
|  | ||||
| @@ -201,22 +164,20 @@ var App = &cli.App{ | ||||
| 						return | ||||
| 					} | ||||
| 					promWatcherErr.Add(1) | ||||
| 					l.Error("while watching log dir events", zap.Error(err)) | ||||
| 					log.Printf("watching for new logs: %e", err) | ||||
| 				} | ||||
| 			} | ||||
| 		}() | ||||
|  | ||||
| 		logDir := ctx.String("log-directory") | ||||
|  | ||||
| 		// simulate create events to pick up files already created | ||||
| 		err = simulateInitialCreate(logDir, watcher.Events) | ||||
| 		if err != nil { | ||||
| 			promWatcherErr.Add(1) | ||||
| 			l.Fatal("listing initial log directory", zap.String("name", logDir), zap.Error(err)) | ||||
| 		if err := simulateInitialCreates(logDir, watcher.Events); err != nil { | ||||
| 			return fmt.Errorf("listing log directory %q: %w", logDir, err) | ||||
| 		} | ||||
|  | ||||
| 		err = watcher.Add(logDir) | ||||
| 		if err != nil { | ||||
| 			promWatcherErr.Add(1) | ||||
| 			l.Fatal("watching log directory", zap.String("name", logDir), zap.Error(err)) | ||||
| 		if err := watcher.Add(logDir); err != nil { | ||||
| 			return fmt.Errorf("watching for new logs in %q: %w", logDir, err) | ||||
| 		} | ||||
|  | ||||
| 		promWatcherOnline.Set(1) | ||||
| @@ -224,84 +185,11 @@ var App = &cli.App{ | ||||
| 		// waiting indefinitely for interrupt | ||||
| 		wg.Wait() // wait for watch and file processors to cleanup | ||||
|  | ||||
| 		return errAppend(watcher.Close(), ctx.Err()) | ||||
| 		return ctx.Err() | ||||
| 	}, | ||||
| } | ||||
|  | ||||
| type HostInfo struct { | ||||
| 	Id   string | ||||
| 	Name string | ||||
| 	Arch string | ||||
| } | ||||
|  | ||||
| func getHostInfo(nodeName string) (h HostInfo, err error) { | ||||
| 	if nodeName == "" { | ||||
| 		nodeName, err = os.Hostname() | ||||
| 		if err != nil { | ||||
| 			err = fmt.Errorf("name: hostname: %w", err) // don't exit early | ||||
| 		} | ||||
| 	} | ||||
| 	h.Name = strings.TrimSpace(nodeName) | ||||
|  | ||||
| 	id, errL := os.ReadFile(MachineId) | ||||
| 	if errL != nil { | ||||
| 		err = errAppend(err, fmt.Errorf("id: %w", errL)) | ||||
| 	} | ||||
|  | ||||
| 	h.Id = strings.TrimSpace(string(id)) | ||||
|  | ||||
| 	h.Arch = runtime.GOARCH | ||||
|  | ||||
| 	return h, err | ||||
| } | ||||
|  | ||||
| func errAppend(a, b error) error { | ||||
| 	if a == nil { | ||||
| 		return b | ||||
| 	} | ||||
| 	if b == nil { | ||||
| 		return a | ||||
| 	} | ||||
| 	return fmt.Errorf("%e; %e", a, b) | ||||
| } | ||||
|  | ||||
| type logMeta struct { | ||||
| 	podName       string | ||||
| 	podNamespace  string | ||||
| 	containerName string | ||||
| 	containerId   string | ||||
| } | ||||
|  | ||||
| func parseLogName(name string) (m logMeta, ok bool) { | ||||
| 	name = filepath.Base(name) | ||||
|  | ||||
| 	// https://github.com/kubernetes/design-proposals-archive/blob/8da1442ea29adccea40693357d04727127e045ed/node/kubelet-cri-logging.md | ||||
| 	// <pod_name>_<pod_namespace>_<container_name>-<container_id>.log` | ||||
|  | ||||
| 	m.podName, name, ok = strings.Cut(name, "_") | ||||
| 	if !ok { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	m.podNamespace, name, ok = strings.Cut(name, "_") | ||||
| 	if !ok { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	m.containerName, name, ok = strings.Cut(name, "-") | ||||
| 	if !ok { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	m.containerId = strings.TrimSuffix(name, ".log") | ||||
| 	if !strings.HasSuffix(name, ".log") { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	return m, true | ||||
| } | ||||
|  | ||||
| func simulateInitialCreate(dirName string, eventChan chan<- fsnotify.Event) error { | ||||
| func simulateInitialCreates(dirName string, eventChan chan<- fsnotify.Event) error { | ||||
| 	dir, err := os.ReadDir(dirName) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
|   | ||||
							
								
								
									
										15
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								go.mod
									
									
									
									
									
								
							| @@ -4,12 +4,10 @@ go 1.19 | ||||
|  | ||||
| require ( | ||||
| 	github.com/fsnotify/fsnotify v1.6.0 | ||||
| 	github.com/jtagcat/util v0.0.0-20221106213317-cab09054fbdd | ||||
| 	github.com/prometheus/client_golang v1.13.1 | ||||
| 	github.com/urfave/cli/v2 v2.23.4 | ||||
| 	go.elastic.co/ecszap v1.0.1 | ||||
| 	github.com/jtagcat/util v0.0.0-20221109113553-753a118dcd99 | ||||
| 	github.com/prometheus/client_golang v1.14.0 | ||||
| 	github.com/urfave/cli/v2 v2.23.5 | ||||
| 	go.mongodb.org/mongo-driver v1.11.0 | ||||
| 	go.uber.org/zap v1.23.0 | ||||
| 	k8s.io/apimachinery v0.25.3 | ||||
| ) | ||||
|  | ||||
| @@ -22,7 +20,6 @@ require ( | ||||
| 	github.com/golang/snappy v0.0.4 // indirect | ||||
| 	github.com/klauspost/compress v1.15.12 // indirect | ||||
| 	github.com/kr/pretty v0.2.0 // indirect | ||||
| 	github.com/magefile/mage v1.14.0 // indirect | ||||
| 	github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect | ||||
| 	github.com/montanaflynn/stats v0.6.6 // indirect | ||||
| 	github.com/pkg/errors v0.9.1 // indirect | ||||
| @@ -35,15 +32,13 @@ require ( | ||||
| 	github.com/xdg-go/stringprep v1.0.3 // indirect | ||||
| 	github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect | ||||
| 	github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect | ||||
| 	go.uber.org/atomic v1.10.0 // indirect | ||||
| 	go.uber.org/multierr v1.8.0 // indirect | ||||
| 	golang.org/x/crypto v0.1.0 // indirect | ||||
| 	golang.org/x/sync v0.1.0 // indirect | ||||
| 	golang.org/x/sys v0.1.0 // indirect | ||||
| 	golang.org/x/sys v0.2.0 // indirect | ||||
| 	golang.org/x/text v0.4.0 // indirect | ||||
| 	google.golang.org/protobuf v1.28.1 // indirect | ||||
| 	k8s.io/klog/v2 v2.80.1 // indirect | ||||
| 	k8s.io/utils v0.0.0-20221101230645-61b03e2f6476 // indirect | ||||
| 	k8s.io/utils v0.0.0-20221108210102-8e77b1f39fe2 // indirect | ||||
| ) | ||||
|  | ||||
| // https://github.com/kubernetes/kubernetes/pull/113398 | ||||
|   | ||||
							
								
								
									
										47
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								go.sum
									
									
									
									
									
								
							| @@ -38,8 +38,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy | ||||
| github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= | ||||
| github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= | ||||
| github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= | ||||
| github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= | ||||
| github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= | ||||
| github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= | ||||
| github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= | ||||
| github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= | ||||
| @@ -149,8 +147,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 | ||||
| github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= | ||||
| github.com/jtagcat/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20221027124836-581f57977fff h1:ZcCL47dbIlY58XGBk10Onnig0Ce+w0kWxJhaEDHJfmY= | ||||
| github.com/jtagcat/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20221027124836-581f57977fff/go.mod h1:C5R3NoUmJXuT6/sTJpOktLUfvCl+H4/7c2QHOp6qwCo= | ||||
| github.com/jtagcat/util v0.0.0-20221106213317-cab09054fbdd h1:B79h8kW0DCqZvnLqleNZf5SzRV8wO58RMv2pCwb9bKc= | ||||
| github.com/jtagcat/util v0.0.0-20221106213317-cab09054fbdd/go.mod h1:VIg6NAm5vU1HwDCL8p/iILmCwvgVCP3/U4QhlS6hftY= | ||||
| github.com/jtagcat/util v0.0.0-20221109113553-753a118dcd99 h1:Z9LcAEgCflX4wmhUmNHnsQYExERHBN1uAxVPbn8VArw= | ||||
| github.com/jtagcat/util v0.0.0-20221109113553-753a118dcd99/go.mod h1:1JdJ6oODhLvHeuhzNlFJZU55eihSnjUj4p04QgF/q5U= | ||||
| github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= | ||||
| github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= | ||||
| github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= | ||||
| @@ -166,9 +164,6 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn | ||||
| github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||||
| github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||||
| github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||||
| github.com/magefile/mage v1.9.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= | ||||
| github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo= | ||||
| github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= | ||||
| @@ -193,8 +188,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn | ||||
| github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= | ||||
| github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= | ||||
| github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= | ||||
| github.com/prometheus/client_golang v1.13.1 h1:3gMjIY2+/hzmqhtUC/aQNYldJA6DtH3CgQvwS+02K1c= | ||||
| github.com/prometheus/client_golang v1.13.1/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= | ||||
| github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= | ||||
| github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= | ||||
| github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= | ||||
| github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | ||||
| github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | ||||
| @@ -226,12 +221,11 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf | ||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||
| github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||||
| github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||
| github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||
| github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= | ||||
| github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= | ||||
| github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= | ||||
| github.com/urfave/cli/v2 v2.23.4 h1:gcaHwki8kGX6lfp2zz7irxu7eZkcIl1Xapt6XW0Ynqc= | ||||
| github.com/urfave/cli/v2 v2.23.4/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= | ||||
| github.com/urfave/cli/v2 v2.23.5 h1:xbrU7tAYviSpqeR3X4nEFWUdB/uDZ6DE+HxmRU7Xtyw= | ||||
| github.com/urfave/cli/v2 v2.23.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= | ||||
| github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= | ||||
| github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= | ||||
| github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E= | ||||
| @@ -246,9 +240,6 @@ github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/ | ||||
| github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||
| github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||
| github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||
| github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= | ||||
| go.elastic.co/ecszap v1.0.1 h1:mBxqEJAEXBlpi5+scXdzL7LTFGogbuxipJC0KTZicyA= | ||||
| go.elastic.co/ecszap v1.0.1/go.mod h1:SVjazT+QgNeHSGOCUHvRgN+ZRj5FkB7IXQQsncdF57A= | ||||
| go.mongodb.org/mongo-driver v1.11.0 h1:FZKhBSTydeuffHj9CBjXlR8vQLee1cQyTWYPA6/tqiE= | ||||
| go.mongodb.org/mongo-driver v1.11.0/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= | ||||
| go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= | ||||
| @@ -256,17 +247,6 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= | ||||
| go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= | ||||
| go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= | ||||
| go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= | ||||
| go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= | ||||
| go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= | ||||
| go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= | ||||
| go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= | ||||
| go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= | ||||
| go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= | ||||
| go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= | ||||
| go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= | ||||
| go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= | ||||
| go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= | ||||
| go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= | ||||
| golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| @@ -307,7 +287,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB | ||||
| golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= | ||||
| golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||||
| golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||||
| golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||||
| golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| @@ -336,7 +315,6 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ | ||||
| golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= | ||||
| golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= | ||||
| golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= | ||||
| golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= | ||||
| golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||
| golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||
| golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= | ||||
| @@ -393,16 +371,14 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= | ||||
| golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= | ||||
| golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
| golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | ||||
| golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| @@ -457,7 +433,6 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY | ||||
| golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= | ||||
| golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= | ||||
| golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= | ||||
| golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= | ||||
| golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| @@ -548,11 +523,9 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= | ||||
| gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||||
| gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
| @@ -564,8 +537,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 | ||||
| honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= | ||||
| k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= | ||||
| k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= | ||||
| k8s.io/utils v0.0.0-20221101230645-61b03e2f6476 h1:L14f2LWkOxG2rYsuSA3ltQnnST1vMfek/GUk+VemxD4= | ||||
| k8s.io/utils v0.0.0-20221101230645-61b03e2f6476/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= | ||||
| k8s.io/utils v0.0.0-20221108210102-8e77b1f39fe2 h1:GfD9OzL11kvZN5iArC6oTS7RTj7oJOIfnislxYlqTj8= | ||||
| k8s.io/utils v0.0.0-20221108210102-8e77b1f39fe2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= | ||||
| rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= | ||||
| rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= | ||||
| rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= | ||||
|   | ||||
							
								
								
									
										14
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								main.go
									
									
									
									
									
								
							| @@ -1,14 +0,0 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"log" | ||||
| 	"os" | ||||
|  | ||||
| 	logmower "git.k-space.ee/k-space/logmower-shipper/cmd" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	if err := logmower.App.Run(os.Args); err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										29
									
								
								pkg/mongoStruct/bsonLookup.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								pkg/mongoStruct/bsonLookup.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| package mongoStruct | ||||
|  | ||||
| import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"go.mongodb.org/mongo-driver/bson" | ||||
| ) | ||||
|  | ||||
| // default values without ok | ||||
|  | ||||
| func bsonLookupBoolean(b *bson.Raw, key ...string) bool { | ||||
| 	v, _ := b.Lookup(key...).BooleanOK() | ||||
| 	return v | ||||
| } | ||||
|  | ||||
| func bsonLookupStringValue(b *bson.Raw, key ...string) string { | ||||
| 	v, _ := b.Lookup(key...).StringValueOK() | ||||
| 	return v | ||||
| } | ||||
|  | ||||
| func bsonLookupInt64(b *bson.Raw, key ...string) int64 { | ||||
| 	v, _ := b.Lookup(key...).Int64OK() | ||||
| 	return v | ||||
| } | ||||
|  | ||||
| func bsonLookupTime(b *bson.Raw, key ...string) time.Time { | ||||
| 	v, _ := b.Lookup(key...).TimeOK() | ||||
| 	return v | ||||
| } | ||||
							
								
								
									
										60
									
								
								pkg/mongoStruct/gather.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								pkg/mongoStruct/gather.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| package mongoStruct | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| func ParseLogName(name string) (m KubeInfo, ok bool) { | ||||
| 	name = filepath.Base(name) | ||||
|  | ||||
| 	// https://github.com/kubernetes/design-proposals-archive/blob/8da1442ea29adccea40693357d04727127e045ed/node/kubelet-cri-logging.md | ||||
| 	// <pod_name>_<pod_namespace>_<container_name>-<container_id>.log` | ||||
|  | ||||
| 	m.Pod, name, ok = strings.Cut(name, "_") | ||||
| 	if !ok { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	m.Namespace, name, ok = strings.Cut(name, "_") | ||||
| 	if !ok { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	m.ContainerName, name, ok = strings.Cut(name, "-") | ||||
| 	if !ok { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	m.ContainerId = strings.TrimSuffix(name, ".log") | ||||
| 	if !strings.HasSuffix(name, ".log") { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	return m, true | ||||
| } | ||||
|  | ||||
| func (h *HostInfo) Populate(nodeName string) (err error) { | ||||
| 	if nodeName == "" { | ||||
| 		nodeName, err = os.Hostname() | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("getting hostname: %w", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	h.Name = strings.TrimSpace(nodeName) | ||||
|  | ||||
| 	id, err := os.ReadFile("/etc/machine-id") | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("getting machineId: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	h.Id = strings.TrimSpace(string(id)) | ||||
|  | ||||
| 	h.Arch = runtime.GOARCH | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										152
									
								
								pkg/mongoStruct/mongoStruct.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								pkg/mongoStruct/mongoStruct.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,152 @@ | ||||
| package mongoStruct | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"time" | ||||
|  | ||||
| 	"go.mongodb.org/mongo-driver/bson" | ||||
| 	"go.mongodb.org/mongo-driver/mongo" | ||||
| ) | ||||
|  | ||||
| // ctx is used directly | ||||
| func InitializeIndexes(ctx context.Context, col *mongo.Collection) error { | ||||
| 	ind := col.Indexes() | ||||
|  | ||||
| 	// (does not create duplicates) | ||||
| 	_, err := ind.CreateOne(ctx, mongo.IndexModel{ | ||||
| 		Keys: bson.D{{Key: RecordKeyFilePath, Value: 1}, {Key: RecordKeyOffset, Value: -1}}, | ||||
| 	}) | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // when editing, also edit everything in this file! | ||||
| type ( | ||||
| 	Record struct { | ||||
| 		File | ||||
| 		Offset int64 // end, of last line | ||||
|  | ||||
| 		String string | ||||
| 		ParsedMetadata | ||||
|  | ||||
| 		ParsedContent // TODO: not implemented | ||||
|  | ||||
| 		// added by ToBson() | ||||
| 		timeShip time.Time | ||||
| 	} | ||||
| 	ParsedMetadata struct { | ||||
| 		TimeKubernetes time.Time | ||||
| 		StdErr         bool | ||||
| 	} | ||||
| 	ParsedContent struct { | ||||
| 		Content      any | ||||
| 		TimeUpstream time.Time | ||||
| 	} | ||||
| 	HostInfo struct { | ||||
| 		Id   string | ||||
| 		Name string | ||||
| 		Arch string | ||||
| 	} | ||||
| 	File struct { | ||||
| 		Host *HostInfo | ||||
| 		Path string // absolute | ||||
| 		KubeInfo | ||||
| 	} | ||||
| 	KubeInfo struct { | ||||
| 		ContainerName string | ||||
| 		ContainerId   string // unused | ||||
| 		Namespace     string | ||||
| 		Pod           string | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// used outside package for mongo commands | ||||
| 	RecordKeyHostId   = recordKeyHost + "." + recordKeyId | ||||
| 	RecordKeyFilePath = recordKeyLog + "." + recordKeyFile + "." + recordKeygenericPath | ||||
| 	RecordKeyOffset   = recordKeyLog + "." + recordKeyOffset | ||||
| ) | ||||
|  | ||||
| // Don't use direct strings in bson types. Use the constants as keys. | ||||
| // This ensures keys (and subkeys) are consistent within the package, and by consumers of it. | ||||
|  | ||||
| const ( | ||||
| 	recordKeygenericName = "name" | ||||
| 	recordKeygenericPath = "path" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	recordKeyString = "message" | ||||
|  | ||||
| 	recordKeyLog    = "log" | ||||
| 	recordKeyFile   = "file" | ||||
| 	recordKeyOffset = "offset" | ||||
| 	// recordKeyLevel  = "level" | ||||
|  | ||||
| 	recordKeyHost = "host" | ||||
| 	recordKeyId   = "id" | ||||
| 	recordKeyName = "name" | ||||
| 	recordKeyArch = "architecture" | ||||
|  | ||||
| 	recordKeyKubernetes = "kubernetes" | ||||
| 	recordKeyContainer  = "container" | ||||
| 	recordKeyNamespace  = "namespace" | ||||
| 	recordKeyPod        = "pod" | ||||
|  | ||||
| 	recordKeyStream = "stderr" | ||||
|  | ||||
| 	recordKeyContainerTime = "container_time" | ||||
| 	recordKeyShipTime      = "ship_time" | ||||
|  | ||||
| 	recordKeyEvent          = "event" | ||||
| 	recordKeyTimeUpstream   = "created" | ||||
| 	recordKeyTimeKubernetes = "ingested" | ||||
|  | ||||
| 	recordKeyTimeMower = "@timestamp" | ||||
| ) | ||||
|  | ||||
| // not using marshal, since it is <0.1x performance | ||||
| func (l *Record) ToBson() bson.M { | ||||
| 	var stream string | ||||
| 	if l.StdErr { | ||||
| 		stream = "stderr" | ||||
| 	} else { | ||||
| 		stream = "stdout" | ||||
| 	} | ||||
|  | ||||
| 	return bson.M{ | ||||
| 		recordKeyString: l.String, | ||||
| 		recordKeyLog: bson.M{ | ||||
| 			recordKeyFile: bson.M{ | ||||
| 				recordKeygenericPath: l.File.Path, | ||||
| 			}, | ||||
| 			recordKeyOffset: l.Offset, | ||||
| 			// recordKeyLevel:  , //TODO: ECS | ||||
| 		}, | ||||
| 		recordKeyKubernetes: bson.M{ | ||||
| 			recordKeyContainer: bson.M{ | ||||
| 				recordKeygenericName: l.File.ContainerName, | ||||
| 			}, | ||||
| 			recordKeyNamespace: l.File.Namespace, | ||||
| 			recordKeyPod: bson.M{ | ||||
| 				recordKeygenericName: l.File.Pod, | ||||
| 			}, | ||||
| 		}, | ||||
| 		recordKeyHost: bson.M{ | ||||
| 			recordKeyId:   l.File.Host.Id, | ||||
| 			recordKeyName: l.File.Host.Name, | ||||
| 			recordKeyArch: l.File.Host.Arch, | ||||
| 		}, | ||||
| 		recordKeyStream: stream, | ||||
| 		recordKeyEvent: bson.M{ | ||||
| 			recordKeyTimeUpstream:   l.TimeUpstream, | ||||
| 			recordKeyTimeKubernetes: l.TimeKubernetes, | ||||
| 		}, | ||||
|  | ||||
| 		recordKeyShipTime: time.Now(), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func RecordOffsetFromBson(b *bson.Raw) int64 { | ||||
| 	return bsonLookupInt64(b, recordKeyLog, recordKeyOffset) | ||||
| } | ||||
							
								
								
									
										21
									
								
								vendor/github.com/jtagcat/util/go.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/jtagcat/util/go.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| package util | ||||
|  | ||||
| import "sync" | ||||
|  | ||||
| // go <func> with single waitgroup | ||||
| // | ||||
| //	waitGo := util.GoWg(func() { | ||||
| //		exampleFunc(foo, bar) | ||||
| //	}) | ||||
| //	defer waitGo() | ||||
| func GoWg(fn func()) (done func()) { | ||||
| 	var wg sync.WaitGroup | ||||
|  | ||||
| 	wg.Add(1) | ||||
| 	go func() { | ||||
| 		fn() | ||||
| 		wg.Done() | ||||
| 	}() | ||||
|  | ||||
| 	return wg.Done | ||||
| } | ||||
							
								
								
									
										201
									
								
								vendor/github.com/magefile/mage/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										201
									
								
								vendor/github.com/magefile/mage/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,201 +0,0 @@ | ||||
|                                  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 2017 the Mage 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. | ||||
							
								
								
									
										80
									
								
								vendor/github.com/magefile/mage/mg/color.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										80
									
								
								vendor/github.com/magefile/mage/mg/color.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,80 +0,0 @@ | ||||
| package mg | ||||
|  | ||||
| // Color is ANSI color type | ||||
| type Color int | ||||
|  | ||||
| // If you add/change/remove any items in this constant, | ||||
| // you will need to run "stringer -type=Color" in this directory again. | ||||
| // NOTE: Please keep the list in an alphabetical order. | ||||
| const ( | ||||
| 	Black Color = iota | ||||
| 	Red | ||||
| 	Green | ||||
| 	Yellow | ||||
| 	Blue | ||||
| 	Magenta | ||||
| 	Cyan | ||||
| 	White | ||||
| 	BrightBlack | ||||
| 	BrightRed | ||||
| 	BrightGreen | ||||
| 	BrightYellow | ||||
| 	BrightBlue | ||||
| 	BrightMagenta | ||||
| 	BrightCyan | ||||
| 	BrightWhite | ||||
| ) | ||||
|  | ||||
| // AnsiColor are ANSI color codes for supported terminal colors. | ||||
| var ansiColor = map[Color]string{ | ||||
| 	Black:         "\u001b[30m", | ||||
| 	Red:           "\u001b[31m", | ||||
| 	Green:         "\u001b[32m", | ||||
| 	Yellow:        "\u001b[33m", | ||||
| 	Blue:          "\u001b[34m", | ||||
| 	Magenta:       "\u001b[35m", | ||||
| 	Cyan:          "\u001b[36m", | ||||
| 	White:         "\u001b[37m", | ||||
| 	BrightBlack:   "\u001b[30;1m", | ||||
| 	BrightRed:     "\u001b[31;1m", | ||||
| 	BrightGreen:   "\u001b[32;1m", | ||||
| 	BrightYellow:  "\u001b[33;1m", | ||||
| 	BrightBlue:    "\u001b[34;1m", | ||||
| 	BrightMagenta: "\u001b[35;1m", | ||||
| 	BrightCyan:    "\u001b[36;1m", | ||||
| 	BrightWhite:   "\u001b[37;1m", | ||||
| } | ||||
|  | ||||
| // AnsiColorReset is an ANSI color code to reset the terminal color. | ||||
| const AnsiColorReset = "\033[0m" | ||||
|  | ||||
| // DefaultTargetAnsiColor is a default ANSI color for colorizing targets. | ||||
| // It is set to Cyan as an arbitrary color, because it has a neutral meaning | ||||
| var DefaultTargetAnsiColor = ansiColor[Cyan] | ||||
|  | ||||
| func toLowerCase(s string) string { | ||||
| 	// this is a naive implementation | ||||
| 	// borrowed from https://golang.org/src/strings/strings.go | ||||
| 	// and only considers alphabetical characters [a-zA-Z] | ||||
| 	// so that we don't depend on the "strings" package | ||||
| 	buf := make([]byte, len(s)) | ||||
| 	for i := 0; i < len(s); i++ { | ||||
| 		c := s[i] | ||||
| 		if 'A' <= c && c <= 'Z' { | ||||
| 			c += 'a' - 'A' | ||||
| 		} | ||||
| 		buf[i] = c | ||||
| 	} | ||||
| 	return string(buf) | ||||
| } | ||||
|  | ||||
| func getAnsiColor(color string) (string, bool) { | ||||
| 	colorLower := toLowerCase(color) | ||||
| 	for k, v := range ansiColor { | ||||
| 		colorConstLower := toLowerCase(k.String()) | ||||
| 		if colorConstLower == colorLower { | ||||
| 			return v, true | ||||
| 		} | ||||
| 	} | ||||
| 	return "", false | ||||
| } | ||||
							
								
								
									
										38
									
								
								vendor/github.com/magefile/mage/mg/color_string.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								vendor/github.com/magefile/mage/mg/color_string.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,38 +0,0 @@ | ||||
| // Code generated by "stringer -type=Color"; DO NOT EDIT. | ||||
|  | ||||
| package mg | ||||
|  | ||||
| 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[Black-0] | ||||
| 	_ = x[Red-1] | ||||
| 	_ = x[Green-2] | ||||
| 	_ = x[Yellow-3] | ||||
| 	_ = x[Blue-4] | ||||
| 	_ = x[Magenta-5] | ||||
| 	_ = x[Cyan-6] | ||||
| 	_ = x[White-7] | ||||
| 	_ = x[BrightBlack-8] | ||||
| 	_ = x[BrightRed-9] | ||||
| 	_ = x[BrightGreen-10] | ||||
| 	_ = x[BrightYellow-11] | ||||
| 	_ = x[BrightBlue-12] | ||||
| 	_ = x[BrightMagenta-13] | ||||
| 	_ = x[BrightCyan-14] | ||||
| 	_ = x[BrightWhite-15] | ||||
| } | ||||
|  | ||||
| const _Color_name = "BlackRedGreenYellowBlueMagentaCyanWhiteBrightBlackBrightRedBrightGreenBrightYellowBrightBlueBrightMagentaBrightCyanBrightWhite" | ||||
|  | ||||
| var _Color_index = [...]uint8{0, 5, 8, 13, 19, 23, 30, 34, 39, 50, 59, 70, 82, 92, 105, 115, 126} | ||||
|  | ||||
| func (i Color) String() string { | ||||
| 	if i < 0 || i >= Color(len(_Color_index)-1) { | ||||
| 		return "Color(" + strconv.FormatInt(int64(i), 10) + ")" | ||||
| 	} | ||||
| 	return _Color_name[_Color_index[i]:_Color_index[i+1]] | ||||
| } | ||||
							
								
								
									
										211
									
								
								vendor/github.com/magefile/mage/mg/deps.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										211
									
								
								vendor/github.com/magefile/mage/mg/deps.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,211 +0,0 @@ | ||||
| package mg | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"reflect" | ||||
| 	"runtime" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| ) | ||||
|  | ||||
| var logger = log.New(os.Stderr, "", 0) | ||||
|  | ||||
| type onceMap struct { | ||||
| 	mu *sync.Mutex | ||||
| 	m  map[onceKey]*onceFun | ||||
| } | ||||
|  | ||||
| type onceKey struct { | ||||
| 	Name string | ||||
| 	ID   string | ||||
| } | ||||
|  | ||||
| func (o *onceMap) LoadOrStore(f Fn) *onceFun { | ||||
| 	defer o.mu.Unlock() | ||||
| 	o.mu.Lock() | ||||
|  | ||||
| 	key := onceKey{ | ||||
| 		Name: f.Name(), | ||||
| 		ID:   f.ID(), | ||||
| 	} | ||||
| 	existing, ok := o.m[key] | ||||
| 	if ok { | ||||
| 		return existing | ||||
| 	} | ||||
| 	one := &onceFun{ | ||||
| 		once:        &sync.Once{}, | ||||
| 		fn:          f, | ||||
| 		displayName: displayName(f.Name()), | ||||
| 	} | ||||
| 	o.m[key] = one | ||||
| 	return one | ||||
| } | ||||
|  | ||||
| var onces = &onceMap{ | ||||
| 	mu: &sync.Mutex{}, | ||||
| 	m:  map[onceKey]*onceFun{}, | ||||
| } | ||||
|  | ||||
| // SerialDeps is like Deps except it runs each dependency serially, instead of | ||||
| // in parallel. This can be useful for resource intensive dependencies that | ||||
| // shouldn't be run at the same time. | ||||
| func SerialDeps(fns ...interface{}) { | ||||
| 	funcs := checkFns(fns) | ||||
| 	ctx := context.Background() | ||||
| 	for i := range fns { | ||||
| 		runDeps(ctx, funcs[i:i+1]) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // SerialCtxDeps is like CtxDeps except it runs each dependency serially, | ||||
| // instead of in parallel. This can be useful for resource intensive | ||||
| // dependencies that shouldn't be run at the same time. | ||||
| func SerialCtxDeps(ctx context.Context, fns ...interface{}) { | ||||
| 	funcs := checkFns(fns) | ||||
| 	for i := range fns { | ||||
| 		runDeps(ctx, funcs[i:i+1]) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // CtxDeps runs the given functions as dependencies of the calling function. | ||||
| // Dependencies must only be of type: | ||||
| //     func() | ||||
| //     func() error | ||||
| //     func(context.Context) | ||||
| //     func(context.Context) error | ||||
| // Or a similar method on a mg.Namespace type. | ||||
| // Or an mg.Fn interface. | ||||
| // | ||||
| // The function calling Deps is guaranteed that all dependent functions will be | ||||
| // run exactly once when Deps returns.  Dependent functions may in turn declare | ||||
| // their own dependencies using Deps. Each dependency is run in their own | ||||
| // goroutines. Each function is given the context provided if the function | ||||
| // prototype allows for it. | ||||
| func CtxDeps(ctx context.Context, fns ...interface{}) { | ||||
| 	funcs := checkFns(fns) | ||||
| 	runDeps(ctx, funcs) | ||||
| } | ||||
|  | ||||
| // runDeps assumes you've already called checkFns. | ||||
| func runDeps(ctx context.Context, fns []Fn) { | ||||
| 	mu := &sync.Mutex{} | ||||
| 	var errs []string | ||||
| 	var exit int | ||||
| 	wg := &sync.WaitGroup{} | ||||
| 	for _, f := range fns { | ||||
| 		fn := onces.LoadOrStore(f) | ||||
| 		wg.Add(1) | ||||
| 		go func() { | ||||
| 			defer func() { | ||||
| 				if v := recover(); v != nil { | ||||
| 					mu.Lock() | ||||
| 					if err, ok := v.(error); ok { | ||||
| 						exit = changeExit(exit, ExitStatus(err)) | ||||
| 					} else { | ||||
| 						exit = changeExit(exit, 1) | ||||
| 					} | ||||
| 					errs = append(errs, fmt.Sprint(v)) | ||||
| 					mu.Unlock() | ||||
| 				} | ||||
| 				wg.Done() | ||||
| 			}() | ||||
| 			if err := fn.run(ctx); err != nil { | ||||
| 				mu.Lock() | ||||
| 				errs = append(errs, fmt.Sprint(err)) | ||||
| 				exit = changeExit(exit, ExitStatus(err)) | ||||
| 				mu.Unlock() | ||||
| 			} | ||||
| 		}() | ||||
| 	} | ||||
|  | ||||
| 	wg.Wait() | ||||
| 	if len(errs) > 0 { | ||||
| 		panic(Fatal(exit, strings.Join(errs, "\n"))) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func checkFns(fns []interface{}) []Fn { | ||||
| 	funcs := make([]Fn, len(fns)) | ||||
| 	for i, f := range fns { | ||||
| 		if fn, ok := f.(Fn); ok { | ||||
| 			funcs[i] = fn | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		// Check if the target provided is a not function so we can give a clear warning | ||||
| 		t := reflect.TypeOf(f) | ||||
| 		if t == nil || t.Kind() != reflect.Func { | ||||
| 			panic(fmt.Errorf("non-function used as a target dependency: %T. The mg.Deps, mg.SerialDeps and mg.CtxDeps functions accept function names, such as mg.Deps(TargetA, TargetB)", f)) | ||||
| 		} | ||||
|  | ||||
| 		funcs[i] = F(f) | ||||
| 	} | ||||
| 	return funcs | ||||
| } | ||||
|  | ||||
| // Deps runs the given functions in parallel, exactly once. Dependencies must | ||||
| // only be of type: | ||||
| //     func() | ||||
| //     func() error | ||||
| //     func(context.Context) | ||||
| //     func(context.Context) error | ||||
| // Or a similar method on a mg.Namespace type. | ||||
| // Or an mg.Fn interface. | ||||
| // | ||||
| // This is a way to build up a tree of dependencies with each dependency | ||||
| // defining its own dependencies.  Functions must have the same signature as a | ||||
| // Mage target, i.e. optional context argument, optional error return. | ||||
| func Deps(fns ...interface{}) { | ||||
| 	CtxDeps(context.Background(), fns...) | ||||
| } | ||||
|  | ||||
| func changeExit(old, new int) int { | ||||
| 	if new == 0 { | ||||
| 		return old | ||||
| 	} | ||||
| 	if old == 0 { | ||||
| 		return new | ||||
| 	} | ||||
| 	if old == new { | ||||
| 		return old | ||||
| 	} | ||||
| 	// both different and both non-zero, just set | ||||
| 	// exit to 1. Nothing more we can do. | ||||
| 	return 1 | ||||
| } | ||||
|  | ||||
| // funcName returns the unique name for the function | ||||
| func funcName(i interface{}) string { | ||||
| 	return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() | ||||
| } | ||||
|  | ||||
| func displayName(name string) string { | ||||
| 	splitByPackage := strings.Split(name, ".") | ||||
| 	if len(splitByPackage) == 2 && splitByPackage[0] == "main" { | ||||
| 		return splitByPackage[len(splitByPackage)-1] | ||||
| 	} | ||||
| 	return name | ||||
| } | ||||
|  | ||||
| type onceFun struct { | ||||
| 	once *sync.Once | ||||
| 	fn   Fn | ||||
| 	err  error | ||||
|  | ||||
| 	displayName string | ||||
| } | ||||
|  | ||||
| // run will run the function exactly once and capture the error output. Further runs simply return | ||||
| // the same error output. | ||||
| func (o *onceFun) run(ctx context.Context) error { | ||||
| 	o.once.Do(func() { | ||||
| 		if Verbose() { | ||||
| 			logger.Println("Running dependency:", displayName(o.fn.Name())) | ||||
| 		} | ||||
| 		o.err = o.fn.Run(ctx) | ||||
| 	}) | ||||
| 	return o.err | ||||
| } | ||||
							
								
								
									
										51
									
								
								vendor/github.com/magefile/mage/mg/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										51
									
								
								vendor/github.com/magefile/mage/mg/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,51 +0,0 @@ | ||||
| package mg | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| ) | ||||
|  | ||||
| type fatalErr struct { | ||||
| 	code int | ||||
| 	error | ||||
| } | ||||
|  | ||||
| func (f fatalErr) ExitStatus() int { | ||||
| 	return f.code | ||||
| } | ||||
|  | ||||
| type exitStatus interface { | ||||
| 	ExitStatus() int | ||||
| } | ||||
|  | ||||
| // Fatal returns an error that will cause mage to print out the | ||||
| // given args and exit with the given exit code. | ||||
| func Fatal(code int, args ...interface{}) error { | ||||
| 	return fatalErr{ | ||||
| 		code:  code, | ||||
| 		error: errors.New(fmt.Sprint(args...)), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Fatalf returns an error that will cause mage to print out the | ||||
| // given message and exit with the given exit code. | ||||
| func Fatalf(code int, format string, args ...interface{}) error { | ||||
| 	return fatalErr{ | ||||
| 		code:  code, | ||||
| 		error: fmt.Errorf(format, args...), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ExitStatus queries the error for an exit status.  If the error is nil, it | ||||
| // returns 0.  If the error does not implement ExitStatus() int, it returns 1. | ||||
| // Otherwise it retiurns the value from ExitStatus(). | ||||
| func ExitStatus(err error) int { | ||||
| 	if err == nil { | ||||
| 		return 0 | ||||
| 	} | ||||
| 	exit, ok := err.(exitStatus) | ||||
| 	if !ok { | ||||
| 		return 1 | ||||
| 	} | ||||
| 	return exit.ExitStatus() | ||||
| } | ||||
							
								
								
									
										192
									
								
								vendor/github.com/magefile/mage/mg/fn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										192
									
								
								vendor/github.com/magefile/mage/mg/fn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,192 +0,0 @@ | ||||
| package mg | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // Fn represents a function that can be run with mg.Deps. Package, Name, and ID must combine to | ||||
| // uniquely identify a function, while ensuring the "same" function has identical values. These are | ||||
| // used as a map key to find and run (or not run) the function. | ||||
| type Fn interface { | ||||
| 	// Name should return the fully qualified name of the function. Usually | ||||
| 	// it's best to use runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name(). | ||||
| 	Name() string | ||||
|  | ||||
| 	// ID should be an additional uniqueness qualifier in case the name is insufficiently unique. | ||||
| 	// This can be the case for functions that take arguments (mg.F json-encodes an array of the | ||||
| 	// args). | ||||
| 	ID() string | ||||
|  | ||||
| 	// Run should run the function. | ||||
| 	Run(ctx context.Context) error | ||||
| } | ||||
|  | ||||
| // F takes a function that is compatible as a mage target, and any args that need to be passed to | ||||
| // it, and wraps it in an mg.Fn that mg.Deps can run. Args must be passed in the same order as they | ||||
| // are declared by the function. Note that you do not need to and should not pass a context.Context | ||||
| // to F, even if the target takes a context. Compatible args are int, bool, string, and | ||||
| // time.Duration. | ||||
| func F(target interface{}, args ...interface{}) Fn { | ||||
| 	hasContext, isNamespace, err := checkF(target, args) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	id, err := json.Marshal(args) | ||||
| 	if err != nil { | ||||
| 		panic(fmt.Errorf("can't convert args into a mage-compatible id for mg.Deps: %s", err)) | ||||
| 	} | ||||
| 	return fn{ | ||||
| 		name: funcName(target), | ||||
| 		id:   string(id), | ||||
| 		f: func(ctx context.Context) error { | ||||
| 			v := reflect.ValueOf(target) | ||||
| 			count := len(args) | ||||
| 			if hasContext { | ||||
| 				count++ | ||||
| 			} | ||||
| 			if isNamespace { | ||||
| 				count++ | ||||
| 			} | ||||
| 			vargs := make([]reflect.Value, count) | ||||
| 			x := 0 | ||||
| 			if isNamespace { | ||||
| 				vargs[0] = reflect.ValueOf(struct{}{}) | ||||
| 				x++ | ||||
| 			} | ||||
| 			if hasContext { | ||||
| 				vargs[x] = reflect.ValueOf(ctx) | ||||
| 				x++ | ||||
| 			} | ||||
| 			for y := range args { | ||||
| 				vargs[x+y] = reflect.ValueOf(args[y]) | ||||
| 			} | ||||
| 			ret := v.Call(vargs) | ||||
| 			if len(ret) > 0 { | ||||
| 				// we only allow functions with a single error return, so this should be safe. | ||||
| 				if ret[0].IsNil() { | ||||
| 					return nil | ||||
| 				} | ||||
| 				return ret[0].Interface().(error) | ||||
| 			} | ||||
| 			return nil | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type fn struct { | ||||
| 	name string | ||||
| 	id   string | ||||
| 	f    func(ctx context.Context) error | ||||
| } | ||||
|  | ||||
| // Name returns the fully qualified name of the function. | ||||
| func (f fn) Name() string { | ||||
| 	return f.name | ||||
| } | ||||
|  | ||||
| // ID returns a hash of the argument values passed in | ||||
| func (f fn) ID() string { | ||||
| 	return f.id | ||||
| } | ||||
|  | ||||
| // Run runs the function. | ||||
| func (f fn) Run(ctx context.Context) error { | ||||
| 	return f.f(ctx) | ||||
| } | ||||
|  | ||||
| func checkF(target interface{}, args []interface{}) (hasContext, isNamespace bool, _ error) { | ||||
| 	t := reflect.TypeOf(target) | ||||
| 	if t == nil || t.Kind() != reflect.Func { | ||||
| 		return false, false, fmt.Errorf("non-function passed to mg.F: %T. The mg.F function accepts function names, such as mg.F(TargetA, \"arg1\", \"arg2\")", target) | ||||
| 	} | ||||
|  | ||||
| 	if t.NumOut() > 1 { | ||||
| 		return false, false, fmt.Errorf("target has too many return values, must be zero or just an error: %T", target) | ||||
| 	} | ||||
| 	if t.NumOut() == 1 && t.Out(0) != errType { | ||||
| 		return false, false, fmt.Errorf("target's return value is not an error") | ||||
| 	} | ||||
|  | ||||
| 	// more inputs than slots is an error if not variadic | ||||
| 	if len(args) > t.NumIn() && !t.IsVariadic() { | ||||
| 		return false, false, fmt.Errorf("too many arguments for target, got %d for %T", len(args), target) | ||||
| 	} | ||||
|  | ||||
| 	if t.NumIn() == 0 { | ||||
| 		return false, false, nil | ||||
| 	} | ||||
|  | ||||
| 	x := 0 | ||||
| 	inputs := t.NumIn() | ||||
|  | ||||
| 	if t.In(0).AssignableTo(emptyType) { | ||||
| 		// nameSpace func | ||||
| 		isNamespace = true | ||||
| 		x++ | ||||
| 		// callers must leave off the namespace value | ||||
| 		inputs-- | ||||
| 	} | ||||
| 	if t.NumIn() > x && t.In(x) == ctxType { | ||||
| 		// callers must leave off the context | ||||
| 		inputs-- | ||||
|  | ||||
| 		// let the upper function know it should pass us a context. | ||||
| 		hasContext = true | ||||
|  | ||||
| 		// skip checking the first argument in the below loop if it's a context, since first arg is | ||||
| 		// special. | ||||
| 		x++ | ||||
| 	} | ||||
|  | ||||
| 	if t.IsVariadic() { | ||||
| 		if len(args) < inputs-1 { | ||||
| 			return false, false, fmt.Errorf("too few arguments for target, got %d for %T", len(args), target) | ||||
|  | ||||
| 		} | ||||
| 	} else if len(args) != inputs { | ||||
| 		return false, false, fmt.Errorf("wrong number of arguments for target, got %d for %T", len(args), target) | ||||
| 	} | ||||
|  | ||||
| 	for _, arg := range args { | ||||
| 		argT := t.In(x) | ||||
| 		if t.IsVariadic() && x == t.NumIn()-1 { | ||||
| 			// For the variadic argument, use the slice element type. | ||||
| 			argT = argT.Elem() | ||||
| 		} | ||||
| 		if !argTypes[argT] { | ||||
| 			return false, false, fmt.Errorf("argument %d (%s), is not a supported argument type", x, argT) | ||||
| 		} | ||||
| 		passedT := reflect.TypeOf(arg) | ||||
| 		if argT != passedT { | ||||
| 			return false, false, fmt.Errorf("argument %d expected to be %s, but is %s", x, argT, passedT) | ||||
| 		} | ||||
| 		if x < t.NumIn()-1 { | ||||
| 			x++ | ||||
| 		} | ||||
| 	} | ||||
| 	return hasContext, isNamespace, nil | ||||
| } | ||||
|  | ||||
| // Here we define the types that are supported as arguments/returns | ||||
| var ( | ||||
| 	ctxType   = reflect.TypeOf(func(context.Context) {}).In(0) | ||||
| 	errType   = reflect.TypeOf(func() error { return nil }).Out(0) | ||||
| 	emptyType = reflect.TypeOf(struct{}{}) | ||||
|  | ||||
| 	intType    = reflect.TypeOf(int(0)) | ||||
| 	stringType = reflect.TypeOf(string("")) | ||||
| 	boolType   = reflect.TypeOf(bool(false)) | ||||
| 	durType    = reflect.TypeOf(time.Second) | ||||
|  | ||||
| 	// don't put ctx in here, this is for non-context types | ||||
| 	argTypes = map[reflect.Type]bool{ | ||||
| 		intType:    true, | ||||
| 		boolType:   true, | ||||
| 		stringType: true, | ||||
| 		durType:    true, | ||||
| 	} | ||||
| ) | ||||
							
								
								
									
										136
									
								
								vendor/github.com/magefile/mage/mg/runtime.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										136
									
								
								vendor/github.com/magefile/mage/mg/runtime.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,136 +0,0 @@ | ||||
| package mg | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
| 	"strconv" | ||||
| ) | ||||
|  | ||||
| // CacheEnv is the environment variable that users may set to change the | ||||
| // location where mage stores its compiled binaries. | ||||
| const CacheEnv = "MAGEFILE_CACHE" | ||||
|  | ||||
| // VerboseEnv is the environment variable that indicates the user requested | ||||
| // verbose mode when running a magefile. | ||||
| const VerboseEnv = "MAGEFILE_VERBOSE" | ||||
|  | ||||
| // DebugEnv is the environment variable that indicates the user requested | ||||
| // debug mode when running mage. | ||||
| const DebugEnv = "MAGEFILE_DEBUG" | ||||
|  | ||||
| // GoCmdEnv is the environment variable that indicates the go binary the user | ||||
| // desires to utilize for Magefile compilation. | ||||
| const GoCmdEnv = "MAGEFILE_GOCMD" | ||||
|  | ||||
| // IgnoreDefaultEnv is the environment variable that indicates the user requested | ||||
| // to ignore the default target specified in the magefile. | ||||
| const IgnoreDefaultEnv = "MAGEFILE_IGNOREDEFAULT" | ||||
|  | ||||
| // HashFastEnv is the environment variable that indicates the user requested to | ||||
| // use a quick hash of magefiles to determine whether or not the magefile binary | ||||
| // needs to be rebuilt. This results in faster runtimes, but means that mage | ||||
| // will fail to rebuild if a dependency has changed. To force a rebuild, run | ||||
| // mage with the -f flag. | ||||
| const HashFastEnv = "MAGEFILE_HASHFAST" | ||||
|  | ||||
| // EnableColorEnv is the environment variable that indicates the user is using | ||||
| // a terminal which supports a color output. The default is false for backwards | ||||
| // compatibility. When the value is true and the detected terminal does support colors | ||||
| // then the list of mage targets will be displayed in ANSI color. When the value | ||||
| // is true but the detected terminal does not support colors, then the list of | ||||
| // mage targets will be displayed in the default colors (e.g. black and white). | ||||
| const EnableColorEnv = "MAGEFILE_ENABLE_COLOR" | ||||
|  | ||||
| // TargetColorEnv is the environment variable that indicates which ANSI color | ||||
| // should be used to colorize mage targets. This is only applicable when | ||||
| // the MAGEFILE_ENABLE_COLOR environment variable is true. | ||||
| // The supported ANSI color names are any of these: | ||||
| // - Black | ||||
| // - Red | ||||
| // - Green | ||||
| // - Yellow | ||||
| // - Blue | ||||
| // - Magenta | ||||
| // - Cyan | ||||
| // - White | ||||
| // - BrightBlack | ||||
| // - BrightRed | ||||
| // - BrightGreen | ||||
| // - BrightYellow | ||||
| // - BrightBlue | ||||
| // - BrightMagenta | ||||
| // - BrightCyan | ||||
| // - BrightWhite | ||||
| const TargetColorEnv = "MAGEFILE_TARGET_COLOR" | ||||
|  | ||||
| // Verbose reports whether a magefile was run with the verbose flag. | ||||
| func Verbose() bool { | ||||
| 	b, _ := strconv.ParseBool(os.Getenv(VerboseEnv)) | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| // Debug reports whether a magefile was run with the debug flag. | ||||
| func Debug() bool { | ||||
| 	b, _ := strconv.ParseBool(os.Getenv(DebugEnv)) | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| // GoCmd reports the command that Mage will use to build go code.  By default mage runs | ||||
| // the "go" binary in the PATH. | ||||
| func GoCmd() string { | ||||
| 	if cmd := os.Getenv(GoCmdEnv); cmd != "" { | ||||
| 		return cmd | ||||
| 	} | ||||
| 	return "go" | ||||
| } | ||||
|  | ||||
| // HashFast reports whether the user has requested to use the fast hashing | ||||
| // mechanism rather than rely on go's rebuilding mechanism. | ||||
| func HashFast() bool { | ||||
| 	b, _ := strconv.ParseBool(os.Getenv(HashFastEnv)) | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| // IgnoreDefault reports whether the user has requested to ignore the default target | ||||
| // in the magefile. | ||||
| func IgnoreDefault() bool { | ||||
| 	b, _ := strconv.ParseBool(os.Getenv(IgnoreDefaultEnv)) | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| // CacheDir returns the directory where mage caches compiled binaries.  It | ||||
| // defaults to $HOME/.magefile, but may be overridden by the MAGEFILE_CACHE | ||||
| // environment variable. | ||||
| func CacheDir() string { | ||||
| 	d := os.Getenv(CacheEnv) | ||||
| 	if d != "" { | ||||
| 		return d | ||||
| 	} | ||||
| 	switch runtime.GOOS { | ||||
| 	case "windows": | ||||
| 		return filepath.Join(os.Getenv("HOMEDRIVE"), os.Getenv("HOMEPATH"), "magefile") | ||||
| 	default: | ||||
| 		return filepath.Join(os.Getenv("HOME"), ".magefile") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // EnableColor reports whether the user has requested to enable a color output. | ||||
| func EnableColor() bool { | ||||
| 	b, _ := strconv.ParseBool(os.Getenv(EnableColorEnv)) | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| // TargetColor returns the configured ANSI color name a color output. | ||||
| func TargetColor() string { | ||||
| 	s, exists := os.LookupEnv(TargetColorEnv) | ||||
| 	if exists { | ||||
| 		if c, ok := getAnsiColor(s); ok { | ||||
| 			return c | ||||
| 		} | ||||
| 	} | ||||
| 	return DefaultTargetAnsiColor | ||||
| } | ||||
|  | ||||
| // Namespace allows for the grouping of similar commands | ||||
| type Namespace struct{} | ||||
							
								
								
									
										6
									
								
								vendor/github.com/prometheus/client_golang/prometheus/counter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/prometheus/client_golang/prometheus/counter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -246,7 +246,8 @@ func (v *CounterVec) GetMetricWith(labels Labels) (Counter, error) { | ||||
| // WithLabelValues works as GetMetricWithLabelValues, but panics where | ||||
| // GetMetricWithLabelValues would have returned an error. Not returning an | ||||
| // error allows shortcuts like | ||||
| //     myVec.WithLabelValues("404", "GET").Add(42) | ||||
| // | ||||
| //	myVec.WithLabelValues("404", "GET").Add(42) | ||||
| func (v *CounterVec) WithLabelValues(lvs ...string) Counter { | ||||
| 	c, err := v.GetMetricWithLabelValues(lvs...) | ||||
| 	if err != nil { | ||||
| @@ -257,7 +258,8 @@ func (v *CounterVec) WithLabelValues(lvs ...string) Counter { | ||||
|  | ||||
| // With works as GetMetricWith, but panics where GetMetricWithLabels would have | ||||
| // returned an error. Not returning an error allows shortcuts like | ||||
| //     myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42) | ||||
| // | ||||
| //	myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42) | ||||
| func (v *CounterVec) With(labels Labels) Counter { | ||||
| 	c, err := v.GetMetricWith(labels) | ||||
| 	if err != nil { | ||||
|   | ||||
							
								
								
									
										93
									
								
								vendor/github.com/prometheus/client_golang/prometheus/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										93
									
								
								vendor/github.com/prometheus/client_golang/prometheus/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -21,55 +21,66 @@ | ||||
| // All exported functions and methods are safe to be used concurrently unless | ||||
| // specified otherwise. | ||||
| // | ||||
| // A Basic Example | ||||
| // # A Basic Example | ||||
| // | ||||
| // As a starting point, a very basic usage example: | ||||
| // | ||||
| //    package main | ||||
| //	package main | ||||
| // | ||||
| //    import ( | ||||
| //    	"log" | ||||
| //    	"net/http" | ||||
| //	import ( | ||||
| //		"log" | ||||
| //		"net/http" | ||||
| // | ||||
| //    	"github.com/prometheus/client_golang/prometheus" | ||||
| //    	"github.com/prometheus/client_golang/prometheus/promhttp" | ||||
| //    ) | ||||
| //		"github.com/prometheus/client_golang/prometheus" | ||||
| //		"github.com/prometheus/client_golang/prometheus/promhttp" | ||||
| //	) | ||||
| // | ||||
| //    var ( | ||||
| //    	cpuTemp = prometheus.NewGauge(prometheus.GaugeOpts{ | ||||
| //    		Name: "cpu_temperature_celsius", | ||||
| //    		Help: "Current temperature of the CPU.", | ||||
| //    	}) | ||||
| //    	hdFailures = prometheus.NewCounterVec( | ||||
| //    		prometheus.CounterOpts{ | ||||
| //    			Name: "hd_errors_total", | ||||
| //    			Help: "Number of hard-disk errors.", | ||||
| //    		}, | ||||
| //    		[]string{"device"}, | ||||
| //    	) | ||||
| //    ) | ||||
| //	type metrics struct { | ||||
| //		cpuTemp  prometheus.Gauge | ||||
| //	  hdFailures *prometheus.CounterVec | ||||
| //	} | ||||
| // | ||||
| //    func init() { | ||||
| //    	// Metrics have to be registered to be exposed: | ||||
| //    	prometheus.MustRegister(cpuTemp) | ||||
| //    	prometheus.MustRegister(hdFailures) | ||||
| //    } | ||||
| //	func NewMetrics(reg prometheus.Registerer) *metrics { | ||||
| //	  m := &metrics{ | ||||
| //	    cpuTemp: prometheus.NewGauge(prometheus.GaugeOpts{ | ||||
| //	      Name: "cpu_temperature_celsius", | ||||
| //	      Help: "Current temperature of the CPU.", | ||||
| //	    }), | ||||
| //	    hdFailures: prometheus.NewCounterVec( | ||||
| //	      prometheus.CounterOpts{ | ||||
| //	        Name: "hd_errors_total", | ||||
| //	        Help: "Number of hard-disk errors.", | ||||
| //	      }, | ||||
| //	      []string{"device"}, | ||||
| //	    ), | ||||
| //	  } | ||||
| //	  reg.MustRegister(m.cpuTemp) | ||||
| //	  reg.MustRegister(m.hdFailures) | ||||
| //	  return m | ||||
| //	} | ||||
| // | ||||
| //    func main() { | ||||
| //    	cpuTemp.Set(65.3) | ||||
| //    	hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc() | ||||
| //	func main() { | ||||
| //	  // Create a non-global registry. | ||||
| //	  reg := prometheus.NewRegistry() | ||||
| // | ||||
| //    	// The Handler function provides a default handler to expose metrics | ||||
| //    	// via an HTTP server. "/metrics" is the usual endpoint for that. | ||||
| //    	http.Handle("/metrics", promhttp.Handler()) | ||||
| //    	log.Fatal(http.ListenAndServe(":8080", nil)) | ||||
| //    } | ||||
| //	  // Create new metrics and register them using the custom registry. | ||||
| //	  m := NewMetrics(reg) | ||||
| //	  // Set values for the new created metrics. | ||||
| //		m.cpuTemp.Set(65.3) | ||||
| //		m.hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc() | ||||
| // | ||||
| //		// Expose metrics and custom registry via an HTTP server | ||||
| //		// using the HandleFor function. "/metrics" is the usual endpoint for that. | ||||
| //		http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg})) | ||||
| //		log.Fatal(http.ListenAndServe(":8080", nil)) | ||||
| //	} | ||||
| // | ||||
| // This is a complete program that exports two metrics, a Gauge and a Counter, | ||||
| // the latter with a label attached to turn it into a (one-dimensional) vector. | ||||
| // It register the metrics using a custom registry and exposes them via an HTTP server | ||||
| // on the /metrics endpoint. | ||||
| // | ||||
| // Metrics | ||||
| // # Metrics | ||||
| // | ||||
| // The number of exported identifiers in this package might appear a bit | ||||
| // overwhelming. However, in addition to the basic plumbing shown in the example | ||||
| @@ -100,7 +111,7 @@ | ||||
| // To create instances of Metrics and their vector versions, you need a suitable | ||||
| // …Opts struct, i.e. GaugeOpts, CounterOpts, SummaryOpts, or HistogramOpts. | ||||
| // | ||||
| // Custom Collectors and constant Metrics | ||||
| // # Custom Collectors and constant Metrics | ||||
| // | ||||
| // While you could create your own implementations of Metric, most likely you | ||||
| // will only ever implement the Collector interface on your own. At a first | ||||
| @@ -141,7 +152,7 @@ | ||||
| // a metric, GaugeFunc, CounterFunc, or UntypedFunc might be interesting | ||||
| // shortcuts. | ||||
| // | ||||
| // Advanced Uses of the Registry | ||||
| // # Advanced Uses of the Registry | ||||
| // | ||||
| // While MustRegister is the by far most common way of registering a Collector, | ||||
| // sometimes you might want to handle the errors the registration might cause. | ||||
| @@ -176,23 +187,23 @@ | ||||
| // NewProcessCollector). With a custom registry, you are in control and decide | ||||
| // yourself about the Collectors to register. | ||||
| // | ||||
| // HTTP Exposition | ||||
| // # HTTP Exposition | ||||
| // | ||||
| // The Registry implements the Gatherer interface. The caller of the Gather | ||||
| // method can then expose the gathered metrics in some way. Usually, the metrics | ||||
| // are served via HTTP on the /metrics endpoint. That's happening in the example | ||||
| // above. The tools to expose metrics via HTTP are in the promhttp sub-package. | ||||
| // | ||||
| // Pushing to the Pushgateway | ||||
| // # Pushing to the Pushgateway | ||||
| // | ||||
| // Function for pushing to the Pushgateway can be found in the push sub-package. | ||||
| // | ||||
| // Graphite Bridge | ||||
| // # Graphite Bridge | ||||
| // | ||||
| // Functions and examples to push metrics from a Gatherer to Graphite can be | ||||
| // found in the graphite sub-package. | ||||
| // | ||||
| // Other Means of Exposition | ||||
| // # Other Means of Exposition | ||||
| // | ||||
| // More ways of exposing metrics can easily be added by following the approaches | ||||
| // of the existing implementations. | ||||
|   | ||||
							
								
								
									
										6
									
								
								vendor/github.com/prometheus/client_golang/prometheus/gauge.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/prometheus/client_golang/prometheus/gauge.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -210,7 +210,8 @@ func (v *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) { | ||||
| // WithLabelValues works as GetMetricWithLabelValues, but panics where | ||||
| // GetMetricWithLabelValues would have returned an error. Not returning an | ||||
| // error allows shortcuts like | ||||
| //     myVec.WithLabelValues("404", "GET").Add(42) | ||||
| // | ||||
| //	myVec.WithLabelValues("404", "GET").Add(42) | ||||
| func (v *GaugeVec) WithLabelValues(lvs ...string) Gauge { | ||||
| 	g, err := v.GetMetricWithLabelValues(lvs...) | ||||
| 	if err != nil { | ||||
| @@ -221,7 +222,8 @@ func (v *GaugeVec) WithLabelValues(lvs ...string) Gauge { | ||||
|  | ||||
| // With works as GetMetricWith, but panics where GetMetricWithLabels would have | ||||
| // returned an error. Not returning an error allows shortcuts like | ||||
| //     myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42) | ||||
| // | ||||
| //	myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42) | ||||
| func (v *GaugeVec) With(labels Labels) Gauge { | ||||
| 	g, err := v.GetMetricWith(labels) | ||||
| 	if err != nil { | ||||
|   | ||||
							
								
								
									
										974
									
								
								vendor/github.com/prometheus/client_golang/prometheus/histogram.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										974
									
								
								vendor/github.com/prometheus/client_golang/prometheus/histogram.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										60
									
								
								vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| // Copyright (c) 2015 Björn Rabenstein | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in all | ||||
| // copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| // SOFTWARE. | ||||
| // | ||||
| // The code in this package is copy/paste to avoid a dependency. Hence this file | ||||
| // carries the copyright of the original repo. | ||||
| // https://github.com/beorn7/floats | ||||
| package internal | ||||
|  | ||||
| import ( | ||||
| 	"math" | ||||
| ) | ||||
|  | ||||
| // minNormalFloat64 is the smallest positive normal value of type float64. | ||||
| var minNormalFloat64 = math.Float64frombits(0x0010000000000000) | ||||
|  | ||||
| // AlmostEqualFloat64 returns true if a and b are equal within a relative error | ||||
| // of epsilon. See http://floating-point-gui.de/errors/comparison/ for the | ||||
| // details of the applied method. | ||||
| func AlmostEqualFloat64(a, b, epsilon float64) bool { | ||||
| 	if a == b { | ||||
| 		return true | ||||
| 	} | ||||
| 	absA := math.Abs(a) | ||||
| 	absB := math.Abs(b) | ||||
| 	diff := math.Abs(a - b) | ||||
| 	if a == 0 || b == 0 || absA+absB < minNormalFloat64 { | ||||
| 		return diff < epsilon*minNormalFloat64 | ||||
| 	} | ||||
| 	return diff/math.Min(absA+absB, math.MaxFloat64) < epsilon | ||||
| } | ||||
|  | ||||
| // AlmostEqualFloat64s is the slice form of AlmostEqualFloat64. | ||||
| func AlmostEqualFloat64s(a, b []float64, epsilon float64) bool { | ||||
| 	if len(a) != len(b) { | ||||
| 		return false | ||||
| 	} | ||||
| 	for i := range a { | ||||
| 		if !AlmostEqualFloat64(a[i], b[i], epsilon) { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
							
								
								
									
										13
									
								
								vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -201,12 +201,15 @@ func (m *SequenceMatcher) isBJunk(s string) bool { | ||||
| // If IsJunk is not defined: | ||||
| // | ||||
| // Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where | ||||
| //     alo <= i <= i+k <= ahi | ||||
| //     blo <= j <= j+k <= bhi | ||||
| // | ||||
| //	alo <= i <= i+k <= ahi | ||||
| //	blo <= j <= j+k <= bhi | ||||
| // | ||||
| // and for all (i',j',k') meeting those conditions, | ||||
| //     k >= k' | ||||
| //     i <= i' | ||||
| //     and if i == i', j <= j' | ||||
| // | ||||
| //	k >= k' | ||||
| //	i <= i' | ||||
| //	and if i == i', j <= j' | ||||
| // | ||||
| // In other words, of all maximal matching blocks, return one that | ||||
| // starts earliest in a, and of all those maximal matching blocks that | ||||
|   | ||||
							
								
								
									
										3
									
								
								vendor/github.com/prometheus/client_golang/prometheus/labels.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/prometheus/client_golang/prometheus/labels.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -25,7 +25,8 @@ import ( | ||||
| // Labels represents a collection of label name -> value mappings. This type is | ||||
| // commonly used with the With(Labels) and GetMetricWith(Labels) methods of | ||||
| // metric vector Collectors, e.g.: | ||||
| //     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42) | ||||
| // | ||||
| //	myVec.With(Labels{"code": "404", "method": "GET"}).Add(42) | ||||
| // | ||||
| // The other use-case is the specification of constant label pairs in Opts or to | ||||
| // create a Desc. | ||||
|   | ||||
							
								
								
									
										170
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promauto/auto.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										170
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promauto/auto.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -14,114 +14,114 @@ | ||||
| // Package promauto provides alternative constructors for the fundamental | ||||
| // Prometheus metric types and their …Vec and …Func variants. The difference to | ||||
| // their counterparts in the prometheus package is that the promauto | ||||
| // constructors return Collectors that are already registered with a | ||||
| // registry. There are two sets of constructors. The constructors in the first | ||||
| // set are top-level functions, while the constructors in the other set are | ||||
| // methods of the Factory type. The top-level function return Collectors | ||||
| // registered with the global registry (prometheus.DefaultRegisterer), while the | ||||
| // methods return Collectors registered with the registry the Factory was | ||||
| // constructed with. All constructors panic if the registration fails. | ||||
| // constructors register the Collectors with a registry before returning them. | ||||
| // There are two sets of constructors. The constructors in the first set are | ||||
| // top-level functions, while the constructors in the other set are methods of | ||||
| // the Factory type. The top-level function return Collectors registered with | ||||
| // the global registry (prometheus.DefaultRegisterer), while the methods return | ||||
| // Collectors registered with the registry the Factory was constructed with. All | ||||
| // constructors panic if the registration fails. | ||||
| // | ||||
| // The following example is a complete program to create a histogram of normally | ||||
| // distributed random numbers from the math/rand package: | ||||
| // | ||||
| //      package main | ||||
| //	package main | ||||
| // | ||||
| //      import ( | ||||
| //              "math/rand" | ||||
| //              "net/http" | ||||
| //	import ( | ||||
| //	        "math/rand" | ||||
| //	        "net/http" | ||||
| // | ||||
| //              "github.com/prometheus/client_golang/prometheus" | ||||
| //              "github.com/prometheus/client_golang/prometheus/promauto" | ||||
| //              "github.com/prometheus/client_golang/prometheus/promhttp" | ||||
| //      ) | ||||
| //	        "github.com/prometheus/client_golang/prometheus" | ||||
| //	        "github.com/prometheus/client_golang/prometheus/promauto" | ||||
| //	        "github.com/prometheus/client_golang/prometheus/promhttp" | ||||
| //	) | ||||
| // | ||||
| //      var histogram = promauto.NewHistogram(prometheus.HistogramOpts{ | ||||
| //              Name:    "random_numbers", | ||||
| //              Help:    "A histogram of normally distributed random numbers.", | ||||
| //              Buckets: prometheus.LinearBuckets(-3, .1, 61), | ||||
| //      }) | ||||
| //	var histogram = promauto.NewHistogram(prometheus.HistogramOpts{ | ||||
| //	        Name:    "random_numbers", | ||||
| //	        Help:    "A histogram of normally distributed random numbers.", | ||||
| //	        Buckets: prometheus.LinearBuckets(-3, .1, 61), | ||||
| //	}) | ||||
| // | ||||
| //      func Random() { | ||||
| //              for { | ||||
| //                      histogram.Observe(rand.NormFloat64()) | ||||
| //              } | ||||
| //      } | ||||
| //	func Random() { | ||||
| //	        for { | ||||
| //	                histogram.Observe(rand.NormFloat64()) | ||||
| //	        } | ||||
| //	} | ||||
| // | ||||
| //      func main() { | ||||
| //              go Random() | ||||
| //              http.Handle("/metrics", promhttp.Handler()) | ||||
| //              http.ListenAndServe(":1971", nil) | ||||
| //      } | ||||
| //	func main() { | ||||
| //	        go Random() | ||||
| //	        http.Handle("/metrics", promhttp.Handler()) | ||||
| //	        http.ListenAndServe(":1971", nil) | ||||
| //	} | ||||
| // | ||||
| // Prometheus's version of a minimal hello-world program: | ||||
| // | ||||
| //      package main | ||||
| //	package main | ||||
| // | ||||
| //      import ( | ||||
| //      	"fmt" | ||||
| //      	"net/http" | ||||
| //	import ( | ||||
| //		"fmt" | ||||
| //		"net/http" | ||||
| // | ||||
| //      	"github.com/prometheus/client_golang/prometheus" | ||||
| //      	"github.com/prometheus/client_golang/prometheus/promauto" | ||||
| //      	"github.com/prometheus/client_golang/prometheus/promhttp" | ||||
| //      ) | ||||
| //		"github.com/prometheus/client_golang/prometheus" | ||||
| //		"github.com/prometheus/client_golang/prometheus/promauto" | ||||
| //		"github.com/prometheus/client_golang/prometheus/promhttp" | ||||
| //	) | ||||
| // | ||||
| //      func main() { | ||||
| //      	http.Handle("/", promhttp.InstrumentHandlerCounter( | ||||
| //      		promauto.NewCounterVec( | ||||
| //      			prometheus.CounterOpts{ | ||||
| //      				Name: "hello_requests_total", | ||||
| //      				Help: "Total number of hello-world requests by HTTP code.", | ||||
| //      			}, | ||||
| //      			[]string{"code"}, | ||||
| //      		), | ||||
| //      		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| //      			fmt.Fprint(w, "Hello, world!") | ||||
| //      		}), | ||||
| //      	)) | ||||
| //      	http.Handle("/metrics", promhttp.Handler()) | ||||
| //      	http.ListenAndServe(":1971", nil) | ||||
| //      } | ||||
| //	func main() { | ||||
| //		http.Handle("/", promhttp.InstrumentHandlerCounter( | ||||
| //			promauto.NewCounterVec( | ||||
| //				prometheus.CounterOpts{ | ||||
| //					Name: "hello_requests_total", | ||||
| //					Help: "Total number of hello-world requests by HTTP code.", | ||||
| //				}, | ||||
| //				[]string{"code"}, | ||||
| //			), | ||||
| //			http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| //				fmt.Fprint(w, "Hello, world!") | ||||
| //			}), | ||||
| //		)) | ||||
| //		http.Handle("/metrics", promhttp.Handler()) | ||||
| //		http.ListenAndServe(":1971", nil) | ||||
| //	} | ||||
| // | ||||
| // A Factory is created with the With(prometheus.Registerer) function, which | ||||
| // enables two usage pattern. With(prometheus.Registerer) can be called once per | ||||
| // line: | ||||
| // | ||||
| //        var ( | ||||
| //        	reg           = prometheus.NewRegistry() | ||||
| //        	randomNumbers = promauto.With(reg).NewHistogram(prometheus.HistogramOpts{ | ||||
| //        		Name:    "random_numbers", | ||||
| //        		Help:    "A histogram of normally distributed random numbers.", | ||||
| //        		Buckets: prometheus.LinearBuckets(-3, .1, 61), | ||||
| //        	}) | ||||
| //        	requestCount = promauto.With(reg).NewCounterVec( | ||||
| //        		prometheus.CounterOpts{ | ||||
| //        			Name: "http_requests_total", | ||||
| //        			Help: "Total number of HTTP requests by status code and method.", | ||||
| //        		}, | ||||
| //        		[]string{"code", "method"}, | ||||
| //        	) | ||||
| //        ) | ||||
| //	var ( | ||||
| //		reg           = prometheus.NewRegistry() | ||||
| //		randomNumbers = promauto.With(reg).NewHistogram(prometheus.HistogramOpts{ | ||||
| //			Name:    "random_numbers", | ||||
| //			Help:    "A histogram of normally distributed random numbers.", | ||||
| //			Buckets: prometheus.LinearBuckets(-3, .1, 61), | ||||
| //		}) | ||||
| //		requestCount = promauto.With(reg).NewCounterVec( | ||||
| //			prometheus.CounterOpts{ | ||||
| //				Name: "http_requests_total", | ||||
| //				Help: "Total number of HTTP requests by status code and method.", | ||||
| //			}, | ||||
| //			[]string{"code", "method"}, | ||||
| //		) | ||||
| //	) | ||||
| // | ||||
| // Or it can be used to create a Factory once to be used multiple times: | ||||
| // | ||||
| //        var ( | ||||
| //        	reg           = prometheus.NewRegistry() | ||||
| //        	factory       = promauto.With(reg) | ||||
| //        	randomNumbers = factory.NewHistogram(prometheus.HistogramOpts{ | ||||
| //        		Name:    "random_numbers", | ||||
| //        		Help:    "A histogram of normally distributed random numbers.", | ||||
| //        		Buckets: prometheus.LinearBuckets(-3, .1, 61), | ||||
| //        	}) | ||||
| //        	requestCount = factory.NewCounterVec( | ||||
| //        		prometheus.CounterOpts{ | ||||
| //        			Name: "http_requests_total", | ||||
| //        			Help: "Total number of HTTP requests by status code and method.", | ||||
| //        		}, | ||||
| //        		[]string{"code", "method"}, | ||||
| //        	) | ||||
| //        ) | ||||
| //	var ( | ||||
| //		reg           = prometheus.NewRegistry() | ||||
| //		factory       = promauto.With(reg) | ||||
| //		randomNumbers = factory.NewHistogram(prometheus.HistogramOpts{ | ||||
| //			Name:    "random_numbers", | ||||
| //			Help:    "A histogram of normally distributed random numbers.", | ||||
| //			Buckets: prometheus.LinearBuckets(-3, .1, 61), | ||||
| //		}) | ||||
| //		requestCount = factory.NewCounterVec( | ||||
| //			prometheus.CounterOpts{ | ||||
| //				Name: "http_requests_total", | ||||
| //				Help: "Total number of HTTP requests by status code and method.", | ||||
| //			}, | ||||
| //			[]string{"code", "method"}, | ||||
| //		) | ||||
| //	) | ||||
| // | ||||
| // This appears very handy. So why are these constructors locked away in a | ||||
| // separate package? | ||||
|   | ||||
							
								
								
									
										4
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -73,7 +73,7 @@ func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.Rou | ||||
| 	return func(r *http.Request) (*http.Response, error) { | ||||
| 		resp, err := next.RoundTrip(r) | ||||
| 		if err == nil { | ||||
| 			exemplarAdd( | ||||
| 			addWithExemplar( | ||||
| 				counter.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)), | ||||
| 				1, | ||||
| 				rtOpts.getExemplarFn(r.Context()), | ||||
| @@ -116,7 +116,7 @@ func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundT | ||||
| 		start := time.Now() | ||||
| 		resp, err := next.RoundTrip(r) | ||||
| 		if err == nil { | ||||
| 			exemplarObserve( | ||||
| 			observeWithExemplar( | ||||
| 				obs.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)), | ||||
| 				time.Since(start).Seconds(), | ||||
| 				rtOpts.getExemplarFn(r.Context()), | ||||
|   | ||||
							
								
								
									
										24
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -28,7 +28,9 @@ import ( | ||||
| // magicString is used for the hacky label test in checkLabels. Remove once fixed. | ||||
| const magicString = "zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa" | ||||
|  | ||||
| func exemplarObserve(obs prometheus.Observer, val float64, labels map[string]string) { | ||||
| // observeWithExemplar is a wrapper for [prometheus.ExemplarAdder.ExemplarObserver], | ||||
| // which falls back to [prometheus.Observer.Observe] if no labels are provided. | ||||
| func observeWithExemplar(obs prometheus.Observer, val float64, labels map[string]string) { | ||||
| 	if labels == nil { | ||||
| 		obs.Observe(val) | ||||
| 		return | ||||
| @@ -36,7 +38,9 @@ func exemplarObserve(obs prometheus.Observer, val float64, labels map[string]str | ||||
| 	obs.(prometheus.ExemplarObserver).ObserveWithExemplar(val, labels) | ||||
| } | ||||
|  | ||||
| func exemplarAdd(obs prometheus.Counter, val float64, labels map[string]string) { | ||||
| // addWithExemplar is a wrapper for [prometheus.ExemplarAdder.AddWithExemplar], | ||||
| // which falls back to [prometheus.Counter.Add] if no labels are provided. | ||||
| func addWithExemplar(obs prometheus.Counter, val float64, labels map[string]string) { | ||||
| 	if labels == nil { | ||||
| 		obs.Add(val) | ||||
| 		return | ||||
| @@ -91,7 +95,7 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, op | ||||
| 			d := newDelegator(w, nil) | ||||
| 			next.ServeHTTP(d, r) | ||||
|  | ||||
| 			exemplarObserve( | ||||
| 			observeWithExemplar( | ||||
| 				obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), | ||||
| 				time.Since(now).Seconds(), | ||||
| 				hOpts.getExemplarFn(r.Context()), | ||||
| @@ -103,7 +107,7 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, op | ||||
| 		now := time.Now() | ||||
| 		next.ServeHTTP(w, r) | ||||
|  | ||||
| 		exemplarObserve( | ||||
| 		observeWithExemplar( | ||||
| 			obs.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), | ||||
| 			time.Since(now).Seconds(), | ||||
| 			hOpts.getExemplarFn(r.Context()), | ||||
| @@ -141,7 +145,7 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, | ||||
| 			d := newDelegator(w, nil) | ||||
| 			next.ServeHTTP(d, r) | ||||
|  | ||||
| 			exemplarAdd( | ||||
| 			addWithExemplar( | ||||
| 				counter.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), | ||||
| 				1, | ||||
| 				hOpts.getExemplarFn(r.Context()), | ||||
| @@ -151,7 +155,7 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, | ||||
|  | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		next.ServeHTTP(w, r) | ||||
| 		exemplarAdd( | ||||
| 		addWithExemplar( | ||||
| 			counter.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), | ||||
| 			1, | ||||
| 			hOpts.getExemplarFn(r.Context()), | ||||
| @@ -192,7 +196,7 @@ func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Ha | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		now := time.Now() | ||||
| 		d := newDelegator(w, func(status int) { | ||||
| 			exemplarObserve( | ||||
| 			observeWithExemplar( | ||||
| 				obs.With(labels(code, method, r.Method, status, hOpts.extraMethods...)), | ||||
| 				time.Since(now).Seconds(), | ||||
| 				hOpts.getExemplarFn(r.Context()), | ||||
| @@ -233,7 +237,7 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, | ||||
| 			d := newDelegator(w, nil) | ||||
| 			next.ServeHTTP(d, r) | ||||
| 			size := computeApproximateRequestSize(r) | ||||
| 			exemplarObserve( | ||||
| 			observeWithExemplar( | ||||
| 				obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), | ||||
| 				float64(size), | ||||
| 				hOpts.getExemplarFn(r.Context()), | ||||
| @@ -244,7 +248,7 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		next.ServeHTTP(w, r) | ||||
| 		size := computeApproximateRequestSize(r) | ||||
| 		exemplarObserve( | ||||
| 		observeWithExemplar( | ||||
| 			obs.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), | ||||
| 			float64(size), | ||||
| 			hOpts.getExemplarFn(r.Context()), | ||||
| @@ -282,7 +286,7 @@ func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler | ||||
| 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 		d := newDelegator(w, nil) | ||||
| 		next.ServeHTTP(d, r) | ||||
| 		exemplarObserve( | ||||
| 		observeWithExemplar( | ||||
| 			obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), | ||||
| 			float64(d.Written()), | ||||
| 			hOpts.getExemplarFn(r.Context()), | ||||
|   | ||||
							
								
								
									
										34
									
								
								vendor/github.com/prometheus/client_golang/prometheus/registry.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/prometheus/client_golang/prometheus/registry.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -252,9 +252,12 @@ func (errs MultiError) MaybeUnwrap() error { | ||||
| } | ||||
|  | ||||
| // Registry registers Prometheus collectors, collects their metrics, and gathers | ||||
| // them into MetricFamilies for exposition. It implements both Registerer and | ||||
| // Gatherer. The zero value is not usable. Create instances with NewRegistry or | ||||
| // NewPedanticRegistry. | ||||
| // them into MetricFamilies for exposition. It implements Registerer, Gatherer, | ||||
| // and Collector. The zero value is not usable. Create instances with | ||||
| // NewRegistry or NewPedanticRegistry. | ||||
| // | ||||
| // Registry implements Collector to allow it to be used for creating groups of | ||||
| // metrics. See the Grouping example for how this can be done. | ||||
| type Registry struct { | ||||
| 	mtx                   sync.RWMutex | ||||
| 	collectorsByID        map[uint64]Collector // ID is a hash of the descIDs. | ||||
| @@ -556,6 +559,31 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) { | ||||
| 	return internal.NormalizeMetricFamilies(metricFamiliesByName), errs.MaybeUnwrap() | ||||
| } | ||||
|  | ||||
| // Describe implements Collector. | ||||
| func (r *Registry) Describe(ch chan<- *Desc) { | ||||
| 	r.mtx.RLock() | ||||
| 	defer r.mtx.RUnlock() | ||||
|  | ||||
| 	// Only report the checked Collectors; unchecked collectors don't report any | ||||
| 	// Desc. | ||||
| 	for _, c := range r.collectorsByID { | ||||
| 		c.Describe(ch) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Collect implements Collector. | ||||
| func (r *Registry) Collect(ch chan<- Metric) { | ||||
| 	r.mtx.RLock() | ||||
| 	defer r.mtx.RUnlock() | ||||
|  | ||||
| 	for _, c := range r.collectorsByID { | ||||
| 		c.Collect(ch) | ||||
| 	} | ||||
| 	for _, c := range r.uncheckedCollectors { | ||||
| 		c.Collect(ch) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // WriteToTextfile calls Gather on the provided Gatherer, encodes the result in the | ||||
| // Prometheus text format, and writes it to a temporary file. Upon success, the | ||||
| // temporary file is renamed to the provided filename. | ||||
|   | ||||
							
								
								
									
										9
									
								
								vendor/github.com/prometheus/client_golang/prometheus/summary.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/prometheus/client_golang/prometheus/summary.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -603,7 +603,8 @@ func (v *SummaryVec) GetMetricWith(labels Labels) (Observer, error) { | ||||
| // WithLabelValues works as GetMetricWithLabelValues, but panics where | ||||
| // GetMetricWithLabelValues would have returned an error. Not returning an | ||||
| // error allows shortcuts like | ||||
| //     myVec.WithLabelValues("404", "GET").Observe(42.21) | ||||
| // | ||||
| //	myVec.WithLabelValues("404", "GET").Observe(42.21) | ||||
| func (v *SummaryVec) WithLabelValues(lvs ...string) Observer { | ||||
| 	s, err := v.GetMetricWithLabelValues(lvs...) | ||||
| 	if err != nil { | ||||
| @@ -614,7 +615,8 @@ func (v *SummaryVec) WithLabelValues(lvs ...string) Observer { | ||||
|  | ||||
| // With works as GetMetricWith, but panics where GetMetricWithLabels would have | ||||
| // returned an error. Not returning an error allows shortcuts like | ||||
| //     myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21) | ||||
| // | ||||
| //	myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21) | ||||
| func (v *SummaryVec) With(labels Labels) Observer { | ||||
| 	s, err := v.GetMetricWith(labels) | ||||
| 	if err != nil { | ||||
| @@ -701,7 +703,8 @@ func (s *constSummary) Write(out *dto.Metric) error { | ||||
| // | ||||
| // quantiles maps ranks to quantile values. For example, a median latency of | ||||
| // 0.23s and a 99th percentile latency of 0.56s would be expressed as: | ||||
| //     map[float64]float64{0.5: 0.23, 0.99: 0.56} | ||||
| // | ||||
| //	map[float64]float64{0.5: 0.23, 0.99: 0.56} | ||||
| // | ||||
| // NewConstSummary returns an error if the length of labelValues is not | ||||
| // consistent with the variable labels in Desc or if Desc is invalid. | ||||
|   | ||||
							
								
								
									
										11
									
								
								vendor/github.com/prometheus/client_golang/prometheus/timer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/prometheus/client_golang/prometheus/timer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -25,11 +25,12 @@ type Timer struct { | ||||
| // NewTimer creates a new Timer. The provided Observer is used to observe a | ||||
| // duration in seconds. Timer is usually used to time a function call in the | ||||
| // following way: | ||||
| //    func TimeMe() { | ||||
| //        timer := NewTimer(myHistogram) | ||||
| //        defer timer.ObserveDuration() | ||||
| //        // Do actual work. | ||||
| //    } | ||||
| // | ||||
| //	func TimeMe() { | ||||
| //	    timer := NewTimer(myHistogram) | ||||
| //	    defer timer.ObserveDuration() | ||||
| //	    // Do actual work. | ||||
| //	} | ||||
| func NewTimer(o Observer) *Timer { | ||||
| 	return &Timer{ | ||||
| 		begin:    time.Now(), | ||||
|   | ||||
							
								
								
									
										3
									
								
								vendor/go.elastic.co/ecszap/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/go.elastic.co/ecszap/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +0,0 @@ | ||||
| ecs-logging-go-zap | ||||
| build | ||||
| html_docs | ||||
| @@ -1,14 +0,0 @@ | ||||
| repos: | ||||
| -   repo: https://github.com/pre-commit/pre-commit-hooks | ||||
|     rev: v2.2.3 | ||||
|     hooks: | ||||
|     -   id: check-case-conflict | ||||
|     -   id: check-executables-have-shebangs | ||||
|     -   id: check-merge-conflict | ||||
|  | ||||
| -   repo: git@github.com:elastic/apm-pipeline-library | ||||
|     rev: current | ||||
|     hooks: | ||||
|     -   id: check-bash-syntax | ||||
|     -   id: check-jenkins-pipelines | ||||
|     -   id: check-jjbb | ||||
							
								
								
									
										36
									
								
								vendor/go.elastic.co/ecszap/CHANGELOG.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								vendor/go.elastic.co/ecszap/CHANGELOG.md
									
									
									
									
										vendored
									
									
								
							| @@ -1,36 +0,0 @@ | ||||
| # CHANGELOG | ||||
| Changelog for ecszap | ||||
|  | ||||
| ## unreleased | ||||
|  | ||||
| ## 1.0.1 | ||||
| * Updated zap to v1.21.1 [pull#42](https://github.com/elastic/ecs-logging-go-zap/pull/42) | ||||
|  | ||||
| ## 1.0.0 | ||||
|  | ||||
| ### Enhancement | ||||
| * Add `ecszap.WrapCoreOption` for convenience [pull#22](https://github.com/elastic/ecs-logging-go-zap/pull/22) | ||||
|  | ||||
| ### Bug Fixes | ||||
| * Change `stacktrace` to `stack_trace` in output and in json and yaml config option for `EncoderConfig.EnableStacktrace` [pull#21](https://github.com/elastic/ecs-logging-go-zap/pull/21) | ||||
| * Do not allow configuration of `@timestamp`, instead always set format to ISO8601 [pull#23](https://github.com/elastic/ecs-logging-go-zap/pull/23) | ||||
|  | ||||
| ## 0.3.0 | ||||
|  | ||||
| ### Enhancement | ||||
| * Update ECS version to 1.6.0 [pull#17](https://github.com/elastic/ecs-logging-go-zap/pull/17) | ||||
|  | ||||
| ## 0.2.0 | ||||
|  | ||||
| ### Enhancement | ||||
| * Add `ecszap.ECSCompatibleEncoderConfig` for making existing encoder config ECS conformant [pull#12](https://github.com/elastic/ecs-logging-go-zap/pull/12) | ||||
| * Add method `ToZapCoreEncoderConfig` to `ecszap.EncoderConfig` for advanced use cases [pull#12](https://github.com/elastic/ecs-logging-go-zap/pull/12) | ||||
|  | ||||
| ### Bug Fixes | ||||
| * Use `zapcore.ISO8601TimeEncoder` as default instead of `ecszap.EpochMicrosTimeEncoder` [pull#12](https://github.com/elastic/ecs-logging-go-zap/pull/12) | ||||
|  | ||||
| ### Breaking Change | ||||
| * remove `ecszap.NewJSONEncoder` [pull#12](https://github.com/elastic/ecs-logging-go-zap/pull/12) | ||||
|  | ||||
| ## 0.1.0 | ||||
| Initial Pre-Release supporting [MVP](https://github.com/elastic/ecs-logging/tree/main/spec#minimum-viable-product) for ECS conformant logging | ||||
							
								
								
									
										202
									
								
								vendor/go.elastic.co/ecszap/LICENSE
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										202
									
								
								vendor/go.elastic.co/ecszap/LICENSE
									
									
									
									
										vendored
									
									
								
							| @@ -1,202 +0,0 @@ | ||||
|  | ||||
|                                  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 2020 Elastic and contributors | ||||
|  | ||||
|    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. | ||||
							
								
								
									
										101
									
								
								vendor/go.elastic.co/ecszap/NOTICE.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										101
									
								
								vendor/go.elastic.co/ecszap/NOTICE.txt
									
									
									
									
										vendored
									
									
								
							| @@ -1,101 +0,0 @@ | ||||
| ecszap | ||||
| Copyright 2020-2020 Elasticsearch B.V. | ||||
|  | ||||
| ========================================================================== | ||||
| Third party libraries used by the Elastic ecszap project: | ||||
| ========================================================================== | ||||
|  | ||||
| Dependency: github.com/stretchr/testify | ||||
| Version: v1.4.0 | ||||
| License type: MIT | ||||
| https://github.com/stretchr/testify/blob/199de5f3a493a9bf2dcc7fa5bf841d7759c13d7d/LICENSE: | ||||
| -------------------------------------------------------------------- | ||||
| MIT License | ||||
|  | ||||
| Copyright (c) 2012-2018 Mat Ryer and Tyler Bunnell | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
| -------------------------------------------------------------------- | ||||
|  | ||||
|  | ||||
| Dependency: go.uber.org/zap | ||||
| Version: v1.14.0 | ||||
| License type: MIT | ||||
| https://github.com/uber-go/zap/blob/0bd02a6308c1bac3a03b02dc385555297cb22f83/LICENSE.txt: | ||||
| -------------------------------------------------------------------- | ||||
| Copyright (c) 2016-2017 Uber Technologies, Inc. | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in | ||||
| all copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| THE SOFTWARE. | ||||
| -------------------------------------------------------------------- | ||||
|  | ||||
|  | ||||
| Dependency: github.com/magefile/mage | ||||
| Version: v1.9.0 | ||||
| License type: Apache-2.0 | ||||
| https://github.com/magefile/mage/blob/324c6690ed410efc1d9b597e477c46d42cbeb340/LICENSE: | ||||
| -------------------------------------------------------------------- | ||||
| Apache License 2.0 | ||||
|  | ||||
|  | ||||
| -------------------------------------------------------------------- | ||||
| Dependency: github.com/pkg/errors | ||||
| Version: v0.9.1 | ||||
| License type (autodetected): BSD-2-Clause | ||||
| https://github.com/pkg/errors/blob/614d223910a179a466c1767a985424175c39b465/LICENSE | ||||
| -------------------------------------------------------------------- | ||||
| Copyright (c) 2015, Dave Cheney <dave@cheney.net> | ||||
| All rights reserved. | ||||
|  | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are met: | ||||
|  | ||||
| * Redistributions of source code must retain the above copyright notice, this | ||||
|   list of conditions and the following disclaimer. | ||||
|  | ||||
| * Redistributions in binary form must reproduce the above copyright notice, | ||||
|   this list of conditions and the following disclaimer in the documentation | ||||
|   and/or other materials provided with the distribution. | ||||
|  | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||||
| FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||||
| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||||
| OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| -------------------------------------------------------------------- | ||||
							
								
								
									
										22
									
								
								vendor/go.elastic.co/ecszap/README.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/go.elastic.co/ecszap/README.md
									
									
									
									
										vendored
									
									
								
							| @@ -1,22 +0,0 @@ | ||||
| # Elastic Common Schema (ECS) support for uber-go/zap logger | ||||
|  | ||||
| Use this library for automatically adding a minimal set of ECS fields to your logs, when using [uber-go/zap](https://github.com/uber-go/zap). | ||||
|  | ||||
| ## Documentation | ||||
|  | ||||
| Ready to get started? Documentation is at [elastic.co](https://www.elastic.co/guide/en/ecs-logging/go-zap/current/index.html). | ||||
|  | ||||
| ## Test | ||||
| ``` | ||||
| go test ./... | ||||
| ``` | ||||
|  | ||||
| ## Contribute | ||||
| Create a Pull Request from your own fork. | ||||
|  | ||||
| Run `mage` to update and format you changes before submitting. | ||||
|  | ||||
| Add new dependencies to the NOTICE.txt. | ||||
|  | ||||
| ## License | ||||
| This software is licensed under the [Apache 2 license](https://github.com/elastic/ecs-logging-go-zap/blob/main/LICENSE). | ||||
							
								
								
									
										87
									
								
								vendor/go.elastic.co/ecszap/core.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										87
									
								
								vendor/go.elastic.co/ecszap/core.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,87 +0,0 @@ | ||||
| // Licensed to Elasticsearch B.V. under one or more contributor | ||||
| // license agreements. See the NOTICE file distributed with | ||||
| // this work for additional information regarding copyright | ||||
| // ownership. Elasticsearch B.V. licenses this file to you 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 ecszap | ||||
|  | ||||
| import ( | ||||
| 	"go.uber.org/zap" | ||||
| 	"go.uber.org/zap/zapcore" | ||||
|  | ||||
| 	"go.elastic.co/ecszap/internal" | ||||
| ) | ||||
|  | ||||
| const version = "1.6.0" | ||||
|  | ||||
| // NewCore creates a zapcore.Core that uses an ECS conformant JSON encoder. | ||||
| // This is the safest way to create an ECS compatible core. | ||||
| func NewCore(cfg EncoderConfig, ws zapcore.WriteSyncer, enab zapcore.LevelEnabler) zapcore.Core { | ||||
| 	enc := zapcore.NewJSONEncoder(cfg.ToZapCoreEncoderConfig()) | ||||
| 	return WrapCore(zapcore.NewCore(enc, ws, enab)) | ||||
| } | ||||
|  | ||||
| // WrapCore wraps a core with ECS core functionality and returns a zapcore.Core. | ||||
| // For ECS compatibility, ensure that the wrapped zapcore.Core uses an encoder | ||||
| // that is created from an ECS compatible configuration. For further details | ||||
| // check out ecszap.EncoderConfig or ecszap.ECSCompatibleEncoderConfig. | ||||
| func WrapCore(c zapcore.Core) zapcore.Core { | ||||
| 	return &core{c} | ||||
| } | ||||
|  | ||||
| // WrapCoreOption returns a zap.Option, wrapping the underlying zapcore.Core. | ||||
| func WrapCoreOption() zap.Option { | ||||
| 	return zap.WrapCore(WrapCore) | ||||
| } | ||||
|  | ||||
| type core struct { | ||||
| 	zapcore.Core | ||||
| } | ||||
|  | ||||
| // With converts error fields into ECS compliant errors | ||||
| // before adding them to the logger. | ||||
| func (c core) With(fields []zapcore.Field) zapcore.Core { | ||||
| 	convertToECSFields(fields) | ||||
| 	return &core{c.Core.With(fields)} | ||||
| } | ||||
|  | ||||
| // Check verifies whether or not the provided entry should be logged, | ||||
| // by comparing the log level with the configured log level in the core. | ||||
| // If it should be logged the core is added to the returned entry. | ||||
| func (c core) Check(ent zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry { | ||||
| 	if c.Enabled(ent.Level) { | ||||
| 		return ce.AddCore(ent, c) | ||||
| 	} | ||||
| 	return ce | ||||
| } | ||||
|  | ||||
| // Write converts error fields into ECS compliant errors | ||||
| // before serializing the entry and fields. | ||||
| func (c core) Write(ent zapcore.Entry, fields []zapcore.Field) error { | ||||
| 	convertToECSFields(fields) | ||||
| 	fields = append(fields, zap.String("ecs.version", version)) | ||||
| 	return c.Core.Write(ent, fields) | ||||
| } | ||||
|  | ||||
| func convertToECSFields(fields []zapcore.Field) { | ||||
| 	for i, f := range fields { | ||||
| 		if f.Type == zapcore.ErrorType { | ||||
| 			fields[i] = zapcore.Field{Key: "error", | ||||
| 				Type:      zapcore.ObjectMarshalerType, | ||||
| 				Interface: internal.NewError(f.Interface.(error)), | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										22
									
								
								vendor/go.elastic.co/ecszap/doc.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/go.elastic.co/ecszap/doc.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,22 +0,0 @@ | ||||
| // Licensed to Elasticsearch B.V. under one or more contributor | ||||
| // license agreements. See the NOTICE file distributed with | ||||
| // this work for additional information regarding copyright | ||||
| // ownership. Elasticsearch B.V. licenses this file to you 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 ecszap provides a formatter to be used | ||||
| // with the go.uber.org/zap logger library | ||||
| // that helps creating Elastic Common Schema (ECS) | ||||
| // conformant log entries. | ||||
| package ecszap // import "go.elastic.co/ecszap" | ||||
							
								
								
									
										89
									
								
								vendor/go.elastic.co/ecszap/encoder.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										89
									
								
								vendor/go.elastic.co/ecszap/encoder.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,89 +0,0 @@ | ||||
| // Licensed to Elasticsearch B.V. under one or more contributor | ||||
| // license agreements. See the NOTICE file distributed with | ||||
| // this work for additional information regarding copyright | ||||
| // ownership. Elasticsearch B.V. licenses this file to you 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 ecszap | ||||
|  | ||||
| import ( | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| 	"go.uber.org/zap/zapcore" | ||||
| ) | ||||
|  | ||||
| // EpochMicrosTimeEncoder encodes a given time in microseconds. | ||||
| func EpochMicrosTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { | ||||
| 	micros := float64(t.UnixNano()) / float64(time.Microsecond) | ||||
| 	enc.AppendFloat64(micros) | ||||
| } | ||||
|  | ||||
| // CallerEncoder is equivalent to zapcore.CallerEncoder, except that its UnmarshalText | ||||
| // method uses FullCallerEncoder and ShortCallerEncoder from this package instead, | ||||
| // in order to encode callers in the ECS format. | ||||
| type CallerEncoder func(zapcore.EntryCaller, zapcore.PrimitiveArrayEncoder) | ||||
|  | ||||
| // FullCallerEncoder serializes the file name and line from the caller | ||||
| // in an ECS compliant way; serializing the full path of the file name | ||||
| // using the underlying zapcore.EntryCaller. | ||||
| func FullCallerEncoder(c zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { | ||||
| 	encodeCaller(&caller{c, true}, enc) | ||||
| } | ||||
|  | ||||
| // ShortCallerEncoder serializes the file name and line from the caller | ||||
| // in an ECS compliant way; removing everything except the final directory from the | ||||
| // file name by calling the underlying zapcore.EntryCaller TrimmedPath(). | ||||
| func ShortCallerEncoder(c zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { | ||||
| 	encodeCaller(&caller{c, false}, enc) | ||||
| } | ||||
|  | ||||
| // UnmarshalText creates a CallerEncoder function, | ||||
| // `full` is unmarshalled to FullCallerEncoder, | ||||
| // defaults to ShortCallerEncoder, | ||||
| func (e *CallerEncoder) UnmarshalText(text []byte) error { | ||||
| 	switch string(text) { | ||||
| 	case "full": | ||||
| 		*e = FullCallerEncoder | ||||
| 	default: | ||||
| 		*e = ShortCallerEncoder | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func encodeCaller(c *caller, enc zapcore.PrimitiveArrayEncoder) { | ||||
| 	// this function can only be called internally so we have full control over it | ||||
| 	// and can ensure that enc is always of type zapcore.ArrayEncoder | ||||
| 	if e, ok := enc.(zapcore.ArrayEncoder); ok { | ||||
| 		e.AppendObject(c) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type caller struct { | ||||
| 	zapcore.EntryCaller | ||||
| 	fullPath bool | ||||
| } | ||||
|  | ||||
| func (c *caller) MarshalLogObject(enc zapcore.ObjectEncoder) error { | ||||
| 	var file string | ||||
| 	if c.fullPath { | ||||
| 		file = c.File | ||||
| 	} else { | ||||
| 		file = c.TrimmedPath() | ||||
| 		file = file[:strings.LastIndex(file, ":")] | ||||
| 	} | ||||
| 	enc.AddString("file.name", file) | ||||
| 	enc.AddInt("file.line", c.Line) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										163
									
								
								vendor/go.elastic.co/ecszap/encoder_config.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										163
									
								
								vendor/go.elastic.co/ecszap/encoder_config.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,163 +0,0 @@ | ||||
| // Licensed to Elasticsearch B.V. under one or more contributor | ||||
| // license agreements. See the NOTICE file distributed with | ||||
| // this work for additional information regarding copyright | ||||
| // ownership. Elasticsearch B.V. licenses this file to you 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 ecszap | ||||
|  | ||||
| import ( | ||||
| 	"go.uber.org/zap/zapcore" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	defaultLineEnding     = zapcore.DefaultLineEnding | ||||
| 	defaultEncodeName     = zapcore.FullNameEncoder | ||||
| 	defaultEncodeDuration = zapcore.NanosDurationEncoder | ||||
| 	defaultEncodeLevel    = zapcore.LowercaseLevelEncoder | ||||
| 	defaultEncodeCaller   = ShortCallerEncoder | ||||
|  | ||||
| 	callerKey     = "log.origin" | ||||
| 	logLevelKey   = "log.level" | ||||
| 	logNameKey    = "log.logger" | ||||
| 	messageKey    = "message" | ||||
| 	stackTraceKey = "log.origin.stack_trace" | ||||
| 	timeKey       = "@timestamp" | ||||
| 	encodeTime    = zapcore.ISO8601TimeEncoder | ||||
| ) | ||||
|  | ||||
| // EncoderConfig exports all non ECS related configurable settings. | ||||
| // The configuration can be used to create an ECS compatible zapcore.Core | ||||
| type EncoderConfig struct { | ||||
| 	// EnableName controls if a logger's name should be serialized | ||||
| 	// when available. If enabled, the EncodeName configuration is | ||||
| 	// used for serialization. | ||||
| 	EnableName bool `json:"enableName" yaml:"enableName"` | ||||
|  | ||||
| 	// EnableStackTrace controls if a stack trace should be serialized when available. | ||||
| 	EnableStackTrace bool `json:"enableStackTrace" yaml:"enableStackTrace"` | ||||
|  | ||||
| 	// EnableCaller controls if the entry caller should be serialized. | ||||
| 	// If enabled, the EncodeCaller configuration is used for serialization. | ||||
| 	EnableCaller bool `json:"enableCaller" yaml:"enableCaller"` | ||||
|  | ||||
| 	// LineEnding defines the string used for line endings. | ||||
| 	LineEnding string `json:"lineEnding" yaml:"lineEnding"` | ||||
|  | ||||
| 	// EncodeName defines how to encode a loggers name. | ||||
| 	// It will only be applied if EnableName is set to true. | ||||
| 	EncodeName zapcore.NameEncoder `json:"nameEncoder" yaml:"nameEncoder"` | ||||
|  | ||||
| 	// EncodeLevel sets the log level for which any context should be logged. | ||||
| 	EncodeLevel zapcore.LevelEncoder `json:"levelEncoder" yaml:"levelEncoder"` | ||||
|  | ||||
| 	// EncodeDuration sets the format for encoding time.Duration values. | ||||
| 	EncodeDuration zapcore.DurationEncoder `json:"durationEncoder" yaml:"durationEncoder"` | ||||
|  | ||||
| 	// EncodeCaller defines how an entry caller should be serialized. | ||||
| 	// It will only be applied if EnableCaller is set to true. | ||||
| 	EncodeCaller CallerEncoder `json:"callerEncoder" yaml:"callerEncoder"` | ||||
| } | ||||
|  | ||||
| // NewDefaultEncoderConfig returns an EncoderConfig with default settings. | ||||
| func NewDefaultEncoderConfig() EncoderConfig { | ||||
| 	return EncoderConfig{ | ||||
| 		EnableName:       true, | ||||
| 		EnableCaller:     true, | ||||
| 		EnableStackTrace: true, | ||||
| 		LineEnding:       defaultLineEnding, | ||||
| 		EncodeName:       defaultEncodeName, | ||||
| 		EncodeLevel:      defaultEncodeLevel, | ||||
| 		EncodeDuration:   defaultEncodeDuration, | ||||
| 		EncodeCaller:     defaultEncodeCaller, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ToZapCoreEncoderConfig transforms the ecszap.EncoderConfig into | ||||
| // a zapcore.EncoderConfig | ||||
| func (cfg EncoderConfig) ToZapCoreEncoderConfig() zapcore.EncoderConfig { | ||||
| 	encCfg := zapcore.EncoderConfig{ | ||||
| 		MessageKey:     messageKey, | ||||
| 		LevelKey:       logLevelKey, | ||||
| 		TimeKey:        timeKey, | ||||
| 		EncodeTime:     encodeTime, | ||||
| 		LineEnding:     cfg.LineEnding, | ||||
| 		EncodeDuration: cfg.EncodeDuration, | ||||
| 		EncodeName:     cfg.EncodeName, | ||||
| 		EncodeLevel:    cfg.EncodeLevel, | ||||
| 	} | ||||
| 	if encCfg.EncodeDuration == nil { | ||||
| 		encCfg.EncodeDuration = defaultEncodeDuration | ||||
| 	} | ||||
| 	if cfg.EnableName { | ||||
| 		encCfg.NameKey = logNameKey | ||||
| 		if encCfg.EncodeName == nil { | ||||
| 			encCfg.EncodeName = defaultEncodeName | ||||
| 		} | ||||
| 	} | ||||
| 	if cfg.EnableStackTrace { | ||||
| 		encCfg.StacktraceKey = stackTraceKey | ||||
| 	} | ||||
| 	if cfg.EnableCaller { | ||||
| 		encCfg.CallerKey = callerKey | ||||
| 		if cfg.EncodeCaller == nil { | ||||
| 			encCfg.EncodeCaller = defaultEncodeCaller | ||||
| 		} else { | ||||
| 			encCfg.EncodeCaller = zapcore.CallerEncoder(cfg.EncodeCaller) | ||||
| 		} | ||||
| 	} | ||||
| 	if encCfg.EncodeLevel == nil { | ||||
| 		encCfg.EncodeLevel = defaultEncodeLevel | ||||
| 	} | ||||
| 	return encCfg | ||||
| } | ||||
|  | ||||
| // ECSCompatibleEncoderConfig takes an existing zapcore.EncoderConfig | ||||
| // and sets ECS relevant configuration options to ECS conformant values. | ||||
| // The returned zapcore.EncoderConfig can be used to create | ||||
| // an ECS conformant encoder. | ||||
| // Be aware that this will always replace any set EncodeCaller function | ||||
| // with the ecszap.ShortCallerEncoder. | ||||
| // This is a pure convenience function for making a transition from | ||||
| // existing an zap logger to an ECS conformant zap loggers easier. | ||||
| // It is recommended to make use of the ecszap.EncoderConfig whenever possible. | ||||
| func ECSCompatibleEncoderConfig(cfg zapcore.EncoderConfig) zapcore.EncoderConfig { | ||||
| 	// set the required MVP ECS keys | ||||
| 	cfg.MessageKey = messageKey | ||||
| 	cfg.LevelKey = logLevelKey | ||||
| 	cfg.TimeKey = timeKey | ||||
| 	if cfg.NameKey != "" { | ||||
| 		cfg.NameKey = logNameKey | ||||
| 	} | ||||
| 	// set further ECS defined keys only if keys were defined, | ||||
| 	// as zap omits these log attributes when keys are not defined | ||||
| 	// and ecszap does not intend to change this logic | ||||
| 	if cfg.StacktraceKey != "" { | ||||
| 		cfg.StacktraceKey = stackTraceKey | ||||
| 	} | ||||
| 	if cfg.CallerKey != "" { | ||||
| 		cfg.CallerKey = callerKey | ||||
| 		cfg.EncodeCaller = defaultEncodeCaller | ||||
| 	} | ||||
| 	// always set the time encoding to the ISO8601 time format | ||||
| 	cfg.EncodeTime = encodeTime | ||||
| 	// ensure all required encoders are set | ||||
| 	if cfg.EncodeDuration == nil { | ||||
| 		cfg.EncodeDuration = defaultEncodeDuration | ||||
| 	} | ||||
| 	if cfg.EncodeLevel == nil { | ||||
| 		cfg.EncodeLevel = defaultEncodeLevel | ||||
| 	} | ||||
| 	return cfg | ||||
| } | ||||
							
								
								
									
										132
									
								
								vendor/go.elastic.co/ecszap/internal/error.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										132
									
								
								vendor/go.elastic.co/ecszap/internal/error.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,132 +0,0 @@ | ||||
| // Licensed to Elasticsearch B.V. under one or more contributor | ||||
| // license agreements. See the NOTICE file distributed with | ||||
| // this work for additional information regarding copyright | ||||
| // ownership. Elasticsearch B.V. licenses this file to you 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 ( | ||||
| 	"fmt" | ||||
| 	"sync" | ||||
|  | ||||
| 	"github.com/pkg/errors" | ||||
| 	"go.uber.org/zap/zapcore" | ||||
| ) | ||||
|  | ||||
| type ecsError struct { | ||||
| 	error | ||||
| } | ||||
|  | ||||
| func NewError(err error) zapcore.ObjectMarshaler { | ||||
| 	return ecsError{err} | ||||
| } | ||||
|  | ||||
| func (err ecsError) MarshalLogObject(enc zapcore.ObjectEncoder) error { | ||||
| 	enc.AddString("message", err.Error()) | ||||
| 	if e, ok := err.error.(stackTracer); ok { | ||||
| 		enc.AddString("stack_trace", fmt.Sprintf("%+v", e.StackTrace())) | ||||
| 	} | ||||
|  | ||||
| 	// TODO(simitt): support for improved error handling | ||||
| 	// https://github.com/elastic/ecs-logging-go-zap/issues/8 | ||||
| 	if e, ok := err.error.(errorGroup); ok { | ||||
| 		if errorCause := e.Errors(); len(errorCause) > 0 { | ||||
| 			return enc.AddArray("cause", errArray(errorCause)) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // interface used by github.com/pkg/errors | ||||
| type stackTracer interface { | ||||
| 	StackTrace() errors.StackTrace | ||||
| } | ||||
|  | ||||
| // *** code below this line is mostly copied from github.com/zapcore/core.go | ||||
| //       and is subject to the license below*** | ||||
|  | ||||
| // Copyright (c) 2017 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| type errorGroup interface { | ||||
| 	// Provides read-only access to the underlying list of errors, preferably | ||||
| 	// without causing any allocs. | ||||
| 	Errors() []error | ||||
| } | ||||
|  | ||||
| // Note that errArry and errArrayElem are very similar to the version | ||||
| // implemented in the top-level error.go file. We can't re-use this because | ||||
| // that would require exporting errArray as part of the zapcore API. | ||||
|  | ||||
| // Encodes a list of errors using the standard error encoding logic. | ||||
| type errArray []error | ||||
|  | ||||
| func (errs errArray) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range errs { | ||||
| 		if errs[i] == nil { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		el := newErrArrayElem(errs[i]) | ||||
| 		arr.AppendObject(el) | ||||
| 		el.Free() | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| var _errArrayElemPool = sync.Pool{New: func() interface{} { | ||||
| 	return &errArrayElem{} | ||||
| }} | ||||
|  | ||||
| // Encodes any error into a {"error": ...} re-using the same errors logic. | ||||
| // | ||||
| // May be passed in place of an array to build a single-element array. | ||||
| type errArrayElem struct{ err error } | ||||
|  | ||||
| func newErrArrayElem(err error) *errArrayElem { | ||||
| 	e := _errArrayElemPool.Get().(*errArrayElem) | ||||
| 	e.err = err | ||||
| 	return e | ||||
| } | ||||
|  | ||||
| func (e *errArrayElem) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	return arr.AppendObject(e) | ||||
| } | ||||
|  | ||||
| func (e *errArrayElem) MarshalLogObject(enc zapcore.ObjectEncoder) error { | ||||
| 	return ecsError{e.err}.MarshalLogObject(enc) | ||||
| } | ||||
|  | ||||
| func (e *errArrayElem) Free() { | ||||
| 	e.err = nil | ||||
| 	_errArrayElemPool.Put(e) | ||||
| } | ||||
							
								
								
									
										58
									
								
								vendor/go.elastic.co/ecszap/magefile.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										58
									
								
								vendor/go.elastic.co/ecszap/magefile.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,58 +0,0 @@ | ||||
| // Licensed to Elasticsearch B.V. under one or more contributor | ||||
| // license agreements. See the NOTICE file distributed with | ||||
| // this work for additional information regarding copyright | ||||
| // ownership. Elasticsearch B.V. licenses this file to you 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. | ||||
|  | ||||
| // +build mage | ||||
|  | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os/exec" | ||||
|  | ||||
| 	"github.com/magefile/mage/mg" // mg contains helpful utility functions, like Deps | ||||
| ) | ||||
|  | ||||
| var Default = Update | ||||
|  | ||||
| // Update go files to contain license header | ||||
| func Update() error { | ||||
| 	mg.Deps(InstallDeps) | ||||
| 	fmt.Println("Updating...") | ||||
| 	for _, cmd := range []*exec.Cmd{ | ||||
| 		exec.Command("go-licenser", "."), | ||||
| 		exec.Command("go", "fmt"), | ||||
| 		exec.Command("go", "mod", "tidy"), | ||||
| 	} { | ||||
| 		if err := cmd.Run(); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Install development dependencies | ||||
| func InstallDeps() error { | ||||
| 	fmt.Println("Installing Deps...") | ||||
| 	for _, cmd := range []*exec.Cmd{ | ||||
| 		exec.Command("go", "get", "github.com/elastic/go-licenser"), | ||||
| 	} { | ||||
| 		if err := cmd.Run(); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										19
									
								
								vendor/go.uber.org/atomic/.codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/go.uber.org/atomic/.codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,19 +0,0 @@ | ||||
| coverage: | ||||
|   range: 80..100 | ||||
|   round: down | ||||
|   precision: 2 | ||||
|  | ||||
|   status: | ||||
|     project:                   # measuring the overall project coverage | ||||
|       default:                 # context, you can create multiple ones with custom titles | ||||
|         enabled: yes           # must be yes|true to enable this status | ||||
|         target: 100            # specify the target coverage for each commit status | ||||
|                                #   option: "auto" (must increase from parent commit or pull request base) | ||||
|                                #   option: "X%" a static target percentage to hit | ||||
|         if_not_found: success  # if parent is not found report status as success, error, or failure | ||||
|         if_ci_failed: error    # if ci fails report status as success, error, or failure | ||||
|  | ||||
| # Also update COVER_IGNORE_PKGS in the Makefile. | ||||
| ignore: | ||||
|   - /internal/gen-atomicint/ | ||||
|   - /internal/gen-valuewrapper/ | ||||
							
								
								
									
										15
									
								
								vendor/go.uber.org/atomic/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/go.uber.org/atomic/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,15 +0,0 @@ | ||||
| /bin | ||||
| .DS_Store | ||||
| /vendor | ||||
| cover.html | ||||
| cover.out | ||||
| lint.log | ||||
|  | ||||
| # Binaries | ||||
| *.test | ||||
|  | ||||
| # Profiling output | ||||
| *.prof | ||||
|  | ||||
| # Output of fossa analyzer | ||||
| /fossa | ||||
							
								
								
									
										117
									
								
								vendor/go.uber.org/atomic/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										117
									
								
								vendor/go.uber.org/atomic/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,117 +0,0 @@ | ||||
| # Changelog | ||||
| All notable changes to this project will be documented in this file. | ||||
|  | ||||
| The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||||
| and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||||
|  | ||||
| ## [1.10.0] - 2022-08-11 | ||||
| ### Added | ||||
| - Add `atomic.Float32` type for atomic operations on `float32`. | ||||
| - Add `CompareAndSwap` and `Swap` methods to `atomic.String`, `atomic.Error`, | ||||
|   and `atomic.Value`. | ||||
| - Add generic `atomic.Pointer[T]` type for atomic operations on pointers of any | ||||
|   type. This is present only for Go 1.18 or higher, and is a drop-in for | ||||
|   replacement for the standard library's `sync/atomic.Pointer` type. | ||||
|  | ||||
| ### Changed | ||||
| - Deprecate `CAS` methods on all types in favor of corresponding | ||||
|   `CompareAndSwap` methods. | ||||
|  | ||||
| Thanks to @eNV25 and @icpd for their contributions to this release. | ||||
|  | ||||
| [1.10.0]: https://github.com/uber-go/atomic/compare/v1.9.0...v1.10.0 | ||||
|  | ||||
| ## [1.9.0] - 2021-07-15 | ||||
| ### Added | ||||
| - Add `Float64.Swap` to match int atomic operations. | ||||
| - Add `atomic.Time` type for atomic operations on `time.Time` values. | ||||
|  | ||||
| [1.9.0]: https://github.com/uber-go/atomic/compare/v1.8.0...v1.9.0 | ||||
|  | ||||
| ## [1.8.0] - 2021-06-09 | ||||
| ### Added | ||||
| - Add `atomic.Uintptr` type for atomic operations on `uintptr` values. | ||||
| - Add `atomic.UnsafePointer` type for atomic operations on `unsafe.Pointer` values. | ||||
|  | ||||
| [1.8.0]: https://github.com/uber-go/atomic/compare/v1.7.0...v1.8.0 | ||||
|  | ||||
| ## [1.7.0] - 2020-09-14 | ||||
| ### Added | ||||
| - Support JSON serialization and deserialization of primitive atomic types. | ||||
| - Support Text marshalling and unmarshalling for string atomics. | ||||
|  | ||||
| ### Changed | ||||
| - Disallow incorrect comparison of atomic values in a non-atomic way. | ||||
|  | ||||
| ### Removed | ||||
| - Remove dependency on `golang.org/x/{lint, tools}`. | ||||
|  | ||||
| [1.7.0]: https://github.com/uber-go/atomic/compare/v1.6.0...v1.7.0 | ||||
|  | ||||
| ## [1.6.0] - 2020-02-24 | ||||
| ### Changed | ||||
| - Drop library dependency on `golang.org/x/{lint, tools}`. | ||||
|  | ||||
| [1.6.0]: https://github.com/uber-go/atomic/compare/v1.5.1...v1.6.0 | ||||
|  | ||||
| ## [1.5.1] - 2019-11-19 | ||||
| - Fix bug where `Bool.CAS` and `Bool.Toggle` do work correctly together | ||||
|   causing `CAS` to fail even though the old value matches. | ||||
|  | ||||
| [1.5.1]: https://github.com/uber-go/atomic/compare/v1.5.0...v1.5.1 | ||||
|  | ||||
| ## [1.5.0] - 2019-10-29 | ||||
| ### Changed | ||||
| - With Go modules, only the `go.uber.org/atomic` import path is supported now. | ||||
|   If you need to use the old import path, please add a `replace` directive to | ||||
|   your `go.mod`. | ||||
|  | ||||
| [1.5.0]: https://github.com/uber-go/atomic/compare/v1.4.0...v1.5.0 | ||||
|  | ||||
| ## [1.4.0] - 2019-05-01 | ||||
| ### Added | ||||
|  - Add `atomic.Error` type for atomic operations on `error` values. | ||||
|  | ||||
| [1.4.0]: https://github.com/uber-go/atomic/compare/v1.3.2...v1.4.0 | ||||
|  | ||||
| ## [1.3.2] - 2018-05-02 | ||||
| ### Added | ||||
| - Add `atomic.Duration` type for atomic operations on `time.Duration` values. | ||||
|  | ||||
| [1.3.2]: https://github.com/uber-go/atomic/compare/v1.3.1...v1.3.2 | ||||
|  | ||||
| ## [1.3.1] - 2017-11-14 | ||||
| ### Fixed | ||||
| - Revert optimization for `atomic.String.Store("")` which caused data races. | ||||
|  | ||||
| [1.3.1]: https://github.com/uber-go/atomic/compare/v1.3.0...v1.3.1 | ||||
|  | ||||
| ## [1.3.0] - 2017-11-13 | ||||
| ### Added | ||||
| - Add `atomic.Bool.CAS` for compare-and-swap semantics on bools. | ||||
|  | ||||
| ### Changed | ||||
| - Optimize `atomic.String.Store("")` by avoiding an allocation. | ||||
|  | ||||
| [1.3.0]: https://github.com/uber-go/atomic/compare/v1.2.0...v1.3.0 | ||||
|  | ||||
| ## [1.2.0] - 2017-04-12 | ||||
| ### Added | ||||
| - Shadow `atomic.Value` from `sync/atomic`. | ||||
|  | ||||
| [1.2.0]: https://github.com/uber-go/atomic/compare/v1.1.0...v1.2.0 | ||||
|  | ||||
| ## [1.1.0] - 2017-03-10 | ||||
| ### Added | ||||
| - Add atomic `Float64` type. | ||||
|  | ||||
| ### Changed | ||||
| - Support new `go.uber.org/atomic` import path. | ||||
|  | ||||
| [1.1.0]: https://github.com/uber-go/atomic/compare/v1.0.0...v1.1.0 | ||||
|  | ||||
| ## [1.0.0] - 2016-07-18 | ||||
|  | ||||
| - Initial release. | ||||
|  | ||||
| [1.0.0]: https://github.com/uber-go/atomic/releases/tag/v1.0.0 | ||||
							
								
								
									
										19
									
								
								vendor/go.uber.org/atomic/LICENSE.txt
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/go.uber.org/atomic/LICENSE.txt
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,19 +0,0 @@ | ||||
| Copyright (c) 2016 Uber Technologies, Inc. | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in | ||||
| all copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| THE SOFTWARE. | ||||
							
								
								
									
										79
									
								
								vendor/go.uber.org/atomic/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										79
									
								
								vendor/go.uber.org/atomic/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,79 +0,0 @@ | ||||
| # Directory to place `go install`ed binaries into. | ||||
| export GOBIN ?= $(shell pwd)/bin | ||||
|  | ||||
| GOLINT = $(GOBIN)/golint | ||||
| GEN_ATOMICINT = $(GOBIN)/gen-atomicint | ||||
| GEN_ATOMICWRAPPER = $(GOBIN)/gen-atomicwrapper | ||||
| STATICCHECK = $(GOBIN)/staticcheck | ||||
|  | ||||
| GO_FILES ?= $(shell find . '(' -path .git -o -path vendor ')' -prune -o -name '*.go' -print) | ||||
|  | ||||
| # Also update ignore section in .codecov.yml. | ||||
| COVER_IGNORE_PKGS = \ | ||||
| 	go.uber.org/atomic/internal/gen-atomicint \ | ||||
| 	go.uber.org/atomic/internal/gen-atomicwrapper | ||||
|  | ||||
| .PHONY: build | ||||
| build: | ||||
| 	go build ./... | ||||
|  | ||||
| .PHONY: test | ||||
| test: | ||||
| 	go test -race ./... | ||||
|  | ||||
| .PHONY: gofmt | ||||
| gofmt: | ||||
| 	$(eval FMT_LOG := $(shell mktemp -t gofmt.XXXXX)) | ||||
| 	gofmt -e -s -l $(GO_FILES) > $(FMT_LOG) || true | ||||
| 	@[ ! -s "$(FMT_LOG)" ] || (echo "gofmt failed:" && cat $(FMT_LOG) && false) | ||||
|  | ||||
| $(GOLINT): | ||||
| 	cd tools && go install golang.org/x/lint/golint | ||||
|  | ||||
| $(STATICCHECK): | ||||
| 	cd tools && go install honnef.co/go/tools/cmd/staticcheck | ||||
|  | ||||
| $(GEN_ATOMICWRAPPER): $(wildcard ./internal/gen-atomicwrapper/*) | ||||
| 	go build -o $@ ./internal/gen-atomicwrapper | ||||
|  | ||||
| $(GEN_ATOMICINT): $(wildcard ./internal/gen-atomicint/*) | ||||
| 	go build -o $@ ./internal/gen-atomicint | ||||
|  | ||||
| .PHONY: golint | ||||
| golint: $(GOLINT) | ||||
| 	$(GOLINT) ./... | ||||
|  | ||||
| .PHONY: staticcheck | ||||
| staticcheck: $(STATICCHECK) | ||||
| 	$(STATICCHECK) ./... | ||||
|  | ||||
| .PHONY: lint | ||||
| lint: gofmt golint staticcheck generatenodirty | ||||
|  | ||||
| # comma separated list of packages to consider for code coverage. | ||||
| COVER_PKG = $(shell \ | ||||
| 	go list -find ./... | \ | ||||
| 	grep -v $(foreach pkg,$(COVER_IGNORE_PKGS),-e "^$(pkg)$$") | \ | ||||
| 	paste -sd, -) | ||||
|  | ||||
| .PHONY: cover | ||||
| cover: | ||||
| 	go test -coverprofile=cover.out -coverpkg  $(COVER_PKG) -v ./... | ||||
| 	go tool cover -html=cover.out -o cover.html | ||||
|  | ||||
| .PHONY: generate | ||||
| generate: $(GEN_ATOMICINT) $(GEN_ATOMICWRAPPER) | ||||
| 	go generate ./... | ||||
|  | ||||
| .PHONY: generatenodirty | ||||
| generatenodirty: | ||||
| 	@[ -z "$$(git status --porcelain)" ] || ( \ | ||||
| 		echo "Working tree is dirty. Commit your changes first."; \ | ||||
| 		git status; \ | ||||
| 		exit 1 ) | ||||
| 	@make generate | ||||
| 	@status=$$(git status --porcelain); \ | ||||
| 		[ -z "$$status" ] || ( \ | ||||
| 		echo "Working tree is dirty after `make generate`:"; \ | ||||
| 		echo "$$status"; \ | ||||
| 		echo "Please ensure that the generated code is up-to-date." ) | ||||
							
								
								
									
										63
									
								
								vendor/go.uber.org/atomic/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										63
									
								
								vendor/go.uber.org/atomic/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,63 +0,0 @@ | ||||
| # atomic [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] [![Go Report Card][reportcard-img]][reportcard] | ||||
|  | ||||
| Simple wrappers for primitive types to enforce atomic access. | ||||
|  | ||||
| ## Installation | ||||
|  | ||||
| ```shell | ||||
| $ go get -u go.uber.org/atomic@v1 | ||||
| ``` | ||||
|  | ||||
| ### Legacy Import Path | ||||
|  | ||||
| As of v1.5.0, the import path `go.uber.org/atomic` is the only supported way | ||||
| of using this package. If you are using Go modules, this package will fail to | ||||
| compile with the legacy import path path `github.com/uber-go/atomic`. | ||||
|  | ||||
| We recommend migrating your code to the new import path but if you're unable | ||||
| to do so, or if your dependencies are still using the old import path, you | ||||
| will have to add a `replace` directive to your `go.mod` file downgrading the | ||||
| legacy import path to an older version. | ||||
|  | ||||
| ``` | ||||
| replace github.com/uber-go/atomic => github.com/uber-go/atomic v1.4.0 | ||||
| ``` | ||||
|  | ||||
| You can do so automatically by running the following command. | ||||
|  | ||||
| ```shell | ||||
| $ go mod edit -replace github.com/uber-go/atomic=github.com/uber-go/atomic@v1.4.0 | ||||
| ``` | ||||
|  | ||||
| ## Usage | ||||
|  | ||||
| The standard library's `sync/atomic` is powerful, but it's easy to forget which | ||||
| variables must be accessed atomically. `go.uber.org/atomic` preserves all the | ||||
| functionality of the standard library, but wraps the primitive types to | ||||
| provide a safer, more convenient API. | ||||
|  | ||||
| ```go | ||||
| var atom atomic.Uint32 | ||||
| atom.Store(42) | ||||
| atom.Sub(2) | ||||
| atom.CAS(40, 11) | ||||
| ``` | ||||
|  | ||||
| See the [documentation][doc] for a complete API specification. | ||||
|  | ||||
| ## Development Status | ||||
|  | ||||
| Stable. | ||||
|  | ||||
| --- | ||||
|  | ||||
| Released under the [MIT License](LICENSE.txt). | ||||
|  | ||||
| [doc-img]: https://godoc.org/github.com/uber-go/atomic?status.svg | ||||
| [doc]: https://godoc.org/go.uber.org/atomic | ||||
| [ci-img]: https://github.com/uber-go/atomic/actions/workflows/go.yml/badge.svg | ||||
| [ci]: https://github.com/uber-go/atomic/actions/workflows/go.yml | ||||
| [cov-img]: https://codecov.io/gh/uber-go/atomic/branch/master/graph/badge.svg | ||||
| [cov]: https://codecov.io/gh/uber-go/atomic | ||||
| [reportcard-img]: https://goreportcard.com/badge/go.uber.org/atomic | ||||
| [reportcard]: https://goreportcard.com/report/go.uber.org/atomic | ||||
							
								
								
									
										88
									
								
								vendor/go.uber.org/atomic/bool.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										88
									
								
								vendor/go.uber.org/atomic/bool.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,88 +0,0 @@ | ||||
| // @generated Code generated by gen-atomicwrapper. | ||||
|  | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| ) | ||||
|  | ||||
| // Bool is an atomic type-safe wrapper for bool values. | ||||
| type Bool struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
|  | ||||
| 	v Uint32 | ||||
| } | ||||
|  | ||||
| var _zeroBool bool | ||||
|  | ||||
| // NewBool creates a new Bool. | ||||
| func NewBool(val bool) *Bool { | ||||
| 	x := &Bool{} | ||||
| 	if val != _zeroBool { | ||||
| 		x.Store(val) | ||||
| 	} | ||||
| 	return x | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped bool. | ||||
| func (x *Bool) Load() bool { | ||||
| 	return truthy(x.v.Load()) | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed bool. | ||||
| func (x *Bool) Store(val bool) { | ||||
| 	x.v.Store(boolToInt(val)) | ||||
| } | ||||
|  | ||||
| // CAS is an atomic compare-and-swap for bool values. | ||||
| // | ||||
| // Deprecated: Use CompareAndSwap. | ||||
| func (x *Bool) CAS(old, new bool) (swapped bool) { | ||||
| 	return x.CompareAndSwap(old, new) | ||||
| } | ||||
|  | ||||
| // CompareAndSwap is an atomic compare-and-swap for bool values. | ||||
| func (x *Bool) CompareAndSwap(old, new bool) (swapped bool) { | ||||
| 	return x.v.CompareAndSwap(boolToInt(old), boolToInt(new)) | ||||
| } | ||||
|  | ||||
| // Swap atomically stores the given bool and returns the old | ||||
| // value. | ||||
| func (x *Bool) Swap(val bool) (old bool) { | ||||
| 	return truthy(x.v.Swap(boolToInt(val))) | ||||
| } | ||||
|  | ||||
| // MarshalJSON encodes the wrapped bool into JSON. | ||||
| func (x *Bool) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(x.Load()) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON decodes a bool from JSON. | ||||
| func (x *Bool) UnmarshalJSON(b []byte) error { | ||||
| 	var v bool | ||||
| 	if err := json.Unmarshal(b, &v); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	x.Store(v) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										53
									
								
								vendor/go.uber.org/atomic/bool_ext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										53
									
								
								vendor/go.uber.org/atomic/bool_ext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,53 +0,0 @@ | ||||
| // Copyright (c) 2020 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import ( | ||||
| 	"strconv" | ||||
| ) | ||||
|  | ||||
| //go:generate bin/gen-atomicwrapper -name=Bool -type=bool -wrapped=Uint32 -pack=boolToInt -unpack=truthy -cas -swap -json -file=bool.go | ||||
|  | ||||
| func truthy(n uint32) bool { | ||||
| 	return n == 1 | ||||
| } | ||||
|  | ||||
| func boolToInt(b bool) uint32 { | ||||
| 	if b { | ||||
| 		return 1 | ||||
| 	} | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| // Toggle atomically negates the Boolean and returns the previous value. | ||||
| func (b *Bool) Toggle() (old bool) { | ||||
| 	for { | ||||
| 		old := b.Load() | ||||
| 		if b.CAS(old, !old) { | ||||
| 			return old | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String encodes the wrapped value as a string. | ||||
| func (b *Bool) String() string { | ||||
| 	return strconv.FormatBool(b.Load()) | ||||
| } | ||||
							
								
								
									
										23
									
								
								vendor/go.uber.org/atomic/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/go.uber.org/atomic/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,23 +0,0 @@ | ||||
| // Copyright (c) 2020 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| // Package atomic provides simple wrappers around numerics to enforce atomic | ||||
| // access. | ||||
| package atomic | ||||
							
								
								
									
										89
									
								
								vendor/go.uber.org/atomic/duration.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										89
									
								
								vendor/go.uber.org/atomic/duration.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,89 +0,0 @@ | ||||
| // @generated Code generated by gen-atomicwrapper. | ||||
|  | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // Duration is an atomic type-safe wrapper for time.Duration values. | ||||
| type Duration struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
|  | ||||
| 	v Int64 | ||||
| } | ||||
|  | ||||
| var _zeroDuration time.Duration | ||||
|  | ||||
| // NewDuration creates a new Duration. | ||||
| func NewDuration(val time.Duration) *Duration { | ||||
| 	x := &Duration{} | ||||
| 	if val != _zeroDuration { | ||||
| 		x.Store(val) | ||||
| 	} | ||||
| 	return x | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped time.Duration. | ||||
| func (x *Duration) Load() time.Duration { | ||||
| 	return time.Duration(x.v.Load()) | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed time.Duration. | ||||
| func (x *Duration) Store(val time.Duration) { | ||||
| 	x.v.Store(int64(val)) | ||||
| } | ||||
|  | ||||
| // CAS is an atomic compare-and-swap for time.Duration values. | ||||
| // | ||||
| // Deprecated: Use CompareAndSwap. | ||||
| func (x *Duration) CAS(old, new time.Duration) (swapped bool) { | ||||
| 	return x.CompareAndSwap(old, new) | ||||
| } | ||||
|  | ||||
| // CompareAndSwap is an atomic compare-and-swap for time.Duration values. | ||||
| func (x *Duration) CompareAndSwap(old, new time.Duration) (swapped bool) { | ||||
| 	return x.v.CompareAndSwap(int64(old), int64(new)) | ||||
| } | ||||
|  | ||||
| // Swap atomically stores the given time.Duration and returns the old | ||||
| // value. | ||||
| func (x *Duration) Swap(val time.Duration) (old time.Duration) { | ||||
| 	return time.Duration(x.v.Swap(int64(val))) | ||||
| } | ||||
|  | ||||
| // MarshalJSON encodes the wrapped time.Duration into JSON. | ||||
| func (x *Duration) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(x.Load()) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON decodes a time.Duration from JSON. | ||||
| func (x *Duration) UnmarshalJSON(b []byte) error { | ||||
| 	var v time.Duration | ||||
| 	if err := json.Unmarshal(b, &v); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	x.Store(v) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										40
									
								
								vendor/go.uber.org/atomic/duration_ext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								vendor/go.uber.org/atomic/duration_ext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,40 +0,0 @@ | ||||
| // Copyright (c) 2020 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import "time" | ||||
|  | ||||
| //go:generate bin/gen-atomicwrapper -name=Duration -type=time.Duration -wrapped=Int64 -pack=int64 -unpack=time.Duration -cas -swap -json -imports time -file=duration.go | ||||
|  | ||||
| // Add atomically adds to the wrapped time.Duration and returns the new value. | ||||
| func (d *Duration) Add(delta time.Duration) time.Duration { | ||||
| 	return time.Duration(d.v.Add(int64(delta))) | ||||
| } | ||||
|  | ||||
| // Sub atomically subtracts from the wrapped time.Duration and returns the new value. | ||||
| func (d *Duration) Sub(delta time.Duration) time.Duration { | ||||
| 	return time.Duration(d.v.Sub(int64(delta))) | ||||
| } | ||||
|  | ||||
| // String encodes the wrapped value as a string. | ||||
| func (d *Duration) String() string { | ||||
| 	return d.Load().String() | ||||
| } | ||||
							
								
								
									
										62
									
								
								vendor/go.uber.org/atomic/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										62
									
								
								vendor/go.uber.org/atomic/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,62 +0,0 @@ | ||||
| // @generated Code generated by gen-atomicwrapper. | ||||
|  | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| // Error is an atomic type-safe wrapper for error values. | ||||
| type Error struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
|  | ||||
| 	v Value | ||||
| } | ||||
|  | ||||
| var _zeroError error | ||||
|  | ||||
| // NewError creates a new Error. | ||||
| func NewError(val error) *Error { | ||||
| 	x := &Error{} | ||||
| 	if val != _zeroError { | ||||
| 		x.Store(val) | ||||
| 	} | ||||
| 	return x | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped error. | ||||
| func (x *Error) Load() error { | ||||
| 	return unpackError(x.v.Load()) | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed error. | ||||
| func (x *Error) Store(val error) { | ||||
| 	x.v.Store(packError(val)) | ||||
| } | ||||
|  | ||||
| // CompareAndSwap is an atomic compare-and-swap for error values. | ||||
| func (x *Error) CompareAndSwap(old, new error) (swapped bool) { | ||||
| 	return x.v.CompareAndSwap(packError(old), packError(new)) | ||||
| } | ||||
|  | ||||
| // Swap atomically stores the given error and returns the old | ||||
| // value. | ||||
| func (x *Error) Swap(val error) (old error) { | ||||
| 	return unpackError(x.v.Swap(packError(val))) | ||||
| } | ||||
							
								
								
									
										39
									
								
								vendor/go.uber.org/atomic/error_ext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								vendor/go.uber.org/atomic/error_ext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,39 +0,0 @@ | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| // atomic.Value panics on nil inputs, or if the underlying type changes. | ||||
| // Stabilize by always storing a custom struct that we control. | ||||
|  | ||||
| //go:generate bin/gen-atomicwrapper -name=Error -type=error -wrapped=Value -pack=packError -unpack=unpackError -compareandswap -swap -file=error.go | ||||
|  | ||||
| type packedError struct{ Value error } | ||||
|  | ||||
| func packError(v error) interface{} { | ||||
| 	return packedError{v} | ||||
| } | ||||
|  | ||||
| func unpackError(v interface{}) error { | ||||
| 	if err, ok := v.(packedError); ok { | ||||
| 		return err.Value | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										77
									
								
								vendor/go.uber.org/atomic/float32.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										77
									
								
								vendor/go.uber.org/atomic/float32.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,77 +0,0 @@ | ||||
| // @generated Code generated by gen-atomicwrapper. | ||||
|  | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"math" | ||||
| ) | ||||
|  | ||||
| // Float32 is an atomic type-safe wrapper for float32 values. | ||||
| type Float32 struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
|  | ||||
| 	v Uint32 | ||||
| } | ||||
|  | ||||
| var _zeroFloat32 float32 | ||||
|  | ||||
| // NewFloat32 creates a new Float32. | ||||
| func NewFloat32(val float32) *Float32 { | ||||
| 	x := &Float32{} | ||||
| 	if val != _zeroFloat32 { | ||||
| 		x.Store(val) | ||||
| 	} | ||||
| 	return x | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped float32. | ||||
| func (x *Float32) Load() float32 { | ||||
| 	return math.Float32frombits(x.v.Load()) | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed float32. | ||||
| func (x *Float32) Store(val float32) { | ||||
| 	x.v.Store(math.Float32bits(val)) | ||||
| } | ||||
|  | ||||
| // Swap atomically stores the given float32 and returns the old | ||||
| // value. | ||||
| func (x *Float32) Swap(val float32) (old float32) { | ||||
| 	return math.Float32frombits(x.v.Swap(math.Float32bits(val))) | ||||
| } | ||||
|  | ||||
| // MarshalJSON encodes the wrapped float32 into JSON. | ||||
| func (x *Float32) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(x.Load()) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON decodes a float32 from JSON. | ||||
| func (x *Float32) UnmarshalJSON(b []byte) error { | ||||
| 	var v float32 | ||||
| 	if err := json.Unmarshal(b, &v); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	x.Store(v) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										76
									
								
								vendor/go.uber.org/atomic/float32_ext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										76
									
								
								vendor/go.uber.org/atomic/float32_ext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,76 +0,0 @@ | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import ( | ||||
| 	"math" | ||||
| 	"strconv" | ||||
| ) | ||||
|  | ||||
| //go:generate bin/gen-atomicwrapper -name=Float32 -type=float32 -wrapped=Uint32 -pack=math.Float32bits -unpack=math.Float32frombits -swap -json -imports math -file=float32.go | ||||
|  | ||||
| // Add atomically adds to the wrapped float32 and returns the new value. | ||||
| func (f *Float32) Add(delta float32) float32 { | ||||
| 	for { | ||||
| 		old := f.Load() | ||||
| 		new := old + delta | ||||
| 		if f.CAS(old, new) { | ||||
| 			return new | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Sub atomically subtracts from the wrapped float32 and returns the new value. | ||||
| func (f *Float32) Sub(delta float32) float32 { | ||||
| 	return f.Add(-delta) | ||||
| } | ||||
|  | ||||
| // CAS is an atomic compare-and-swap for float32 values. | ||||
| // | ||||
| // Deprecated: Use CompareAndSwap | ||||
| func (f *Float32) CAS(old, new float32) (swapped bool) { | ||||
| 	return f.CompareAndSwap(old, new) | ||||
| } | ||||
|  | ||||
| // CompareAndSwap is an atomic compare-and-swap for float32 values. | ||||
| // | ||||
| // Note: CompareAndSwap handles NaN incorrectly. NaN != NaN using Go's inbuilt operators | ||||
| // but CompareAndSwap allows a stored NaN to compare equal to a passed in NaN. | ||||
| // This avoids typical CompareAndSwap loops from blocking forever, e.g., | ||||
| // | ||||
| //	for { | ||||
| //	  old := atom.Load() | ||||
| //	  new = f(old) | ||||
| //	  if atom.CompareAndSwap(old, new) { | ||||
| //	    break | ||||
| //	  } | ||||
| //	} | ||||
| // | ||||
| // If CompareAndSwap did not match NaN to match, then the above would loop forever. | ||||
| func (f *Float32) CompareAndSwap(old, new float32) (swapped bool) { | ||||
| 	return f.v.CompareAndSwap(math.Float32bits(old), math.Float32bits(new)) | ||||
| } | ||||
|  | ||||
| // String encodes the wrapped value as a string. | ||||
| func (f *Float32) String() string { | ||||
| 	// 'g' is the behavior for floats with %v. | ||||
| 	return strconv.FormatFloat(float64(f.Load()), 'g', -1, 32) | ||||
| } | ||||
							
								
								
									
										77
									
								
								vendor/go.uber.org/atomic/float64.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										77
									
								
								vendor/go.uber.org/atomic/float64.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,77 +0,0 @@ | ||||
| // @generated Code generated by gen-atomicwrapper. | ||||
|  | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"math" | ||||
| ) | ||||
|  | ||||
| // Float64 is an atomic type-safe wrapper for float64 values. | ||||
| type Float64 struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
|  | ||||
| 	v Uint64 | ||||
| } | ||||
|  | ||||
| var _zeroFloat64 float64 | ||||
|  | ||||
| // NewFloat64 creates a new Float64. | ||||
| func NewFloat64(val float64) *Float64 { | ||||
| 	x := &Float64{} | ||||
| 	if val != _zeroFloat64 { | ||||
| 		x.Store(val) | ||||
| 	} | ||||
| 	return x | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped float64. | ||||
| func (x *Float64) Load() float64 { | ||||
| 	return math.Float64frombits(x.v.Load()) | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed float64. | ||||
| func (x *Float64) Store(val float64) { | ||||
| 	x.v.Store(math.Float64bits(val)) | ||||
| } | ||||
|  | ||||
| // Swap atomically stores the given float64 and returns the old | ||||
| // value. | ||||
| func (x *Float64) Swap(val float64) (old float64) { | ||||
| 	return math.Float64frombits(x.v.Swap(math.Float64bits(val))) | ||||
| } | ||||
|  | ||||
| // MarshalJSON encodes the wrapped float64 into JSON. | ||||
| func (x *Float64) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(x.Load()) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON decodes a float64 from JSON. | ||||
| func (x *Float64) UnmarshalJSON(b []byte) error { | ||||
| 	var v float64 | ||||
| 	if err := json.Unmarshal(b, &v); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	x.Store(v) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										76
									
								
								vendor/go.uber.org/atomic/float64_ext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										76
									
								
								vendor/go.uber.org/atomic/float64_ext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,76 +0,0 @@ | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import ( | ||||
| 	"math" | ||||
| 	"strconv" | ||||
| ) | ||||
|  | ||||
| //go:generate bin/gen-atomicwrapper -name=Float64 -type=float64 -wrapped=Uint64 -pack=math.Float64bits -unpack=math.Float64frombits -swap -json -imports math -file=float64.go | ||||
|  | ||||
| // Add atomically adds to the wrapped float64 and returns the new value. | ||||
| func (f *Float64) Add(delta float64) float64 { | ||||
| 	for { | ||||
| 		old := f.Load() | ||||
| 		new := old + delta | ||||
| 		if f.CAS(old, new) { | ||||
| 			return new | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Sub atomically subtracts from the wrapped float64 and returns the new value. | ||||
| func (f *Float64) Sub(delta float64) float64 { | ||||
| 	return f.Add(-delta) | ||||
| } | ||||
|  | ||||
| // CAS is an atomic compare-and-swap for float64 values. | ||||
| // | ||||
| // Deprecated: Use CompareAndSwap | ||||
| func (f *Float64) CAS(old, new float64) (swapped bool) { | ||||
| 	return f.CompareAndSwap(old, new) | ||||
| } | ||||
|  | ||||
| // CompareAndSwap is an atomic compare-and-swap for float64 values. | ||||
| // | ||||
| // Note: CompareAndSwap handles NaN incorrectly. NaN != NaN using Go's inbuilt operators | ||||
| // but CompareAndSwap allows a stored NaN to compare equal to a passed in NaN. | ||||
| // This avoids typical CompareAndSwap loops from blocking forever, e.g., | ||||
| // | ||||
| //	for { | ||||
| //	  old := atom.Load() | ||||
| //	  new = f(old) | ||||
| //	  if atom.CompareAndSwap(old, new) { | ||||
| //	    break | ||||
| //	  } | ||||
| //	} | ||||
| // | ||||
| // If CompareAndSwap did not match NaN to match, then the above would loop forever. | ||||
| func (f *Float64) CompareAndSwap(old, new float64) (swapped bool) { | ||||
| 	return f.v.CompareAndSwap(math.Float64bits(old), math.Float64bits(new)) | ||||
| } | ||||
|  | ||||
| // String encodes the wrapped value as a string. | ||||
| func (f *Float64) String() string { | ||||
| 	// 'g' is the behavior for floats with %v. | ||||
| 	return strconv.FormatFloat(f.Load(), 'g', -1, 64) | ||||
| } | ||||
							
								
								
									
										27
									
								
								vendor/go.uber.org/atomic/gen.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								vendor/go.uber.org/atomic/gen.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,27 +0,0 @@ | ||||
| // Copyright (c) 2020 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| //go:generate bin/gen-atomicint -name=Int32 -wrapped=int32 -file=int32.go | ||||
| //go:generate bin/gen-atomicint -name=Int64 -wrapped=int64 -file=int64.go | ||||
| //go:generate bin/gen-atomicint -name=Uint32 -wrapped=uint32 -unsigned -file=uint32.go | ||||
| //go:generate bin/gen-atomicint -name=Uint64 -wrapped=uint64 -unsigned -file=uint64.go | ||||
| //go:generate bin/gen-atomicint -name=Uintptr -wrapped=uintptr -unsigned -file=uintptr.go | ||||
							
								
								
									
										109
									
								
								vendor/go.uber.org/atomic/int32.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								vendor/go.uber.org/atomic/int32.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,109 +0,0 @@ | ||||
| // @generated Code generated by gen-atomicint. | ||||
|  | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"strconv" | ||||
| 	"sync/atomic" | ||||
| ) | ||||
|  | ||||
| // Int32 is an atomic wrapper around int32. | ||||
| type Int32 struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
|  | ||||
| 	v int32 | ||||
| } | ||||
|  | ||||
| // NewInt32 creates a new Int32. | ||||
| func NewInt32(val int32) *Int32 { | ||||
| 	return &Int32{v: val} | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped value. | ||||
| func (i *Int32) Load() int32 { | ||||
| 	return atomic.LoadInt32(&i.v) | ||||
| } | ||||
|  | ||||
| // Add atomically adds to the wrapped int32 and returns the new value. | ||||
| func (i *Int32) Add(delta int32) int32 { | ||||
| 	return atomic.AddInt32(&i.v, delta) | ||||
| } | ||||
|  | ||||
| // Sub atomically subtracts from the wrapped int32 and returns the new value. | ||||
| func (i *Int32) Sub(delta int32) int32 { | ||||
| 	return atomic.AddInt32(&i.v, -delta) | ||||
| } | ||||
|  | ||||
| // Inc atomically increments the wrapped int32 and returns the new value. | ||||
| func (i *Int32) Inc() int32 { | ||||
| 	return i.Add(1) | ||||
| } | ||||
|  | ||||
| // Dec atomically decrements the wrapped int32 and returns the new value. | ||||
| func (i *Int32) Dec() int32 { | ||||
| 	return i.Sub(1) | ||||
| } | ||||
|  | ||||
| // CAS is an atomic compare-and-swap. | ||||
| // | ||||
| // Deprecated: Use CompareAndSwap. | ||||
| func (i *Int32) CAS(old, new int32) (swapped bool) { | ||||
| 	return i.CompareAndSwap(old, new) | ||||
| } | ||||
|  | ||||
| // CompareAndSwap is an atomic compare-and-swap. | ||||
| func (i *Int32) CompareAndSwap(old, new int32) (swapped bool) { | ||||
| 	return atomic.CompareAndSwapInt32(&i.v, old, new) | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed value. | ||||
| func (i *Int32) Store(val int32) { | ||||
| 	atomic.StoreInt32(&i.v, val) | ||||
| } | ||||
|  | ||||
| // Swap atomically swaps the wrapped int32 and returns the old value. | ||||
| func (i *Int32) Swap(val int32) (old int32) { | ||||
| 	return atomic.SwapInt32(&i.v, val) | ||||
| } | ||||
|  | ||||
| // MarshalJSON encodes the wrapped int32 into JSON. | ||||
| func (i *Int32) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(i.Load()) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON decodes JSON into the wrapped int32. | ||||
| func (i *Int32) UnmarshalJSON(b []byte) error { | ||||
| 	var v int32 | ||||
| 	if err := json.Unmarshal(b, &v); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	i.Store(v) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // String encodes the wrapped value as a string. | ||||
| func (i *Int32) String() string { | ||||
| 	v := i.Load() | ||||
| 	return strconv.FormatInt(int64(v), 10) | ||||
| } | ||||
							
								
								
									
										109
									
								
								vendor/go.uber.org/atomic/int64.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								vendor/go.uber.org/atomic/int64.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,109 +0,0 @@ | ||||
| // @generated Code generated by gen-atomicint. | ||||
|  | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"strconv" | ||||
| 	"sync/atomic" | ||||
| ) | ||||
|  | ||||
| // Int64 is an atomic wrapper around int64. | ||||
| type Int64 struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
|  | ||||
| 	v int64 | ||||
| } | ||||
|  | ||||
| // NewInt64 creates a new Int64. | ||||
| func NewInt64(val int64) *Int64 { | ||||
| 	return &Int64{v: val} | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped value. | ||||
| func (i *Int64) Load() int64 { | ||||
| 	return atomic.LoadInt64(&i.v) | ||||
| } | ||||
|  | ||||
| // Add atomically adds to the wrapped int64 and returns the new value. | ||||
| func (i *Int64) Add(delta int64) int64 { | ||||
| 	return atomic.AddInt64(&i.v, delta) | ||||
| } | ||||
|  | ||||
| // Sub atomically subtracts from the wrapped int64 and returns the new value. | ||||
| func (i *Int64) Sub(delta int64) int64 { | ||||
| 	return atomic.AddInt64(&i.v, -delta) | ||||
| } | ||||
|  | ||||
| // Inc atomically increments the wrapped int64 and returns the new value. | ||||
| func (i *Int64) Inc() int64 { | ||||
| 	return i.Add(1) | ||||
| } | ||||
|  | ||||
| // Dec atomically decrements the wrapped int64 and returns the new value. | ||||
| func (i *Int64) Dec() int64 { | ||||
| 	return i.Sub(1) | ||||
| } | ||||
|  | ||||
| // CAS is an atomic compare-and-swap. | ||||
| // | ||||
| // Deprecated: Use CompareAndSwap. | ||||
| func (i *Int64) CAS(old, new int64) (swapped bool) { | ||||
| 	return i.CompareAndSwap(old, new) | ||||
| } | ||||
|  | ||||
| // CompareAndSwap is an atomic compare-and-swap. | ||||
| func (i *Int64) CompareAndSwap(old, new int64) (swapped bool) { | ||||
| 	return atomic.CompareAndSwapInt64(&i.v, old, new) | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed value. | ||||
| func (i *Int64) Store(val int64) { | ||||
| 	atomic.StoreInt64(&i.v, val) | ||||
| } | ||||
|  | ||||
| // Swap atomically swaps the wrapped int64 and returns the old value. | ||||
| func (i *Int64) Swap(val int64) (old int64) { | ||||
| 	return atomic.SwapInt64(&i.v, val) | ||||
| } | ||||
|  | ||||
| // MarshalJSON encodes the wrapped int64 into JSON. | ||||
| func (i *Int64) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(i.Load()) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON decodes JSON into the wrapped int64. | ||||
| func (i *Int64) UnmarshalJSON(b []byte) error { | ||||
| 	var v int64 | ||||
| 	if err := json.Unmarshal(b, &v); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	i.Store(v) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // String encodes the wrapped value as a string. | ||||
| func (i *Int64) String() string { | ||||
| 	v := i.Load() | ||||
| 	return strconv.FormatInt(int64(v), 10) | ||||
| } | ||||
							
								
								
									
										35
									
								
								vendor/go.uber.org/atomic/nocmp.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								vendor/go.uber.org/atomic/nocmp.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,35 +0,0 @@ | ||||
| // Copyright (c) 2020 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| // nocmp is an uncomparable struct. Embed this inside another struct to make | ||||
| // it uncomparable. | ||||
| // | ||||
| //	type Foo struct { | ||||
| //	  nocmp | ||||
| //	  // ... | ||||
| //	} | ||||
| // | ||||
| // This DOES NOT: | ||||
| // | ||||
| //   - Disallow shallow copies of structs | ||||
| //   - Disallow comparison of pointers to uncomparable structs | ||||
| type nocmp [0]func() | ||||
							
								
								
									
										60
									
								
								vendor/go.uber.org/atomic/pointer_go118.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										60
									
								
								vendor/go.uber.org/atomic/pointer_go118.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,60 +0,0 @@ | ||||
| // Copyright (c) 2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| //go:build go1.18 && !go1.19 | ||||
| // +build go1.18,!go1.19 | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import "unsafe" | ||||
|  | ||||
| type Pointer[T any] struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
| 	p UnsafePointer | ||||
| } | ||||
|  | ||||
| // NewPointer creates a new Pointer. | ||||
| func NewPointer[T any](v *T) *Pointer[T] { | ||||
| 	var p Pointer[T] | ||||
| 	if v != nil { | ||||
| 		p.p.Store(unsafe.Pointer(v)) | ||||
| 	} | ||||
| 	return &p | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped value. | ||||
| func (p *Pointer[T]) Load() *T { | ||||
| 	return (*T)(p.p.Load()) | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed value. | ||||
| func (p *Pointer[T]) Store(val *T) { | ||||
| 	p.p.Store(unsafe.Pointer(val)) | ||||
| } | ||||
|  | ||||
| // Swap atomically swaps the wrapped pointer and returns the old value. | ||||
| func (p *Pointer[T]) Swap(val *T) (old *T) { | ||||
| 	return (*T)(p.p.Swap(unsafe.Pointer(val))) | ||||
| } | ||||
|  | ||||
| // CompareAndSwap is an atomic compare-and-swap. | ||||
| func (p *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) { | ||||
| 	return p.p.CompareAndSwap(unsafe.Pointer(old), unsafe.Pointer(new)) | ||||
| } | ||||
							
								
								
									
										61
									
								
								vendor/go.uber.org/atomic/pointer_go119.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										61
									
								
								vendor/go.uber.org/atomic/pointer_go119.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,61 +0,0 @@ | ||||
| // Copyright (c) 2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| //go:build go1.19 | ||||
| // +build go1.19 | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import "sync/atomic" | ||||
|  | ||||
| // Pointer is an atomic pointer of type *T. | ||||
| type Pointer[T any] struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
| 	p atomic.Pointer[T] | ||||
| } | ||||
|  | ||||
| // NewPointer creates a new Pointer. | ||||
| func NewPointer[T any](v *T) *Pointer[T] { | ||||
| 	var p Pointer[T] | ||||
| 	if v != nil { | ||||
| 		p.p.Store(v) | ||||
| 	} | ||||
| 	return &p | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped value. | ||||
| func (p *Pointer[T]) Load() *T { | ||||
| 	return p.p.Load() | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed value. | ||||
| func (p *Pointer[T]) Store(val *T) { | ||||
| 	p.p.Store(val) | ||||
| } | ||||
|  | ||||
| // Swap atomically swaps the wrapped pointer and returns the old value. | ||||
| func (p *Pointer[T]) Swap(val *T) (old *T) { | ||||
| 	return p.p.Swap(val) | ||||
| } | ||||
|  | ||||
| // CompareAndSwap is an atomic compare-and-swap. | ||||
| func (p *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) { | ||||
| 	return p.p.CompareAndSwap(old, new) | ||||
| } | ||||
							
								
								
									
										65
									
								
								vendor/go.uber.org/atomic/string.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										65
									
								
								vendor/go.uber.org/atomic/string.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,65 +0,0 @@ | ||||
| // @generated Code generated by gen-atomicwrapper. | ||||
|  | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| // String is an atomic type-safe wrapper for string values. | ||||
| type String struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
|  | ||||
| 	v Value | ||||
| } | ||||
|  | ||||
| var _zeroString string | ||||
|  | ||||
| // NewString creates a new String. | ||||
| func NewString(val string) *String { | ||||
| 	x := &String{} | ||||
| 	if val != _zeroString { | ||||
| 		x.Store(val) | ||||
| 	} | ||||
| 	return x | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped string. | ||||
| func (x *String) Load() string { | ||||
| 	if v := x.v.Load(); v != nil { | ||||
| 		return v.(string) | ||||
| 	} | ||||
| 	return _zeroString | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed string. | ||||
| func (x *String) Store(val string) { | ||||
| 	x.v.Store(val) | ||||
| } | ||||
|  | ||||
| // CompareAndSwap is an atomic compare-and-swap for string values. | ||||
| func (x *String) CompareAndSwap(old, new string) (swapped bool) { | ||||
| 	return x.v.CompareAndSwap(old, new) | ||||
| } | ||||
|  | ||||
| // Swap atomically stores the given string and returns the old | ||||
| // value. | ||||
| func (x *String) Swap(val string) (old string) { | ||||
| 	return x.v.Swap(val).(string) | ||||
| } | ||||
							
								
								
									
										43
									
								
								vendor/go.uber.org/atomic/string_ext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								vendor/go.uber.org/atomic/string_ext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,43 +0,0 @@ | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| //go:generate bin/gen-atomicwrapper -name=String -type=string -wrapped=Value -compareandswap -swap -file=string.go | ||||
|  | ||||
| // String returns the wrapped value. | ||||
| func (s *String) String() string { | ||||
| 	return s.Load() | ||||
| } | ||||
|  | ||||
| // MarshalText encodes the wrapped string into a textual form. | ||||
| // | ||||
| // This makes it encodable as JSON, YAML, XML, and more. | ||||
| func (s *String) MarshalText() ([]byte, error) { | ||||
| 	return []byte(s.Load()), nil | ||||
| } | ||||
|  | ||||
| // UnmarshalText decodes text and replaces the wrapped string with it. | ||||
| // | ||||
| // This makes it decodable from JSON, YAML, XML, and more. | ||||
| func (s *String) UnmarshalText(b []byte) error { | ||||
| 	s.Store(string(b)) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										55
									
								
								vendor/go.uber.org/atomic/time.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										55
									
								
								vendor/go.uber.org/atomic/time.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,55 +0,0 @@ | ||||
| // @generated Code generated by gen-atomicwrapper. | ||||
|  | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import ( | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // Time is an atomic type-safe wrapper for time.Time values. | ||||
| type Time struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
|  | ||||
| 	v Value | ||||
| } | ||||
|  | ||||
| var _zeroTime time.Time | ||||
|  | ||||
| // NewTime creates a new Time. | ||||
| func NewTime(val time.Time) *Time { | ||||
| 	x := &Time{} | ||||
| 	if val != _zeroTime { | ||||
| 		x.Store(val) | ||||
| 	} | ||||
| 	return x | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped time.Time. | ||||
| func (x *Time) Load() time.Time { | ||||
| 	return unpackTime(x.v.Load()) | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed time.Time. | ||||
| func (x *Time) Store(val time.Time) { | ||||
| 	x.v.Store(packTime(val)) | ||||
| } | ||||
							
								
								
									
										36
									
								
								vendor/go.uber.org/atomic/time_ext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								vendor/go.uber.org/atomic/time_ext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,36 +0,0 @@ | ||||
| //  Copyright (c) 2021 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import "time" | ||||
|  | ||||
| //go:generate bin/gen-atomicwrapper -name=Time -type=time.Time -wrapped=Value -pack=packTime -unpack=unpackTime -imports time -file=time.go | ||||
|  | ||||
| func packTime(t time.Time) interface{} { | ||||
| 	return t | ||||
| } | ||||
|  | ||||
| func unpackTime(v interface{}) time.Time { | ||||
| 	if t, ok := v.(time.Time); ok { | ||||
| 		return t | ||||
| 	} | ||||
| 	return time.Time{} | ||||
| } | ||||
							
								
								
									
										109
									
								
								vendor/go.uber.org/atomic/uint32.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								vendor/go.uber.org/atomic/uint32.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,109 +0,0 @@ | ||||
| // @generated Code generated by gen-atomicint. | ||||
|  | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"strconv" | ||||
| 	"sync/atomic" | ||||
| ) | ||||
|  | ||||
| // Uint32 is an atomic wrapper around uint32. | ||||
| type Uint32 struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
|  | ||||
| 	v uint32 | ||||
| } | ||||
|  | ||||
| // NewUint32 creates a new Uint32. | ||||
| func NewUint32(val uint32) *Uint32 { | ||||
| 	return &Uint32{v: val} | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped value. | ||||
| func (i *Uint32) Load() uint32 { | ||||
| 	return atomic.LoadUint32(&i.v) | ||||
| } | ||||
|  | ||||
| // Add atomically adds to the wrapped uint32 and returns the new value. | ||||
| func (i *Uint32) Add(delta uint32) uint32 { | ||||
| 	return atomic.AddUint32(&i.v, delta) | ||||
| } | ||||
|  | ||||
| // Sub atomically subtracts from the wrapped uint32 and returns the new value. | ||||
| func (i *Uint32) Sub(delta uint32) uint32 { | ||||
| 	return atomic.AddUint32(&i.v, ^(delta - 1)) | ||||
| } | ||||
|  | ||||
| // Inc atomically increments the wrapped uint32 and returns the new value. | ||||
| func (i *Uint32) Inc() uint32 { | ||||
| 	return i.Add(1) | ||||
| } | ||||
|  | ||||
| // Dec atomically decrements the wrapped uint32 and returns the new value. | ||||
| func (i *Uint32) Dec() uint32 { | ||||
| 	return i.Sub(1) | ||||
| } | ||||
|  | ||||
| // CAS is an atomic compare-and-swap. | ||||
| // | ||||
| // Deprecated: Use CompareAndSwap. | ||||
| func (i *Uint32) CAS(old, new uint32) (swapped bool) { | ||||
| 	return i.CompareAndSwap(old, new) | ||||
| } | ||||
|  | ||||
| // CompareAndSwap is an atomic compare-and-swap. | ||||
| func (i *Uint32) CompareAndSwap(old, new uint32) (swapped bool) { | ||||
| 	return atomic.CompareAndSwapUint32(&i.v, old, new) | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed value. | ||||
| func (i *Uint32) Store(val uint32) { | ||||
| 	atomic.StoreUint32(&i.v, val) | ||||
| } | ||||
|  | ||||
| // Swap atomically swaps the wrapped uint32 and returns the old value. | ||||
| func (i *Uint32) Swap(val uint32) (old uint32) { | ||||
| 	return atomic.SwapUint32(&i.v, val) | ||||
| } | ||||
|  | ||||
| // MarshalJSON encodes the wrapped uint32 into JSON. | ||||
| func (i *Uint32) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(i.Load()) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON decodes JSON into the wrapped uint32. | ||||
| func (i *Uint32) UnmarshalJSON(b []byte) error { | ||||
| 	var v uint32 | ||||
| 	if err := json.Unmarshal(b, &v); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	i.Store(v) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // String encodes the wrapped value as a string. | ||||
| func (i *Uint32) String() string { | ||||
| 	v := i.Load() | ||||
| 	return strconv.FormatUint(uint64(v), 10) | ||||
| } | ||||
							
								
								
									
										109
									
								
								vendor/go.uber.org/atomic/uint64.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								vendor/go.uber.org/atomic/uint64.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,109 +0,0 @@ | ||||
| // @generated Code generated by gen-atomicint. | ||||
|  | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"strconv" | ||||
| 	"sync/atomic" | ||||
| ) | ||||
|  | ||||
| // Uint64 is an atomic wrapper around uint64. | ||||
| type Uint64 struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
|  | ||||
| 	v uint64 | ||||
| } | ||||
|  | ||||
| // NewUint64 creates a new Uint64. | ||||
| func NewUint64(val uint64) *Uint64 { | ||||
| 	return &Uint64{v: val} | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped value. | ||||
| func (i *Uint64) Load() uint64 { | ||||
| 	return atomic.LoadUint64(&i.v) | ||||
| } | ||||
|  | ||||
| // Add atomically adds to the wrapped uint64 and returns the new value. | ||||
| func (i *Uint64) Add(delta uint64) uint64 { | ||||
| 	return atomic.AddUint64(&i.v, delta) | ||||
| } | ||||
|  | ||||
| // Sub atomically subtracts from the wrapped uint64 and returns the new value. | ||||
| func (i *Uint64) Sub(delta uint64) uint64 { | ||||
| 	return atomic.AddUint64(&i.v, ^(delta - 1)) | ||||
| } | ||||
|  | ||||
| // Inc atomically increments the wrapped uint64 and returns the new value. | ||||
| func (i *Uint64) Inc() uint64 { | ||||
| 	return i.Add(1) | ||||
| } | ||||
|  | ||||
| // Dec atomically decrements the wrapped uint64 and returns the new value. | ||||
| func (i *Uint64) Dec() uint64 { | ||||
| 	return i.Sub(1) | ||||
| } | ||||
|  | ||||
| // CAS is an atomic compare-and-swap. | ||||
| // | ||||
| // Deprecated: Use CompareAndSwap. | ||||
| func (i *Uint64) CAS(old, new uint64) (swapped bool) { | ||||
| 	return i.CompareAndSwap(old, new) | ||||
| } | ||||
|  | ||||
| // CompareAndSwap is an atomic compare-and-swap. | ||||
| func (i *Uint64) CompareAndSwap(old, new uint64) (swapped bool) { | ||||
| 	return atomic.CompareAndSwapUint64(&i.v, old, new) | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed value. | ||||
| func (i *Uint64) Store(val uint64) { | ||||
| 	atomic.StoreUint64(&i.v, val) | ||||
| } | ||||
|  | ||||
| // Swap atomically swaps the wrapped uint64 and returns the old value. | ||||
| func (i *Uint64) Swap(val uint64) (old uint64) { | ||||
| 	return atomic.SwapUint64(&i.v, val) | ||||
| } | ||||
|  | ||||
| // MarshalJSON encodes the wrapped uint64 into JSON. | ||||
| func (i *Uint64) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(i.Load()) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON decodes JSON into the wrapped uint64. | ||||
| func (i *Uint64) UnmarshalJSON(b []byte) error { | ||||
| 	var v uint64 | ||||
| 	if err := json.Unmarshal(b, &v); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	i.Store(v) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // String encodes the wrapped value as a string. | ||||
| func (i *Uint64) String() string { | ||||
| 	v := i.Load() | ||||
| 	return strconv.FormatUint(uint64(v), 10) | ||||
| } | ||||
							
								
								
									
										109
									
								
								vendor/go.uber.org/atomic/uintptr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								vendor/go.uber.org/atomic/uintptr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,109 +0,0 @@ | ||||
| // @generated Code generated by gen-atomicint. | ||||
|  | ||||
| // Copyright (c) 2020-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"strconv" | ||||
| 	"sync/atomic" | ||||
| ) | ||||
|  | ||||
| // Uintptr is an atomic wrapper around uintptr. | ||||
| type Uintptr struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
|  | ||||
| 	v uintptr | ||||
| } | ||||
|  | ||||
| // NewUintptr creates a new Uintptr. | ||||
| func NewUintptr(val uintptr) *Uintptr { | ||||
| 	return &Uintptr{v: val} | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped value. | ||||
| func (i *Uintptr) Load() uintptr { | ||||
| 	return atomic.LoadUintptr(&i.v) | ||||
| } | ||||
|  | ||||
| // Add atomically adds to the wrapped uintptr and returns the new value. | ||||
| func (i *Uintptr) Add(delta uintptr) uintptr { | ||||
| 	return atomic.AddUintptr(&i.v, delta) | ||||
| } | ||||
|  | ||||
| // Sub atomically subtracts from the wrapped uintptr and returns the new value. | ||||
| func (i *Uintptr) Sub(delta uintptr) uintptr { | ||||
| 	return atomic.AddUintptr(&i.v, ^(delta - 1)) | ||||
| } | ||||
|  | ||||
| // Inc atomically increments the wrapped uintptr and returns the new value. | ||||
| func (i *Uintptr) Inc() uintptr { | ||||
| 	return i.Add(1) | ||||
| } | ||||
|  | ||||
| // Dec atomically decrements the wrapped uintptr and returns the new value. | ||||
| func (i *Uintptr) Dec() uintptr { | ||||
| 	return i.Sub(1) | ||||
| } | ||||
|  | ||||
| // CAS is an atomic compare-and-swap. | ||||
| // | ||||
| // Deprecated: Use CompareAndSwap. | ||||
| func (i *Uintptr) CAS(old, new uintptr) (swapped bool) { | ||||
| 	return i.CompareAndSwap(old, new) | ||||
| } | ||||
|  | ||||
| // CompareAndSwap is an atomic compare-and-swap. | ||||
| func (i *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool) { | ||||
| 	return atomic.CompareAndSwapUintptr(&i.v, old, new) | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed value. | ||||
| func (i *Uintptr) Store(val uintptr) { | ||||
| 	atomic.StoreUintptr(&i.v, val) | ||||
| } | ||||
|  | ||||
| // Swap atomically swaps the wrapped uintptr and returns the old value. | ||||
| func (i *Uintptr) Swap(val uintptr) (old uintptr) { | ||||
| 	return atomic.SwapUintptr(&i.v, val) | ||||
| } | ||||
|  | ||||
| // MarshalJSON encodes the wrapped uintptr into JSON. | ||||
| func (i *Uintptr) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(i.Load()) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON decodes JSON into the wrapped uintptr. | ||||
| func (i *Uintptr) UnmarshalJSON(b []byte) error { | ||||
| 	var v uintptr | ||||
| 	if err := json.Unmarshal(b, &v); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	i.Store(v) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // String encodes the wrapped value as a string. | ||||
| func (i *Uintptr) String() string { | ||||
| 	v := i.Load() | ||||
| 	return strconv.FormatUint(uint64(v), 10) | ||||
| } | ||||
							
								
								
									
										65
									
								
								vendor/go.uber.org/atomic/unsafe_pointer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										65
									
								
								vendor/go.uber.org/atomic/unsafe_pointer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,65 +0,0 @@ | ||||
| // Copyright (c) 2021-2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import ( | ||||
| 	"sync/atomic" | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| // UnsafePointer is an atomic wrapper around unsafe.Pointer. | ||||
| type UnsafePointer struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
|  | ||||
| 	v unsafe.Pointer | ||||
| } | ||||
|  | ||||
| // NewUnsafePointer creates a new UnsafePointer. | ||||
| func NewUnsafePointer(val unsafe.Pointer) *UnsafePointer { | ||||
| 	return &UnsafePointer{v: val} | ||||
| } | ||||
|  | ||||
| // Load atomically loads the wrapped value. | ||||
| func (p *UnsafePointer) Load() unsafe.Pointer { | ||||
| 	return atomic.LoadPointer(&p.v) | ||||
| } | ||||
|  | ||||
| // Store atomically stores the passed value. | ||||
| func (p *UnsafePointer) Store(val unsafe.Pointer) { | ||||
| 	atomic.StorePointer(&p.v, val) | ||||
| } | ||||
|  | ||||
| // Swap atomically swaps the wrapped unsafe.Pointer and returns the old value. | ||||
| func (p *UnsafePointer) Swap(val unsafe.Pointer) (old unsafe.Pointer) { | ||||
| 	return atomic.SwapPointer(&p.v, val) | ||||
| } | ||||
|  | ||||
| // CAS is an atomic compare-and-swap. | ||||
| // | ||||
| // Deprecated: Use CompareAndSwap | ||||
| func (p *UnsafePointer) CAS(old, new unsafe.Pointer) (swapped bool) { | ||||
| 	return p.CompareAndSwap(old, new) | ||||
| } | ||||
|  | ||||
| // CompareAndSwap is an atomic compare-and-swap. | ||||
| func (p *UnsafePointer) CompareAndSwap(old, new unsafe.Pointer) (swapped bool) { | ||||
| 	return atomic.CompareAndSwapPointer(&p.v, old, new) | ||||
| } | ||||
							
								
								
									
										31
									
								
								vendor/go.uber.org/atomic/value.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								vendor/go.uber.org/atomic/value.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,31 +0,0 @@ | ||||
| // Copyright (c) 2020 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package atomic | ||||
|  | ||||
| import "sync/atomic" | ||||
|  | ||||
| // Value shadows the type of the same name from sync/atomic | ||||
| // https://godoc.org/sync/atomic#Value | ||||
| type Value struct { | ||||
| 	_ nocmp // disallow non-atomic comparison | ||||
|  | ||||
| 	atomic.Value | ||||
| } | ||||
							
								
								
									
										15
									
								
								vendor/go.uber.org/multierr/.codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/go.uber.org/multierr/.codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,15 +0,0 @@ | ||||
| coverage: | ||||
|   range: 80..100 | ||||
|   round: down | ||||
|   precision: 2 | ||||
|  | ||||
|   status: | ||||
|     project:                   # measuring the overall project coverage | ||||
|       default:                 # context, you can create multiple ones with custom titles | ||||
|         enabled: yes           # must be yes|true to enable this status | ||||
|         target: 100            # specify the target coverage for each commit status | ||||
|                                #   option: "auto" (must increase from parent commit or pull request base) | ||||
|                                #   option: "X%" a static target percentage to hit | ||||
|         if_not_found: success  # if parent is not found report status as success, error, or failure | ||||
|         if_ci_failed: error    # if ci fails report status as success, error, or failure | ||||
|  | ||||
							
								
								
									
										4
									
								
								vendor/go.uber.org/multierr/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/go.uber.org/multierr/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +0,0 @@ | ||||
| /vendor | ||||
| cover.html | ||||
| cover.out | ||||
| /bin | ||||
							
								
								
									
										72
									
								
								vendor/go.uber.org/multierr/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										72
									
								
								vendor/go.uber.org/multierr/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,72 +0,0 @@ | ||||
| Releases | ||||
| ======== | ||||
|  | ||||
| v1.8.0 (2022-02-28) | ||||
| =================== | ||||
|  | ||||
| -   `Combine`: perform zero allocations when there are no errors. | ||||
|  | ||||
|  | ||||
| v1.7.0 (2021-05-06) | ||||
| =================== | ||||
|  | ||||
| -   Add `AppendInvoke` to append into errors from `defer` blocks. | ||||
|  | ||||
|  | ||||
| v1.6.0 (2020-09-14) | ||||
| =================== | ||||
|  | ||||
| -   Actually drop library dependency on development-time tooling. | ||||
|  | ||||
|  | ||||
| v1.5.0 (2020-02-24) | ||||
| =================== | ||||
|  | ||||
| -   Drop library dependency on development-time tooling. | ||||
|  | ||||
|  | ||||
| v1.4.0 (2019-11-04) | ||||
| =================== | ||||
|  | ||||
| -   Add `AppendInto` function to more ergonomically build errors inside a | ||||
|     loop. | ||||
|  | ||||
|  | ||||
| v1.3.0 (2019-10-29) | ||||
| =================== | ||||
|  | ||||
| -   Switch to Go modules. | ||||
|  | ||||
|  | ||||
| v1.2.0 (2019-09-26) | ||||
| =================== | ||||
|  | ||||
| -   Support extracting and matching against wrapped errors with `errors.As` | ||||
|     and `errors.Is`. | ||||
|  | ||||
|  | ||||
| v1.1.0 (2017-06-30) | ||||
| =================== | ||||
|  | ||||
| -   Added an `Errors(error) []error` function to extract the underlying list of | ||||
|     errors for a multierr error. | ||||
|  | ||||
|  | ||||
| v1.0.0 (2017-05-31) | ||||
| =================== | ||||
|  | ||||
| No changes since v0.2.0. This release is committing to making no breaking | ||||
| changes to the current API in the 1.X series. | ||||
|  | ||||
|  | ||||
| v0.2.0 (2017-04-11) | ||||
| =================== | ||||
|  | ||||
| -   Repeatedly appending to the same error is now faster due to fewer | ||||
|     allocations. | ||||
|  | ||||
|  | ||||
| v0.1.0 (2017-31-03) | ||||
| =================== | ||||
|  | ||||
| -   Initial release | ||||
							
								
								
									
										19
									
								
								vendor/go.uber.org/multierr/LICENSE.txt
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/go.uber.org/multierr/LICENSE.txt
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,19 +0,0 @@ | ||||
| Copyright (c) 2017-2021 Uber Technologies, Inc. | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in | ||||
| all copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| THE SOFTWARE. | ||||
							
								
								
									
										38
									
								
								vendor/go.uber.org/multierr/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								vendor/go.uber.org/multierr/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,38 +0,0 @@ | ||||
| # Directory to put `go install`ed binaries in. | ||||
| export GOBIN ?= $(shell pwd)/bin | ||||
|  | ||||
| GO_FILES := $(shell \ | ||||
| 	find . '(' -path '*/.*' -o -path './vendor' ')' -prune \ | ||||
| 	-o -name '*.go' -print | cut -b3-) | ||||
|  | ||||
| .PHONY: build | ||||
| build: | ||||
| 	go build ./... | ||||
|  | ||||
| .PHONY: test | ||||
| test: | ||||
| 	go test -race ./... | ||||
|  | ||||
| .PHONY: gofmt | ||||
| gofmt: | ||||
| 	$(eval FMT_LOG := $(shell mktemp -t gofmt.XXXXX)) | ||||
| 	@gofmt -e -s -l $(GO_FILES) > $(FMT_LOG) || true | ||||
| 	@[ ! -s "$(FMT_LOG)" ] || (echo "gofmt failed:" | cat - $(FMT_LOG) && false) | ||||
|  | ||||
| .PHONY: golint | ||||
| golint: | ||||
| 	@cd tools && go install golang.org/x/lint/golint | ||||
| 	@$(GOBIN)/golint ./... | ||||
|  | ||||
| .PHONY: staticcheck | ||||
| staticcheck: | ||||
| 	@cd tools && go install honnef.co/go/tools/cmd/staticcheck | ||||
| 	@$(GOBIN)/staticcheck ./... | ||||
|  | ||||
| .PHONY: lint | ||||
| lint: gofmt golint staticcheck | ||||
|  | ||||
| .PHONY: cover | ||||
| cover: | ||||
| 	go test -race -coverprofile=cover.out -coverpkg=./... -v ./... | ||||
| 	go tool cover -html=cover.out -o cover.html | ||||
							
								
								
									
										23
									
								
								vendor/go.uber.org/multierr/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/go.uber.org/multierr/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,23 +0,0 @@ | ||||
| # multierr [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] | ||||
|  | ||||
| `multierr` allows combining one or more Go `error`s together. | ||||
|  | ||||
| ## Installation | ||||
|  | ||||
|     go get -u go.uber.org/multierr | ||||
|  | ||||
| ## Status | ||||
|  | ||||
| Stable: No breaking changes will be made before 2.0. | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
|  | ||||
| Released under the [MIT License]. | ||||
|  | ||||
| [MIT License]: LICENSE.txt | ||||
| [doc-img]: https://pkg.go.dev/badge/go.uber.org/multierr | ||||
| [doc]: https://pkg.go.dev/go.uber.org/multierr | ||||
| [ci-img]: https://github.com/uber-go/multierr/actions/workflows/go.yml/badge.svg | ||||
| [cov-img]: https://codecov.io/gh/uber-go/multierr/branch/master/graph/badge.svg | ||||
| [ci]: https://github.com/uber-go/multierr/actions/workflows/go.yml | ||||
| [cov]: https://codecov.io/gh/uber-go/multierr | ||||
							
								
								
									
										652
									
								
								vendor/go.uber.org/multierr/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										652
									
								
								vendor/go.uber.org/multierr/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,652 +0,0 @@ | ||||
| // Copyright (c) 2017-2021 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| // Package multierr allows combining one or more errors together. | ||||
| // | ||||
| // Overview | ||||
| // | ||||
| // Errors can be combined with the use of the Combine function. | ||||
| // | ||||
| // 	multierr.Combine( | ||||
| // 		reader.Close(), | ||||
| // 		writer.Close(), | ||||
| // 		conn.Close(), | ||||
| // 	) | ||||
| // | ||||
| // If only two errors are being combined, the Append function may be used | ||||
| // instead. | ||||
| // | ||||
| // 	err = multierr.Append(reader.Close(), writer.Close()) | ||||
| // | ||||
| // The underlying list of errors for a returned error object may be retrieved | ||||
| // with the Errors function. | ||||
| // | ||||
| // 	errors := multierr.Errors(err) | ||||
| // 	if len(errors) > 0 { | ||||
| // 		fmt.Println("The following errors occurred:", errors) | ||||
| // 	} | ||||
| // | ||||
| // Appending from a loop | ||||
| // | ||||
| // You sometimes need to append into an error from a loop. | ||||
| // | ||||
| // 	var err error | ||||
| // 	for _, item := range items { | ||||
| // 		err = multierr.Append(err, process(item)) | ||||
| // 	} | ||||
| // | ||||
| // Cases like this may require knowledge of whether an individual instance | ||||
| // failed. This usually requires introduction of a new variable. | ||||
| // | ||||
| // 	var err error | ||||
| // 	for _, item := range items { | ||||
| // 		if perr := process(item); perr != nil { | ||||
| // 			log.Warn("skipping item", item) | ||||
| // 			err = multierr.Append(err, perr) | ||||
| // 		} | ||||
| // 	} | ||||
| // | ||||
| // multierr includes AppendInto to simplify cases like this. | ||||
| // | ||||
| // 	var err error | ||||
| // 	for _, item := range items { | ||||
| // 		if multierr.AppendInto(&err, process(item)) { | ||||
| // 			log.Warn("skipping item", item) | ||||
| // 		} | ||||
| // 	} | ||||
| // | ||||
| // This will append the error into the err variable, and return true if that | ||||
| // individual error was non-nil. | ||||
| // | ||||
| // See AppendInto for more information. | ||||
| // | ||||
| // Deferred Functions | ||||
| // | ||||
| // Go makes it possible to modify the return value of a function in a defer | ||||
| // block if the function was using named returns. This makes it possible to | ||||
| // record resource cleanup failures from deferred blocks. | ||||
| // | ||||
| // 	func sendRequest(req Request) (err error) { | ||||
| // 		conn, err := openConnection() | ||||
| // 		if err != nil { | ||||
| // 			return err | ||||
| // 		} | ||||
| // 		defer func() { | ||||
| // 			err = multierr.Append(err, conn.Close()) | ||||
| // 		}() | ||||
| // 		// ... | ||||
| // 	} | ||||
| // | ||||
| // multierr provides the Invoker type and AppendInvoke function to make cases | ||||
| // like the above simpler and obviate the need for a closure. The following is | ||||
| // roughly equivalent to the example above. | ||||
| // | ||||
| // 	func sendRequest(req Request) (err error) { | ||||
| // 		conn, err := openConnection() | ||||
| // 		if err != nil { | ||||
| // 			return err | ||||
| // 		} | ||||
| // 		defer multierr.AppendInvoke(&err, multierr.Close(conn)) | ||||
| // 		// ... | ||||
| // 	} | ||||
| // | ||||
| // See AppendInvoke and Invoker for more information. | ||||
| // | ||||
| // Advanced Usage | ||||
| // | ||||
| // Errors returned by Combine and Append MAY implement the following | ||||
| // interface. | ||||
| // | ||||
| // 	type errorGroup interface { | ||||
| // 		// Returns a slice containing the underlying list of errors. | ||||
| // 		// | ||||
| // 		// This slice MUST NOT be modified by the caller. | ||||
| // 		Errors() []error | ||||
| // 	} | ||||
| // | ||||
| // Note that if you need access to list of errors behind a multierr error, you | ||||
| // should prefer using the Errors function. That said, if you need cheap | ||||
| // read-only access to the underlying errors slice, you can attempt to cast | ||||
| // the error to this interface. You MUST handle the failure case gracefully | ||||
| // because errors returned by Combine and Append are not guaranteed to | ||||
| // implement this interface. | ||||
| // | ||||
| // 	var errors []error | ||||
| // 	group, ok := err.(errorGroup) | ||||
| // 	if ok { | ||||
| // 		errors = group.Errors() | ||||
| // 	} else { | ||||
| // 		errors = []error{err} | ||||
| // 	} | ||||
| package multierr // import "go.uber.org/multierr" | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
|  | ||||
| 	"go.uber.org/atomic" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// Separator for single-line error messages. | ||||
| 	_singlelineSeparator = []byte("; ") | ||||
|  | ||||
| 	// Prefix for multi-line messages | ||||
| 	_multilinePrefix = []byte("the following errors occurred:") | ||||
|  | ||||
| 	// Prefix for the first and following lines of an item in a list of | ||||
| 	// multi-line error messages. | ||||
| 	// | ||||
| 	// For example, if a single item is: | ||||
| 	// | ||||
| 	// 	foo | ||||
| 	// 	bar | ||||
| 	// | ||||
| 	// It will become, | ||||
| 	// | ||||
| 	// 	 -  foo | ||||
| 	// 	    bar | ||||
| 	_multilineSeparator = []byte("\n -  ") | ||||
| 	_multilineIndent    = []byte("    ") | ||||
| ) | ||||
|  | ||||
| // _bufferPool is a pool of bytes.Buffers. | ||||
| var _bufferPool = sync.Pool{ | ||||
| 	New: func() interface{} { | ||||
| 		return &bytes.Buffer{} | ||||
| 	}, | ||||
| } | ||||
|  | ||||
| type errorGroup interface { | ||||
| 	Errors() []error | ||||
| } | ||||
|  | ||||
| // Errors returns a slice containing zero or more errors that the supplied | ||||
| // error is composed of. If the error is nil, a nil slice is returned. | ||||
| // | ||||
| // 	err := multierr.Append(r.Close(), w.Close()) | ||||
| // 	errors := multierr.Errors(err) | ||||
| // | ||||
| // If the error is not composed of other errors, the returned slice contains | ||||
| // just the error that was passed in. | ||||
| // | ||||
| // Callers of this function are free to modify the returned slice. | ||||
| func Errors(err error) []error { | ||||
| 	if err == nil { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	// Note that we're casting to multiError, not errorGroup. Our contract is | ||||
| 	// that returned errors MAY implement errorGroup. Errors, however, only | ||||
| 	// has special behavior for multierr-specific error objects. | ||||
| 	// | ||||
| 	// This behavior can be expanded in the future but I think it's prudent to | ||||
| 	// start with as little as possible in terms of contract and possibility | ||||
| 	// of misuse. | ||||
| 	eg, ok := err.(*multiError) | ||||
| 	if !ok { | ||||
| 		return []error{err} | ||||
| 	} | ||||
|  | ||||
| 	errors := eg.Errors() | ||||
| 	result := make([]error, len(errors)) | ||||
| 	copy(result, errors) | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| // multiError is an error that holds one or more errors. | ||||
| // | ||||
| // An instance of this is guaranteed to be non-empty and flattened. That is, | ||||
| // none of the errors inside multiError are other multiErrors. | ||||
| // | ||||
| // multiError formats to a semi-colon delimited list of error messages with | ||||
| // %v and with a more readable multi-line format with %+v. | ||||
| type multiError struct { | ||||
| 	copyNeeded atomic.Bool | ||||
| 	errors     []error | ||||
| } | ||||
|  | ||||
| var _ errorGroup = (*multiError)(nil) | ||||
|  | ||||
| // Errors returns the list of underlying errors. | ||||
| // | ||||
| // This slice MUST NOT be modified. | ||||
| func (merr *multiError) Errors() []error { | ||||
| 	if merr == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return merr.errors | ||||
| } | ||||
|  | ||||
| // As attempts to find the first error in the error list that matches the type | ||||
| // of the value that target points to. | ||||
| // | ||||
| // This function allows errors.As to traverse the values stored on the | ||||
| // multierr error. | ||||
| func (merr *multiError) As(target interface{}) bool { | ||||
| 	for _, err := range merr.Errors() { | ||||
| 		if errors.As(err, target) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // Is attempts to match the provided error against errors in the error list. | ||||
| // | ||||
| // This function allows errors.Is to traverse the values stored on the | ||||
| // multierr error. | ||||
| func (merr *multiError) Is(target error) bool { | ||||
| 	for _, err := range merr.Errors() { | ||||
| 		if errors.Is(err, target) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (merr *multiError) Error() string { | ||||
| 	if merr == nil { | ||||
| 		return "" | ||||
| 	} | ||||
|  | ||||
| 	buff := _bufferPool.Get().(*bytes.Buffer) | ||||
| 	buff.Reset() | ||||
|  | ||||
| 	merr.writeSingleline(buff) | ||||
|  | ||||
| 	result := buff.String() | ||||
| 	_bufferPool.Put(buff) | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| func (merr *multiError) Format(f fmt.State, c rune) { | ||||
| 	if c == 'v' && f.Flag('+') { | ||||
| 		merr.writeMultiline(f) | ||||
| 	} else { | ||||
| 		merr.writeSingleline(f) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (merr *multiError) writeSingleline(w io.Writer) { | ||||
| 	first := true | ||||
| 	for _, item := range merr.errors { | ||||
| 		if first { | ||||
| 			first = false | ||||
| 		} else { | ||||
| 			w.Write(_singlelineSeparator) | ||||
| 		} | ||||
| 		io.WriteString(w, item.Error()) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (merr *multiError) writeMultiline(w io.Writer) { | ||||
| 	w.Write(_multilinePrefix) | ||||
| 	for _, item := range merr.errors { | ||||
| 		w.Write(_multilineSeparator) | ||||
| 		writePrefixLine(w, _multilineIndent, fmt.Sprintf("%+v", item)) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Writes s to the writer with the given prefix added before each line after | ||||
| // the first. | ||||
| func writePrefixLine(w io.Writer, prefix []byte, s string) { | ||||
| 	first := true | ||||
| 	for len(s) > 0 { | ||||
| 		if first { | ||||
| 			first = false | ||||
| 		} else { | ||||
| 			w.Write(prefix) | ||||
| 		} | ||||
|  | ||||
| 		idx := strings.IndexByte(s, '\n') | ||||
| 		if idx < 0 { | ||||
| 			idx = len(s) - 1 | ||||
| 		} | ||||
|  | ||||
| 		io.WriteString(w, s[:idx+1]) | ||||
| 		s = s[idx+1:] | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type inspectResult struct { | ||||
| 	// Number of top-level non-nil errors | ||||
| 	Count int | ||||
|  | ||||
| 	// Total number of errors including multiErrors | ||||
| 	Capacity int | ||||
|  | ||||
| 	// Index of the first non-nil error in the list. Value is meaningless if | ||||
| 	// Count is zero. | ||||
| 	FirstErrorIdx int | ||||
|  | ||||
| 	// Whether the list contains at least one multiError | ||||
| 	ContainsMultiError bool | ||||
| } | ||||
|  | ||||
| // Inspects the given slice of errors so that we can efficiently allocate | ||||
| // space for it. | ||||
| func inspect(errors []error) (res inspectResult) { | ||||
| 	first := true | ||||
| 	for i, err := range errors { | ||||
| 		if err == nil { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		res.Count++ | ||||
| 		if first { | ||||
| 			first = false | ||||
| 			res.FirstErrorIdx = i | ||||
| 		} | ||||
|  | ||||
| 		if merr, ok := err.(*multiError); ok { | ||||
| 			res.Capacity += len(merr.errors) | ||||
| 			res.ContainsMultiError = true | ||||
| 		} else { | ||||
| 			res.Capacity++ | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // fromSlice converts the given list of errors into a single error. | ||||
| func fromSlice(errors []error) error { | ||||
| 	// Don't pay to inspect small slices. | ||||
| 	switch len(errors) { | ||||
| 	case 0: | ||||
| 		return nil | ||||
| 	case 1: | ||||
| 		return errors[0] | ||||
| 	} | ||||
|  | ||||
| 	res := inspect(errors) | ||||
| 	switch res.Count { | ||||
| 	case 0: | ||||
| 		return nil | ||||
| 	case 1: | ||||
| 		// only one non-nil entry | ||||
| 		return errors[res.FirstErrorIdx] | ||||
| 	case len(errors): | ||||
| 		if !res.ContainsMultiError { | ||||
| 			// Error list is flat. Make a copy of it | ||||
| 			// Otherwise "errors" escapes to the heap | ||||
| 			// unconditionally for all other cases. | ||||
| 			// This lets us optimize for the "no errors" case. | ||||
| 			out := make([]error, len(errors)) | ||||
| 			copy(out, errors) | ||||
| 			return &multiError{errors: out} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	nonNilErrs := make([]error, 0, res.Capacity) | ||||
| 	for _, err := range errors[res.FirstErrorIdx:] { | ||||
| 		if err == nil { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if nested, ok := err.(*multiError); ok { | ||||
| 			nonNilErrs = append(nonNilErrs, nested.errors...) | ||||
| 		} else { | ||||
| 			nonNilErrs = append(nonNilErrs, err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return &multiError{errors: nonNilErrs} | ||||
| } | ||||
|  | ||||
| // Combine combines the passed errors into a single error. | ||||
| // | ||||
| // If zero arguments were passed or if all items are nil, a nil error is | ||||
| // returned. | ||||
| // | ||||
| // 	Combine(nil, nil)  // == nil | ||||
| // | ||||
| // If only a single error was passed, it is returned as-is. | ||||
| // | ||||
| // 	Combine(err)  // == err | ||||
| // | ||||
| // Combine skips over nil arguments so this function may be used to combine | ||||
| // together errors from operations that fail independently of each other. | ||||
| // | ||||
| // 	multierr.Combine( | ||||
| // 		reader.Close(), | ||||
| // 		writer.Close(), | ||||
| // 		pipe.Close(), | ||||
| // 	) | ||||
| // | ||||
| // If any of the passed errors is a multierr error, it will be flattened along | ||||
| // with the other errors. | ||||
| // | ||||
| // 	multierr.Combine(multierr.Combine(err1, err2), err3) | ||||
| // 	// is the same as | ||||
| // 	multierr.Combine(err1, err2, err3) | ||||
| // | ||||
| // The returned error formats into a readable multi-line error message if | ||||
| // formatted with %+v. | ||||
| // | ||||
| // 	fmt.Sprintf("%+v", multierr.Combine(err1, err2)) | ||||
| func Combine(errors ...error) error { | ||||
| 	return fromSlice(errors) | ||||
| } | ||||
|  | ||||
| // Append appends the given errors together. Either value may be nil. | ||||
| // | ||||
| // This function is a specialization of Combine for the common case where | ||||
| // there are only two errors. | ||||
| // | ||||
| // 	err = multierr.Append(reader.Close(), writer.Close()) | ||||
| // | ||||
| // The following pattern may also be used to record failure of deferred | ||||
| // operations without losing information about the original error. | ||||
| // | ||||
| // 	func doSomething(..) (err error) { | ||||
| // 		f := acquireResource() | ||||
| // 		defer func() { | ||||
| // 			err = multierr.Append(err, f.Close()) | ||||
| // 		}() | ||||
| func Append(left error, right error) error { | ||||
| 	switch { | ||||
| 	case left == nil: | ||||
| 		return right | ||||
| 	case right == nil: | ||||
| 		return left | ||||
| 	} | ||||
|  | ||||
| 	if _, ok := right.(*multiError); !ok { | ||||
| 		if l, ok := left.(*multiError); ok && !l.copyNeeded.Swap(true) { | ||||
| 			// Common case where the error on the left is constantly being | ||||
| 			// appended to. | ||||
| 			errs := append(l.errors, right) | ||||
| 			return &multiError{errors: errs} | ||||
| 		} else if !ok { | ||||
| 			// Both errors are single errors. | ||||
| 			return &multiError{errors: []error{left, right}} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Either right or both, left and right, are multiErrors. Rely on usual | ||||
| 	// expensive logic. | ||||
| 	errors := [2]error{left, right} | ||||
| 	return fromSlice(errors[0:]) | ||||
| } | ||||
|  | ||||
| // AppendInto appends an error into the destination of an error pointer and | ||||
| // returns whether the error being appended was non-nil. | ||||
| // | ||||
| // 	var err error | ||||
| // 	multierr.AppendInto(&err, r.Close()) | ||||
| // 	multierr.AppendInto(&err, w.Close()) | ||||
| // | ||||
| // The above is equivalent to, | ||||
| // | ||||
| // 	err := multierr.Append(r.Close(), w.Close()) | ||||
| // | ||||
| // As AppendInto reports whether the provided error was non-nil, it may be | ||||
| // used to build a multierr error in a loop more ergonomically. For example: | ||||
| // | ||||
| // 	var err error | ||||
| // 	for line := range lines { | ||||
| // 		var item Item | ||||
| // 		if multierr.AppendInto(&err, parse(line, &item)) { | ||||
| // 			continue | ||||
| // 		} | ||||
| // 		items = append(items, item) | ||||
| // 	} | ||||
| // | ||||
| // Compare this with a version that relies solely on Append: | ||||
| // | ||||
| // 	var err error | ||||
| // 	for line := range lines { | ||||
| // 		var item Item | ||||
| // 		if parseErr := parse(line, &item); parseErr != nil { | ||||
| // 			err = multierr.Append(err, parseErr) | ||||
| // 			continue | ||||
| // 		} | ||||
| // 		items = append(items, item) | ||||
| // 	} | ||||
| func AppendInto(into *error, err error) (errored bool) { | ||||
| 	if into == nil { | ||||
| 		// We panic if 'into' is nil. This is not documented above | ||||
| 		// because suggesting that the pointer must be non-nil may | ||||
| 		// confuse users into thinking that the error that it points | ||||
| 		// to must be non-nil. | ||||
| 		panic("misuse of multierr.AppendInto: into pointer must not be nil") | ||||
| 	} | ||||
|  | ||||
| 	if err == nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	*into = Append(*into, err) | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // Invoker is an operation that may fail with an error. Use it with | ||||
| // AppendInvoke to append the result of calling the function into an error. | ||||
| // This allows you to conveniently defer capture of failing operations. | ||||
| // | ||||
| // See also, Close and Invoke. | ||||
| type Invoker interface { | ||||
| 	Invoke() error | ||||
| } | ||||
|  | ||||
| // Invoke wraps a function which may fail with an error to match the Invoker | ||||
| // interface. Use it to supply functions matching this signature to | ||||
| // AppendInvoke. | ||||
| // | ||||
| // For example, | ||||
| // | ||||
| // 	func processReader(r io.Reader) (err error) { | ||||
| // 		scanner := bufio.NewScanner(r) | ||||
| // 		defer multierr.AppendInvoke(&err, multierr.Invoke(scanner.Err)) | ||||
| // 		for scanner.Scan() { | ||||
| // 			// ... | ||||
| // 		} | ||||
| // 		// ... | ||||
| // 	} | ||||
| // | ||||
| // In this example, the following line will construct the Invoker right away, | ||||
| // but defer the invocation of scanner.Err() until the function returns. | ||||
| // | ||||
| // 	defer multierr.AppendInvoke(&err, multierr.Invoke(scanner.Err)) | ||||
| type Invoke func() error | ||||
|  | ||||
| // Invoke calls the supplied function and returns its result. | ||||
| func (i Invoke) Invoke() error { return i() } | ||||
|  | ||||
| // Close builds an Invoker that closes the provided io.Closer. Use it with | ||||
| // AppendInvoke to close io.Closers and append their results into an error. | ||||
| // | ||||
| // For example, | ||||
| // | ||||
| // 	func processFile(path string) (err error) { | ||||
| // 		f, err := os.Open(path) | ||||
| // 		if err != nil { | ||||
| // 			return err | ||||
| // 		} | ||||
| // 		defer multierr.AppendInvoke(&err, multierr.Close(f)) | ||||
| // 		return processReader(f) | ||||
| // 	} | ||||
| // | ||||
| // In this example, multierr.Close will construct the Invoker right away, but | ||||
| // defer the invocation of f.Close until the function returns. | ||||
| // | ||||
| // 	defer multierr.AppendInvoke(&err, multierr.Close(f)) | ||||
| func Close(closer io.Closer) Invoker { | ||||
| 	return Invoke(closer.Close) | ||||
| } | ||||
|  | ||||
| // AppendInvoke appends the result of calling the given Invoker into the | ||||
| // provided error pointer. Use it with named returns to safely defer | ||||
| // invocation of fallible operations until a function returns, and capture the | ||||
| // resulting errors. | ||||
| // | ||||
| // 	func doSomething(...) (err error) { | ||||
| // 		// ... | ||||
| // 		f, err := openFile(..) | ||||
| // 		if err != nil { | ||||
| // 			return err | ||||
| // 		} | ||||
| // | ||||
| // 		// multierr will call f.Close() when this function returns and | ||||
| // 		// if the operation fails, its append its error into the | ||||
| // 		// returned error. | ||||
| // 		defer multierr.AppendInvoke(&err, multierr.Close(f)) | ||||
| // | ||||
| // 		scanner := bufio.NewScanner(f) | ||||
| // 		// Similarly, this scheduled scanner.Err to be called and | ||||
| // 		// inspected when the function returns and append its error | ||||
| // 		// into the returned error. | ||||
| // 		defer multierr.AppendInvoke(&err, multierr.Invoke(scanner.Err)) | ||||
| // | ||||
| // 		// ... | ||||
| // 	} | ||||
| // | ||||
| // Without defer, AppendInvoke behaves exactly like AppendInto. | ||||
| // | ||||
| // 	err := // ... | ||||
| // 	multierr.AppendInvoke(&err, mutltierr.Invoke(foo)) | ||||
| // | ||||
| // 	// ...is roughly equivalent to... | ||||
| // | ||||
| // 	err := // ... | ||||
| // 	multierr.AppendInto(&err, foo()) | ||||
| // | ||||
| // The advantage of the indirection introduced by Invoker is to make it easy | ||||
| // to defer the invocation of a function. Without this indirection, the | ||||
| // invoked function will be evaluated at the time of the defer block rather | ||||
| // than when the function returns. | ||||
| // | ||||
| // 	// BAD: This is likely not what the caller intended. This will evaluate | ||||
| // 	// foo() right away and append its result into the error when the | ||||
| // 	// function returns. | ||||
| // 	defer multierr.AppendInto(&err, foo()) | ||||
| // | ||||
| // 	// GOOD: This will defer invocation of foo unutil the function returns. | ||||
| // 	defer multierr.AppendInvoke(&err, multierr.Invoke(foo)) | ||||
| // | ||||
| // multierr provides a few Invoker implementations out of the box for | ||||
| // convenience. See Invoker for more information. | ||||
| func AppendInvoke(into *error, invoker Invoker) { | ||||
| 	AppendInto(into, invoker.Invoke()) | ||||
| } | ||||
							
								
								
									
										8
									
								
								vendor/go.uber.org/multierr/glide.yaml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/go.uber.org/multierr/glide.yaml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,8 +0,0 @@ | ||||
| package: go.uber.org/multierr | ||||
| import: | ||||
| - package: go.uber.org/atomic | ||||
|   version: ^1 | ||||
| testImport: | ||||
| - package: github.com/stretchr/testify | ||||
|   subpackages: | ||||
|   - assert | ||||
							
								
								
									
										17
									
								
								vendor/go.uber.org/zap/.codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								vendor/go.uber.org/zap/.codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,17 +0,0 @@ | ||||
| coverage: | ||||
|   range: 80..100 | ||||
|   round: down | ||||
|   precision: 2 | ||||
|  | ||||
|   status: | ||||
|     project:                   # measuring the overall project coverage | ||||
|       default:                 # context, you can create multiple ones with custom titles | ||||
|         enabled: yes           # must be yes|true to enable this status | ||||
|         target: 95%            # specify the target coverage for each commit status | ||||
|                                #   option: "auto" (must increase from parent commit or pull request base) | ||||
|                                #   option: "X%" a static target percentage to hit | ||||
|         if_not_found: success  # if parent is not found report status as success, error, or failure | ||||
|         if_ci_failed: error    # if ci fails report status as success, error, or failure | ||||
| ignore: | ||||
|   - internal/readme/readme.go | ||||
|  | ||||
							
								
								
									
										32
									
								
								vendor/go.uber.org/zap/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/go.uber.org/zap/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,32 +0,0 @@ | ||||
| # Compiled Object files, Static and Dynamic libs (Shared Objects) | ||||
| *.o | ||||
| *.a | ||||
| *.so | ||||
|  | ||||
| # Folders | ||||
| _obj | ||||
| _test | ||||
| vendor | ||||
|  | ||||
| # Architecture specific extensions/prefixes | ||||
| *.[568vq] | ||||
| [568vq].out | ||||
|  | ||||
| *.cgo1.go | ||||
| *.cgo2.c | ||||
| _cgo_defun.c | ||||
| _cgo_gotypes.go | ||||
| _cgo_export.* | ||||
|  | ||||
| _testmain.go | ||||
|  | ||||
| *.exe | ||||
| *.test | ||||
| *.prof | ||||
| *.pprof | ||||
| *.out | ||||
| *.log | ||||
|  | ||||
| /bin | ||||
| cover.out | ||||
| cover.html | ||||
							
								
								
									
										109
									
								
								vendor/go.uber.org/zap/.readme.tmpl
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								vendor/go.uber.org/zap/.readme.tmpl
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,109 +0,0 @@ | ||||
| # :zap: zap [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] | ||||
|  | ||||
| Blazing fast, structured, leveled logging in Go. | ||||
|  | ||||
| ## Installation | ||||
|  | ||||
| `go get -u go.uber.org/zap` | ||||
|  | ||||
| Note that zap only supports the two most recent minor versions of Go. | ||||
|  | ||||
| ## Quick Start | ||||
|  | ||||
| In contexts where performance is nice, but not critical, use the | ||||
| `SugaredLogger`. It's 4-10x faster than other structured logging | ||||
| packages and includes both structured and `printf`-style APIs. | ||||
|  | ||||
| ```go | ||||
| logger, _ := zap.NewProduction() | ||||
| defer logger.Sync() // flushes buffer, if any | ||||
| sugar := logger.Sugar() | ||||
| sugar.Infow("failed to fetch URL", | ||||
|   // Structured context as loosely typed key-value pairs. | ||||
|   "url", url, | ||||
|   "attempt", 3, | ||||
|   "backoff", time.Second, | ||||
| ) | ||||
| sugar.Infof("Failed to fetch URL: %s", url) | ||||
| ``` | ||||
|  | ||||
| When performance and type safety are critical, use the `Logger`. It's even | ||||
| faster than the `SugaredLogger` and allocates far less, but it only supports | ||||
| structured logging. | ||||
|  | ||||
| ```go | ||||
| logger, _ := zap.NewProduction() | ||||
| defer logger.Sync() | ||||
| logger.Info("failed to fetch URL", | ||||
|   // Structured context as strongly typed Field values. | ||||
|   zap.String("url", url), | ||||
|   zap.Int("attempt", 3), | ||||
|   zap.Duration("backoff", time.Second), | ||||
| ) | ||||
| ``` | ||||
|  | ||||
| See the [documentation][doc] and [FAQ](FAQ.md) for more details. | ||||
|  | ||||
| ## Performance | ||||
|  | ||||
| For applications that log in the hot path, reflection-based serialization and | ||||
| string formatting are prohibitively expensive — they're CPU-intensive | ||||
| and make many small allocations. Put differently, using `encoding/json` and | ||||
| `fmt.Fprintf` to log tons of `interface{}`s makes your application slow. | ||||
|  | ||||
| Zap takes a different approach. It includes a reflection-free, zero-allocation | ||||
| JSON encoder, and the base `Logger` strives to avoid serialization overhead | ||||
| and allocations wherever possible. By building the high-level `SugaredLogger` | ||||
| on that foundation, zap lets users *choose* when they need to count every | ||||
| allocation and when they'd prefer a more familiar, loosely typed API. | ||||
|  | ||||
| As measured by its own [benchmarking suite][], not only is zap more performant | ||||
| than comparable structured logging packages — it's also faster than the | ||||
| standard library. Like all benchmarks, take these with a grain of salt.<sup | ||||
| id="anchor-versions">[1](#footnote-versions)</sup> | ||||
|  | ||||
| Log a message and 10 fields: | ||||
|  | ||||
| {{.BenchmarkAddingFields}} | ||||
|  | ||||
| Log a message with a logger that already has 10 fields of context: | ||||
|  | ||||
| {{.BenchmarkAccumulatedContext}} | ||||
|  | ||||
| Log a static string, without any context or `printf`-style templating: | ||||
|  | ||||
| {{.BenchmarkWithoutFields}} | ||||
|  | ||||
| ## Development Status: Stable | ||||
|  | ||||
| All APIs are finalized, and no breaking changes will be made in the 1.x series | ||||
| of releases. Users of semver-aware dependency management systems should pin | ||||
| zap to `^1`. | ||||
|  | ||||
| ## Contributing | ||||
|  | ||||
| We encourage and support an active, healthy community of contributors — | ||||
| including you! Details are in the [contribution guide](CONTRIBUTING.md) and | ||||
| the [code of conduct](CODE_OF_CONDUCT.md). The zap maintainers keep an eye on | ||||
| issues and pull requests, but you can also report any negative conduct to | ||||
| oss-conduct@uber.com. That email list is a private, safe space; even the zap | ||||
| maintainers don't have access, so don't hesitate to hold us to a high | ||||
| standard. | ||||
|  | ||||
| <hr> | ||||
|  | ||||
| Released under the [MIT License](LICENSE.txt). | ||||
|  | ||||
| <sup id="footnote-versions">1</sup> In particular, keep in mind that we may be | ||||
| benchmarking against slightly older versions of other packages. Versions are | ||||
| pinned in the [benchmarks/go.mod][] file. [↩](#anchor-versions) | ||||
|  | ||||
| [doc-img]: https://pkg.go.dev/badge/go.uber.org/zap | ||||
| [doc]: https://pkg.go.dev/go.uber.org/zap | ||||
| [ci-img]: https://github.com/uber-go/zap/actions/workflows/go.yml/badge.svg | ||||
| [ci]: https://github.com/uber-go/zap/actions/workflows/go.yml | ||||
| [cov-img]: https://codecov.io/gh/uber-go/zap/branch/master/graph/badge.svg | ||||
| [cov]: https://codecov.io/gh/uber-go/zap | ||||
| [benchmarking suite]: https://github.com/uber-go/zap/tree/master/benchmarks | ||||
| [benchmarks/go.mod]: https://github.com/uber-go/zap/blob/master/benchmarks/go.mod | ||||
|  | ||||
							
								
								
									
										604
									
								
								vendor/go.uber.org/zap/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										604
									
								
								vendor/go.uber.org/zap/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,604 +0,0 @@ | ||||
| # Changelog | ||||
| All notable changes to this project will be documented in this file. | ||||
|  | ||||
| This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). | ||||
|  | ||||
| ## 1.23.0 (24 Aug 2022) | ||||
|  | ||||
| Enhancements: | ||||
| * [#1147][]: Add a `zapcore.LevelOf` function to determine the level of a | ||||
|   `LevelEnabler` or `Core`. | ||||
| * [#1155][]: Add `zap.Stringers` field constructor to log arrays of objects | ||||
|   that implement `String() string`. | ||||
|  | ||||
| [#1147]: https://github.com/uber-go/zap/pull/1147 | ||||
| [#1155]: https://github.com/uber-go/zap/pull/1155 | ||||
|  | ||||
|  | ||||
| ## 1.22.0 (8 Aug 2022) | ||||
|  | ||||
| Enhancements: | ||||
| * [#1071][]: Add `zap.Objects` and `zap.ObjectValues` field constructors to log | ||||
|   arrays of objects. With these two constructors, you don't need to implement | ||||
|   `zapcore.ArrayMarshaler` for use with `zap.Array` if those objects implement | ||||
|   `zapcore.ObjectMarshaler`. | ||||
| * [#1079][]: Add `SugaredLogger.WithOptions` to build a copy of an existing | ||||
|   `SugaredLogger` with the provided options applied. | ||||
| * [#1080][]: Add `*ln` variants to `SugaredLogger` for each log level. | ||||
|   These functions provide a string joining behavior similar to `fmt.Println`. | ||||
| * [#1088][]: Add `zap.WithFatalHook` option to control the behavior of the | ||||
|   logger for `Fatal`-level log entries. This defaults to exiting the program. | ||||
| * [#1108][]: Add a `zap.Must` function that you can use with `NewProduction` or | ||||
|   `NewDevelopment` to panic if the system was unable to build the logger. | ||||
| * [#1118][]: Add a `Logger.Log` method that allows specifying the log level for | ||||
|   a statement dynamically. | ||||
|  | ||||
| Thanks to @cardil, @craigpastro, @sashamelentyev, @shota3506, and @zhupeijun | ||||
| for their contributions to this release. | ||||
|  | ||||
| [#1071]: https://github.com/uber-go/zap/pull/1071 | ||||
| [#1079]: https://github.com/uber-go/zap/pull/1079 | ||||
| [#1080]: https://github.com/uber-go/zap/pull/1080 | ||||
| [#1088]: https://github.com/uber-go/zap/pull/1088 | ||||
| [#1108]: https://github.com/uber-go/zap/pull/1108 | ||||
| [#1118]: https://github.com/uber-go/zap/pull/1118 | ||||
|  | ||||
| ## 1.21.0 (7 Feb 2022) | ||||
|  | ||||
| Enhancements: | ||||
| *  [#1047][]: Add `zapcore.ParseLevel` to parse a `Level` from a string. | ||||
| *  [#1048][]: Add `zap.ParseAtomicLevel` to parse an `AtomicLevel` from a | ||||
|    string. | ||||
|  | ||||
| Bugfixes: | ||||
| * [#1058][]: Fix panic in JSON encoder when `EncodeLevel` is unset. | ||||
|  | ||||
| Other changes: | ||||
| * [#1052][]: Improve encoding performance when the `AddCaller` and | ||||
|   `AddStacktrace` options are used together. | ||||
|  | ||||
| [#1047]: https://github.com/uber-go/zap/pull/1047 | ||||
| [#1048]: https://github.com/uber-go/zap/pull/1048 | ||||
| [#1052]: https://github.com/uber-go/zap/pull/1052 | ||||
| [#1058]: https://github.com/uber-go/zap/pull/1058 | ||||
|  | ||||
| Thanks to @aerosol and @Techassi for their contributions to this release. | ||||
|  | ||||
| ## 1.20.0 (4 Jan 2022) | ||||
|  | ||||
| Enhancements: | ||||
| * [#989][]: Add `EncoderConfig.SkipLineEnding` flag to disable adding newline | ||||
|   characters between log statements. | ||||
| * [#1039][]: Add `EncoderConfig.NewReflectedEncoder` field to customize JSON | ||||
|   encoding of reflected log fields. | ||||
|  | ||||
| Bugfixes: | ||||
| * [#1011][]: Fix inaccurate precision when encoding complex64 as JSON. | ||||
| * [#554][], [#1017][]: Close JSON namespaces opened in `MarshalLogObject` | ||||
|   methods when the methods return. | ||||
| * [#1033][]: Avoid panicking in Sampler core if `thereafter` is zero. | ||||
|  | ||||
| Other changes: | ||||
| * [#1028][]: Drop support for Go < 1.15. | ||||
|  | ||||
| [#554]: https://github.com/uber-go/zap/pull/554 | ||||
| [#989]: https://github.com/uber-go/zap/pull/989 | ||||
| [#1011]: https://github.com/uber-go/zap/pull/1011 | ||||
| [#1017]: https://github.com/uber-go/zap/pull/1017 | ||||
| [#1028]: https://github.com/uber-go/zap/pull/1028 | ||||
| [#1033]: https://github.com/uber-go/zap/pull/1033 | ||||
| [#1039]: https://github.com/uber-go/zap/pull/1039 | ||||
|  | ||||
| Thanks to @psrajat, @lruggieri, @sammyrnycreal for their contributions to this release. | ||||
|  | ||||
| ## 1.19.1 (8 Sep 2021) | ||||
|  | ||||
| Bugfixes: | ||||
| * [#1001][]: JSON: Fix complex number encoding with negative imaginary part. Thanks to @hemantjadon. | ||||
| * [#1003][]: JSON: Fix inaccurate precision when encoding float32. | ||||
|  | ||||
| [#1001]: https://github.com/uber-go/zap/pull/1001 | ||||
| [#1003]: https://github.com/uber-go/zap/pull/1003 | ||||
|  | ||||
| ## 1.19.0 (9 Aug 2021) | ||||
|  | ||||
| Enhancements: | ||||
| * [#975][]: Avoid panicking in Sampler core if the level is out of bounds. | ||||
| * [#984][]: Reduce the size of BufferedWriteSyncer by aligning the fields | ||||
|   better. | ||||
|  | ||||
| [#975]: https://github.com/uber-go/zap/pull/975 | ||||
| [#984]: https://github.com/uber-go/zap/pull/984 | ||||
|  | ||||
| Thanks to @lancoLiu and @thockin for their contributions to this release. | ||||
|  | ||||
| ## 1.18.1 (28 Jun 2021) | ||||
|  | ||||
| Bugfixes: | ||||
| * [#974][]: Fix nil dereference in logger constructed by `zap.NewNop`. | ||||
|  | ||||
| [#974]: https://github.com/uber-go/zap/pull/974 | ||||
|  | ||||
| ## 1.18.0 (28 Jun 2021) | ||||
|  | ||||
| Enhancements: | ||||
| * [#961][]: Add `zapcore.BufferedWriteSyncer`, a new `WriteSyncer` that buffers | ||||
|   messages in-memory and flushes them periodically. | ||||
| * [#971][]: Add `zapio.Writer` to use a Zap logger as an `io.Writer`. | ||||
| * [#897][]: Add `zap.WithClock` option to control the source of time via the | ||||
|   new `zapcore.Clock` interface. | ||||
| * [#949][]: Avoid panicking in `zap.SugaredLogger` when arguments of `*w` | ||||
|   methods don't match expectations. | ||||
| * [#943][]: Add support for filtering by level or arbitrary matcher function to | ||||
|   `zaptest/observer`. | ||||
| * [#691][]: Comply with `io.StringWriter` and `io.ByteWriter` in Zap's | ||||
|   `buffer.Buffer`. | ||||
|  | ||||
| Thanks to @atrn0, @ernado, @heyanfu, @hnlq715, @zchee | ||||
| for their contributions to this release. | ||||
|  | ||||
| [#691]: https://github.com/uber-go/zap/pull/691 | ||||
| [#897]: https://github.com/uber-go/zap/pull/897 | ||||
| [#943]: https://github.com/uber-go/zap/pull/943 | ||||
| [#949]: https://github.com/uber-go/zap/pull/949 | ||||
| [#961]: https://github.com/uber-go/zap/pull/961 | ||||
| [#971]: https://github.com/uber-go/zap/pull/971 | ||||
|  | ||||
| ## 1.17.0 (25 May 2021) | ||||
|  | ||||
| Bugfixes: | ||||
| * [#867][]: Encode `<nil>` for nil `error` instead of a panic. | ||||
| * [#931][], [#936][]: Update minimum version constraints to address | ||||
|   vulnerabilities in dependencies. | ||||
|  | ||||
| Enhancements: | ||||
| * [#865][]: Improve alignment of fields of the Logger struct, reducing its | ||||
|   size from 96 to 80 bytes. | ||||
| * [#881][]: Support `grpclog.LoggerV2` in zapgrpc. | ||||
| * [#903][]: Support URL-encoded POST requests to the AtomicLevel HTTP handler | ||||
|   with the `application/x-www-form-urlencoded` content type. | ||||
| * [#912][]: Support multi-field encoding with `zap.Inline`. | ||||
| * [#913][]: Speed up SugaredLogger for calls with a single string. | ||||
| * [#928][]: Add support for filtering by field name to `zaptest/observer`. | ||||
|  | ||||
| Thanks to @ash2k, @FMLS, @jimmystewpot, @Oncilla, @tsoslow, @tylitianrui, @withshubh, and @wziww for their contributions to this release. | ||||
|  | ||||
| ## 1.16.0 (1 Sep 2020) | ||||
|  | ||||
| Bugfixes: | ||||
| * [#828][]: Fix missing newline in IncreaseLevel error messages. | ||||
| * [#835][]: Fix panic in JSON encoder when encoding times or durations | ||||
|   without specifying a time or duration encoder. | ||||
| * [#843][]: Honor CallerSkip when taking stack traces. | ||||
| * [#862][]: Fix the default file permissions to use `0666` and rely on the umask instead. | ||||
| * [#854][]: Encode `<nil>` for nil `Stringer` instead of a panic error log. | ||||
|  | ||||
| Enhancements: | ||||
| * [#629][]: Added `zapcore.TimeEncoderOfLayout` to easily create time encoders | ||||
|   for custom layouts. | ||||
| * [#697][]: Added support for a configurable delimiter in the console encoder. | ||||
| * [#852][]: Optimize console encoder by pooling the underlying JSON encoder. | ||||
| * [#844][]: Add ability to include the calling function as part of logs. | ||||
| * [#843][]: Add `StackSkip` for including truncated stacks as a field. | ||||
| * [#861][]: Add options to customize Fatal behaviour for better testability. | ||||
|  | ||||
| Thanks to @SteelPhase, @tmshn, @lixingwang, @wyxloading, @moul, @segevfiner, @andy-retailnext and @jcorbin for their contributions to this release. | ||||
|  | ||||
| ## 1.15.0 (23 Apr 2020) | ||||
|  | ||||
| Bugfixes: | ||||
| * [#804][]: Fix handling of `Time` values out of `UnixNano` range. | ||||
| * [#812][]: Fix `IncreaseLevel` being reset after a call to `With`. | ||||
|  | ||||
| Enhancements: | ||||
| * [#806][]: Add `WithCaller` option to supersede the `AddCaller` option. This | ||||
|   allows disabling annotation of log entries with caller information if | ||||
|   previously enabled with `AddCaller`. | ||||
| * [#813][]: Deprecate `NewSampler` constructor in favor of | ||||
|   `NewSamplerWithOptions` which supports a `SamplerHook` option. This option | ||||
|    adds support for monitoring sampling decisions through a hook. | ||||
|  | ||||
| Thanks to @danielbprice for their contributions to this release. | ||||
|  | ||||
| ## 1.14.1 (14 Mar 2020) | ||||
|  | ||||
| Bugfixes: | ||||
| * [#791][]: Fix panic on attempting to build a logger with an invalid Config. | ||||
| * [#795][]: Vendoring Zap with `go mod vendor` no longer includes Zap's | ||||
|   development-time dependencies. | ||||
| * [#799][]: Fix issue introduced in 1.14.0 that caused invalid JSON output to | ||||
|   be generated for arrays of `time.Time` objects when using string-based time | ||||
|   formats. | ||||
|  | ||||
| Thanks to @YashishDua for their contributions to this release. | ||||
|  | ||||
| ## 1.14.0 (20 Feb 2020) | ||||
|  | ||||
| Enhancements: | ||||
| * [#771][]: Optimize calls for disabled log levels. | ||||
| * [#773][]: Add millisecond duration encoder. | ||||
| * [#775][]: Add option to increase the level of a logger. | ||||
| * [#786][]: Optimize time formatters using `Time.AppendFormat` where possible. | ||||
|  | ||||
| Thanks to @caibirdme for their contributions to this release. | ||||
|  | ||||
| ## 1.13.0 (13 Nov 2019) | ||||
|  | ||||
| Enhancements: | ||||
| * [#758][]: Add `Intp`, `Stringp`, and other similar `*p` field constructors | ||||
|   to log pointers to primitives with support for `nil` values. | ||||
|  | ||||
| Thanks to @jbizzle for their contributions to this release. | ||||
|  | ||||
| ## 1.12.0 (29 Oct 2019) | ||||
|  | ||||
| Enhancements: | ||||
| * [#751][]: Migrate to Go modules. | ||||
|  | ||||
| ## 1.11.0 (21 Oct 2019) | ||||
|  | ||||
| Enhancements: | ||||
| * [#725][]: Add `zapcore.OmitKey` to omit keys in an `EncoderConfig`. | ||||
| * [#736][]: Add `RFC3339` and `RFC3339Nano` time encoders. | ||||
|  | ||||
| Thanks to @juicemia, @uhthomas for their contributions to this release. | ||||
|  | ||||
| ## 1.10.0 (29 Apr 2019) | ||||
|  | ||||
| Bugfixes: | ||||
| * [#657][]: Fix `MapObjectEncoder.AppendByteString` not adding value as a | ||||
|   string. | ||||
| * [#706][]: Fix incorrect call depth to determine caller in Go 1.12. | ||||
|  | ||||
| Enhancements: | ||||
| * [#610][]: Add `zaptest.WrapOptions` to wrap `zap.Option` for creating test | ||||
|   loggers. | ||||
| * [#675][]: Don't panic when encoding a String field. | ||||
| * [#704][]: Disable HTML escaping for JSON objects encoded using the | ||||
|   reflect-based encoder. | ||||
|  | ||||
| Thanks to @iaroslav-ciupin, @lelenanam, @joa, @NWilson for their contributions | ||||
| to this release. | ||||
|  | ||||
| ## v1.9.1 (06 Aug 2018) | ||||
|  | ||||
| Bugfixes: | ||||
|  | ||||
| * [#614][]: MapObjectEncoder should not ignore empty slices. | ||||
|  | ||||
| ## v1.9.0 (19 Jul 2018) | ||||
|  | ||||
| Enhancements: | ||||
| * [#602][]: Reduce number of allocations when logging with reflection. | ||||
| * [#572][], [#606][]: Expose a registry for third-party logging sinks. | ||||
|  | ||||
| Thanks to @nfarah86, @AlekSi, @JeanMertz, @philippgille, @etsangsplk, and | ||||
| @dimroc for their contributions to this release. | ||||
|  | ||||
| ## v1.8.0 (13 Apr 2018) | ||||
|  | ||||
| Enhancements: | ||||
| * [#508][]: Make log level configurable when redirecting the standard | ||||
|   library's logger. | ||||
| * [#518][]: Add a logger that writes to a `*testing.TB`. | ||||
| * [#577][]: Add a top-level alias for `zapcore.Field` to clean up GoDoc. | ||||
|  | ||||
| Bugfixes: | ||||
| * [#574][]: Add a missing import comment to `go.uber.org/zap/buffer`. | ||||
|  | ||||
| Thanks to @DiSiqueira and @djui for their contributions to this release. | ||||
|  | ||||
| ## v1.7.1 (25 Sep 2017) | ||||
|  | ||||
| Bugfixes: | ||||
| * [#504][]: Store strings when using AddByteString with the map encoder. | ||||
|  | ||||
| ## v1.7.0 (21 Sep 2017) | ||||
|  | ||||
| Enhancements: | ||||
|  | ||||
| * [#487][]: Add `NewStdLogAt`, which extends `NewStdLog` by allowing the user | ||||
|   to specify the level of the logged messages. | ||||
|  | ||||
| ## v1.6.0 (30 Aug 2017) | ||||
|  | ||||
| Enhancements: | ||||
|  | ||||
| * [#491][]: Omit zap stack frames from stacktraces. | ||||
| * [#490][]: Add a `ContextMap` method to observer logs for simpler | ||||
|   field validation in tests. | ||||
|  | ||||
| ## v1.5.0 (22 Jul 2017) | ||||
|  | ||||
| Enhancements: | ||||
|  | ||||
| * [#460][] and [#470][]: Support errors produced by `go.uber.org/multierr`. | ||||
| * [#465][]: Support user-supplied encoders for logger names. | ||||
|  | ||||
| Bugfixes: | ||||
|  | ||||
| * [#477][]: Fix a bug that incorrectly truncated deep stacktraces. | ||||
|  | ||||
| Thanks to @richard-tunein and @pavius for their contributions to this release. | ||||
|  | ||||
| ## v1.4.1 (08 Jun 2017) | ||||
|  | ||||
| This release fixes two bugs. | ||||
|  | ||||
| Bugfixes: | ||||
|  | ||||
| * [#435][]: Support a variety of case conventions when unmarshaling levels. | ||||
| * [#444][]: Fix a panic in the observer. | ||||
|  | ||||
| ## v1.4.0 (12 May 2017) | ||||
|  | ||||
| This release adds a few small features and is fully backward-compatible. | ||||
|  | ||||
| Enhancements: | ||||
|  | ||||
| * [#424][]: Add a `LineEnding` field to `EncoderConfig`, allowing users to | ||||
|   override the Unix-style default. | ||||
| * [#425][]: Preserve time zones when logging times. | ||||
| * [#431][]: Make `zap.AtomicLevel` implement `fmt.Stringer`, which makes a | ||||
|   variety of operations a bit simpler. | ||||
|  | ||||
| ## v1.3.0 (25 Apr 2017) | ||||
|  | ||||
| This release adds an enhancement to zap's testing helpers as well as the | ||||
| ability to marshal an AtomicLevel. It is fully backward-compatible. | ||||
|  | ||||
| Enhancements: | ||||
|  | ||||
| * [#415][]: Add a substring-filtering helper to zap's observer. This is | ||||
|   particularly useful when testing the `SugaredLogger`. | ||||
| * [#416][]: Make `AtomicLevel` implement `encoding.TextMarshaler`. | ||||
|  | ||||
| ## v1.2.0 (13 Apr 2017) | ||||
|  | ||||
| This release adds a gRPC compatibility wrapper. It is fully backward-compatible. | ||||
|  | ||||
| Enhancements: | ||||
|  | ||||
| * [#402][]: Add a `zapgrpc` package that wraps zap's Logger and implements | ||||
|   `grpclog.Logger`. | ||||
|  | ||||
| ## v1.1.0 (31 Mar 2017) | ||||
|  | ||||
| This release fixes two bugs and adds some enhancements to zap's testing helpers. | ||||
| It is fully backward-compatible. | ||||
|  | ||||
| Bugfixes: | ||||
|  | ||||
| * [#385][]: Fix caller path trimming on Windows. | ||||
| * [#396][]: Fix a panic when attempting to use non-existent directories with | ||||
|   zap's configuration struct. | ||||
|  | ||||
| Enhancements: | ||||
|  | ||||
| * [#386][]: Add filtering helpers to zaptest's observing logger. | ||||
|  | ||||
| Thanks to @moitias for contributing to this release. | ||||
|  | ||||
| ## v1.0.0 (14 Mar 2017) | ||||
|  | ||||
| This is zap's first stable release. All exported APIs are now final, and no | ||||
| further breaking changes will be made in the 1.x release series. Anyone using a | ||||
| semver-aware dependency manager should now pin to `^1`. | ||||
|  | ||||
| Breaking changes: | ||||
|  | ||||
| * [#366][]: Add byte-oriented APIs to encoders to log UTF-8 encoded text without | ||||
|   casting from `[]byte` to `string`. | ||||
| * [#364][]: To support buffering outputs, add `Sync` methods to `zapcore.Core`, | ||||
|   `zap.Logger`, and `zap.SugaredLogger`. | ||||
| * [#371][]: Rename the `testutils` package to `zaptest`, which is less likely to | ||||
|   clash with other testing helpers. | ||||
|  | ||||
| Bugfixes: | ||||
|  | ||||
| * [#362][]: Make the ISO8601 time formatters fixed-width, which is friendlier | ||||
|   for tab-separated console output. | ||||
| * [#369][]: Remove the automatic locks in `zapcore.NewCore`, which allows zap to | ||||
|   work with concurrency-safe `WriteSyncer` implementations. | ||||
| * [#347][]: Stop reporting errors when trying to `fsync` standard out on Linux | ||||
|   systems. | ||||
| * [#373][]: Report the correct caller from zap's standard library | ||||
|   interoperability wrappers. | ||||
|  | ||||
| Enhancements: | ||||
|  | ||||
| * [#348][]: Add a registry allowing third-party encodings to work with zap's | ||||
|   built-in `Config`. | ||||
| * [#327][]: Make the representation of logger callers configurable (like times, | ||||
|   levels, and durations). | ||||
| * [#376][]: Allow third-party encoders to use their own buffer pools, which | ||||
|   removes the last performance advantage that zap's encoders have over plugins. | ||||
| * [#346][]: Add `CombineWriteSyncers`, a convenience function to tee multiple | ||||
|   `WriteSyncer`s and lock the result. | ||||
| * [#365][]: Make zap's stacktraces compatible with mid-stack inlining (coming in | ||||
|   Go 1.9). | ||||
| * [#372][]: Export zap's observing logger as `zaptest/observer`. This makes it | ||||
|   easier for particularly punctilious users to unit test their application's | ||||
|   logging. | ||||
|  | ||||
| Thanks to @suyash, @htrendev, @flisky, @Ulexus, and @skipor for their | ||||
| contributions to this release. | ||||
|  | ||||
| ## v1.0.0-rc.3 (7 Mar 2017) | ||||
|  | ||||
| This is the third release candidate for zap's stable release. There are no | ||||
| breaking changes. | ||||
|  | ||||
| Bugfixes: | ||||
|  | ||||
| * [#339][]: Byte slices passed to `zap.Any` are now correctly treated as binary blobs | ||||
|   rather than `[]uint8`. | ||||
|  | ||||
| Enhancements: | ||||
|  | ||||
| * [#307][]: Users can opt into colored output for log levels. | ||||
| * [#353][]: In addition to hijacking the output of the standard library's | ||||
|   package-global logging functions, users can now construct a zap-backed | ||||
|   `log.Logger` instance. | ||||
| * [#311][]: Frames from common runtime functions and some of zap's internal | ||||
|   machinery are now omitted from stacktraces. | ||||
|  | ||||
| Thanks to @ansel1 and @suyash for their contributions to this release. | ||||
|  | ||||
| ## v1.0.0-rc.2 (21 Feb 2017) | ||||
|  | ||||
| This is the second release candidate for zap's stable release. It includes two | ||||
| breaking changes. | ||||
|  | ||||
| Breaking changes: | ||||
|  | ||||
| * [#316][]: Zap's global loggers are now fully concurrency-safe | ||||
|   (previously, users had to ensure that `ReplaceGlobals` was called before the | ||||
|   loggers were in use). However, they must now be accessed via the `L()` and | ||||
|   `S()` functions. Users can update their projects with | ||||
|  | ||||
|   ``` | ||||
|   gofmt -r "zap.L -> zap.L()" -w . | ||||
|   gofmt -r "zap.S -> zap.S()" -w . | ||||
|   ``` | ||||
| * [#309][] and [#317][]: RC1 was mistakenly shipped with invalid | ||||
|   JSON and YAML struct tags on all config structs. This release fixes the tags | ||||
|   and adds static analysis to prevent similar bugs in the future. | ||||
|  | ||||
| Bugfixes: | ||||
|  | ||||
| * [#321][]: Redirecting the standard library's `log` output now | ||||
|   correctly reports the logger's caller. | ||||
|  | ||||
| Enhancements: | ||||
|  | ||||
| * [#325][] and [#333][]: Zap now transparently supports non-standard, rich | ||||
|   errors like those produced by `github.com/pkg/errors`. | ||||
| * [#326][]: Though `New(nil)` continues to return a no-op logger, `NewNop()` is | ||||
|   now preferred. Users can update their projects with `gofmt -r 'zap.New(nil) -> | ||||
|   zap.NewNop()' -w .`. | ||||
| * [#300][]: Incorrectly importing zap as `github.com/uber-go/zap` now returns a | ||||
|   more informative error. | ||||
|  | ||||
| Thanks to @skipor and @chapsuk for their contributions to this release. | ||||
|  | ||||
| ## v1.0.0-rc.1 (14 Feb 2017) | ||||
|  | ||||
| This is the first release candidate for zap's stable release. There are multiple | ||||
| breaking changes and improvements from the pre-release version. Most notably: | ||||
|  | ||||
| * **Zap's import path is now "go.uber.org/zap"** — all users will | ||||
|   need to update their code. | ||||
| * User-facing types and functions remain in the `zap` package. Code relevant | ||||
|   largely to extension authors is now in the `zapcore` package. | ||||
| * The `zapcore.Core` type makes it easy for third-party packages to use zap's | ||||
|   internals but provide a different user-facing API. | ||||
| * `Logger` is now a concrete type instead of an interface. | ||||
| * A less verbose (though slower) logging API is included by default. | ||||
| * Package-global loggers `L` and `S` are included. | ||||
| * A human-friendly console encoder is included. | ||||
| * A declarative config struct allows common logger configurations to be managed | ||||
|   as configuration instead of code. | ||||
| * Sampling is more accurate, and doesn't depend on the standard library's shared | ||||
|   timer heap. | ||||
|  | ||||
| ## v0.1.0-beta.1 (6 Feb 2017) | ||||
|  | ||||
| This is a minor version, tagged to allow users to pin to the pre-1.0 APIs and | ||||
| upgrade at their leisure. Since this is the first tagged release, there are no | ||||
| backward compatibility concerns and all functionality is new. | ||||
|  | ||||
| Early zap adopters should pin to the 0.1.x minor version until they're ready to | ||||
| upgrade to the upcoming stable release. | ||||
|  | ||||
| [#316]: https://github.com/uber-go/zap/pull/316 | ||||
| [#309]: https://github.com/uber-go/zap/pull/309 | ||||
| [#317]: https://github.com/uber-go/zap/pull/317 | ||||
| [#321]: https://github.com/uber-go/zap/pull/321 | ||||
| [#325]: https://github.com/uber-go/zap/pull/325 | ||||
| [#333]: https://github.com/uber-go/zap/pull/333 | ||||
| [#326]: https://github.com/uber-go/zap/pull/326 | ||||
| [#300]: https://github.com/uber-go/zap/pull/300 | ||||
| [#339]: https://github.com/uber-go/zap/pull/339 | ||||
| [#307]: https://github.com/uber-go/zap/pull/307 | ||||
| [#353]: https://github.com/uber-go/zap/pull/353 | ||||
| [#311]: https://github.com/uber-go/zap/pull/311 | ||||
| [#366]: https://github.com/uber-go/zap/pull/366 | ||||
| [#364]: https://github.com/uber-go/zap/pull/364 | ||||
| [#371]: https://github.com/uber-go/zap/pull/371 | ||||
| [#362]: https://github.com/uber-go/zap/pull/362 | ||||
| [#369]: https://github.com/uber-go/zap/pull/369 | ||||
| [#347]: https://github.com/uber-go/zap/pull/347 | ||||
| [#373]: https://github.com/uber-go/zap/pull/373 | ||||
| [#348]: https://github.com/uber-go/zap/pull/348 | ||||
| [#327]: https://github.com/uber-go/zap/pull/327 | ||||
| [#376]: https://github.com/uber-go/zap/pull/376 | ||||
| [#346]: https://github.com/uber-go/zap/pull/346 | ||||
| [#365]: https://github.com/uber-go/zap/pull/365 | ||||
| [#372]: https://github.com/uber-go/zap/pull/372 | ||||
| [#385]: https://github.com/uber-go/zap/pull/385 | ||||
| [#396]: https://github.com/uber-go/zap/pull/396 | ||||
| [#386]: https://github.com/uber-go/zap/pull/386 | ||||
| [#402]: https://github.com/uber-go/zap/pull/402 | ||||
| [#415]: https://github.com/uber-go/zap/pull/415 | ||||
| [#416]: https://github.com/uber-go/zap/pull/416 | ||||
| [#424]: https://github.com/uber-go/zap/pull/424 | ||||
| [#425]: https://github.com/uber-go/zap/pull/425 | ||||
| [#431]: https://github.com/uber-go/zap/pull/431 | ||||
| [#435]: https://github.com/uber-go/zap/pull/435 | ||||
| [#444]: https://github.com/uber-go/zap/pull/444 | ||||
| [#477]: https://github.com/uber-go/zap/pull/477 | ||||
| [#465]: https://github.com/uber-go/zap/pull/465 | ||||
| [#460]: https://github.com/uber-go/zap/pull/460 | ||||
| [#470]: https://github.com/uber-go/zap/pull/470 | ||||
| [#487]: https://github.com/uber-go/zap/pull/487 | ||||
| [#490]: https://github.com/uber-go/zap/pull/490 | ||||
| [#491]: https://github.com/uber-go/zap/pull/491 | ||||
| [#504]: https://github.com/uber-go/zap/pull/504 | ||||
| [#508]: https://github.com/uber-go/zap/pull/508 | ||||
| [#518]: https://github.com/uber-go/zap/pull/518 | ||||
| [#577]: https://github.com/uber-go/zap/pull/577 | ||||
| [#574]: https://github.com/uber-go/zap/pull/574 | ||||
| [#602]: https://github.com/uber-go/zap/pull/602 | ||||
| [#572]: https://github.com/uber-go/zap/pull/572 | ||||
| [#606]: https://github.com/uber-go/zap/pull/606 | ||||
| [#614]: https://github.com/uber-go/zap/pull/614 | ||||
| [#657]: https://github.com/uber-go/zap/pull/657 | ||||
| [#706]: https://github.com/uber-go/zap/pull/706 | ||||
| [#610]: https://github.com/uber-go/zap/pull/610 | ||||
| [#675]: https://github.com/uber-go/zap/pull/675 | ||||
| [#704]: https://github.com/uber-go/zap/pull/704 | ||||
| [#725]: https://github.com/uber-go/zap/pull/725 | ||||
| [#736]: https://github.com/uber-go/zap/pull/736 | ||||
| [#751]: https://github.com/uber-go/zap/pull/751 | ||||
| [#758]: https://github.com/uber-go/zap/pull/758 | ||||
| [#771]: https://github.com/uber-go/zap/pull/771 | ||||
| [#773]: https://github.com/uber-go/zap/pull/773 | ||||
| [#775]: https://github.com/uber-go/zap/pull/775 | ||||
| [#786]: https://github.com/uber-go/zap/pull/786 | ||||
| [#791]: https://github.com/uber-go/zap/pull/791 | ||||
| [#795]: https://github.com/uber-go/zap/pull/795 | ||||
| [#799]: https://github.com/uber-go/zap/pull/799 | ||||
| [#804]: https://github.com/uber-go/zap/pull/804 | ||||
| [#812]: https://github.com/uber-go/zap/pull/812 | ||||
| [#806]: https://github.com/uber-go/zap/pull/806 | ||||
| [#813]: https://github.com/uber-go/zap/pull/813 | ||||
| [#629]: https://github.com/uber-go/zap/pull/629 | ||||
| [#697]: https://github.com/uber-go/zap/pull/697 | ||||
| [#828]: https://github.com/uber-go/zap/pull/828 | ||||
| [#835]: https://github.com/uber-go/zap/pull/835 | ||||
| [#843]: https://github.com/uber-go/zap/pull/843 | ||||
| [#844]: https://github.com/uber-go/zap/pull/844 | ||||
| [#852]: https://github.com/uber-go/zap/pull/852 | ||||
| [#854]: https://github.com/uber-go/zap/pull/854 | ||||
| [#861]: https://github.com/uber-go/zap/pull/861 | ||||
| [#862]: https://github.com/uber-go/zap/pull/862 | ||||
| [#865]: https://github.com/uber-go/zap/pull/865 | ||||
| [#867]: https://github.com/uber-go/zap/pull/867 | ||||
| [#881]: https://github.com/uber-go/zap/pull/881 | ||||
| [#903]: https://github.com/uber-go/zap/pull/903 | ||||
| [#912]: https://github.com/uber-go/zap/pull/912 | ||||
| [#913]: https://github.com/uber-go/zap/pull/913 | ||||
| [#928]: https://github.com/uber-go/zap/pull/928 | ||||
| [#931]: https://github.com/uber-go/zap/pull/931 | ||||
| [#936]: https://github.com/uber-go/zap/pull/936 | ||||
							
								
								
									
										75
									
								
								vendor/go.uber.org/zap/CODE_OF_CONDUCT.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										75
									
								
								vendor/go.uber.org/zap/CODE_OF_CONDUCT.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,75 +0,0 @@ | ||||
| # Contributor Covenant Code of Conduct | ||||
|  | ||||
| ## Our Pledge | ||||
|  | ||||
| In the interest of fostering an open and welcoming environment, we as | ||||
| contributors and maintainers pledge to making participation in our project and | ||||
| our community a harassment-free experience for everyone, regardless of age, | ||||
| body size, disability, ethnicity, gender identity and expression, level of | ||||
| experience, nationality, personal appearance, race, religion, or sexual | ||||
| identity and orientation. | ||||
|  | ||||
| ## Our Standards | ||||
|  | ||||
| Examples of behavior that contributes to creating a positive environment | ||||
| include: | ||||
|  | ||||
| * Using welcoming and inclusive language | ||||
| * Being respectful of differing viewpoints and experiences | ||||
| * Gracefully accepting constructive criticism | ||||
| * Focusing on what is best for the community | ||||
| * Showing empathy towards other community members | ||||
|  | ||||
| Examples of unacceptable behavior by participants include: | ||||
|  | ||||
| * The use of sexualized language or imagery and unwelcome sexual attention or | ||||
|   advances | ||||
| * Trolling, insulting/derogatory comments, and personal or political attacks | ||||
| * Public or private harassment | ||||
| * Publishing others' private information, such as a physical or electronic | ||||
|   address, without explicit permission | ||||
| * Other conduct which could reasonably be considered inappropriate in a | ||||
|   professional setting | ||||
|  | ||||
| ## Our Responsibilities | ||||
|  | ||||
| Project maintainers are responsible for clarifying the standards of acceptable | ||||
| behavior and are expected to take appropriate and fair corrective action in | ||||
| response to any instances of unacceptable behavior. | ||||
|  | ||||
| Project maintainers have the right and responsibility to remove, edit, or | ||||
| reject comments, commits, code, wiki edits, issues, and other contributions | ||||
| that are not aligned to this Code of Conduct, or to ban temporarily or | ||||
| permanently any contributor for other behaviors that they deem inappropriate, | ||||
| threatening, offensive, or harmful. | ||||
|  | ||||
| ## Scope | ||||
|  | ||||
| This Code of Conduct applies both within project spaces and in public spaces | ||||
| when an individual is representing the project or its community. Examples of | ||||
| representing a project or community include using an official project e-mail | ||||
| address, posting via an official social media account, or acting as an | ||||
| appointed representative at an online or offline event. Representation of a | ||||
| project may be further defined and clarified by project maintainers. | ||||
|  | ||||
| ## Enforcement | ||||
|  | ||||
| Instances of abusive, harassing, or otherwise unacceptable behavior may be | ||||
| reported by contacting the project team at oss-conduct@uber.com. The project | ||||
| team will review and investigate all complaints, and will respond in a way | ||||
| that it deems appropriate to the circumstances. The project team is obligated | ||||
| to maintain confidentiality with regard to the reporter of an incident. | ||||
| Further details of specific enforcement policies may be posted separately. | ||||
|  | ||||
| Project maintainers who do not follow or enforce the Code of Conduct in good | ||||
| faith may face temporary or permanent repercussions as determined by other | ||||
| members of the project's leadership. | ||||
|  | ||||
| ## Attribution | ||||
|  | ||||
| This Code of Conduct is adapted from the [Contributor Covenant][homepage], | ||||
| version 1.4, available at | ||||
| [http://contributor-covenant.org/version/1/4][version]. | ||||
|  | ||||
| [homepage]: http://contributor-covenant.org | ||||
| [version]: http://contributor-covenant.org/version/1/4/ | ||||
							
								
								
									
										70
									
								
								vendor/go.uber.org/zap/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										70
									
								
								vendor/go.uber.org/zap/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,70 +0,0 @@ | ||||
| # Contributing | ||||
|  | ||||
| We'd love your help making zap the very best structured logging library in Go! | ||||
|  | ||||
| If you'd like to add new exported APIs, please [open an issue][open-issue] | ||||
| describing your proposal — discussing API changes ahead of time makes | ||||
| pull request review much smoother. In your issue, pull request, and any other | ||||
| communications, please remember to treat your fellow contributors with | ||||
| respect! We take our [code of conduct](CODE_OF_CONDUCT.md) seriously. | ||||
|  | ||||
| Note that you'll need to sign [Uber's Contributor License Agreement][cla] | ||||
| before we can accept any of your contributions. If necessary, a bot will remind | ||||
| you to accept the CLA when you open your pull request. | ||||
|  | ||||
| ## Setup | ||||
|  | ||||
| [Fork][fork], then clone the repository: | ||||
|  | ||||
| ```bash | ||||
| mkdir -p $GOPATH/src/go.uber.org | ||||
| cd $GOPATH/src/go.uber.org | ||||
| git clone git@github.com:your_github_username/zap.git | ||||
| cd zap | ||||
| git remote add upstream https://github.com/uber-go/zap.git | ||||
| git fetch upstream | ||||
| ``` | ||||
|  | ||||
| Make sure that the tests and the linters pass: | ||||
|  | ||||
| ```bash | ||||
| make test | ||||
| make lint | ||||
| ``` | ||||
|  | ||||
| ## Making Changes | ||||
|  | ||||
| Start by creating a new branch for your changes: | ||||
|  | ||||
| ```bash | ||||
| cd $GOPATH/src/go.uber.org/zap | ||||
| git checkout master | ||||
| git fetch upstream | ||||
| git rebase upstream/master | ||||
| git checkout -b cool_new_feature | ||||
| ``` | ||||
|  | ||||
| Make your changes, then ensure that `make lint` and `make test` still pass. If | ||||
| you're satisfied with your changes, push them to your fork. | ||||
|  | ||||
| ```bash | ||||
| git push origin cool_new_feature | ||||
| ``` | ||||
|  | ||||
| Then use the GitHub UI to open a pull request. | ||||
|  | ||||
| At this point, you're waiting on us to review your changes. We _try_ to respond | ||||
| to issues and pull requests within a few business days, and we may suggest some | ||||
| improvements or alternatives. Once your changes are approved, one of the | ||||
| project maintainers will merge them. | ||||
|  | ||||
| We're much more likely to approve your changes if you: | ||||
|  | ||||
| - Add tests for new functionality. | ||||
| - Write a [good commit message][commit-message]. | ||||
| - Maintain backward compatibility. | ||||
|  | ||||
| [fork]: https://github.com/uber-go/zap/fork | ||||
| [open-issue]: https://github.com/uber-go/zap/issues/new | ||||
| [cla]: https://cla-assistant.io/uber-go/zap | ||||
| [commit-message]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html | ||||
							
								
								
									
										164
									
								
								vendor/go.uber.org/zap/FAQ.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										164
									
								
								vendor/go.uber.org/zap/FAQ.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,164 +0,0 @@ | ||||
| # Frequently Asked Questions | ||||
|  | ||||
| ## Design | ||||
|  | ||||
| ### Why spend so much effort on logger performance? | ||||
|  | ||||
| Of course, most applications won't notice the impact of a slow logger: they | ||||
| already take tens or hundreds of milliseconds for each operation, so an extra | ||||
| millisecond doesn't matter. | ||||
|  | ||||
| On the other hand, why *not* make structured logging fast? The `SugaredLogger` | ||||
| isn't any harder to use than other logging packages, and the `Logger` makes | ||||
| structured logging possible in performance-sensitive contexts. Across a fleet | ||||
| of Go microservices, making each application even slightly more efficient adds | ||||
| up quickly. | ||||
|  | ||||
| ### Why aren't `Logger` and `SugaredLogger` interfaces? | ||||
|  | ||||
| Unlike the familiar `io.Writer` and `http.Handler`, `Logger` and | ||||
| `SugaredLogger` interfaces would include *many* methods. As [Rob Pike points | ||||
| out][go-proverbs], "The bigger the interface, the weaker the abstraction." | ||||
| Interfaces are also rigid — *any* change requires releasing a new major | ||||
| version, since it breaks all third-party implementations. | ||||
|  | ||||
| Making the `Logger` and `SugaredLogger` concrete types doesn't sacrifice much | ||||
| abstraction, and it lets us add methods without introducing breaking changes. | ||||
| Your applications should define and depend upon an interface that includes | ||||
| just the methods you use. | ||||
|  | ||||
| ### Why are some of my logs missing? | ||||
|  | ||||
| Logs are dropped intentionally by zap when sampling is enabled. The production | ||||
| configuration (as returned by `NewProductionConfig()` enables sampling which will | ||||
| cause repeated logs within a second to be sampled. See more details on why sampling | ||||
| is enabled in [Why sample application logs](https://github.com/uber-go/zap/blob/master/FAQ.md#why-sample-application-logs). | ||||
|  | ||||
| ### Why sample application logs? | ||||
|  | ||||
| Applications often experience runs of errors, either because of a bug or | ||||
| because of a misbehaving user. Logging errors is usually a good idea, but it | ||||
| can easily make this bad situation worse: not only is your application coping | ||||
| with a flood of errors, it's also spending extra CPU cycles and I/O logging | ||||
| those errors. Since writes are typically serialized, logging limits throughput | ||||
| when you need it most. | ||||
|  | ||||
| Sampling fixes this problem by dropping repetitive log entries. Under normal | ||||
| conditions, your application writes out every entry. When similar entries are | ||||
| logged hundreds or thousands of times each second, though, zap begins dropping | ||||
| duplicates to preserve throughput. | ||||
|  | ||||
| ### Why do the structured logging APIs take a message in addition to fields? | ||||
|  | ||||
| Subjectively, we find it helpful to accompany structured context with a brief | ||||
| description. This isn't critical during development, but it makes debugging | ||||
| and operating unfamiliar systems much easier. | ||||
|  | ||||
| More concretely, zap's sampling algorithm uses the message to identify | ||||
| duplicate entries. In our experience, this is a practical middle ground | ||||
| between random sampling (which often drops the exact entry that you need while | ||||
| debugging) and hashing the complete entry (which is prohibitively expensive). | ||||
|  | ||||
| ### Why include package-global loggers? | ||||
|  | ||||
| Since so many other logging packages include a global logger, many | ||||
| applications aren't designed to accept loggers as explicit parameters. | ||||
| Changing function signatures is often a breaking change, so zap includes | ||||
| global loggers to simplify migration. | ||||
|  | ||||
| Avoid them where possible. | ||||
|  | ||||
| ### Why include dedicated Panic and Fatal log levels? | ||||
|  | ||||
| In general, application code should handle errors gracefully instead of using | ||||
| `panic` or `os.Exit`. However, every rule has exceptions, and it's common to | ||||
| crash when an error is truly unrecoverable. To avoid losing any information | ||||
| — especially the reason for the crash — the logger must flush any | ||||
| buffered entries before the process exits. | ||||
|  | ||||
| Zap makes this easy by offering `Panic` and `Fatal` logging methods that | ||||
| automatically flush before exiting. Of course, this doesn't guarantee that | ||||
| logs will never be lost, but it eliminates a common error. | ||||
|  | ||||
| See the discussion in uber-go/zap#207 for more details. | ||||
|  | ||||
| ### What's `DPanic`? | ||||
|  | ||||
| `DPanic` stands for "panic in development." In development, it logs at | ||||
| `PanicLevel`; otherwise, it logs at `ErrorLevel`. `DPanic` makes it easier to | ||||
| catch errors that are theoretically possible, but shouldn't actually happen, | ||||
| *without* crashing in production. | ||||
|  | ||||
| If you've ever written code like this, you need `DPanic`: | ||||
|  | ||||
| ```go | ||||
| if err != nil { | ||||
|   panic(fmt.Sprintf("shouldn't ever get here: %v", err)) | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ## Installation | ||||
|  | ||||
| ### What does the error `expects import "go.uber.org/zap"` mean? | ||||
|  | ||||
| Either zap was installed incorrectly or you're referencing the wrong package | ||||
| name in your code. | ||||
|  | ||||
| Zap's source code happens to be hosted on GitHub, but the [import | ||||
| path][import-path] is `go.uber.org/zap`. This gives us, the project | ||||
| maintainers, the freedom to move the source code if necessary. However, it | ||||
| means that you need to take a little care when installing and using the | ||||
| package. | ||||
|  | ||||
| If you follow two simple rules, everything should work: install zap with `go | ||||
| get -u go.uber.org/zap`, and always import it in your code with `import | ||||
| "go.uber.org/zap"`. Your code shouldn't contain *any* references to | ||||
| `github.com/uber-go/zap`. | ||||
|  | ||||
| ## Usage | ||||
|  | ||||
| ### Does zap support log rotation? | ||||
|  | ||||
| Zap doesn't natively support rotating log files, since we prefer to leave this | ||||
| to an external program like `logrotate`. | ||||
|  | ||||
| However, it's easy to integrate a log rotation package like | ||||
| [`gopkg.in/natefinch/lumberjack.v2`][lumberjack] as a `zapcore.WriteSyncer`. | ||||
|  | ||||
| ```go | ||||
| // lumberjack.Logger is already safe for concurrent use, so we don't need to | ||||
| // lock it. | ||||
| w := zapcore.AddSync(&lumberjack.Logger{ | ||||
|   Filename:   "/var/log/myapp/foo.log", | ||||
|   MaxSize:    500, // megabytes | ||||
|   MaxBackups: 3, | ||||
|   MaxAge:     28, // days | ||||
| }) | ||||
| core := zapcore.NewCore( | ||||
|   zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), | ||||
|   w, | ||||
|   zap.InfoLevel, | ||||
| ) | ||||
| logger := zap.New(core) | ||||
| ``` | ||||
|  | ||||
| ## Extensions | ||||
|  | ||||
| We'd love to support every logging need within zap itself, but we're only | ||||
| familiar with a handful of log ingestion systems, flag-parsing packages, and | ||||
| the like. Rather than merging code that we can't effectively debug and | ||||
| support, we'd rather grow an ecosystem of zap extensions. | ||||
|  | ||||
| We're aware of the following extensions, but haven't used them ourselves: | ||||
|  | ||||
| | Package | Integration | | ||||
| | --- | --- | | ||||
| | `github.com/tchap/zapext` | Sentry, syslog | | ||||
| | `github.com/fgrosse/zaptest` | Ginkgo | | ||||
| | `github.com/blendle/zapdriver` | Stackdriver | | ||||
| | `github.com/moul/zapgorm` | Gorm | | ||||
| | `github.com/moul/zapfilter` | Advanced filtering rules | | ||||
|  | ||||
| [go-proverbs]: https://go-proverbs.github.io/ | ||||
| [import-path]: https://golang.org/cmd/go/#hdr-Remote_import_paths | ||||
| [lumberjack]: https://godoc.org/gopkg.in/natefinch/lumberjack.v2 | ||||
							
								
								
									
										19
									
								
								vendor/go.uber.org/zap/LICENSE.txt
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/go.uber.org/zap/LICENSE.txt
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,19 +0,0 @@ | ||||
| Copyright (c) 2016-2017 Uber Technologies, Inc. | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in | ||||
| all copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| THE SOFTWARE. | ||||
							
								
								
									
										73
									
								
								vendor/go.uber.org/zap/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										73
									
								
								vendor/go.uber.org/zap/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,73 +0,0 @@ | ||||
| export GOBIN ?= $(shell pwd)/bin | ||||
|  | ||||
| GOLINT = $(GOBIN)/golint | ||||
| STATICCHECK = $(GOBIN)/staticcheck | ||||
| BENCH_FLAGS ?= -cpuprofile=cpu.pprof -memprofile=mem.pprof -benchmem | ||||
|  | ||||
| # Directories containing independent Go modules. | ||||
| # | ||||
| # We track coverage only for the main module. | ||||
| MODULE_DIRS = . ./benchmarks ./zapgrpc/internal/test | ||||
|  | ||||
| # Many Go tools take file globs or directories as arguments instead of packages. | ||||
| GO_FILES := $(shell \ | ||||
| 	find . '(' -path '*/.*' -o -path './vendor' ')' -prune \ | ||||
| 	-o -name '*.go' -print | cut -b3-) | ||||
|  | ||||
| .PHONY: all | ||||
| all: lint test | ||||
|  | ||||
| .PHONY: lint | ||||
| lint: $(GOLINT) $(STATICCHECK) | ||||
| 	@rm -rf lint.log | ||||
| 	@echo "Checking formatting..." | ||||
| 	@gofmt -d -s $(GO_FILES) 2>&1 | tee lint.log | ||||
| 	@echo "Checking vet..." | ||||
| 	@$(foreach dir,$(MODULE_DIRS),(cd $(dir) && go vet ./... 2>&1) &&) true | tee -a lint.log | ||||
| 	@echo "Checking lint..." | ||||
| 	@$(foreach dir,$(MODULE_DIRS),(cd $(dir) && $(GOLINT) ./... 2>&1) &&) true | tee -a lint.log | ||||
| 	@echo "Checking staticcheck..." | ||||
| 	@$(foreach dir,$(MODULE_DIRS),(cd $(dir) && $(STATICCHECK) ./... 2>&1) &&) true | tee -a lint.log | ||||
| 	@echo "Checking for unresolved FIXMEs..." | ||||
| 	@git grep -i fixme | grep -v -e Makefile | tee -a lint.log | ||||
| 	@echo "Checking for license headers..." | ||||
| 	@./checklicense.sh | tee -a lint.log | ||||
| 	@[ ! -s lint.log ] | ||||
| 	@echo "Checking 'go mod tidy'..." | ||||
| 	@make tidy | ||||
| 	@if ! git diff --quiet; then \ | ||||
| 		echo "'go mod tidy' resulted in changes or working tree is dirty:"; \ | ||||
| 		git --no-pager diff; \ | ||||
| 	fi | ||||
|  | ||||
| $(GOLINT): | ||||
| 	cd tools && go install golang.org/x/lint/golint | ||||
|  | ||||
| $(STATICCHECK): | ||||
| 	cd tools && go install honnef.co/go/tools/cmd/staticcheck | ||||
|  | ||||
| .PHONY: test | ||||
| test: | ||||
| 	@$(foreach dir,$(MODULE_DIRS),(cd $(dir) && go test -race ./...) &&) true | ||||
|  | ||||
| .PHONY: cover | ||||
| cover: | ||||
| 	go test -race -coverprofile=cover.out -coverpkg=./... ./... | ||||
| 	go tool cover -html=cover.out -o cover.html | ||||
|  | ||||
| .PHONY: bench | ||||
| BENCH ?= . | ||||
| bench: | ||||
| 	@$(foreach dir,$(MODULE_DIRS), ( \ | ||||
| 		cd $(dir) && \ | ||||
| 		go list ./... | xargs -n1 go test -bench=$(BENCH) -run="^$$" $(BENCH_FLAGS) \ | ||||
| 	) &&) true | ||||
|  | ||||
| .PHONY: updatereadme | ||||
| updatereadme: | ||||
| 	rm -f README.md | ||||
| 	cat .readme.tmpl | go run internal/readme/readme.go > README.md | ||||
|  | ||||
| .PHONY: tidy | ||||
| tidy: | ||||
| 	@$(foreach dir,$(MODULE_DIRS),(cd $(dir) && go mod tidy) &&) true | ||||
							
								
								
									
										133
									
								
								vendor/go.uber.org/zap/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										133
									
								
								vendor/go.uber.org/zap/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,133 +0,0 @@ | ||||
| # :zap: zap [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] | ||||
|  | ||||
| Blazing fast, structured, leveled logging in Go. | ||||
|  | ||||
| ## Installation | ||||
|  | ||||
| `go get -u go.uber.org/zap` | ||||
|  | ||||
| Note that zap only supports the two most recent minor versions of Go. | ||||
|  | ||||
| ## Quick Start | ||||
|  | ||||
| In contexts where performance is nice, but not critical, use the | ||||
| `SugaredLogger`. It's 4-10x faster than other structured logging | ||||
| packages and includes both structured and `printf`-style APIs. | ||||
|  | ||||
| ```go | ||||
| logger, _ := zap.NewProduction() | ||||
| defer logger.Sync() // flushes buffer, if any | ||||
| sugar := logger.Sugar() | ||||
| sugar.Infow("failed to fetch URL", | ||||
|   // Structured context as loosely typed key-value pairs. | ||||
|   "url", url, | ||||
|   "attempt", 3, | ||||
|   "backoff", time.Second, | ||||
| ) | ||||
| sugar.Infof("Failed to fetch URL: %s", url) | ||||
| ``` | ||||
|  | ||||
| When performance and type safety are critical, use the `Logger`. It's even | ||||
| faster than the `SugaredLogger` and allocates far less, but it only supports | ||||
| structured logging. | ||||
|  | ||||
| ```go | ||||
| logger, _ := zap.NewProduction() | ||||
| defer logger.Sync() | ||||
| logger.Info("failed to fetch URL", | ||||
|   // Structured context as strongly typed Field values. | ||||
|   zap.String("url", url), | ||||
|   zap.Int("attempt", 3), | ||||
|   zap.Duration("backoff", time.Second), | ||||
| ) | ||||
| ``` | ||||
|  | ||||
| See the [documentation][doc] and [FAQ](FAQ.md) for more details. | ||||
|  | ||||
| ## Performance | ||||
|  | ||||
| For applications that log in the hot path, reflection-based serialization and | ||||
| string formatting are prohibitively expensive — they're CPU-intensive | ||||
| and make many small allocations. Put differently, using `encoding/json` and | ||||
| `fmt.Fprintf` to log tons of `interface{}`s makes your application slow. | ||||
|  | ||||
| Zap takes a different approach. It includes a reflection-free, zero-allocation | ||||
| JSON encoder, and the base `Logger` strives to avoid serialization overhead | ||||
| and allocations wherever possible. By building the high-level `SugaredLogger` | ||||
| on that foundation, zap lets users _choose_ when they need to count every | ||||
| allocation and when they'd prefer a more familiar, loosely typed API. | ||||
|  | ||||
| As measured by its own [benchmarking suite][], not only is zap more performant | ||||
| than comparable structured logging packages — it's also faster than the | ||||
| standard library. Like all benchmarks, take these with a grain of salt.<sup | ||||
| id="anchor-versions">[1](#footnote-versions)</sup> | ||||
|  | ||||
| Log a message and 10 fields: | ||||
|  | ||||
| | Package             |    Time     | Time % to zap | Objects Allocated | | ||||
| | :------------------ | :---------: | :-----------: | :---------------: | | ||||
| | :zap: zap           | 2900 ns/op  |      +0%      |    5 allocs/op    | | ||||
| | :zap: zap (sugared) | 3475 ns/op  |     +20%      |   10 allocs/op    | | ||||
| | zerolog             | 10639 ns/op |     +267%     |   32 allocs/op    | | ||||
| | go-kit              | 14434 ns/op |     +398%     |   59 allocs/op    | | ||||
| | logrus              | 17104 ns/op |     +490%     |   81 allocs/op    | | ||||
| | apex/log            | 32424 ns/op |    +1018%     |   66 allocs/op    | | ||||
| | log15               | 33579 ns/op |    +1058%     |   76 allocs/op    | | ||||
|  | ||||
| Log a message with a logger that already has 10 fields of context: | ||||
|  | ||||
| | Package             |    Time     | Time % to zap | Objects Allocated | | ||||
| | :------------------ | :---------: | :-----------: | :---------------: | | ||||
| | :zap: zap           |  373 ns/op  |      +0%      |    0 allocs/op    | | ||||
| | :zap: zap (sugared) |  452 ns/op  |     +21%      |    1 allocs/op    | | ||||
| | zerolog             |  288 ns/op  |     -23%      |    0 allocs/op    | | ||||
| | go-kit              | 11785 ns/op |    +3060%     |   58 allocs/op    | | ||||
| | logrus              | 19629 ns/op |    +5162%     |   70 allocs/op    | | ||||
| | log15               | 21866 ns/op |    +5762%     |   72 allocs/op    | | ||||
| | apex/log            | 30890 ns/op |    +8182%     |   55 allocs/op    | | ||||
|  | ||||
| Log a static string, without any context or `printf`-style templating: | ||||
|  | ||||
| | Package             |    Time    | Time % to zap | Objects Allocated | | ||||
| | :------------------ | :--------: | :-----------: | :---------------: | | ||||
| | :zap: zap           | 381 ns/op  |      +0%      |    0 allocs/op    | | ||||
| | :zap: zap (sugared) | 410 ns/op  |      +8%      |    1 allocs/op    | | ||||
| | zerolog             | 369 ns/op  |      -3%      |    0 allocs/op    | | ||||
| | standard library    | 385 ns/op  |      +1%      |    2 allocs/op    | | ||||
| | go-kit              | 606 ns/op  |     +59%      |   11 allocs/op    | | ||||
| | logrus              | 1730 ns/op |     +354%     |   25 allocs/op    | | ||||
| | apex/log            | 1998 ns/op |     +424%     |    7 allocs/op    | | ||||
| | log15               | 4546 ns/op |    +1093%     |   22 allocs/op    | | ||||
|  | ||||
| ## Development Status: Stable | ||||
|  | ||||
| All APIs are finalized, and no breaking changes will be made in the 1.x series | ||||
| of releases. Users of semver-aware dependency management systems should pin | ||||
| zap to `^1`. | ||||
|  | ||||
| ## Contributing | ||||
|  | ||||
| We encourage and support an active, healthy community of contributors — | ||||
| including you! Details are in the [contribution guide](CONTRIBUTING.md) and | ||||
| the [code of conduct](CODE_OF_CONDUCT.md). The zap maintainers keep an eye on | ||||
| issues and pull requests, but you can also report any negative conduct to | ||||
| oss-conduct@uber.com. That email list is a private, safe space; even the zap | ||||
| maintainers don't have access, so don't hesitate to hold us to a high | ||||
| standard. | ||||
|  | ||||
| <hr> | ||||
|  | ||||
| Released under the [MIT License](LICENSE.txt). | ||||
|  | ||||
| <sup id="footnote-versions">1</sup> In particular, keep in mind that we may be | ||||
| benchmarking against slightly older versions of other packages. Versions are | ||||
| pinned in the [benchmarks/go.mod][] file. [↩](#anchor-versions) | ||||
|  | ||||
| [doc-img]: https://pkg.go.dev/badge/go.uber.org/zap | ||||
| [doc]: https://pkg.go.dev/go.uber.org/zap | ||||
| [ci-img]: https://github.com/uber-go/zap/actions/workflows/go.yml/badge.svg | ||||
| [ci]: https://github.com/uber-go/zap/actions/workflows/go.yml | ||||
| [cov-img]: https://codecov.io/gh/uber-go/zap/branch/master/graph/badge.svg | ||||
| [cov]: https://codecov.io/gh/uber-go/zap | ||||
| [benchmarking suite]: https://github.com/uber-go/zap/tree/master/benchmarks | ||||
| [benchmarks/go.mod]: https://github.com/uber-go/zap/blob/master/benchmarks/go.mod | ||||
							
								
								
									
										320
									
								
								vendor/go.uber.org/zap/array.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										320
									
								
								vendor/go.uber.org/zap/array.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,320 +0,0 @@ | ||||
| // Copyright (c) 2016 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package zap | ||||
|  | ||||
| import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"go.uber.org/zap/zapcore" | ||||
| ) | ||||
|  | ||||
| // Array constructs a field with the given key and ArrayMarshaler. It provides | ||||
| // a flexible, but still type-safe and efficient, way to add array-like types | ||||
| // to the logging context. The struct's MarshalLogArray method is called lazily. | ||||
| func Array(key string, val zapcore.ArrayMarshaler) Field { | ||||
| 	return Field{Key: key, Type: zapcore.ArrayMarshalerType, Interface: val} | ||||
| } | ||||
|  | ||||
| // Bools constructs a field that carries a slice of bools. | ||||
| func Bools(key string, bs []bool) Field { | ||||
| 	return Array(key, bools(bs)) | ||||
| } | ||||
|  | ||||
| // ByteStrings constructs a field that carries a slice of []byte, each of which | ||||
| // must be UTF-8 encoded text. | ||||
| func ByteStrings(key string, bss [][]byte) Field { | ||||
| 	return Array(key, byteStringsArray(bss)) | ||||
| } | ||||
|  | ||||
| // Complex128s constructs a field that carries a slice of complex numbers. | ||||
| func Complex128s(key string, nums []complex128) Field { | ||||
| 	return Array(key, complex128s(nums)) | ||||
| } | ||||
|  | ||||
| // Complex64s constructs a field that carries a slice of complex numbers. | ||||
| func Complex64s(key string, nums []complex64) Field { | ||||
| 	return Array(key, complex64s(nums)) | ||||
| } | ||||
|  | ||||
| // Durations constructs a field that carries a slice of time.Durations. | ||||
| func Durations(key string, ds []time.Duration) Field { | ||||
| 	return Array(key, durations(ds)) | ||||
| } | ||||
|  | ||||
| // Float64s constructs a field that carries a slice of floats. | ||||
| func Float64s(key string, nums []float64) Field { | ||||
| 	return Array(key, float64s(nums)) | ||||
| } | ||||
|  | ||||
| // Float32s constructs a field that carries a slice of floats. | ||||
| func Float32s(key string, nums []float32) Field { | ||||
| 	return Array(key, float32s(nums)) | ||||
| } | ||||
|  | ||||
| // Ints constructs a field that carries a slice of integers. | ||||
| func Ints(key string, nums []int) Field { | ||||
| 	return Array(key, ints(nums)) | ||||
| } | ||||
|  | ||||
| // Int64s constructs a field that carries a slice of integers. | ||||
| func Int64s(key string, nums []int64) Field { | ||||
| 	return Array(key, int64s(nums)) | ||||
| } | ||||
|  | ||||
| // Int32s constructs a field that carries a slice of integers. | ||||
| func Int32s(key string, nums []int32) Field { | ||||
| 	return Array(key, int32s(nums)) | ||||
| } | ||||
|  | ||||
| // Int16s constructs a field that carries a slice of integers. | ||||
| func Int16s(key string, nums []int16) Field { | ||||
| 	return Array(key, int16s(nums)) | ||||
| } | ||||
|  | ||||
| // Int8s constructs a field that carries a slice of integers. | ||||
| func Int8s(key string, nums []int8) Field { | ||||
| 	return Array(key, int8s(nums)) | ||||
| } | ||||
|  | ||||
| // Strings constructs a field that carries a slice of strings. | ||||
| func Strings(key string, ss []string) Field { | ||||
| 	return Array(key, stringArray(ss)) | ||||
| } | ||||
|  | ||||
| // Times constructs a field that carries a slice of time.Times. | ||||
| func Times(key string, ts []time.Time) Field { | ||||
| 	return Array(key, times(ts)) | ||||
| } | ||||
|  | ||||
| // Uints constructs a field that carries a slice of unsigned integers. | ||||
| func Uints(key string, nums []uint) Field { | ||||
| 	return Array(key, uints(nums)) | ||||
| } | ||||
|  | ||||
| // Uint64s constructs a field that carries a slice of unsigned integers. | ||||
| func Uint64s(key string, nums []uint64) Field { | ||||
| 	return Array(key, uint64s(nums)) | ||||
| } | ||||
|  | ||||
| // Uint32s constructs a field that carries a slice of unsigned integers. | ||||
| func Uint32s(key string, nums []uint32) Field { | ||||
| 	return Array(key, uint32s(nums)) | ||||
| } | ||||
|  | ||||
| // Uint16s constructs a field that carries a slice of unsigned integers. | ||||
| func Uint16s(key string, nums []uint16) Field { | ||||
| 	return Array(key, uint16s(nums)) | ||||
| } | ||||
|  | ||||
| // Uint8s constructs a field that carries a slice of unsigned integers. | ||||
| func Uint8s(key string, nums []uint8) Field { | ||||
| 	return Array(key, uint8s(nums)) | ||||
| } | ||||
|  | ||||
| // Uintptrs constructs a field that carries a slice of pointer addresses. | ||||
| func Uintptrs(key string, us []uintptr) Field { | ||||
| 	return Array(key, uintptrs(us)) | ||||
| } | ||||
|  | ||||
| // Errors constructs a field that carries a slice of errors. | ||||
| func Errors(key string, errs []error) Field { | ||||
| 	return Array(key, errArray(errs)) | ||||
| } | ||||
|  | ||||
| type bools []bool | ||||
|  | ||||
| func (bs bools) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range bs { | ||||
| 		arr.AppendBool(bs[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type byteStringsArray [][]byte | ||||
|  | ||||
| func (bss byteStringsArray) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range bss { | ||||
| 		arr.AppendByteString(bss[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type complex128s []complex128 | ||||
|  | ||||
| func (nums complex128s) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendComplex128(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type complex64s []complex64 | ||||
|  | ||||
| func (nums complex64s) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendComplex64(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type durations []time.Duration | ||||
|  | ||||
| func (ds durations) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range ds { | ||||
| 		arr.AppendDuration(ds[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type float64s []float64 | ||||
|  | ||||
| func (nums float64s) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendFloat64(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type float32s []float32 | ||||
|  | ||||
| func (nums float32s) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendFloat32(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type ints []int | ||||
|  | ||||
| func (nums ints) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendInt(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type int64s []int64 | ||||
|  | ||||
| func (nums int64s) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendInt64(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type int32s []int32 | ||||
|  | ||||
| func (nums int32s) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendInt32(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type int16s []int16 | ||||
|  | ||||
| func (nums int16s) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendInt16(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type int8s []int8 | ||||
|  | ||||
| func (nums int8s) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendInt8(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type stringArray []string | ||||
|  | ||||
| func (ss stringArray) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range ss { | ||||
| 		arr.AppendString(ss[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type times []time.Time | ||||
|  | ||||
| func (ts times) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range ts { | ||||
| 		arr.AppendTime(ts[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type uints []uint | ||||
|  | ||||
| func (nums uints) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendUint(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type uint64s []uint64 | ||||
|  | ||||
| func (nums uint64s) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendUint64(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type uint32s []uint32 | ||||
|  | ||||
| func (nums uint32s) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendUint32(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type uint16s []uint16 | ||||
|  | ||||
| func (nums uint16s) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendUint16(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type uint8s []uint8 | ||||
|  | ||||
| func (nums uint8s) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendUint8(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type uintptrs []uintptr | ||||
|  | ||||
| func (nums uintptrs) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range nums { | ||||
| 		arr.AppendUintptr(nums[i]) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										156
									
								
								vendor/go.uber.org/zap/array_go118.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										156
									
								
								vendor/go.uber.org/zap/array_go118.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,156 +0,0 @@ | ||||
| // Copyright (c) 2022 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| //go:build go1.18 | ||||
| // +build go1.18 | ||||
|  | ||||
| package zap | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"go.uber.org/zap/zapcore" | ||||
| ) | ||||
|  | ||||
| // Objects constructs a field with the given key, holding a list of the | ||||
| // provided objects that can be marshaled by Zap. | ||||
| // | ||||
| // Note that these objects must implement zapcore.ObjectMarshaler directly. | ||||
| // That is, if you're trying to marshal a []Request, the MarshalLogObject | ||||
| // method must be declared on the Request type, not its pointer (*Request). | ||||
| // If it's on the pointer, use ObjectValues. | ||||
| // | ||||
| // Given an object that implements MarshalLogObject on the value receiver, you | ||||
| // can log a slice of those objects with Objects like so: | ||||
| // | ||||
| //	type Author struct{ ... } | ||||
| //	func (a Author) MarshalLogObject(enc zapcore.ObjectEncoder) error | ||||
| // | ||||
| //	var authors []Author = ... | ||||
| //	logger.Info("loading article", zap.Objects("authors", authors)) | ||||
| // | ||||
| // Similarly, given a type that implements MarshalLogObject on its pointer | ||||
| // receiver, you can log a slice of pointers to that object with Objects like | ||||
| // so: | ||||
| // | ||||
| //	type Request struct{ ... } | ||||
| //	func (r *Request) MarshalLogObject(enc zapcore.ObjectEncoder) error | ||||
| // | ||||
| //	var requests []*Request = ... | ||||
| //	logger.Info("sending requests", zap.Objects("requests", requests)) | ||||
| // | ||||
| // If instead, you have a slice of values of such an object, use the | ||||
| // ObjectValues constructor. | ||||
| // | ||||
| //	var requests []Request = ... | ||||
| //	logger.Info("sending requests", zap.ObjectValues("requests", requests)) | ||||
| func Objects[T zapcore.ObjectMarshaler](key string, values []T) Field { | ||||
| 	return Array(key, objects[T](values)) | ||||
| } | ||||
|  | ||||
| type objects[T zapcore.ObjectMarshaler] []T | ||||
|  | ||||
| func (os objects[T]) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for _, o := range os { | ||||
| 		if err := arr.AppendObject(o); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // objectMarshalerPtr is a constraint that specifies that the given type | ||||
| // implements zapcore.ObjectMarshaler on a pointer receiver. | ||||
| type objectMarshalerPtr[T any] interface { | ||||
| 	*T | ||||
| 	zapcore.ObjectMarshaler | ||||
| } | ||||
|  | ||||
| // ObjectValues constructs a field with the given key, holding a list of the | ||||
| // provided objects, where pointers to these objects can be marshaled by Zap. | ||||
| // | ||||
| // Note that pointers to these objects must implement zapcore.ObjectMarshaler. | ||||
| // That is, if you're trying to marshal a []Request, the MarshalLogObject | ||||
| // method must be declared on the *Request type, not the value (Request). | ||||
| // If it's on the value, use Objects. | ||||
| // | ||||
| // Given an object that implements MarshalLogObject on the pointer receiver, | ||||
| // you can log a slice of those objects with ObjectValues like so: | ||||
| // | ||||
| //	type Request struct{ ... } | ||||
| //	func (r *Request) MarshalLogObject(enc zapcore.ObjectEncoder) error | ||||
| // | ||||
| //	var requests []Request = ... | ||||
| //	logger.Info("sending requests", zap.ObjectValues("requests", requests)) | ||||
| // | ||||
| // If instead, you have a slice of pointers of such an object, use the Objects | ||||
| // field constructor. | ||||
| // | ||||
| //	var requests []*Request = ... | ||||
| //	logger.Info("sending requests", zap.Objects("requests", requests)) | ||||
| func ObjectValues[T any, P objectMarshalerPtr[T]](key string, values []T) Field { | ||||
| 	return Array(key, objectValues[T, P](values)) | ||||
| } | ||||
|  | ||||
| type objectValues[T any, P objectMarshalerPtr[T]] []T | ||||
|  | ||||
| func (os objectValues[T, P]) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for i := range os { | ||||
| 		// It is necessary for us to explicitly reference the "P" type. | ||||
| 		// We cannot simply pass "&os[i]" to AppendObject because its type | ||||
| 		// is "*T", which the type system does not consider as | ||||
| 		// implementing ObjectMarshaler. | ||||
| 		// Only the type "P" satisfies ObjectMarshaler, which we have | ||||
| 		// to convert "*T" to explicitly. | ||||
| 		var p P = &os[i] | ||||
| 		if err := arr.AppendObject(p); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Stringers constructs a field with the given key, holding a list of the | ||||
| // output provided by the value's String method | ||||
| // | ||||
| // Given an object that implements String on the value receiver, you | ||||
| // can log a slice of those objects with Objects like so: | ||||
| // | ||||
| //	type Request struct{ ... } | ||||
| //	func (a Request) String() string | ||||
| // | ||||
| //	var requests []Request = ... | ||||
| //	logger.Info("sending requests", zap.Stringers("requests", requests)) | ||||
| // | ||||
| // Note that these objects must implement fmt.Stringer directly. | ||||
| // That is, if you're trying to marshal a []Request, the String method | ||||
| // must be declared on the Request type, not its pointer (*Request). | ||||
| func Stringers[T fmt.Stringer](key string, values []T) Field { | ||||
| 	return Array(key, stringers[T](values)) | ||||
| } | ||||
|  | ||||
| type stringers[T fmt.Stringer] []T | ||||
|  | ||||
| func (os stringers[T]) MarshalLogArray(arr zapcore.ArrayEncoder) error { | ||||
| 	for _, o := range os { | ||||
| 		arr.AppendString(o.String()) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										141
									
								
								vendor/go.uber.org/zap/buffer/buffer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										141
									
								
								vendor/go.uber.org/zap/buffer/buffer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,141 +0,0 @@ | ||||
| // Copyright (c) 2016 Uber Technologies, Inc. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| // Package buffer provides a thin wrapper around a byte slice. Unlike the | ||||
| // standard library's bytes.Buffer, it supports a portion of the strconv | ||||
| // package's zero-allocation formatters. | ||||
| package buffer // import "go.uber.org/zap/buffer" | ||||
|  | ||||
| import ( | ||||
| 	"strconv" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| const _size = 1024 // by default, create 1 KiB buffers | ||||
|  | ||||
| // Buffer is a thin wrapper around a byte slice. It's intended to be pooled, so | ||||
| // the only way to construct one is via a Pool. | ||||
| type Buffer struct { | ||||
| 	bs   []byte | ||||
| 	pool Pool | ||||
| } | ||||
|  | ||||
| // AppendByte writes a single byte to the Buffer. | ||||
| func (b *Buffer) AppendByte(v byte) { | ||||
| 	b.bs = append(b.bs, v) | ||||
| } | ||||
|  | ||||
| // AppendString writes a string to the Buffer. | ||||
| func (b *Buffer) AppendString(s string) { | ||||
| 	b.bs = append(b.bs, s...) | ||||
| } | ||||
|  | ||||
| // AppendInt appends an integer to the underlying buffer (assuming base 10). | ||||
| func (b *Buffer) AppendInt(i int64) { | ||||
| 	b.bs = strconv.AppendInt(b.bs, i, 10) | ||||
| } | ||||
|  | ||||
| // AppendTime appends the time formatted using the specified layout. | ||||
| func (b *Buffer) AppendTime(t time.Time, layout string) { | ||||
| 	b.bs = t.AppendFormat(b.bs, layout) | ||||
| } | ||||
|  | ||||
| // AppendUint appends an unsigned integer to the underlying buffer (assuming | ||||
| // base 10). | ||||
| func (b *Buffer) AppendUint(i uint64) { | ||||
| 	b.bs = strconv.AppendUint(b.bs, i, 10) | ||||
| } | ||||
|  | ||||
| // AppendBool appends a bool to the underlying buffer. | ||||
| func (b *Buffer) AppendBool(v bool) { | ||||
| 	b.bs = strconv.AppendBool(b.bs, v) | ||||
| } | ||||
|  | ||||
| // AppendFloat appends a float to the underlying buffer. It doesn't quote NaN | ||||
| // or +/- Inf. | ||||
| func (b *Buffer) AppendFloat(f float64, bitSize int) { | ||||
| 	b.bs = strconv.AppendFloat(b.bs, f, 'f', -1, bitSize) | ||||
| } | ||||
|  | ||||
| // Len returns the length of the underlying byte slice. | ||||
| func (b *Buffer) Len() int { | ||||
| 	return len(b.bs) | ||||
| } | ||||
|  | ||||
| // Cap returns the capacity of the underlying byte slice. | ||||
| func (b *Buffer) Cap() int { | ||||
| 	return cap(b.bs) | ||||
| } | ||||
|  | ||||
| // Bytes returns a mutable reference to the underlying byte slice. | ||||
| func (b *Buffer) Bytes() []byte { | ||||
| 	return b.bs | ||||
| } | ||||
|  | ||||
| // String returns a string copy of the underlying byte slice. | ||||
| func (b *Buffer) String() string { | ||||
| 	return string(b.bs) | ||||
| } | ||||
|  | ||||
| // Reset resets the underlying byte slice. Subsequent writes re-use the slice's | ||||
| // backing array. | ||||
| func (b *Buffer) Reset() { | ||||
| 	b.bs = b.bs[:0] | ||||
| } | ||||
|  | ||||
| // Write implements io.Writer. | ||||
| func (b *Buffer) Write(bs []byte) (int, error) { | ||||
| 	b.bs = append(b.bs, bs...) | ||||
| 	return len(bs), nil | ||||
| } | ||||
|  | ||||
| // WriteByte writes a single byte to the Buffer. | ||||
| // | ||||
| // Error returned is always nil, function signature is compatible | ||||
| // with bytes.Buffer and bufio.Writer | ||||
| func (b *Buffer) WriteByte(v byte) error { | ||||
| 	b.AppendByte(v) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // WriteString writes a string to the Buffer. | ||||
| // | ||||
| // Error returned is always nil, function signature is compatible | ||||
| // with bytes.Buffer and bufio.Writer | ||||
| func (b *Buffer) WriteString(s string) (int, error) { | ||||
| 	b.AppendString(s) | ||||
| 	return len(s), nil | ||||
| } | ||||
|  | ||||
| // TrimNewline trims any final "\n" byte from the end of the buffer. | ||||
| func (b *Buffer) TrimNewline() { | ||||
| 	if i := len(b.bs) - 1; i >= 0 { | ||||
| 		if b.bs[i] == '\n' { | ||||
| 			b.bs = b.bs[:i] | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Free returns the Buffer to its Pool. | ||||
| // | ||||
| // Callers must not retain references to the Buffer after calling Free. | ||||
| func (b *Buffer) Free() { | ||||
| 	b.pool.put(b) | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user