refactor: use py mongo struct + stdlib log
+ restructure project
This commit is contained in:
parent
bd667c0fc1
commit
69e0230949
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
Loading…
Reference in New Issue
Block a user