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 | package logmower | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"log" | ||||||
| 	"fmt" |  | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
|  | 	ms "git.k-space.ee/k-space/logmower-shipper/pkg/mongoStruct" | ||||||
| 	prom "github.com/prometheus/client_golang/prometheus" | 	prom "github.com/prometheus/client_golang/prometheus" | ||||||
| 	"github.com/prometheus/client_golang/prometheus/promauto" | 	"github.com/prometheus/client_golang/prometheus/promauto" | ||||||
| 	"go.uber.org/zap" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var promRecordDroppedTooLarge = promauto.NewCounterVec(prom.CounterOpts{ | ||||||
| 	promRecordPrefixParsingErr = promauto.NewCounterVec(prom.CounterOpts{ | 	Namespace: PrometheusPrefix, | ||||||
| 		Namespace: PrometheusPrefix, | 	// Subsystem: "record", | ||||||
| 		Subsystem: "record", | 	Name: "dropped_lines", // "dropped", | ||||||
| 		Name:      "parsing_errors", | 	Help: "Records dropped due to being too large", | ||||||
| 		Help:      "Errors while parsing log line prefixes", | }, []string{"filename"}) | ||||||
| 	}, []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"}) |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type ( | type ( | ||||||
| 	rawLine struct { | 	RawLines <-chan RawLine | ||||||
| 		RecordMetadata | 	RawLine  struct { | ||||||
| 		line []byte | 		*file | ||||||
| 	} | 		Offset int64 | ||||||
|  | 		B      []byte | ||||||
| 	singleLine struct { |  | ||||||
| 		mLog |  | ||||||
| 		line      []byte |  | ||||||
| 		isPartial bool // P or F |  | ||||||
| 	} | 	} | ||||||
| ) | ) | ||||||
|  |  | ||||||
| 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 | // 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) | 	lines := make(chan singleLine) | ||||||
| 	go s.parseContainerLogLines(unparsed, lines) | 	go unparsed.parse(lines) | ||||||
|  |  | ||||||
| 	var wg sync.WaitGroup | 	var wg sync.WaitGroup | ||||||
| 	wg.Add(2) | 	wg.Add(2) | ||||||
|  |  | ||||||
| 	stdOut, stdErr := make(chan singleLine), make(chan singleLine) | 	stdOut, stdErr := make(chan singleLine), make(chan singleLine) | ||||||
| 	go func() { | 	go func() { | ||||||
| 		s.parseStdChannel(bufferLimitBytes, stdOut, parsed) | 		singleLines(stdOut).process(bufferLimitBytes, parsed) | ||||||
| 		wg.Done() | 		wg.Done() | ||||||
| 	}() | 	}() | ||||||
| 	go func() { | 	go func() { | ||||||
| 		s.parseStdChannel(bufferLimitBytes, stdErr, parsed) | 		singleLines(stdErr).process(bufferLimitBytes, parsed) | ||||||
| 		wg.Done() | 		wg.Done() | ||||||
| 	}() | 	}() | ||||||
|  |  | ||||||
| @@ -118,58 +62,42 @@ func (s *submitter) parseLines(bufferLimitBytes int, unparsed <-chan rawLine, pa | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // partial is ended with full | func (lines singleLines) process(bufferLimitBytes int, parsed chan<- ms.Record) { | ||||||
|  | 	var firstMetadata *ms.ParsedMetadata | ||||||
| func (s *submitter) parseStdChannel(bufferLimitBytes int, lines <-chan singleLine, parsed chan<- mLog) { |  | ||||||
| 	var firstTime time.Time |  | ||||||
| 	var buffer []byte | 	var buffer []byte | ||||||
|  |  | ||||||
| 	flush := func(last *mLog) { |  | ||||||
| 		parsed <- mLog{ |  | ||||||
| 			RecordMetadata: last.RecordMetadata, |  | ||||||
| 			StdErr:         last.StdErr, |  | ||||||
|  |  | ||||||
| 			ContainerTime: firstTime, |  | ||||||
| 			Content:       parseRecord(buffer), |  | ||||||
| 		} |  | ||||||
| 		buffer = nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for { | 	for { | ||||||
| 		line, ok := <-lines | 		line, ok := <-lines | ||||||
| 		if !ok { | 		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 | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if len(buffer) == 0 { | 		if len(buffer) == 0 { | ||||||
| 			firstTime = line.ContainerTime | 			firstMetadata = &line.ParsedMetadata | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		buffer = append(buffer, line.line...) | 		buffer = append(buffer, line.B...) | ||||||
|  |  | ||||||
| 		if len(buffer) > bufferLimitBytes { | 		if len(buffer) > bufferLimitBytes { | ||||||
|  | 			promRecordDroppedTooLarge.WithLabelValues(line.metricsName).Add(1) | ||||||
|  | 			log.Printf("dropped record: size in bytes exceeds limit of %d", bufferLimitBytes) | ||||||
|  |  | ||||||
| 			buffer = nil | 			buffer = nil | ||||||
| 			promRecordDroppedTooLarge.WithLabelValues(line.File).Add(1) |  | ||||||
| 			s.l.Warn("dropped record: too large", zap.Int("cap_bytes", bufferLimitBytes)) |  | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if !line.isPartial { | 		if !line.partial { | ||||||
| 			flush(&line.mLog) | 			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 ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"fmt" | ||||||
|  | 	"log" | ||||||
|  | 	"net/url" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	ms "git.k-space.ee/k-space/logmower-shipper/pkg/mongoStruct" | ||||||
| 	prom "github.com/prometheus/client_golang/prometheus" | 	prom "github.com/prometheus/client_golang/prometheus" | ||||||
| 	"github.com/prometheus/client_golang/prometheus/promauto" | 	"github.com/prometheus/client_golang/prometheus/promauto" | ||||||
| 	mongoEvent "go.mongodb.org/mongo-driver/event" | 	mongoEvent "go.mongodb.org/mongo-driver/event" | ||||||
|  | 	"go.mongodb.org/mongo-driver/mongo" | ||||||
| 	mongoOpt "go.mongodb.org/mongo-driver/mongo/options" | 	mongoOpt "go.mongodb.org/mongo-driver/mongo/options" | ||||||
| 	"go.uber.org/zap" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| @@ -36,7 +40,7 @@ var ( | |||||||
| 	}, []string{"connection_id", "command_name"}) | 	}, []string{"connection_id", "command_name"}) | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func mongoMonitoredClientOptions(l *zap.Logger) *mongoOpt.ClientOptions { | func mongoMonitoredClientOptions() *mongoOpt.ClientOptions { | ||||||
| 	return mongoOpt.Client(). | 	return mongoOpt.Client(). | ||||||
| 		SetServerMonitor(&mongoEvent.ServerMonitor{ | 		SetServerMonitor(&mongoEvent.ServerMonitor{ | ||||||
| 			ServerHeartbeatSucceeded: func(ev *mongoEvent.ServerHeartbeatSucceededEvent) { | 			ServerHeartbeatSucceeded: func(ev *mongoEvent.ServerHeartbeatSucceededEvent) { | ||||||
| @@ -44,7 +48,7 @@ func mongoMonitoredClientOptions(l *zap.Logger) *mongoOpt.ClientOptions { | |||||||
| 			}, | 			}, | ||||||
| 			ServerHeartbeatFailed: func(ev *mongoEvent.ServerHeartbeatFailedEvent) { | 			ServerHeartbeatFailed: func(ev *mongoEvent.ServerHeartbeatFailedEvent) { | ||||||
| 				promDbHeartbeat.WithLabelValues(ev.ConnectionID).Observe(0) | 				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{ | 		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 ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"path/filepath" | 	"log" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	ms "git.k-space.ee/k-space/logmower-shipper/pkg/mongoStruct" | ||||||
| 	"github.com/jtagcat/util" | 	"github.com/jtagcat/util" | ||||||
| 	prom "github.com/prometheus/client_golang/prometheus" | 	prom "github.com/prometheus/client_golang/prometheus" | ||||||
| 	"github.com/prometheus/client_golang/prometheus/promauto" | 	"github.com/prometheus/client_golang/prometheus/promauto" | ||||||
| 	"go.uber.org/zap" | 	"go.mongodb.org/mongo-driver/mongo" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| @@ -50,20 +51,20 @@ const ( | |||||||
| 	MaxBatchTime  = 5 * time.Second | 	MaxBatchTime  = 5 * time.Second | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func (s *submitter) sender(name string, sendQueue <-chan mLog) { | type queueT <-chan ms.Record | ||||||
| 	baseName := filepath.Base(name) |  | ||||||
|  |  | ||||||
| 	batched := make(chan []mLog) | func (queue queueT) sender(db *mongo.Collection, metricsFilename string) { | ||||||
|  | 	batched := make(chan []ms.Record) | ||||||
|  |  | ||||||
|  | 	// batcher and queue metrics | ||||||
| 	go func() { | 	go func() { | ||||||
| 		ctx, cancel := context.WithCancel(context.Background()) | 		ctx, cancel := context.WithCancel(context.Background()) | ||||||
| 		defer cancel() | 		defer cancel() | ||||||
|  |  | ||||||
| 		go func() { | 		go func() { | ||||||
| 			baseName := filepath.Base(name) |  | ||||||
| 			for { | 			for { | ||||||
| 				promShipperQueued.WithLabelValues(baseName).Set(float64( | 				promShipperQueued.WithLabelValues(metricsFilename).Set(float64( | ||||||
| 					len(sendQueue))) | 					len(queue))) | ||||||
|  |  | ||||||
| 				timer := time.NewTimer(time.Second) | 				timer := time.NewTimer(time.Second) | ||||||
| 				select { | 				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 | 		// returns when sendQueue is closed | ||||||
| 	}() | 	}() | ||||||
|  |  | ||||||
| 	s.Add(1) |  | ||||||
| 	defer s.Done() |  | ||||||
|  |  | ||||||
| 	for { | 	for { | ||||||
| 		promShipperSynced.WithLabelValues(baseName).Set(1) | 		promShipperSynced.WithLabelValues(metricsFilename).Set(1) | ||||||
|  |  | ||||||
| 		batch, ok := <-batched | 		batch, ok := <-batched | ||||||
| 		if !ok { | 		if !ok { | ||||||
| @@ -90,21 +88,21 @@ func (s *submitter) sender(name string, sendQueue <-chan mLog) { | |||||||
| 		} | 		} | ||||||
| 		promShipperBatchSizeResult.Observe(float64(len(batch))) | 		promShipperBatchSizeResult.Observe(float64(len(batch))) | ||||||
|  |  | ||||||
| 		promShipperSynced.WithLabelValues(baseName).Set(0) | 		promShipperSynced.WithLabelValues(metricsFilename).Set(0) | ||||||
|  |  | ||||||
| 		var batchBson []interface{} // mongo does not like typing | 		var batchBson []interface{} // mongo does not like typing | ||||||
| 		for _, b := range batch { | 		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 { | 		if err != nil { | ||||||
| 			promShipperDbSendError.WithLabelValues(baseName).Add(1) | 			promShipperDbSendError.WithLabelValues(metricsFilename).Add(1) | ||||||
| 			s.l.Error("submission to database", zap.Error(err)) // TODO: add some selective retry here or something | 			log.Printf("failure in batch submit to database: %e", err) // TODO: add some selective retry here or something, better error handling | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		promShipperDbSent.WithLabelValues(baseName).Add(float64( | 		promShipperDbSent.WithLabelValues(metricsFilename).Add(float64( | ||||||
| 			len(result.InsertedIDs))) | 			len(result.InsertedIDs))) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,18 +5,17 @@ import ( | |||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
|  | 	"log" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" |  | ||||||
| 	"sync" |  | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	ms "git.k-space.ee/k-space/logmower-shipper/pkg/mongoStruct" | ||||||
| 	"github.com/jtagcat/util" | 	"github.com/jtagcat/util" | ||||||
| 	prom "github.com/prometheus/client_golang/prometheus" | 	prom "github.com/prometheus/client_golang/prometheus" | ||||||
| 	"github.com/prometheus/client_golang/prometheus/promauto" | 	"github.com/prometheus/client_golang/prometheus/promauto" | ||||||
| 	"go.mongodb.org/mongo-driver/bson" | 	"go.mongodb.org/mongo-driver/bson" | ||||||
| 	"go.mongodb.org/mongo-driver/mongo" | 	"go.mongodb.org/mongo-driver/mongo" | ||||||
| 	mongoOpt "go.mongodb.org/mongo-driver/mongo/options" | 	mongoOpt "go.mongodb.org/mongo-driver/mongo/options" | ||||||
| 	"go.uber.org/zap" |  | ||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -48,49 +47,43 @@ var ( | |||||||
| 	}, []string{"filename"}) | 	}, []string{"filename"}) | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type ( |  | ||||||
| 	submitter struct { |  | ||||||
| 		l *zap.Logger |  | ||||||
|  |  | ||||||
| 		hostInfo HostInfo |  | ||||||
| 		db       *mongo.Collection |  | ||||||
|  |  | ||||||
| 		sync.WaitGroup |  | ||||||
| 	} |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| const SendQueueLimit = 1024 | const SendQueueLimit = 1024 | ||||||
|  |  | ||||||
| // TODO: caller may call duplicate shipFile of same name on file replace; sends might not work properly | type file struct { | ||||||
| func (s *submitter) shipFile(ctx context.Context, name string, recordLimitBytes int) { | 	ms.File | ||||||
| 	baseName := filepath.Base(name) | 	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) | 	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) | 	waitGo := util.GoWg(func() { | ||||||
|  | 		queueT(dbQueue).sender(db, f.metricsName) | ||||||
| 	go s.sender(name, sendChan) | 	}) | ||||||
|  | 	defer waitGo() | ||||||
|  |  | ||||||
| 	// TODO: better way to kill or wait for sendQueue before retrying (or duplicates?) | 	// TODO: better way to kill or wait for sendQueue before retrying (or duplicates?) | ||||||
| 	_ = wait.ManagedExponentialBackoffWithContext(ctx, defaultBackoff(), func() (done bool, _ error) { | 	_ = wait.ManagedExponentialBackoffWithContext(ctx, defaultBackoff(), func() (done bool, _ error) { | ||||||
| 		// | 		err := f.trySubmit(ctx, db, lineChan) | ||||||
| 		err := s.shipFileRoutine(ctx, name, lineChan) |  | ||||||
| 		if err == nil { | 		if err == nil { | ||||||
| 			return true, nil | 			return true, nil | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		promFileErr.WithLabelValues(baseName).Add(1) | 		promFileErr.WithLabelValues(f.metricsName).Add(1) | ||||||
| 		s.l.Error("shipping file", zap.String("filename", name), zap.Error(err)) | 		log.Printf("processing file %q: %e", f.metricsName, err) | ||||||
| 		return false, nil // nil since we want to loop and keep retrying indefinitely |  | ||||||
|  | 		// nil: loop and keep retrying indefinitely | ||||||
|  | 		return false, nil | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (s *submitter) shipFileRoutine(ctx context.Context, name string, sendQueue chan<- rawLine) error { | // use submitter(), don't use directly | ||||||
| 	baseName := filepath.Base(name) | func (f file) trySubmit(ctx context.Context, db *mongo.Collection, sendQueue chan<- RawLine) error { | ||||||
|  |  | ||||||
| 	// TODO: better way for respecting ?killing sender for retry | 	// TODO: better way for respecting ?killing sender for retry | ||||||
| 	for { | 	for { | ||||||
| 		if len(sendQueue) == 0 { | 		if len(sendQueue) == 0 { | ||||||
| @@ -100,9 +93,9 @@ func (s *submitter) shipFileRoutine(ctx context.Context, name string, sendQueue | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// get files with offset | 	// get files with offset | ||||||
| 	offsetResult, _ := mongoWithErr(s.db.FindOne(mongoTimeoutCtx(ctx), | 	offsetResult, _ := mongoWithErr(db.FindOne(mongoTimeoutCtx(ctx), | ||||||
| 		bson.D{{Key: mLogKeyHostId, Value: s.hostInfo.Id}, {Key: mLogKeyFileBasename, Value: baseName}}, | 		bson.D{{Key: ms.RecordKeyHostId, Value: f.Host.Id}, {Key: ms.RecordKeyFilePath, Value: f.Path}}, | ||||||
| 		&mongoOpt.FindOneOptions{Sort: bson.D{{Key: mLogKeyOffset, Value: -1}}}, // sort descending (get largest) | 		&mongoOpt.FindOneOptions{Sort: bson.D{{Key: ms.RecordKeyOffset, Value: -1}}}, // sort descending (get largest) | ||||||
| 	)) | 	)) | ||||||
|  |  | ||||||
| 	offsetResultBytes, err := offsetResult.DecodeBytes() | 	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) | 		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 { | 	if err != nil { | ||||||
| 		return fmt.Errorf("getting original file size: %w", err) | 		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) | 	sctx, cancel := context.WithCancel(ctx) | ||||||
| 	defer cancel() | 	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 { | 	if err != nil { | ||||||
| 		return fmt.Errorf("tailing file: %w", err) | 		return fmt.Errorf("tailing file: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var catchUpped bool // cache | 	var catchUpped bool | ||||||
| 	promFileCatchupDone.WithLabelValues(baseName).Set(0) | 	promFileCatchupDone.WithLabelValues(f.metricsName).Set(0) | ||||||
|  |  | ||||||
| 	// TODO: partial line combining |  | ||||||
| 	// TODO: promRecordDroppedTooLarge |  | ||||||
|  |  | ||||||
| 	for { | 	for { | ||||||
| 		select { | 		select { | ||||||
| @@ -144,13 +134,13 @@ func (s *submitter) shipFileRoutine(ctx context.Context, name string, sendQueue | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			promFileLineSize.WithLabelValues(baseName).Observe(float64(len(line.Bytes))) | 			promFileLineSize.WithLabelValues(f.metricsName).Observe(float64(len(line.Bytes))) | ||||||
|  |  | ||||||
| 			if !catchUpped { | 			if !catchUpped { | ||||||
| 				catchUpped = line.EndOffset >= startSize | 				catchUpped = line.EndOffset >= startSize | ||||||
|  |  | ||||||
| 				if catchUpped { | 				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 | 				continue | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			sendQueue <- rawLine{ | 			sendQueue <- RawLine{ | ||||||
| 				RecordMetadata: RecordMetadata{ | 				file: &f, | ||||||
| 					HostInfo: s.hostInfo, |  | ||||||
| 					File:     baseName, |  | ||||||
|  |  | ||||||
| 					Offset: line.EndOffset, | 				Offset: line.EndOffset, | ||||||
| 				}, | 				B:      line.Bytes, | ||||||
| 				line: line.Bytes, |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
							
								
								
									
										180
									
								
								cmd/watcher.go
									
									
									
									
									
								
							
							
						
						
									
										180
									
								
								cmd/watcher.go
									
									
									
									
									
								
							| @@ -2,34 +2,23 @@ package logmower | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"errors" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/http" | 	"log" | ||||||
| 	"net/url" |  | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/signal" | 	"os/signal" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"runtime" |  | ||||||
| 	"strings" |  | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	ms "git.k-space.ee/k-space/logmower-shipper/pkg/mongoStruct" | ||||||
| 	"github.com/fsnotify/fsnotify" | 	"github.com/fsnotify/fsnotify" | ||||||
| 	prom "github.com/prometheus/client_golang/prometheus" | 	prom "github.com/prometheus/client_golang/prometheus" | ||||||
| 	"github.com/prometheus/client_golang/prometheus/promauto" | 	"github.com/prometheus/client_golang/prometheus/promauto" | ||||||
| 	"github.com/prometheus/client_golang/prometheus/promhttp" |  | ||||||
| 	"github.com/urfave/cli/v2" | 	"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" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const DatabaseCommandTimeout = 10 * time.Second | ||||||
| 	MachineId              = "/etc/machine-id" |  | ||||||
| 	DatabaseCommandTimeout = 10 * time.Second |  | ||||||
| 	PrometheusPrefix       = "logmower" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // wrapper to force copying before use | // wrapper to force copying before use | ||||||
| func defaultBackoff() wait.Backoff { | func defaultBackoff() wait.Backoff { | ||||||
| @@ -73,16 +62,6 @@ var App = &cli.App{ | |||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
| 	Action: func(ctx *cli.Context) error { | 	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 ( | 		var ( | ||||||
| 			promWatcherOnline = promauto.NewGauge(prom.GaugeOpts{ | 			promWatcherOnline = promauto.NewGauge(prom.GaugeOpts{ | ||||||
| 				Namespace: PrometheusPrefix, | 				Namespace: PrometheusPrefix, | ||||||
| @@ -115,52 +94,27 @@ var App = &cli.App{ | |||||||
| 				Help: "Number of events while watchng (includes initial create events for existing file discovery)", | 				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) { | 		ctx.Context, _ = signal.NotifyContext(ctx.Context, os.Interrupt) // TODO: test | ||||||
| 				l.Fatal("failed to serve /metrics", zap.Error(err)) | 		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")) | 		db, err := initDatabase(ctx.Context, ctx.String("mongo-uri")) | ||||||
|  |  | ||||||
| 		dbClient, err := mongo.Connect(mongoTimeoutCtx(ctx.Context)) |  | ||||||
| 		if err != nil { | 		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")) | 		var hostInfo ms.HostInfo | ||||||
| 		if err != nil { | 		if err := hostInfo.Populate(ctx.String("node-name")); err != nil { | ||||||
| 			l.Fatal("parsing URI for mongo database name", zap.Error(err)) | 			return fmt.Errorf("populating host info: %w", 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)) |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		watcher, err := fsnotify.NewWatcher() | 		watcher, err := fsnotify.NewWatcher() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			l.Fatal("setting up watcher", zap.Error(err)) | 			return fmt.Errorf("initializing log directory watcher: %w", err) | ||||||
| 		} | 		} | ||||||
|  | 		defer watcher.Close() | ||||||
| 		logDir := ctx.String("log-directory") |  | ||||||
|  |  | ||||||
| 		wg.Add(1) | 		wg.Add(1) | ||||||
| 		go func() { | 		go func() { | ||||||
| @@ -181,10 +135,10 @@ var App = &cli.App{ | |||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					// TODO: #1: || if not in filterset | 					// TODO: #1: || if not in filterset | ||||||
| 					_, ok = parseLogName(event.Name) | 					kubeInfo, ok := ms.ParseLogName(event.Name) | ||||||
| 					if !ok { | 					if !ok { | ||||||
| 						promWatcherFilesSkipped.Add(1) | 						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 | 						continue | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| @@ -192,7 +146,16 @@ var App = &cli.App{ | |||||||
|  |  | ||||||
| 					wg.Add(1) | 					wg.Add(1) | ||||||
| 					go func() { | 					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() | 						wg.Done() | ||||||
| 					}() | 					}() | ||||||
|  |  | ||||||
| @@ -201,22 +164,20 @@ var App = &cli.App{ | |||||||
| 						return | 						return | ||||||
| 					} | 					} | ||||||
| 					promWatcherErr.Add(1) | 					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 | 		// simulate create events to pick up files already created | ||||||
| 		err = simulateInitialCreate(logDir, watcher.Events) | 		if err := simulateInitialCreates(logDir, watcher.Events); err != nil { | ||||||
| 		if err != nil { | 			return fmt.Errorf("listing log directory %q: %w", logDir, err) | ||||||
| 			promWatcherErr.Add(1) |  | ||||||
| 			l.Fatal("listing initial log directory", zap.String("name", logDir), zap.Error(err)) |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		err = watcher.Add(logDir) | 		if err := watcher.Add(logDir); err != nil { | ||||||
| 		if err != nil { | 			return fmt.Errorf("watching for new logs in %q: %w", logDir, err) | ||||||
| 			promWatcherErr.Add(1) |  | ||||||
| 			l.Fatal("watching log directory", zap.String("name", logDir), zap.Error(err)) |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		promWatcherOnline.Set(1) | 		promWatcherOnline.Set(1) | ||||||
| @@ -224,84 +185,11 @@ var App = &cli.App{ | |||||||
| 		// waiting indefinitely for interrupt | 		// waiting indefinitely for interrupt | ||||||
| 		wg.Wait() // wait for watch and file processors to cleanup | 		wg.Wait() // wait for watch and file processors to cleanup | ||||||
|  |  | ||||||
| 		return errAppend(watcher.Close(), ctx.Err()) | 		return ctx.Err() | ||||||
| 	}, | 	}, | ||||||
| } | } | ||||||
|  |  | ||||||
| type HostInfo struct { | func simulateInitialCreates(dirName string, eventChan chan<- fsnotify.Event) error { | ||||||
| 	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 { |  | ||||||
| 	dir, err := os.ReadDir(dirName) | 	dir, err := os.ReadDir(dirName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								go.mod
									
									
									
									
									
								
							| @@ -4,12 +4,10 @@ go 1.19 | |||||||
|  |  | ||||||
| require ( | require ( | ||||||
| 	github.com/fsnotify/fsnotify v1.6.0 | 	github.com/fsnotify/fsnotify v1.6.0 | ||||||
| 	github.com/jtagcat/util v0.0.0-20221106213317-cab09054fbdd | 	github.com/jtagcat/util v0.0.0-20221109113553-753a118dcd99 | ||||||
| 	github.com/prometheus/client_golang v1.13.1 | 	github.com/prometheus/client_golang v1.14.0 | ||||||
| 	github.com/urfave/cli/v2 v2.23.4 | 	github.com/urfave/cli/v2 v2.23.5 | ||||||
| 	go.elastic.co/ecszap v1.0.1 |  | ||||||
| 	go.mongodb.org/mongo-driver v1.11.0 | 	go.mongodb.org/mongo-driver v1.11.0 | ||||||
| 	go.uber.org/zap v1.23.0 |  | ||||||
| 	k8s.io/apimachinery v0.25.3 | 	k8s.io/apimachinery v0.25.3 | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -22,7 +20,6 @@ require ( | |||||||
| 	github.com/golang/snappy v0.0.4 // indirect | 	github.com/golang/snappy v0.0.4 // indirect | ||||||
| 	github.com/klauspost/compress v1.15.12 // indirect | 	github.com/klauspost/compress v1.15.12 // indirect | ||||||
| 	github.com/kr/pretty v0.2.0 // 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/matttproud/golang_protobuf_extensions v1.0.4 // indirect | ||||||
| 	github.com/montanaflynn/stats v0.6.6 // indirect | 	github.com/montanaflynn/stats v0.6.6 // indirect | ||||||
| 	github.com/pkg/errors v0.9.1 // 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/xdg-go/stringprep v1.0.3 // indirect | ||||||
| 	github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect | 	github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect | ||||||
| 	github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // 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/crypto v0.1.0 // indirect | ||||||
| 	golang.org/x/sync 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 | 	golang.org/x/text v0.4.0 // indirect | ||||||
| 	google.golang.org/protobuf v1.28.1 // indirect | 	google.golang.org/protobuf v1.28.1 // indirect | ||||||
| 	k8s.io/klog/v2 v2.80.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 | // 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-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-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= | ||||||
| github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= | 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 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.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= | ||||||
| github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= | 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/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 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/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-20221109113553-753a118dcd99 h1:Z9LcAEgCflX4wmhUmNHnsQYExERHBN1uAxVPbn8VArw= | ||||||
| github.com/jtagcat/util v0.0.0-20221106213317-cab09054fbdd/go.mod h1:VIg6NAm5vU1HwDCL8p/iILmCwvgVCP3/U4QhlS6hftY= | 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.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= | ||||||
| github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= | 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= | 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/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.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||||||
| github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | 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.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 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= | ||||||
| github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= | 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.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.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.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.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= | ||||||
| github.com/prometheus/client_golang v1.13.1/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= | 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-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-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | ||||||
| github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/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.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||||
| github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | 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.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/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= | ||||||
| github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= | github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= | ||||||
| github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= | 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.5 h1:xbrU7tAYviSpqeR3X4nEFWUdB/uDZ6DE+HxmRU7Xtyw= | ||||||
| github.com/urfave/cli/v2 v2.23.4/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= | 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 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= | ||||||
| github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= | 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= | 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.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||||
| github.com/yuin/goldmark v1.1.27/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.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 h1:FZKhBSTydeuffHj9CBjXlR8vQLee1cQyTWYPA6/tqiE= | ||||||
| go.mongodb.org/mongo-driver v1.11.0/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= | go.mongodb.org/mongo-driver v1.11.0/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= | ||||||
| go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= | 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.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= | ||||||
| go.opencensus.io v0.22.3/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.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-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-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||||
| golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | 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.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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||||||
| golang.org/x/mod v0.3.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-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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||||
| golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/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-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-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-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-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-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||||
| golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= | 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-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-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-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-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-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-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-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-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.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.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= | ||||||
| golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | 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-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||||
| golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | 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= | 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-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-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= | ||||||
| golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/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-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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
| golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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.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.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.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.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= | 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-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 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||||||
| gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | 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= | 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= | 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 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= | ||||||
| k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= | 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-20221108210102-8e77b1f39fe2 h1:GfD9OzL11kvZN5iArC6oTS7RTj7oJOIfnislxYlqTj8= | ||||||
| k8s.io/utils v0.0.0-20221101230645-61b03e2f6476/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= | 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/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/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= | ||||||
| rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= | 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 | // WithLabelValues works as GetMetricWithLabelValues, but panics where | ||||||
| // GetMetricWithLabelValues would have returned an error. Not returning an | // GetMetricWithLabelValues would have returned an error. Not returning an | ||||||
| // error allows shortcuts like | // error allows shortcuts like | ||||||
| //     myVec.WithLabelValues("404", "GET").Add(42) | // | ||||||
|  | //	myVec.WithLabelValues("404", "GET").Add(42) | ||||||
| func (v *CounterVec) WithLabelValues(lvs ...string) Counter { | func (v *CounterVec) WithLabelValues(lvs ...string) Counter { | ||||||
| 	c, err := v.GetMetricWithLabelValues(lvs...) | 	c, err := v.GetMetricWithLabelValues(lvs...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -257,7 +258,8 @@ func (v *CounterVec) WithLabelValues(lvs ...string) Counter { | |||||||
|  |  | ||||||
| // With works as GetMetricWith, but panics where GetMetricWithLabels would have | // With works as GetMetricWith, but panics where GetMetricWithLabels would have | ||||||
| // returned an error. Not returning an error allows shortcuts like | // 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 { | func (v *CounterVec) With(labels Labels) Counter { | ||||||
| 	c, err := v.GetMetricWith(labels) | 	c, err := v.GetMetricWith(labels) | ||||||
| 	if err != nil { | 	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 | // All exported functions and methods are safe to be used concurrently unless | ||||||
| // specified otherwise. | // specified otherwise. | ||||||
| // | // | ||||||
| // A Basic Example | // # A Basic Example | ||||||
| // | // | ||||||
| // As a starting point, a very basic usage example: | // As a starting point, a very basic usage example: | ||||||
| // | // | ||||||
| //    package main | //	package main | ||||||
| // | // | ||||||
| //    import ( | //	import ( | ||||||
| //    	"log" | //		"log" | ||||||
| //    	"net/http" | //		"net/http" | ||||||
| // | // | ||||||
| //    	"github.com/prometheus/client_golang/prometheus" | //		"github.com/prometheus/client_golang/prometheus" | ||||||
| //    	"github.com/prometheus/client_golang/prometheus/promhttp" | //		"github.com/prometheus/client_golang/prometheus/promhttp" | ||||||
| //    ) | //	) | ||||||
| // | // | ||||||
| //    var ( | //	type metrics struct { | ||||||
| //    	cpuTemp = prometheus.NewGauge(prometheus.GaugeOpts{ | //		cpuTemp  prometheus.Gauge | ||||||
| //    		Name: "cpu_temperature_celsius", | //	  hdFailures *prometheus.CounterVec | ||||||
| //    		Help: "Current temperature of the CPU.", | //	} | ||||||
| //    	}) |  | ||||||
| //    	hdFailures = prometheus.NewCounterVec( |  | ||||||
| //    		prometheus.CounterOpts{ |  | ||||||
| //    			Name: "hd_errors_total", |  | ||||||
| //    			Help: "Number of hard-disk errors.", |  | ||||||
| //    		}, |  | ||||||
| //    		[]string{"device"}, |  | ||||||
| //    	) |  | ||||||
| //    ) |  | ||||||
| // | // | ||||||
| //    func init() { | //	func NewMetrics(reg prometheus.Registerer) *metrics { | ||||||
| //    	// Metrics have to be registered to be exposed: | //	  m := &metrics{ | ||||||
| //    	prometheus.MustRegister(cpuTemp) | //	    cpuTemp: prometheus.NewGauge(prometheus.GaugeOpts{ | ||||||
| //    	prometheus.MustRegister(hdFailures) | //	      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() { | //	func main() { | ||||||
| //    	cpuTemp.Set(65.3) | //	  // Create a non-global registry. | ||||||
| //    	hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc() | //	  reg := prometheus.NewRegistry() | ||||||
| // | // | ||||||
| //    	// The Handler function provides a default handler to expose metrics | //	  // Create new metrics and register them using the custom registry. | ||||||
| //    	// via an HTTP server. "/metrics" is the usual endpoint for that. | //	  m := NewMetrics(reg) | ||||||
| //    	http.Handle("/metrics", promhttp.Handler()) | //	  // Set values for the new created metrics. | ||||||
| //    	log.Fatal(http.ListenAndServe(":8080", nil)) | //		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, | // 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. | // 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 | // The number of exported identifiers in this package might appear a bit | ||||||
| // overwhelming. However, in addition to the basic plumbing shown in the example | // 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 | // To create instances of Metrics and their vector versions, you need a suitable | ||||||
| // …Opts struct, i.e. GaugeOpts, CounterOpts, SummaryOpts, or HistogramOpts. | // …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 | // 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 | // 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 | // a metric, GaugeFunc, CounterFunc, or UntypedFunc might be interesting | ||||||
| // shortcuts. | // shortcuts. | ||||||
| // | // | ||||||
| // Advanced Uses of the Registry | // # Advanced Uses of the Registry | ||||||
| // | // | ||||||
| // While MustRegister is the by far most common way of registering a Collector, | // 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. | // 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 | // NewProcessCollector). With a custom registry, you are in control and decide | ||||||
| // yourself about the Collectors to register. | // yourself about the Collectors to register. | ||||||
| // | // | ||||||
| // HTTP Exposition | // # HTTP Exposition | ||||||
| // | // | ||||||
| // The Registry implements the Gatherer interface. The caller of the Gather | // The Registry implements the Gatherer interface. The caller of the Gather | ||||||
| // method can then expose the gathered metrics in some way. Usually, the metrics | // 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 | // 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. | // 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. | // 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 | // Functions and examples to push metrics from a Gatherer to Graphite can be | ||||||
| // found in the graphite sub-package. | // 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 | // More ways of exposing metrics can easily be added by following the approaches | ||||||
| // of the existing implementations. | // 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 | // WithLabelValues works as GetMetricWithLabelValues, but panics where | ||||||
| // GetMetricWithLabelValues would have returned an error. Not returning an | // GetMetricWithLabelValues would have returned an error. Not returning an | ||||||
| // error allows shortcuts like | // error allows shortcuts like | ||||||
| //     myVec.WithLabelValues("404", "GET").Add(42) | // | ||||||
|  | //	myVec.WithLabelValues("404", "GET").Add(42) | ||||||
| func (v *GaugeVec) WithLabelValues(lvs ...string) Gauge { | func (v *GaugeVec) WithLabelValues(lvs ...string) Gauge { | ||||||
| 	g, err := v.GetMetricWithLabelValues(lvs...) | 	g, err := v.GetMetricWithLabelValues(lvs...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -221,7 +222,8 @@ func (v *GaugeVec) WithLabelValues(lvs ...string) Gauge { | |||||||
|  |  | ||||||
| // With works as GetMetricWith, but panics where GetMetricWithLabels would have | // With works as GetMetricWith, but panics where GetMetricWithLabels would have | ||||||
| // returned an error. Not returning an error allows shortcuts like | // 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 { | func (v *GaugeVec) With(labels Labels) Gauge { | ||||||
| 	g, err := v.GetMetricWith(labels) | 	g, err := v.GetMetricWith(labels) | ||||||
| 	if err != nil { | 	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: | // If IsJunk is not defined: | ||||||
| // | // | ||||||
| // Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where | // 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, | // and for all (i',j',k') meeting those conditions, | ||||||
| //     k >= k' | // | ||||||
| //     i <= i' | //	k >= k' | ||||||
| //     and if i == i', j <= j' | //	i <= i' | ||||||
|  | //	and if i == i', j <= j' | ||||||
| // | // | ||||||
| // In other words, of all maximal matching blocks, return one that | // In other words, of all maximal matching blocks, return one that | ||||||
| // starts earliest in a, and of all those maximal matching blocks 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 | // Labels represents a collection of label name -> value mappings. This type is | ||||||
| // commonly used with the With(Labels) and GetMetricWith(Labels) methods of | // commonly used with the With(Labels) and GetMetricWith(Labels) methods of | ||||||
| // metric vector Collectors, e.g.: | // 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 | // The other use-case is the specification of constant label pairs in Opts or to | ||||||
| // create a Desc. | // 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 | // Package promauto provides alternative constructors for the fundamental | ||||||
| // Prometheus metric types and their …Vec and …Func variants. The difference to | // Prometheus metric types and their …Vec and …Func variants. The difference to | ||||||
| // their counterparts in the prometheus package is that the promauto | // their counterparts in the prometheus package is that the promauto | ||||||
| // constructors return Collectors that are already registered with a | // constructors register the Collectors with a registry before returning them. | ||||||
| // registry. There are two sets of constructors. The constructors in the first | // There are two sets of constructors. The constructors in the first set are | ||||||
| // set are top-level functions, while the constructors in the other set are | // top-level functions, while the constructors in the other set are methods of | ||||||
| // methods of the Factory type. The top-level function return Collectors | // the Factory type. The top-level function return Collectors registered with | ||||||
| // registered with the global registry (prometheus.DefaultRegisterer), while the | // the global registry (prometheus.DefaultRegisterer), while the methods return | ||||||
| // methods return Collectors registered with the registry the Factory was | // Collectors registered with the registry the Factory was constructed with. All | ||||||
| // constructed with. All constructors panic if the registration fails. | // constructors panic if the registration fails. | ||||||
| // | // | ||||||
| // The following example is a complete program to create a histogram of normally | // The following example is a complete program to create a histogram of normally | ||||||
| // distributed random numbers from the math/rand package: | // distributed random numbers from the math/rand package: | ||||||
| // | // | ||||||
| //      package main | //	package main | ||||||
| // | // | ||||||
| //      import ( | //	import ( | ||||||
| //              "math/rand" | //	        "math/rand" | ||||||
| //              "net/http" | //	        "net/http" | ||||||
| // | // | ||||||
| //              "github.com/prometheus/client_golang/prometheus" | //	        "github.com/prometheus/client_golang/prometheus" | ||||||
| //              "github.com/prometheus/client_golang/prometheus/promauto" | //	        "github.com/prometheus/client_golang/prometheus/promauto" | ||||||
| //              "github.com/prometheus/client_golang/prometheus/promhttp" | //	        "github.com/prometheus/client_golang/prometheus/promhttp" | ||||||
| //      ) | //	) | ||||||
| // | // | ||||||
| //      var histogram = promauto.NewHistogram(prometheus.HistogramOpts{ | //	var histogram = promauto.NewHistogram(prometheus.HistogramOpts{ | ||||||
| //              Name:    "random_numbers", | //	        Name:    "random_numbers", | ||||||
| //              Help:    "A histogram of normally distributed random numbers.", | //	        Help:    "A histogram of normally distributed random numbers.", | ||||||
| //              Buckets: prometheus.LinearBuckets(-3, .1, 61), | //	        Buckets: prometheus.LinearBuckets(-3, .1, 61), | ||||||
| //      }) | //	}) | ||||||
| // | // | ||||||
| //      func Random() { | //	func Random() { | ||||||
| //              for { | //	        for { | ||||||
| //                      histogram.Observe(rand.NormFloat64()) | //	                histogram.Observe(rand.NormFloat64()) | ||||||
| //              } | //	        } | ||||||
| //      } | //	} | ||||||
| // | // | ||||||
| //      func main() { | //	func main() { | ||||||
| //              go Random() | //	        go Random() | ||||||
| //              http.Handle("/metrics", promhttp.Handler()) | //	        http.Handle("/metrics", promhttp.Handler()) | ||||||
| //              http.ListenAndServe(":1971", nil) | //	        http.ListenAndServe(":1971", nil) | ||||||
| //      } | //	} | ||||||
| // | // | ||||||
| // Prometheus's version of a minimal hello-world program: | // Prometheus's version of a minimal hello-world program: | ||||||
| // | // | ||||||
| //      package main | //	package main | ||||||
| // | // | ||||||
| //      import ( | //	import ( | ||||||
| //      	"fmt" | //		"fmt" | ||||||
| //      	"net/http" | //		"net/http" | ||||||
| // | // | ||||||
| //      	"github.com/prometheus/client_golang/prometheus" | //		"github.com/prometheus/client_golang/prometheus" | ||||||
| //      	"github.com/prometheus/client_golang/prometheus/promauto" | //		"github.com/prometheus/client_golang/prometheus/promauto" | ||||||
| //      	"github.com/prometheus/client_golang/prometheus/promhttp" | //		"github.com/prometheus/client_golang/prometheus/promhttp" | ||||||
| //      ) | //	) | ||||||
| // | // | ||||||
| //      func main() { | //	func main() { | ||||||
| //      	http.Handle("/", promhttp.InstrumentHandlerCounter( | //		http.Handle("/", promhttp.InstrumentHandlerCounter( | ||||||
| //      		promauto.NewCounterVec( | //			promauto.NewCounterVec( | ||||||
| //      			prometheus.CounterOpts{ | //				prometheus.CounterOpts{ | ||||||
| //      				Name: "hello_requests_total", | //					Name: "hello_requests_total", | ||||||
| //      				Help: "Total number of hello-world requests by HTTP code.", | //					Help: "Total number of hello-world requests by HTTP code.", | ||||||
| //      			}, | //				}, | ||||||
| //      			[]string{"code"}, | //				[]string{"code"}, | ||||||
| //      		), | //			), | ||||||
| //      		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | //			http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||||
| //      			fmt.Fprint(w, "Hello, world!") | //				fmt.Fprint(w, "Hello, world!") | ||||||
| //      		}), | //			}), | ||||||
| //      	)) | //		)) | ||||||
| //      	http.Handle("/metrics", promhttp.Handler()) | //		http.Handle("/metrics", promhttp.Handler()) | ||||||
| //      	http.ListenAndServe(":1971", nil) | //		http.ListenAndServe(":1971", nil) | ||||||
| //      } | //	} | ||||||
| // | // | ||||||
| // A Factory is created with the With(prometheus.Registerer) function, which | // A Factory is created with the With(prometheus.Registerer) function, which | ||||||
| // enables two usage pattern. With(prometheus.Registerer) can be called once per | // enables two usage pattern. With(prometheus.Registerer) can be called once per | ||||||
| // line: | // line: | ||||||
| // | // | ||||||
| //        var ( | //	var ( | ||||||
| //        	reg           = prometheus.NewRegistry() | //		reg           = prometheus.NewRegistry() | ||||||
| //        	randomNumbers = promauto.With(reg).NewHistogram(prometheus.HistogramOpts{ | //		randomNumbers = promauto.With(reg).NewHistogram(prometheus.HistogramOpts{ | ||||||
| //        		Name:    "random_numbers", | //			Name:    "random_numbers", | ||||||
| //        		Help:    "A histogram of normally distributed random numbers.", | //			Help:    "A histogram of normally distributed random numbers.", | ||||||
| //        		Buckets: prometheus.LinearBuckets(-3, .1, 61), | //			Buckets: prometheus.LinearBuckets(-3, .1, 61), | ||||||
| //        	}) | //		}) | ||||||
| //        	requestCount = promauto.With(reg).NewCounterVec( | //		requestCount = promauto.With(reg).NewCounterVec( | ||||||
| //        		prometheus.CounterOpts{ | //			prometheus.CounterOpts{ | ||||||
| //        			Name: "http_requests_total", | //				Name: "http_requests_total", | ||||||
| //        			Help: "Total number of HTTP requests by status code and method.", | //				Help: "Total number of HTTP requests by status code and method.", | ||||||
| //        		}, | //			}, | ||||||
| //        		[]string{"code", "method"}, | //			[]string{"code", "method"}, | ||||||
| //        	) | //		) | ||||||
| //        ) | //	) | ||||||
| // | // | ||||||
| // Or it can be used to create a Factory once to be used multiple times: | // Or it can be used to create a Factory once to be used multiple times: | ||||||
| // | // | ||||||
| //        var ( | //	var ( | ||||||
| //        	reg           = prometheus.NewRegistry() | //		reg           = prometheus.NewRegistry() | ||||||
| //        	factory       = promauto.With(reg) | //		factory       = promauto.With(reg) | ||||||
| //        	randomNumbers = factory.NewHistogram(prometheus.HistogramOpts{ | //		randomNumbers = factory.NewHistogram(prometheus.HistogramOpts{ | ||||||
| //        		Name:    "random_numbers", | //			Name:    "random_numbers", | ||||||
| //        		Help:    "A histogram of normally distributed random numbers.", | //			Help:    "A histogram of normally distributed random numbers.", | ||||||
| //        		Buckets: prometheus.LinearBuckets(-3, .1, 61), | //			Buckets: prometheus.LinearBuckets(-3, .1, 61), | ||||||
| //        	}) | //		}) | ||||||
| //        	requestCount = factory.NewCounterVec( | //		requestCount = factory.NewCounterVec( | ||||||
| //        		prometheus.CounterOpts{ | //			prometheus.CounterOpts{ | ||||||
| //        			Name: "http_requests_total", | //				Name: "http_requests_total", | ||||||
| //        			Help: "Total number of HTTP requests by status code and method.", | //				Help: "Total number of HTTP requests by status code and method.", | ||||||
| //        		}, | //			}, | ||||||
| //        		[]string{"code", "method"}, | //			[]string{"code", "method"}, | ||||||
| //        	) | //		) | ||||||
| //        ) | //	) | ||||||
| // | // | ||||||
| // This appears very handy. So why are these constructors locked away in a | // This appears very handy. So why are these constructors locked away in a | ||||||
| // separate package? | // 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) { | 	return func(r *http.Request) (*http.Response, error) { | ||||||
| 		resp, err := next.RoundTrip(r) | 		resp, err := next.RoundTrip(r) | ||||||
| 		if err == nil { | 		if err == nil { | ||||||
| 			exemplarAdd( | 			addWithExemplar( | ||||||
| 				counter.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)), | 				counter.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)), | ||||||
| 				1, | 				1, | ||||||
| 				rtOpts.getExemplarFn(r.Context()), | 				rtOpts.getExemplarFn(r.Context()), | ||||||
| @@ -116,7 +116,7 @@ func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundT | |||||||
| 		start := time.Now() | 		start := time.Now() | ||||||
| 		resp, err := next.RoundTrip(r) | 		resp, err := next.RoundTrip(r) | ||||||
| 		if err == nil { | 		if err == nil { | ||||||
| 			exemplarObserve( | 			observeWithExemplar( | ||||||
| 				obs.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)), | 				obs.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)), | ||||||
| 				time.Since(start).Seconds(), | 				time.Since(start).Seconds(), | ||||||
| 				rtOpts.getExemplarFn(r.Context()), | 				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. | // magicString is used for the hacky label test in checkLabels. Remove once fixed. | ||||||
| const magicString = "zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa" | 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 { | 	if labels == nil { | ||||||
| 		obs.Observe(val) | 		obs.Observe(val) | ||||||
| 		return | 		return | ||||||
| @@ -36,7 +38,9 @@ func exemplarObserve(obs prometheus.Observer, val float64, labels map[string]str | |||||||
| 	obs.(prometheus.ExemplarObserver).ObserveWithExemplar(val, labels) | 	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 { | 	if labels == nil { | ||||||
| 		obs.Add(val) | 		obs.Add(val) | ||||||
| 		return | 		return | ||||||
| @@ -91,7 +95,7 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, op | |||||||
| 			d := newDelegator(w, nil) | 			d := newDelegator(w, nil) | ||||||
| 			next.ServeHTTP(d, r) | 			next.ServeHTTP(d, r) | ||||||
|  |  | ||||||
| 			exemplarObserve( | 			observeWithExemplar( | ||||||
| 				obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), | 				obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), | ||||||
| 				time.Since(now).Seconds(), | 				time.Since(now).Seconds(), | ||||||
| 				hOpts.getExemplarFn(r.Context()), | 				hOpts.getExemplarFn(r.Context()), | ||||||
| @@ -103,7 +107,7 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, op | |||||||
| 		now := time.Now() | 		now := time.Now() | ||||||
| 		next.ServeHTTP(w, r) | 		next.ServeHTTP(w, r) | ||||||
|  |  | ||||||
| 		exemplarObserve( | 		observeWithExemplar( | ||||||
| 			obs.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), | 			obs.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), | ||||||
| 			time.Since(now).Seconds(), | 			time.Since(now).Seconds(), | ||||||
| 			hOpts.getExemplarFn(r.Context()), | 			hOpts.getExemplarFn(r.Context()), | ||||||
| @@ -141,7 +145,7 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, | |||||||
| 			d := newDelegator(w, nil) | 			d := newDelegator(w, nil) | ||||||
| 			next.ServeHTTP(d, r) | 			next.ServeHTTP(d, r) | ||||||
|  |  | ||||||
| 			exemplarAdd( | 			addWithExemplar( | ||||||
| 				counter.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), | 				counter.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), | ||||||
| 				1, | 				1, | ||||||
| 				hOpts.getExemplarFn(r.Context()), | 				hOpts.getExemplarFn(r.Context()), | ||||||
| @@ -151,7 +155,7 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, | |||||||
|  |  | ||||||
| 	return func(w http.ResponseWriter, r *http.Request) { | 	return func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		next.ServeHTTP(w, r) | 		next.ServeHTTP(w, r) | ||||||
| 		exemplarAdd( | 		addWithExemplar( | ||||||
| 			counter.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), | 			counter.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), | ||||||
| 			1, | 			1, | ||||||
| 			hOpts.getExemplarFn(r.Context()), | 			hOpts.getExemplarFn(r.Context()), | ||||||
| @@ -192,7 +196,7 @@ func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Ha | |||||||
| 	return func(w http.ResponseWriter, r *http.Request) { | 	return func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		now := time.Now() | 		now := time.Now() | ||||||
| 		d := newDelegator(w, func(status int) { | 		d := newDelegator(w, func(status int) { | ||||||
| 			exemplarObserve( | 			observeWithExemplar( | ||||||
| 				obs.With(labels(code, method, r.Method, status, hOpts.extraMethods...)), | 				obs.With(labels(code, method, r.Method, status, hOpts.extraMethods...)), | ||||||
| 				time.Since(now).Seconds(), | 				time.Since(now).Seconds(), | ||||||
| 				hOpts.getExemplarFn(r.Context()), | 				hOpts.getExemplarFn(r.Context()), | ||||||
| @@ -233,7 +237,7 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, | |||||||
| 			d := newDelegator(w, nil) | 			d := newDelegator(w, nil) | ||||||
| 			next.ServeHTTP(d, r) | 			next.ServeHTTP(d, r) | ||||||
| 			size := computeApproximateRequestSize(r) | 			size := computeApproximateRequestSize(r) | ||||||
| 			exemplarObserve( | 			observeWithExemplar( | ||||||
| 				obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), | 				obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), | ||||||
| 				float64(size), | 				float64(size), | ||||||
| 				hOpts.getExemplarFn(r.Context()), | 				hOpts.getExemplarFn(r.Context()), | ||||||
| @@ -244,7 +248,7 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, | |||||||
| 	return func(w http.ResponseWriter, r *http.Request) { | 	return func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		next.ServeHTTP(w, r) | 		next.ServeHTTP(w, r) | ||||||
| 		size := computeApproximateRequestSize(r) | 		size := computeApproximateRequestSize(r) | ||||||
| 		exemplarObserve( | 		observeWithExemplar( | ||||||
| 			obs.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), | 			obs.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), | ||||||
| 			float64(size), | 			float64(size), | ||||||
| 			hOpts.getExemplarFn(r.Context()), | 			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) { | 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		d := newDelegator(w, nil) | 		d := newDelegator(w, nil) | ||||||
| 		next.ServeHTTP(d, r) | 		next.ServeHTTP(d, r) | ||||||
| 		exemplarObserve( | 		observeWithExemplar( | ||||||
| 			obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), | 			obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), | ||||||
| 			float64(d.Written()), | 			float64(d.Written()), | ||||||
| 			hOpts.getExemplarFn(r.Context()), | 			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 | // Registry registers Prometheus collectors, collects their metrics, and gathers | ||||||
| // them into MetricFamilies for exposition. It implements both Registerer and | // them into MetricFamilies for exposition. It implements Registerer, Gatherer, | ||||||
| // Gatherer. The zero value is not usable. Create instances with NewRegistry or | // and Collector. The zero value is not usable. Create instances with | ||||||
| // NewPedanticRegistry. | // 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 { | type Registry struct { | ||||||
| 	mtx                   sync.RWMutex | 	mtx                   sync.RWMutex | ||||||
| 	collectorsByID        map[uint64]Collector // ID is a hash of the descIDs. | 	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() | 	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 | // 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 | // Prometheus text format, and writes it to a temporary file. Upon success, the | ||||||
| // temporary file is renamed to the provided filename. | // 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 | // WithLabelValues works as GetMetricWithLabelValues, but panics where | ||||||
| // GetMetricWithLabelValues would have returned an error. Not returning an | // GetMetricWithLabelValues would have returned an error. Not returning an | ||||||
| // error allows shortcuts like | // 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 { | func (v *SummaryVec) WithLabelValues(lvs ...string) Observer { | ||||||
| 	s, err := v.GetMetricWithLabelValues(lvs...) | 	s, err := v.GetMetricWithLabelValues(lvs...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -614,7 +615,8 @@ func (v *SummaryVec) WithLabelValues(lvs ...string) Observer { | |||||||
|  |  | ||||||
| // With works as GetMetricWith, but panics where GetMetricWithLabels would have | // With works as GetMetricWith, but panics where GetMetricWithLabels would have | ||||||
| // returned an error. Not returning an error allows shortcuts like | // 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 { | func (v *SummaryVec) With(labels Labels) Observer { | ||||||
| 	s, err := v.GetMetricWith(labels) | 	s, err := v.GetMetricWith(labels) | ||||||
| 	if err != nil { | 	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 | // 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: | // 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 | // NewConstSummary returns an error if the length of labelValues is not | ||||||
| // consistent with the variable labels in Desc or if Desc is invalid. | // 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 | // 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 | // duration in seconds. Timer is usually used to time a function call in the | ||||||
| // following way: | // following way: | ||||||
| //    func TimeMe() { | // | ||||||
| //        timer := NewTimer(myHistogram) | //	func TimeMe() { | ||||||
| //        defer timer.ObserveDuration() | //	    timer := NewTimer(myHistogram) | ||||||
| //        // Do actual work. | //	    defer timer.ObserveDuration() | ||||||
| //    } | //	    // Do actual work. | ||||||
|  | //	} | ||||||
| func NewTimer(o Observer) *Timer { | func NewTimer(o Observer) *Timer { | ||||||
| 	return &Timer{ | 	return &Timer{ | ||||||
| 		begin:    time.Now(), | 		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