refactor: log with zap
This commit is contained in:
		@@ -5,6 +5,7 @@ import (
 | 
			
		||||
	"github.com/cyrilix/robocar-base/cli"
 | 
			
		||||
	"github.com/cyrilix/robocar-steering/part"
 | 
			
		||||
	"log"
 | 
			
		||||
	"go.uber.org/zap"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -15,6 +16,7 @@ const (
 | 
			
		||||
func main() {
 | 
			
		||||
	var mqttBroker, username, password, clientId string
 | 
			
		||||
	var steeringTopic, driveModeTopic, rcSteeringTopic, tfSteeringTopic string
 | 
			
		||||
	var debug bool
 | 
			
		||||
 | 
			
		||||
	mqttQos := cli.InitIntFlag("MQTT_QOS", 0)
 | 
			
		||||
	_, mqttRetain := os.LookupEnv("MQTT_RETAIN")
 | 
			
		||||
@@ -26,12 +28,31 @@ func main() {
 | 
			
		||||
	flag.StringVar(&tfSteeringTopic, "mqtt-topic-tf-steering", os.Getenv("MQTT_TOPIC_TF_STEERING"), "Mqtt topic that contains tenorflow steering value, use MQTT_TOPIC_TF_STEERING if args not set")
 | 
			
		||||
	flag.StringVar(&driveModeTopic, "mqtt-topic-drive-mode", os.Getenv("MQTT_TOPIC_DRIVE_MODE"), "Mqtt topic that contains DriveMode value, use MQTT_TOPIC_DRIVE_MODE if args not set")
 | 
			
		||||
 | 
			
		||||
	flag.BoolVar(&debug, "debug", false, "Display raw value to debug")
 | 
			
		||||
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
	if len(os.Args) <= 1 {
 | 
			
		||||
		flag.PrintDefaults()
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	config := zap.NewDevelopmentConfig()
 | 
			
		||||
	if debug {
 | 
			
		||||
		config.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
 | 
			
		||||
	} else {
 | 
			
		||||
		config.Level = zap.NewAtomicLevelAt(zap.InfoLevel)
 | 
			
		||||
	}
 | 
			
		||||
	lgr, err := config.Build()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("unable to init logger: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if err := lgr.Sync(); err != nil {
 | 
			
		||||
			log.Printf("unable to Sync logger: %v\n", err)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	zap.ReplaceGlobals(lgr)
 | 
			
		||||
 | 
			
		||||
	client, err := cli.Connect(mqttBroker, username, password, clientId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("unable to connect to mqtt bus: %v", err)
 | 
			
		||||
@@ -45,6 +66,6 @@ func main() {
 | 
			
		||||
 | 
			
		||||
	err = p.Start()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("unable to start service: %v", err)
 | 
			
		||||
		zap.S().Fatalf("unable to start service: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								go.mod
									
									
									
									
									
								
							@@ -7,13 +7,15 @@ require (
 | 
			
		||||
	github.com/cyrilix/robocar-protobuf/go v1.0.3
 | 
			
		||||
	github.com/eclipse/paho.mqtt.golang v1.3.5
 | 
			
		||||
	github.com/golang/protobuf v1.5.2
 | 
			
		||||
	github.com/sirupsen/logrus v1.8.1
 | 
			
		||||
	go.uber.org/zap v1.19.1
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/gorilla/websocket v1.4.2 // indirect
 | 
			
		||||
	github.com/stretchr/testify v1.6.1 // indirect
 | 
			
		||||
	golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect
 | 
			
		||||
	golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd // indirect
 | 
			
		||||
	github.com/sirupsen/logrus v1.8.1 // indirect
 | 
			
		||||
	go.uber.org/atomic v1.7.0 // indirect
 | 
			
		||||
	go.uber.org/multierr v1.6.0 // indirect
 | 
			
		||||
	golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect
 | 
			
		||||
	golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect
 | 
			
		||||
	google.golang.org/protobuf v1.26.0 // indirect
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										47
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								go.sum
									
									
									
									
									
								
							@@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
 | 
			
		||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
 | 
			
		||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
 | 
			
		||||
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
 | 
			
		||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
 | 
			
		||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
 | 
			
		||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
 | 
			
		||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 | 
			
		||||
github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
 | 
			
		||||
@@ -64,6 +66,8 @@ github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQ
 | 
			
		||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
 | 
			
		||||
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
 | 
			
		||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
			
		||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
			
		||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 | 
			
		||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
			
		||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
			
		||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
			
		||||
@@ -76,36 +80,67 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
 | 
			
		||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 | 
			
		||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 | 
			
		||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 | 
			
		||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
 | 
			
		||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 | 
			
		||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 | 
			
		||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 | 
			
		||||
github.com/testcontainers/testcontainers-go v0.9.0/go.mod h1:b22BFXhRbg4PJmeMVWh6ftqjyZHgiIl3w274e9r3C2E=
 | 
			
		||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
 | 
			
		||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
 | 
			
		||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 | 
			
		||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
 | 
			
		||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 | 
			
		||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4=
 | 
			
		||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
 | 
			
		||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
 | 
			
		||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
 | 
			
		||||
go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI=
 | 
			
		||||
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
 | 
			
		||||
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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 | 
			
		||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 | 
			
		||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 | 
			
		||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 | 
			
		||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
			
		||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
			
		||||
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U=
 | 
			
		||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 | 
			
		||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 | 
			
		||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 | 
			
		||||
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 | 
			
		||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
 | 
			
		||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 | 
			
		||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
 | 
			
		||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 | 
			
		||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 | 
			
		||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 | 
			
		||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
			
		||||
golang.org/x/tools v0.0.0-20180810170437-e96c4e24768d/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 | 
			
		||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 | 
			
		||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 | 
			
		||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 | 
			
		||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 | 
			
		||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 | 
			
		||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 | 
			
		||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 | 
			
		||||
@@ -119,8 +154,10 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
 | 
			
		||||
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.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
			
		||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
 | 
			
		||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
			
		||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 | 
			
		||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
			
		||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
 | 
			
		||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
			
		||||
gotest.tools v0.0.0-20181223230014-1083505acf35/go.mod h1:R//lfYlUuTOTfblYI3lGoAAAebUdzjvbmQsuB7Ykd90=
 | 
			
		||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								part/part.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								part/part.go
									
									
									
									
									
								
							@@ -5,7 +5,7 @@ import (
 | 
			
		||||
	"github.com/cyrilix/robocar-protobuf/go/events"
 | 
			
		||||
	mqtt "github.com/eclipse/paho.mqtt.golang"
 | 
			
		||||
	"github.com/golang/protobuf/proto"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
	"go.uber.org/zap"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -34,7 +34,7 @@ type SteeringPart struct {
 | 
			
		||||
 | 
			
		||||
func (p *SteeringPart) Start() error {
 | 
			
		||||
	if err := registerCallbacks(p); err != nil {
 | 
			
		||||
		log.Infof("unable to rgeister callbacks: %v", err)
 | 
			
		||||
		zap.S().Errorf("unable to rgeister callbacks: %v", err)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -52,7 +52,7 @@ func (p *SteeringPart) onDriveMode(_ mqtt.Client, message mqtt.Message) {
 | 
			
		||||
	var msg events.DriveModeMessage
 | 
			
		||||
	err := proto.Unmarshal(message.Payload(), &msg)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Errorf("unable to unmarshal protobuf %T message: %v", msg, err)
 | 
			
		||||
		zap.S().Errorf("unable to unmarshal protobuf %T message: %v", msg, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -64,7 +64,7 @@ func (p *SteeringPart) onDriveMode(_ mqtt.Client, message mqtt.Message) {
 | 
			
		||||
func (p *SteeringPart) onRCSteering(_ mqtt.Client, message mqtt.Message) {
 | 
			
		||||
	p.muDriveMode.RLock()
 | 
			
		||||
	defer p.muDriveMode.RUnlock()
 | 
			
		||||
	log.Debugf("receive steering message from radio command: %v",message)
 | 
			
		||||
	zap.S().Debugf("receive steering message from radio command: %v",message)
 | 
			
		||||
	if p.driveMode == events.DriveMode_USER {
 | 
			
		||||
		// Republish same content
 | 
			
		||||
		payload := message.Payload()
 | 
			
		||||
@@ -74,7 +74,7 @@ func (p *SteeringPart) onRCSteering(_ mqtt.Client, message mqtt.Message) {
 | 
			
		||||
func (p *SteeringPart) onTFSteering(_ mqtt.Client, message mqtt.Message) {
 | 
			
		||||
	p.muDriveMode.RLock()
 | 
			
		||||
	defer p.muDriveMode.RUnlock()
 | 
			
		||||
	log.Debugf("receive steering message from tensorflow: %v",message)
 | 
			
		||||
	zap.S().Debugf("receive steering message from tensorflow: %v",message)
 | 
			
		||||
	if p.driveMode == events.DriveMode_PILOT {
 | 
			
		||||
		// Republish same content
 | 
			
		||||
		payload := message.Payload()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								vendor/go.uber.org/atomic/.codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								vendor/go.uber.org/atomic/.codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
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/
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/go.uber.org/atomic/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								vendor/go.uber.org/atomic/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
/bin
 | 
			
		||||
.DS_Store
 | 
			
		||||
/vendor
 | 
			
		||||
cover.html
 | 
			
		||||
cover.out
 | 
			
		||||
lint.log
 | 
			
		||||
 | 
			
		||||
# Binaries
 | 
			
		||||
*.test
 | 
			
		||||
 | 
			
		||||
# Profiling output
 | 
			
		||||
*.prof
 | 
			
		||||
							
								
								
									
										27
									
								
								vendor/go.uber.org/atomic/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/go.uber.org/atomic/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
sudo: false
 | 
			
		||||
language: go
 | 
			
		||||
go_import_path: go.uber.org/atomic
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  global:
 | 
			
		||||
    - GO111MODULE=on
 | 
			
		||||
 | 
			
		||||
matrix:
 | 
			
		||||
  include:
 | 
			
		||||
  - go: oldstable
 | 
			
		||||
  - go: stable
 | 
			
		||||
    env: LINT=1
 | 
			
		||||
 | 
			
		||||
cache:
 | 
			
		||||
  directories:
 | 
			
		||||
    - vendor
 | 
			
		||||
 | 
			
		||||
before_install:
 | 
			
		||||
  - go version
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
  - test -z "$LINT" || make lint
 | 
			
		||||
  - make cover
 | 
			
		||||
 | 
			
		||||
after_success:
 | 
			
		||||
  - bash <(curl -s https://codecov.io/bash)
 | 
			
		||||
							
								
								
									
										76
									
								
								vendor/go.uber.org/atomic/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								vendor/go.uber.org/atomic/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
# 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.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.6.0] - 2020-02-24
 | 
			
		||||
### Changed
 | 
			
		||||
- Drop library dependency on `golang.org/x/{lint, tools}`.
 | 
			
		||||
 | 
			
		||||
## [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.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.4.0] - 2019-05-01
 | 
			
		||||
### Added
 | 
			
		||||
 - Add `atomic.Error` type for atomic operations on `error` values.
 | 
			
		||||
 | 
			
		||||
## [1.3.2] - 2018-05-02
 | 
			
		||||
### Added
 | 
			
		||||
- Add `atomic.Duration` type for atomic operations on `time.Duration` values.
 | 
			
		||||
 | 
			
		||||
## [1.3.1] - 2017-11-14
 | 
			
		||||
### Fixed
 | 
			
		||||
- Revert optimization for `atomic.String.Store("")` which caused data races.
 | 
			
		||||
 | 
			
		||||
## [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.2.0] - 2017-04-12
 | 
			
		||||
### Added
 | 
			
		||||
- Shadow `atomic.Value` from `sync/atomic`.
 | 
			
		||||
 | 
			
		||||
## [1.1.0] - 2017-03-10
 | 
			
		||||
### Added
 | 
			
		||||
- Add atomic `Float64` type.
 | 
			
		||||
 | 
			
		||||
### Changed
 | 
			
		||||
- Support new `go.uber.org/atomic` import path.
 | 
			
		||||
 | 
			
		||||
## [1.0.0] - 2016-07-18
 | 
			
		||||
 | 
			
		||||
- Initial release.
 | 
			
		||||
 | 
			
		||||
[1.7.0]: https://github.com/uber-go/atomic/compare/v1.6.0...v1.7.0
 | 
			
		||||
[1.6.0]: https://github.com/uber-go/atomic/compare/v1.5.1...v1.6.0
 | 
			
		||||
[1.5.1]: https://github.com/uber-go/atomic/compare/v1.5.0...v1.5.1
 | 
			
		||||
[1.5.0]: https://github.com/uber-go/atomic/compare/v1.4.0...v1.5.0
 | 
			
		||||
[1.4.0]: https://github.com/uber-go/atomic/compare/v1.3.2...v1.4.0
 | 
			
		||||
[1.3.2]: https://github.com/uber-go/atomic/compare/v1.3.1...v1.3.2
 | 
			
		||||
[1.3.1]: https://github.com/uber-go/atomic/compare/v1.3.0...v1.3.1
 | 
			
		||||
[1.3.0]: https://github.com/uber-go/atomic/compare/v1.2.0...v1.3.0
 | 
			
		||||
[1.2.0]: https://github.com/uber-go/atomic/compare/v1.1.0...v1.2.0
 | 
			
		||||
[1.1.0]: https://github.com/uber-go/atomic/compare/v1.0.0...v1.1.0
 | 
			
		||||
[1.0.0]: https://github.com/uber-go/atomic/releases/tag/v1.0.0
 | 
			
		||||
							
								
								
									
										19
									
								
								vendor/go.uber.org/atomic/LICENSE.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								vendor/go.uber.org/atomic/LICENSE.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
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.
 | 
			
		||||
							
								
								
									
										78
									
								
								vendor/go.uber.org/atomic/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								vendor/go.uber.org/atomic/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
# 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."; \
 | 
			
		||||
		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
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								vendor/go.uber.org/atomic/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
# 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://travis-ci.com/uber-go/atomic.svg?branch=master
 | 
			
		||||
[ci]: https://travis-ci.com/uber-go/atomic
 | 
			
		||||
[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
 | 
			
		||||
							
								
								
									
										81
									
								
								vendor/go.uber.org/atomic/bool.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								vendor/go.uber.org/atomic/bool.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
// @generated Code generated by gen-atomicwrapper.
 | 
			
		||||
 | 
			
		||||
// 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 (
 | 
			
		||||
	"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(v bool) *Bool {
 | 
			
		||||
	x := &Bool{}
 | 
			
		||||
	if v != _zeroBool {
 | 
			
		||||
		x.Store(v)
 | 
			
		||||
	}
 | 
			
		||||
	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(v bool) {
 | 
			
		||||
	x.v.Store(boolToInt(v))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CAS is an atomic compare-and-swap for bool values.
 | 
			
		||||
func (x *Bool) CAS(o, n bool) bool {
 | 
			
		||||
	return x.v.CAS(boolToInt(o), boolToInt(n))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Swap atomically stores the given bool and returns the old
 | 
			
		||||
// value.
 | 
			
		||||
func (x *Bool) Swap(o bool) bool {
 | 
			
		||||
	return truthy(x.v.Swap(boolToInt(o)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								vendor/go.uber.org/atomic/bool_ext.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
// 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() 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
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/go.uber.org/atomic/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
// 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
 | 
			
		||||
							
								
								
									
										82
									
								
								vendor/go.uber.org/atomic/duration.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								vendor/go.uber.org/atomic/duration.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
// @generated Code generated by gen-atomicwrapper.
 | 
			
		||||
 | 
			
		||||
// 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 (
 | 
			
		||||
	"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(v time.Duration) *Duration {
 | 
			
		||||
	x := &Duration{}
 | 
			
		||||
	if v != _zeroDuration {
 | 
			
		||||
		x.Store(v)
 | 
			
		||||
	}
 | 
			
		||||
	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(v time.Duration) {
 | 
			
		||||
	x.v.Store(int64(v))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CAS is an atomic compare-and-swap for time.Duration values.
 | 
			
		||||
func (x *Duration) CAS(o, n time.Duration) bool {
 | 
			
		||||
	return x.v.CAS(int64(o), int64(n))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Swap atomically stores the given time.Duration and returns the old
 | 
			
		||||
// value.
 | 
			
		||||
func (x *Duration) Swap(o time.Duration) time.Duration {
 | 
			
		||||
	return time.Duration(x.v.Swap(int64(o)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								vendor/go.uber.org/atomic/duration_ext.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
// 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(n time.Duration) time.Duration {
 | 
			
		||||
	return time.Duration(d.v.Add(int64(n)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sub atomically subtracts from the wrapped time.Duration and returns the new value.
 | 
			
		||||
func (d *Duration) Sub(n time.Duration) time.Duration {
 | 
			
		||||
	return time.Duration(d.v.Sub(int64(n)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String encodes the wrapped value as a string.
 | 
			
		||||
func (d *Duration) String() string {
 | 
			
		||||
	return d.Load().String()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								vendor/go.uber.org/atomic/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								vendor/go.uber.org/atomic/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
// @generated Code generated by gen-atomicwrapper.
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
// 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(v error) *Error {
 | 
			
		||||
	x := &Error{}
 | 
			
		||||
	if v != _zeroError {
 | 
			
		||||
		x.Store(v)
 | 
			
		||||
	}
 | 
			
		||||
	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(v error) {
 | 
			
		||||
	x.v.Store(packError(v))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								vendor/go.uber.org/atomic/error_ext.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								vendor/go.uber.org/atomic/error_ext.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
// 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 -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										76
									
								
								vendor/go.uber.org/atomic/float64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								vendor/go.uber.org/atomic/float64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
// @generated Code generated by gen-atomicwrapper.
 | 
			
		||||
 | 
			
		||||
// 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 (
 | 
			
		||||
	"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(v float64) *Float64 {
 | 
			
		||||
	x := &Float64{}
 | 
			
		||||
	if v != _zeroFloat64 {
 | 
			
		||||
		x.Store(v)
 | 
			
		||||
	}
 | 
			
		||||
	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(v float64) {
 | 
			
		||||
	x.v.Store(math.Float64bits(v))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CAS is an atomic compare-and-swap for float64 values.
 | 
			
		||||
func (x *Float64) CAS(o, n float64) bool {
 | 
			
		||||
	return x.v.CAS(math.Float64bits(o), math.Float64bits(n))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								vendor/go.uber.org/atomic/float64_ext.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								vendor/go.uber.org/atomic/float64_ext.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
// 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=Float64 -type=float64 -wrapped=Uint64 -pack=math.Float64bits -unpack=math.Float64frombits -cas -json -imports math -file=float64.go
 | 
			
		||||
 | 
			
		||||
// Add atomically adds to the wrapped float64 and returns the new value.
 | 
			
		||||
func (f *Float64) Add(s float64) float64 {
 | 
			
		||||
	for {
 | 
			
		||||
		old := f.Load()
 | 
			
		||||
		new := old + s
 | 
			
		||||
		if f.CAS(old, new) {
 | 
			
		||||
			return new
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sub atomically subtracts from the wrapped float64 and returns the new value.
 | 
			
		||||
func (f *Float64) Sub(s float64) float64 {
 | 
			
		||||
	return f.Add(-s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								vendor/go.uber.org/atomic/gen.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/go.uber.org/atomic/gen.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
// 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
 | 
			
		||||
							
								
								
									
										102
									
								
								vendor/go.uber.org/atomic/int32.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								vendor/go.uber.org/atomic/int32.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
			
		||||
// @generated Code generated by gen-atomicint.
 | 
			
		||||
 | 
			
		||||
// 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 (
 | 
			
		||||
	"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(i int32) *Int32 {
 | 
			
		||||
	return &Int32{v: i}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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(n int32) int32 {
 | 
			
		||||
	return atomic.AddInt32(&i.v, n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sub atomically subtracts from the wrapped int32 and returns the new value.
 | 
			
		||||
func (i *Int32) Sub(n int32) int32 {
 | 
			
		||||
	return atomic.AddInt32(&i.v, -n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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.
 | 
			
		||||
func (i *Int32) CAS(old, new int32) bool {
 | 
			
		||||
	return atomic.CompareAndSwapInt32(&i.v, old, new)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Store atomically stores the passed value.
 | 
			
		||||
func (i *Int32) Store(n int32) {
 | 
			
		||||
	atomic.StoreInt32(&i.v, n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Swap atomically swaps the wrapped int32 and returns the old value.
 | 
			
		||||
func (i *Int32) Swap(n int32) int32 {
 | 
			
		||||
	return atomic.SwapInt32(&i.v, n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										102
									
								
								vendor/go.uber.org/atomic/int64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								vendor/go.uber.org/atomic/int64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
			
		||||
// @generated Code generated by gen-atomicint.
 | 
			
		||||
 | 
			
		||||
// 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 (
 | 
			
		||||
	"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(i int64) *Int64 {
 | 
			
		||||
	return &Int64{v: i}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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(n int64) int64 {
 | 
			
		||||
	return atomic.AddInt64(&i.v, n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sub atomically subtracts from the wrapped int64 and returns the new value.
 | 
			
		||||
func (i *Int64) Sub(n int64) int64 {
 | 
			
		||||
	return atomic.AddInt64(&i.v, -n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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.
 | 
			
		||||
func (i *Int64) CAS(old, new int64) bool {
 | 
			
		||||
	return atomic.CompareAndSwapInt64(&i.v, old, new)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Store atomically stores the passed value.
 | 
			
		||||
func (i *Int64) Store(n int64) {
 | 
			
		||||
	atomic.StoreInt64(&i.v, n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Swap atomically swaps the wrapped int64 and returns the old value.
 | 
			
		||||
func (i *Int64) Swap(n int64) int64 {
 | 
			
		||||
	return atomic.SwapInt64(&i.v, n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								vendor/go.uber.org/atomic/nocmp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
// 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()
 | 
			
		||||
							
								
								
									
										54
									
								
								vendor/go.uber.org/atomic/string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								vendor/go.uber.org/atomic/string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
// @generated Code generated by gen-atomicwrapper.
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
// 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(v string) *String {
 | 
			
		||||
	x := &String{}
 | 
			
		||||
	if v != _zeroString {
 | 
			
		||||
		x.Store(v)
 | 
			
		||||
	}
 | 
			
		||||
	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(v string) {
 | 
			
		||||
	x.v.Store(v)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								vendor/go.uber.org/atomic/string_ext.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								vendor/go.uber.org/atomic/string_ext.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
// 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-atomicwrapper -name=String -type=string -wrapped=Value -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										102
									
								
								vendor/go.uber.org/atomic/uint32.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								vendor/go.uber.org/atomic/uint32.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
			
		||||
// @generated Code generated by gen-atomicint.
 | 
			
		||||
 | 
			
		||||
// 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 (
 | 
			
		||||
	"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(i uint32) *Uint32 {
 | 
			
		||||
	return &Uint32{v: i}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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(n uint32) uint32 {
 | 
			
		||||
	return atomic.AddUint32(&i.v, n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sub atomically subtracts from the wrapped uint32 and returns the new value.
 | 
			
		||||
func (i *Uint32) Sub(n uint32) uint32 {
 | 
			
		||||
	return atomic.AddUint32(&i.v, ^(n - 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.
 | 
			
		||||
func (i *Uint32) CAS(old, new uint32) bool {
 | 
			
		||||
	return atomic.CompareAndSwapUint32(&i.v, old, new)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Store atomically stores the passed value.
 | 
			
		||||
func (i *Uint32) Store(n uint32) {
 | 
			
		||||
	atomic.StoreUint32(&i.v, n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Swap atomically swaps the wrapped uint32 and returns the old value.
 | 
			
		||||
func (i *Uint32) Swap(n uint32) uint32 {
 | 
			
		||||
	return atomic.SwapUint32(&i.v, n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										102
									
								
								vendor/go.uber.org/atomic/uint64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								vendor/go.uber.org/atomic/uint64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
			
		||||
// @generated Code generated by gen-atomicint.
 | 
			
		||||
 | 
			
		||||
// 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 (
 | 
			
		||||
	"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(i uint64) *Uint64 {
 | 
			
		||||
	return &Uint64{v: i}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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(n uint64) uint64 {
 | 
			
		||||
	return atomic.AddUint64(&i.v, n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sub atomically subtracts from the wrapped uint64 and returns the new value.
 | 
			
		||||
func (i *Uint64) Sub(n uint64) uint64 {
 | 
			
		||||
	return atomic.AddUint64(&i.v, ^(n - 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.
 | 
			
		||||
func (i *Uint64) CAS(old, new uint64) bool {
 | 
			
		||||
	return atomic.CompareAndSwapUint64(&i.v, old, new)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Store atomically stores the passed value.
 | 
			
		||||
func (i *Uint64) Store(n uint64) {
 | 
			
		||||
	atomic.StoreUint64(&i.v, n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Swap atomically swaps the wrapped uint64 and returns the old value.
 | 
			
		||||
func (i *Uint64) Swap(n uint64) uint64 {
 | 
			
		||||
	return atomic.SwapUint64(&i.v, n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								vendor/go.uber.org/atomic/value.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								vendor/go.uber.org/atomic/value.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
// 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 {
 | 
			
		||||
	atomic.Value
 | 
			
		||||
 | 
			
		||||
	_ nocmp // disallow non-atomic comparison
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								vendor/go.uber.org/multierr/.codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/go.uber.org/multierr/.codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
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
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								vendor/go.uber.org/multierr/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
/vendor
 | 
			
		||||
cover.html
 | 
			
		||||
cover.out
 | 
			
		||||
/bin
 | 
			
		||||
							
								
								
									
										23
									
								
								vendor/go.uber.org/multierr/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/go.uber.org/multierr/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
sudo: false
 | 
			
		||||
language: go
 | 
			
		||||
go_import_path: go.uber.org/multierr
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  global:
 | 
			
		||||
    - GO111MODULE=on
 | 
			
		||||
 | 
			
		||||
go:
 | 
			
		||||
  - oldstable
 | 
			
		||||
  - stable
 | 
			
		||||
 | 
			
		||||
before_install:
 | 
			
		||||
- go version
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
- |
 | 
			
		||||
  set -e
 | 
			
		||||
  make lint
 | 
			
		||||
  make cover
 | 
			
		||||
 | 
			
		||||
after_success:
 | 
			
		||||
- bash <(curl -s https://codecov.io/bash)
 | 
			
		||||
							
								
								
									
										60
									
								
								vendor/go.uber.org/multierr/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								vendor/go.uber.org/multierr/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
Releases
 | 
			
		||||
========
 | 
			
		||||
 | 
			
		||||
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
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								vendor/go.uber.org/multierr/LICENSE.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
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.
 | 
			
		||||
							
								
								
									
										42
									
								
								vendor/go.uber.org/multierr/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/go.uber.org/multierr/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
# 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 -coverprofile=cover.out -coverpkg=./... -v ./...
 | 
			
		||||
	go tool cover -html=cover.out -o cover.html
 | 
			
		||||
 | 
			
		||||
update-license:
 | 
			
		||||
	@cd tools && go install go.uber.org/tools/update-license
 | 
			
		||||
	@$(GOBIN)/update-license $(GO_FILES)
 | 
			
		||||
							
								
								
									
										23
									
								
								vendor/go.uber.org/multierr/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/go.uber.org/multierr/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
# 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://godoc.org/go.uber.org/multierr?status.svg
 | 
			
		||||
[doc]: https://godoc.org/go.uber.org/multierr
 | 
			
		||||
[ci-img]: https://travis-ci.com/uber-go/multierr.svg?branch=master
 | 
			
		||||
[cov-img]: https://codecov.io/gh/uber-go/multierr/branch/master/graph/badge.svg
 | 
			
		||||
[ci]: https://travis-ci.com/uber-go/multierr
 | 
			
		||||
[cov]: https://codecov.io/gh/uber-go/multierr
 | 
			
		||||
							
								
								
									
										449
									
								
								vendor/go.uber.org/multierr/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										449
									
								
								vendor/go.uber.org/multierr/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,449 @@
 | 
			
		||||
// Copyright (c) 2019 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())
 | 
			
		||||
//
 | 
			
		||||
// This makes it possible to record resource cleanup failures from deferred
 | 
			
		||||
// blocks with the help of named return values.
 | 
			
		||||
//
 | 
			
		||||
// 	func sendRequest(req Request) (err error) {
 | 
			
		||||
// 		conn, err := openConnection()
 | 
			
		||||
// 		if err != nil {
 | 
			
		||||
// 			return err
 | 
			
		||||
// 		}
 | 
			
		||||
// 		defer func() {
 | 
			
		||||
// 			err = multierr.Append(err, conn.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)
 | 
			
		||||
// 	}
 | 
			
		||||
//
 | 
			
		||||
// 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"
 | 
			
		||||
	"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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
	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 {
 | 
			
		||||
			// already flat
 | 
			
		||||
			return &multiError{errors: errors}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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 verison 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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								vendor/go.uber.org/multierr/glide.yaml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/go.uber.org/multierr/glide.yaml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
package: go.uber.org/multierr
 | 
			
		||||
import:
 | 
			
		||||
- package: go.uber.org/atomic
 | 
			
		||||
  version: ^1
 | 
			
		||||
testImport:
 | 
			
		||||
- package: github.com/stretchr/testify
 | 
			
		||||
  subpackages:
 | 
			
		||||
  - assert
 | 
			
		||||
							
								
								
									
										52
									
								
								vendor/go.uber.org/multierr/go113.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								vendor/go.uber.org/multierr/go113.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
// Copyright (c) 2019 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.
 | 
			
		||||
 | 
			
		||||
// +build go1.13
 | 
			
		||||
 | 
			
		||||
package multierr
 | 
			
		||||
 | 
			
		||||
import "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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								vendor/go.uber.org/zap/.codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								vendor/go.uber.org/zap/.codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
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
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								vendor/go.uber.org/zap/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
# 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
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								vendor/go.uber.org/zap/.readme.tmpl
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
			
		||||
# :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 zap's [glide.lock][] file. [↩](#anchor-versions)
 | 
			
		||||
 | 
			
		||||
[doc-img]: https://godoc.org/go.uber.org/zap?status.svg
 | 
			
		||||
[doc]: https://godoc.org/go.uber.org/zap
 | 
			
		||||
[ci-img]: https://travis-ci.com/uber-go/zap.svg?branch=master
 | 
			
		||||
[ci]: https://travis-ci.com/uber-go/zap
 | 
			
		||||
[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
 | 
			
		||||
[glide.lock]: https://github.com/uber-go/zap/blob/master/glide.lock
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										516
									
								
								vendor/go.uber.org/zap/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										516
									
								
								vendor/go.uber.org/zap/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,516 @@
 | 
			
		||||
# 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.19.1 (8 Sep 2021)
 | 
			
		||||
 | 
			
		||||
### Fixed
 | 
			
		||||
* [#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
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								vendor/go.uber.org/zap/CODE_OF_CONDUCT.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
# 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/
 | 
			
		||||
							
								
								
									
										75
									
								
								vendor/go.uber.org/zap/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								vendor/go.uber.org/zap/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
# 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:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
make test
 | 
			
		||||
make lint
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If you're not using the minor version of Go specified in the Makefile's
 | 
			
		||||
`LINTABLE_MINOR_VERSIONS` variable, `make lint` doesn't do anything. This is
 | 
			
		||||
fine, but it means that you'll only discover lint failures after you open your
 | 
			
		||||
pull request.
 | 
			
		||||
 | 
			
		||||
## Making Changes
 | 
			
		||||
 | 
			
		||||
Start by creating a new branch for your changes:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
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
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								vendor/go.uber.org/zap/FAQ.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,164 @@
 | 
			
		||||
# 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
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								vendor/go.uber.org/zap/LICENSE.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
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
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								vendor/go.uber.org/zap/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										134
									
								
								vendor/go.uber.org/zap/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								vendor/go.uber.org/zap/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
# :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 | 862 ns/op | +0% | 5 allocs/op
 | 
			
		||||
| :zap: zap (sugared) | 1250 ns/op | +45% | 11 allocs/op
 | 
			
		||||
| zerolog | 4021 ns/op | +366% | 76 allocs/op
 | 
			
		||||
| go-kit | 4542 ns/op | +427% | 105 allocs/op
 | 
			
		||||
| apex/log | 26785 ns/op | +3007% | 115 allocs/op
 | 
			
		||||
| logrus | 29501 ns/op | +3322% | 125 allocs/op
 | 
			
		||||
| log15 | 29906 ns/op | +3369% | 122 allocs/op
 | 
			
		||||
 | 
			
		||||
Log a message with a logger that already has 10 fields of context:
 | 
			
		||||
 | 
			
		||||
| Package | Time | Time % to zap | Objects Allocated |
 | 
			
		||||
| :------ | :--: | :-----------: | :---------------: |
 | 
			
		||||
| :zap: zap | 126 ns/op | +0% | 0 allocs/op
 | 
			
		||||
| :zap: zap (sugared) | 187 ns/op | +48% | 2 allocs/op
 | 
			
		||||
| zerolog | 88 ns/op | -30% | 0 allocs/op
 | 
			
		||||
| go-kit | 5087 ns/op | +3937% | 103 allocs/op
 | 
			
		||||
| log15 | 18548 ns/op | +14621% | 73 allocs/op
 | 
			
		||||
| apex/log | 26012 ns/op | +20544% | 104 allocs/op
 | 
			
		||||
| logrus | 27236 ns/op | +21516% | 113 allocs/op
 | 
			
		||||
 | 
			
		||||
Log a static string, without any context or `printf`-style templating:
 | 
			
		||||
 | 
			
		||||
| Package | Time | Time % to zap | Objects Allocated |
 | 
			
		||||
| :------ | :--: | :-----------: | :---------------: |
 | 
			
		||||
| :zap: zap | 118 ns/op | +0% | 0 allocs/op
 | 
			
		||||
| :zap: zap (sugared) | 191 ns/op | +62% | 2 allocs/op
 | 
			
		||||
| zerolog | 93 ns/op | -21% | 0 allocs/op
 | 
			
		||||
| go-kit | 280 ns/op | +137% | 11 allocs/op
 | 
			
		||||
| standard library | 499 ns/op | +323% | 2 allocs/op
 | 
			
		||||
| apex/log | 1990 ns/op | +1586% | 10 allocs/op
 | 
			
		||||
| logrus | 3129 ns/op | +2552% | 24 allocs/op
 | 
			
		||||
| log15 | 3887 ns/op | +3194% | 23 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
									
									
										Normal file
									
								
							
							
						
						
									
										320
									
								
								vendor/go.uber.org/zap/array.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,320 @@
 | 
			
		||||
// 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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										141
									
								
								vendor/go.uber.org/zap/buffer/buffer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								vendor/go.uber.org/zap/buffer/buffer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
			
		||||
// 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)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								vendor/go.uber.org/zap/buffer/pool.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								vendor/go.uber.org/zap/buffer/pool.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
import "sync"
 | 
			
		||||
 | 
			
		||||
// A Pool is a type-safe wrapper around a sync.Pool.
 | 
			
		||||
type Pool struct {
 | 
			
		||||
	p *sync.Pool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewPool constructs a new Pool.
 | 
			
		||||
func NewPool() Pool {
 | 
			
		||||
	return Pool{p: &sync.Pool{
 | 
			
		||||
		New: func() interface{} {
 | 
			
		||||
			return &Buffer{bs: make([]byte, 0, _size)}
 | 
			
		||||
		},
 | 
			
		||||
	}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get retrieves a Buffer from the pool, creating one if necessary.
 | 
			
		||||
func (p Pool) Get() *Buffer {
 | 
			
		||||
	buf := p.p.Get().(*Buffer)
 | 
			
		||||
	buf.Reset()
 | 
			
		||||
	buf.pool = p
 | 
			
		||||
	return buf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p Pool) put(buf *Buffer) {
 | 
			
		||||
	p.p.Put(buf)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								vendor/go.uber.org/zap/checklicense.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								vendor/go.uber.org/zap/checklicense.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
#!/bin/bash -e
 | 
			
		||||
 | 
			
		||||
ERROR_COUNT=0
 | 
			
		||||
while read -r file
 | 
			
		||||
do
 | 
			
		||||
	case "$(head -1 "${file}")" in
 | 
			
		||||
		*"Copyright (c) "*" Uber Technologies, Inc.")
 | 
			
		||||
			# everything's cool
 | 
			
		||||
			;;
 | 
			
		||||
		*)
 | 
			
		||||
			echo "$file is missing license header."
 | 
			
		||||
			(( ERROR_COUNT++ ))
 | 
			
		||||
			;;
 | 
			
		||||
	esac
 | 
			
		||||
done < <(git ls-files "*\.go")
 | 
			
		||||
 | 
			
		||||
exit $ERROR_COUNT
 | 
			
		||||
							
								
								
									
										264
									
								
								vendor/go.uber.org/zap/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										264
									
								
								vendor/go.uber.org/zap/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,264 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/zapcore"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// SamplingConfig sets a sampling strategy for the logger. Sampling caps the
 | 
			
		||||
// global CPU and I/O load that logging puts on your process while attempting
 | 
			
		||||
// to preserve a representative subset of your logs.
 | 
			
		||||
//
 | 
			
		||||
// If specified, the Sampler will invoke the Hook after each decision.
 | 
			
		||||
//
 | 
			
		||||
// Values configured here are per-second. See zapcore.NewSamplerWithOptions for
 | 
			
		||||
// details.
 | 
			
		||||
type SamplingConfig struct {
 | 
			
		||||
	Initial    int                                           `json:"initial" yaml:"initial"`
 | 
			
		||||
	Thereafter int                                           `json:"thereafter" yaml:"thereafter"`
 | 
			
		||||
	Hook       func(zapcore.Entry, zapcore.SamplingDecision) `json:"-" yaml:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Config offers a declarative way to construct a logger. It doesn't do
 | 
			
		||||
// anything that can't be done with New, Options, and the various
 | 
			
		||||
// zapcore.WriteSyncer and zapcore.Core wrappers, but it's a simpler way to
 | 
			
		||||
// toggle common options.
 | 
			
		||||
//
 | 
			
		||||
// Note that Config intentionally supports only the most common options. More
 | 
			
		||||
// unusual logging setups (logging to network connections or message queues,
 | 
			
		||||
// splitting output between multiple files, etc.) are possible, but require
 | 
			
		||||
// direct use of the zapcore package. For sample code, see the package-level
 | 
			
		||||
// BasicConfiguration and AdvancedConfiguration examples.
 | 
			
		||||
//
 | 
			
		||||
// For an example showing runtime log level changes, see the documentation for
 | 
			
		||||
// AtomicLevel.
 | 
			
		||||
type Config struct {
 | 
			
		||||
	// Level is the minimum enabled logging level. Note that this is a dynamic
 | 
			
		||||
	// level, so calling Config.Level.SetLevel will atomically change the log
 | 
			
		||||
	// level of all loggers descended from this config.
 | 
			
		||||
	Level AtomicLevel `json:"level" yaml:"level"`
 | 
			
		||||
	// Development puts the logger in development mode, which changes the
 | 
			
		||||
	// behavior of DPanicLevel and takes stacktraces more liberally.
 | 
			
		||||
	Development bool `json:"development" yaml:"development"`
 | 
			
		||||
	// DisableCaller stops annotating logs with the calling function's file
 | 
			
		||||
	// name and line number. By default, all logs are annotated.
 | 
			
		||||
	DisableCaller bool `json:"disableCaller" yaml:"disableCaller"`
 | 
			
		||||
	// DisableStacktrace completely disables automatic stacktrace capturing. By
 | 
			
		||||
	// default, stacktraces are captured for WarnLevel and above logs in
 | 
			
		||||
	// development and ErrorLevel and above in production.
 | 
			
		||||
	DisableStacktrace bool `json:"disableStacktrace" yaml:"disableStacktrace"`
 | 
			
		||||
	// Sampling sets a sampling policy. A nil SamplingConfig disables sampling.
 | 
			
		||||
	Sampling *SamplingConfig `json:"sampling" yaml:"sampling"`
 | 
			
		||||
	// Encoding sets the logger's encoding. Valid values are "json" and
 | 
			
		||||
	// "console", as well as any third-party encodings registered via
 | 
			
		||||
	// RegisterEncoder.
 | 
			
		||||
	Encoding string `json:"encoding" yaml:"encoding"`
 | 
			
		||||
	// EncoderConfig sets options for the chosen encoder. See
 | 
			
		||||
	// zapcore.EncoderConfig for details.
 | 
			
		||||
	EncoderConfig zapcore.EncoderConfig `json:"encoderConfig" yaml:"encoderConfig"`
 | 
			
		||||
	// OutputPaths is a list of URLs or file paths to write logging output to.
 | 
			
		||||
	// See Open for details.
 | 
			
		||||
	OutputPaths []string `json:"outputPaths" yaml:"outputPaths"`
 | 
			
		||||
	// ErrorOutputPaths is a list of URLs to write internal logger errors to.
 | 
			
		||||
	// The default is standard error.
 | 
			
		||||
	//
 | 
			
		||||
	// Note that this setting only affects internal errors; for sample code that
 | 
			
		||||
	// sends error-level logs to a different location from info- and debug-level
 | 
			
		||||
	// logs, see the package-level AdvancedConfiguration example.
 | 
			
		||||
	ErrorOutputPaths []string `json:"errorOutputPaths" yaml:"errorOutputPaths"`
 | 
			
		||||
	// InitialFields is a collection of fields to add to the root logger.
 | 
			
		||||
	InitialFields map[string]interface{} `json:"initialFields" yaml:"initialFields"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewProductionEncoderConfig returns an opinionated EncoderConfig for
 | 
			
		||||
// production environments.
 | 
			
		||||
func NewProductionEncoderConfig() zapcore.EncoderConfig {
 | 
			
		||||
	return zapcore.EncoderConfig{
 | 
			
		||||
		TimeKey:        "ts",
 | 
			
		||||
		LevelKey:       "level",
 | 
			
		||||
		NameKey:        "logger",
 | 
			
		||||
		CallerKey:      "caller",
 | 
			
		||||
		FunctionKey:    zapcore.OmitKey,
 | 
			
		||||
		MessageKey:     "msg",
 | 
			
		||||
		StacktraceKey:  "stacktrace",
 | 
			
		||||
		LineEnding:     zapcore.DefaultLineEnding,
 | 
			
		||||
		EncodeLevel:    zapcore.LowercaseLevelEncoder,
 | 
			
		||||
		EncodeTime:     zapcore.EpochTimeEncoder,
 | 
			
		||||
		EncodeDuration: zapcore.SecondsDurationEncoder,
 | 
			
		||||
		EncodeCaller:   zapcore.ShortCallerEncoder,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewProductionConfig is a reasonable production logging configuration.
 | 
			
		||||
// Logging is enabled at InfoLevel and above.
 | 
			
		||||
//
 | 
			
		||||
// It uses a JSON encoder, writes to standard error, and enables sampling.
 | 
			
		||||
// Stacktraces are automatically included on logs of ErrorLevel and above.
 | 
			
		||||
func NewProductionConfig() Config {
 | 
			
		||||
	return Config{
 | 
			
		||||
		Level:       NewAtomicLevelAt(InfoLevel),
 | 
			
		||||
		Development: false,
 | 
			
		||||
		Sampling: &SamplingConfig{
 | 
			
		||||
			Initial:    100,
 | 
			
		||||
			Thereafter: 100,
 | 
			
		||||
		},
 | 
			
		||||
		Encoding:         "json",
 | 
			
		||||
		EncoderConfig:    NewProductionEncoderConfig(),
 | 
			
		||||
		OutputPaths:      []string{"stderr"},
 | 
			
		||||
		ErrorOutputPaths: []string{"stderr"},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewDevelopmentEncoderConfig returns an opinionated EncoderConfig for
 | 
			
		||||
// development environments.
 | 
			
		||||
func NewDevelopmentEncoderConfig() zapcore.EncoderConfig {
 | 
			
		||||
	return zapcore.EncoderConfig{
 | 
			
		||||
		// Keys can be anything except the empty string.
 | 
			
		||||
		TimeKey:        "T",
 | 
			
		||||
		LevelKey:       "L",
 | 
			
		||||
		NameKey:        "N",
 | 
			
		||||
		CallerKey:      "C",
 | 
			
		||||
		FunctionKey:    zapcore.OmitKey,
 | 
			
		||||
		MessageKey:     "M",
 | 
			
		||||
		StacktraceKey:  "S",
 | 
			
		||||
		LineEnding:     zapcore.DefaultLineEnding,
 | 
			
		||||
		EncodeLevel:    zapcore.CapitalLevelEncoder,
 | 
			
		||||
		EncodeTime:     zapcore.ISO8601TimeEncoder,
 | 
			
		||||
		EncodeDuration: zapcore.StringDurationEncoder,
 | 
			
		||||
		EncodeCaller:   zapcore.ShortCallerEncoder,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewDevelopmentConfig is a reasonable development logging configuration.
 | 
			
		||||
// Logging is enabled at DebugLevel and above.
 | 
			
		||||
//
 | 
			
		||||
// It enables development mode (which makes DPanicLevel logs panic), uses a
 | 
			
		||||
// console encoder, writes to standard error, and disables sampling.
 | 
			
		||||
// Stacktraces are automatically included on logs of WarnLevel and above.
 | 
			
		||||
func NewDevelopmentConfig() Config {
 | 
			
		||||
	return Config{
 | 
			
		||||
		Level:            NewAtomicLevelAt(DebugLevel),
 | 
			
		||||
		Development:      true,
 | 
			
		||||
		Encoding:         "console",
 | 
			
		||||
		EncoderConfig:    NewDevelopmentEncoderConfig(),
 | 
			
		||||
		OutputPaths:      []string{"stderr"},
 | 
			
		||||
		ErrorOutputPaths: []string{"stderr"},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Build constructs a logger from the Config and Options.
 | 
			
		||||
func (cfg Config) Build(opts ...Option) (*Logger, error) {
 | 
			
		||||
	enc, err := cfg.buildEncoder()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sink, errSink, err := cfg.openSinks()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if cfg.Level == (AtomicLevel{}) {
 | 
			
		||||
		return nil, fmt.Errorf("missing Level")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log := New(
 | 
			
		||||
		zapcore.NewCore(enc, sink, cfg.Level),
 | 
			
		||||
		cfg.buildOptions(errSink)...,
 | 
			
		||||
	)
 | 
			
		||||
	if len(opts) > 0 {
 | 
			
		||||
		log = log.WithOptions(opts...)
 | 
			
		||||
	}
 | 
			
		||||
	return log, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cfg Config) buildOptions(errSink zapcore.WriteSyncer) []Option {
 | 
			
		||||
	opts := []Option{ErrorOutput(errSink)}
 | 
			
		||||
 | 
			
		||||
	if cfg.Development {
 | 
			
		||||
		opts = append(opts, Development())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !cfg.DisableCaller {
 | 
			
		||||
		opts = append(opts, AddCaller())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stackLevel := ErrorLevel
 | 
			
		||||
	if cfg.Development {
 | 
			
		||||
		stackLevel = WarnLevel
 | 
			
		||||
	}
 | 
			
		||||
	if !cfg.DisableStacktrace {
 | 
			
		||||
		opts = append(opts, AddStacktrace(stackLevel))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if scfg := cfg.Sampling; scfg != nil {
 | 
			
		||||
		opts = append(opts, WrapCore(func(core zapcore.Core) zapcore.Core {
 | 
			
		||||
			var samplerOpts []zapcore.SamplerOption
 | 
			
		||||
			if scfg.Hook != nil {
 | 
			
		||||
				samplerOpts = append(samplerOpts, zapcore.SamplerHook(scfg.Hook))
 | 
			
		||||
			}
 | 
			
		||||
			return zapcore.NewSamplerWithOptions(
 | 
			
		||||
				core,
 | 
			
		||||
				time.Second,
 | 
			
		||||
				cfg.Sampling.Initial,
 | 
			
		||||
				cfg.Sampling.Thereafter,
 | 
			
		||||
				samplerOpts...,
 | 
			
		||||
			)
 | 
			
		||||
		}))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(cfg.InitialFields) > 0 {
 | 
			
		||||
		fs := make([]Field, 0, len(cfg.InitialFields))
 | 
			
		||||
		keys := make([]string, 0, len(cfg.InitialFields))
 | 
			
		||||
		for k := range cfg.InitialFields {
 | 
			
		||||
			keys = append(keys, k)
 | 
			
		||||
		}
 | 
			
		||||
		sort.Strings(keys)
 | 
			
		||||
		for _, k := range keys {
 | 
			
		||||
			fs = append(fs, Any(k, cfg.InitialFields[k]))
 | 
			
		||||
		}
 | 
			
		||||
		opts = append(opts, Fields(fs...))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return opts
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cfg Config) openSinks() (zapcore.WriteSyncer, zapcore.WriteSyncer, error) {
 | 
			
		||||
	sink, closeOut, err := Open(cfg.OutputPaths...)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
	errSink, _, err := Open(cfg.ErrorOutputPaths...)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		closeOut()
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return sink, errSink, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cfg Config) buildEncoder() (zapcore.Encoder, error) {
 | 
			
		||||
	return newEncoder(cfg.Encoding, cfg.EncoderConfig)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										113
									
								
								vendor/go.uber.org/zap/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								vendor/go.uber.org/zap/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
			
		||||
// 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 provides fast, structured, leveled logging.
 | 
			
		||||
//
 | 
			
		||||
// 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 json.Marshal and
 | 
			
		||||
// fmt.Fprintf to log tons of interface{} 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.
 | 
			
		||||
//
 | 
			
		||||
// Choosing a Logger
 | 
			
		||||
//
 | 
			
		||||
// In contexts where performance is nice, but not critical, use the
 | 
			
		||||
// SugaredLogger. It's 4-10x faster than other structured logging packages and
 | 
			
		||||
// supports both structured and printf-style logging. Like log15 and go-kit,
 | 
			
		||||
// the SugaredLogger's structured logging APIs are loosely typed and accept a
 | 
			
		||||
// variadic number of key-value pairs. (For more advanced use cases, they also
 | 
			
		||||
// accept strongly typed fields - see the SugaredLogger.With documentation for
 | 
			
		||||
// details.)
 | 
			
		||||
//  sugar := zap.NewExample().Sugar()
 | 
			
		||||
//  defer sugar.Sync()
 | 
			
		||||
//  sugar.Infow("failed to fetch URL",
 | 
			
		||||
//    "url", "http://example.com",
 | 
			
		||||
//    "attempt", 3,
 | 
			
		||||
//    "backoff", time.Second,
 | 
			
		||||
//  )
 | 
			
		||||
//  sugar.Infof("failed to fetch URL: %s", "http://example.com")
 | 
			
		||||
//
 | 
			
		||||
// By default, loggers are unbuffered. However, since zap's low-level APIs
 | 
			
		||||
// allow buffering, calling Sync before letting your process exit is a good
 | 
			
		||||
// habit.
 | 
			
		||||
//
 | 
			
		||||
// In the rare contexts where every microsecond and every allocation matter,
 | 
			
		||||
// use the Logger. It's even faster than the SugaredLogger and allocates far
 | 
			
		||||
// less, but it only supports strongly-typed, structured logging.
 | 
			
		||||
//  logger := zap.NewExample()
 | 
			
		||||
//  defer logger.Sync()
 | 
			
		||||
//  logger.Info("failed to fetch URL",
 | 
			
		||||
//    zap.String("url", "http://example.com"),
 | 
			
		||||
//    zap.Int("attempt", 3),
 | 
			
		||||
//    zap.Duration("backoff", time.Second),
 | 
			
		||||
//  )
 | 
			
		||||
//
 | 
			
		||||
// Choosing between the Logger and SugaredLogger doesn't need to be an
 | 
			
		||||
// application-wide decision: converting between the two is simple and
 | 
			
		||||
// inexpensive.
 | 
			
		||||
//   logger := zap.NewExample()
 | 
			
		||||
//   defer logger.Sync()
 | 
			
		||||
//   sugar := logger.Sugar()
 | 
			
		||||
//   plain := sugar.Desugar()
 | 
			
		||||
//
 | 
			
		||||
// Configuring Zap
 | 
			
		||||
//
 | 
			
		||||
// The simplest way to build a Logger is to use zap's opinionated presets:
 | 
			
		||||
// NewExample, NewProduction, and NewDevelopment. These presets build a logger
 | 
			
		||||
// with a single function call:
 | 
			
		||||
//  logger, err := zap.NewProduction()
 | 
			
		||||
//  if err != nil {
 | 
			
		||||
//    log.Fatalf("can't initialize zap logger: %v", err)
 | 
			
		||||
//  }
 | 
			
		||||
//  defer logger.Sync()
 | 
			
		||||
//
 | 
			
		||||
// Presets are fine for small projects, but larger projects and organizations
 | 
			
		||||
// naturally require a bit more customization. For most users, zap's Config
 | 
			
		||||
// struct strikes the right balance between flexibility and convenience. See
 | 
			
		||||
// the package-level BasicConfiguration example for sample code.
 | 
			
		||||
//
 | 
			
		||||
// More unusual configurations (splitting output between files, sending logs
 | 
			
		||||
// to a message queue, etc.) are possible, but require direct use of
 | 
			
		||||
// go.uber.org/zap/zapcore. See the package-level AdvancedConfiguration
 | 
			
		||||
// example for sample code.
 | 
			
		||||
//
 | 
			
		||||
// Extending Zap
 | 
			
		||||
//
 | 
			
		||||
// The zap package itself is a relatively thin wrapper around the interfaces
 | 
			
		||||
// in go.uber.org/zap/zapcore. Extending zap to support a new encoding (e.g.,
 | 
			
		||||
// BSON), a new log sink (e.g., Kafka), or something more exotic (perhaps an
 | 
			
		||||
// exception aggregation service, like Sentry or Rollbar) typically requires
 | 
			
		||||
// implementing the zapcore.Encoder, zapcore.WriteSyncer, or zapcore.Core
 | 
			
		||||
// interfaces. See the zapcore documentation for details.
 | 
			
		||||
//
 | 
			
		||||
// Similarly, package authors can use the high-performance Encoder and Core
 | 
			
		||||
// implementations in the zapcore package to build their own loggers.
 | 
			
		||||
//
 | 
			
		||||
// Frequently Asked Questions
 | 
			
		||||
//
 | 
			
		||||
// An FAQ covering everything from installation errors to design decisions is
 | 
			
		||||
// available at https://github.com/uber-go/zap/blob/master/FAQ.md.
 | 
			
		||||
package zap // import "go.uber.org/zap"
 | 
			
		||||
							
								
								
									
										79
									
								
								vendor/go.uber.org/zap/encoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								vendor/go.uber.org/zap/encoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/zapcore"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	errNoEncoderNameSpecified = errors.New("no encoder name specified")
 | 
			
		||||
 | 
			
		||||
	_encoderNameToConstructor = map[string]func(zapcore.EncoderConfig) (zapcore.Encoder, error){
 | 
			
		||||
		"console": func(encoderConfig zapcore.EncoderConfig) (zapcore.Encoder, error) {
 | 
			
		||||
			return zapcore.NewConsoleEncoder(encoderConfig), nil
 | 
			
		||||
		},
 | 
			
		||||
		"json": func(encoderConfig zapcore.EncoderConfig) (zapcore.Encoder, error) {
 | 
			
		||||
			return zapcore.NewJSONEncoder(encoderConfig), nil
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	_encoderMutex sync.RWMutex
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// RegisterEncoder registers an encoder constructor, which the Config struct
 | 
			
		||||
// can then reference. By default, the "json" and "console" encoders are
 | 
			
		||||
// registered.
 | 
			
		||||
//
 | 
			
		||||
// Attempting to register an encoder whose name is already taken returns an
 | 
			
		||||
// error.
 | 
			
		||||
func RegisterEncoder(name string, constructor func(zapcore.EncoderConfig) (zapcore.Encoder, error)) error {
 | 
			
		||||
	_encoderMutex.Lock()
 | 
			
		||||
	defer _encoderMutex.Unlock()
 | 
			
		||||
	if name == "" {
 | 
			
		||||
		return errNoEncoderNameSpecified
 | 
			
		||||
	}
 | 
			
		||||
	if _, ok := _encoderNameToConstructor[name]; ok {
 | 
			
		||||
		return fmt.Errorf("encoder already registered for name %q", name)
 | 
			
		||||
	}
 | 
			
		||||
	_encoderNameToConstructor[name] = constructor
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newEncoder(name string, encoderConfig zapcore.EncoderConfig) (zapcore.Encoder, error) {
 | 
			
		||||
	if encoderConfig.TimeKey != "" && encoderConfig.EncodeTime == nil {
 | 
			
		||||
		return nil, fmt.Errorf("missing EncodeTime in EncoderConfig")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_encoderMutex.RLock()
 | 
			
		||||
	defer _encoderMutex.RUnlock()
 | 
			
		||||
	if name == "" {
 | 
			
		||||
		return nil, errNoEncoderNameSpecified
 | 
			
		||||
	}
 | 
			
		||||
	constructor, ok := _encoderNameToConstructor[name]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, fmt.Errorf("no encoder registered for name %q", name)
 | 
			
		||||
	}
 | 
			
		||||
	return constructor(encoderConfig)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										80
									
								
								vendor/go.uber.org/zap/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								vendor/go.uber.org/zap/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
package zap
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/zapcore"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _errArrayElemPool = sync.Pool{New: func() interface{} {
 | 
			
		||||
	return &errArrayElem{}
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
// Error is shorthand for the common idiom NamedError("error", err).
 | 
			
		||||
func Error(err error) Field {
 | 
			
		||||
	return NamedError("error", err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NamedError constructs a field that lazily stores err.Error() under the
 | 
			
		||||
// provided key. Errors which also implement fmt.Formatter (like those produced
 | 
			
		||||
// by github.com/pkg/errors) will also have their verbose representation stored
 | 
			
		||||
// under key+"Verbose". If passed a nil error, the field is a no-op.
 | 
			
		||||
//
 | 
			
		||||
// For the common case in which the key is simply "error", the Error function
 | 
			
		||||
// is shorter and less repetitive.
 | 
			
		||||
func NamedError(key string, err error) Field {
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		return Skip()
 | 
			
		||||
	}
 | 
			
		||||
	return Field{Key: key, Type: zapcore.ErrorType, Interface: err}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type errArray []error
 | 
			
		||||
 | 
			
		||||
func (errs errArray) MarshalLogArray(arr zapcore.ArrayEncoder) error {
 | 
			
		||||
	for i := range errs {
 | 
			
		||||
		if errs[i] == nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		// To represent each error as an object with an "error" attribute and
 | 
			
		||||
		// potentially an "errorVerbose" attribute, we need to wrap it in a
 | 
			
		||||
		// type that implements LogObjectMarshaler. To prevent this from
 | 
			
		||||
		// allocating, pool the wrapper type.
 | 
			
		||||
		elem := _errArrayElemPool.Get().(*errArrayElem)
 | 
			
		||||
		elem.error = errs[i]
 | 
			
		||||
		arr.AppendObject(elem)
 | 
			
		||||
		elem.error = nil
 | 
			
		||||
		_errArrayElemPool.Put(elem)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type errArrayElem struct {
 | 
			
		||||
	error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *errArrayElem) MarshalLogObject(enc zapcore.ObjectEncoder) error {
 | 
			
		||||
	// Re-use the error field's logic, which supports non-standard error types.
 | 
			
		||||
	Error(e.error).AddTo(enc)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										549
									
								
								vendor/go.uber.org/zap/field.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										549
									
								
								vendor/go.uber.org/zap/field.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,549 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"math"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/zapcore"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Field is an alias for Field. Aliasing this type dramatically
 | 
			
		||||
// improves the navigability of this package's API documentation.
 | 
			
		||||
type Field = zapcore.Field
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_minTimeInt64 = time.Unix(0, math.MinInt64)
 | 
			
		||||
	_maxTimeInt64 = time.Unix(0, math.MaxInt64)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Skip constructs a no-op field, which is often useful when handling invalid
 | 
			
		||||
// inputs in other Field constructors.
 | 
			
		||||
func Skip() Field {
 | 
			
		||||
	return Field{Type: zapcore.SkipType}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// nilField returns a field which will marshal explicitly as nil. See motivation
 | 
			
		||||
// in https://github.com/uber-go/zap/issues/753 . If we ever make breaking
 | 
			
		||||
// changes and add zapcore.NilType and zapcore.ObjectEncoder.AddNil, the
 | 
			
		||||
// implementation here should be changed to reflect that.
 | 
			
		||||
func nilField(key string) Field { return Reflect(key, nil) }
 | 
			
		||||
 | 
			
		||||
// Binary constructs a field that carries an opaque binary blob.
 | 
			
		||||
//
 | 
			
		||||
// Binary data is serialized in an encoding-appropriate format. For example,
 | 
			
		||||
// zap's JSON encoder base64-encodes binary blobs. To log UTF-8 encoded text,
 | 
			
		||||
// use ByteString.
 | 
			
		||||
func Binary(key string, val []byte) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.BinaryType, Interface: val}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Bool constructs a field that carries a bool.
 | 
			
		||||
func Bool(key string, val bool) Field {
 | 
			
		||||
	var ival int64
 | 
			
		||||
	if val {
 | 
			
		||||
		ival = 1
 | 
			
		||||
	}
 | 
			
		||||
	return Field{Key: key, Type: zapcore.BoolType, Integer: ival}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Boolp constructs a field that carries a *bool. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Boolp(key string, val *bool) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Bool(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ByteString constructs a field that carries UTF-8 encoded text as a []byte.
 | 
			
		||||
// To log opaque binary blobs (which aren't necessarily valid UTF-8), use
 | 
			
		||||
// Binary.
 | 
			
		||||
func ByteString(key string, val []byte) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.ByteStringType, Interface: val}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Complex128 constructs a field that carries a complex number. Unlike most
 | 
			
		||||
// numeric fields, this costs an allocation (to convert the complex128 to
 | 
			
		||||
// interface{}).
 | 
			
		||||
func Complex128(key string, val complex128) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.Complex128Type, Interface: val}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Complex128p constructs a field that carries a *complex128. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Complex128p(key string, val *complex128) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Complex128(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Complex64 constructs a field that carries a complex number. Unlike most
 | 
			
		||||
// numeric fields, this costs an allocation (to convert the complex64 to
 | 
			
		||||
// interface{}).
 | 
			
		||||
func Complex64(key string, val complex64) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.Complex64Type, Interface: val}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Complex64p constructs a field that carries a *complex64. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Complex64p(key string, val *complex64) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Complex64(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64 constructs a field that carries a float64. The way the
 | 
			
		||||
// floating-point value is represented is encoder-dependent, so marshaling is
 | 
			
		||||
// necessarily lazy.
 | 
			
		||||
func Float64(key string, val float64) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.Float64Type, Integer: int64(math.Float64bits(val))}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float64p constructs a field that carries a *float64. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Float64p(key string, val *float64) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Float64(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float32 constructs a field that carries a float32. The way the
 | 
			
		||||
// floating-point value is represented is encoder-dependent, so marshaling is
 | 
			
		||||
// necessarily lazy.
 | 
			
		||||
func Float32(key string, val float32) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.Float32Type, Integer: int64(math.Float32bits(val))}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Float32p constructs a field that carries a *float32. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Float32p(key string, val *float32) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Float32(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int constructs a field with the given key and value.
 | 
			
		||||
func Int(key string, val int) Field {
 | 
			
		||||
	return Int64(key, int64(val))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Intp constructs a field that carries a *int. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Intp(key string, val *int) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Int(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int64 constructs a field with the given key and value.
 | 
			
		||||
func Int64(key string, val int64) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.Int64Type, Integer: val}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int64p constructs a field that carries a *int64. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Int64p(key string, val *int64) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Int64(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int32 constructs a field with the given key and value.
 | 
			
		||||
func Int32(key string, val int32) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.Int32Type, Integer: int64(val)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int32p constructs a field that carries a *int32. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Int32p(key string, val *int32) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Int32(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int16 constructs a field with the given key and value.
 | 
			
		||||
func Int16(key string, val int16) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.Int16Type, Integer: int64(val)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int16p constructs a field that carries a *int16. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Int16p(key string, val *int16) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Int16(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int8 constructs a field with the given key and value.
 | 
			
		||||
func Int8(key string, val int8) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.Int8Type, Integer: int64(val)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int8p constructs a field that carries a *int8. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Int8p(key string, val *int8) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Int8(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String constructs a field with the given key and value.
 | 
			
		||||
func String(key string, val string) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.StringType, String: val}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stringp constructs a field that carries a *string. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Stringp(key string, val *string) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return String(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uint constructs a field with the given key and value.
 | 
			
		||||
func Uint(key string, val uint) Field {
 | 
			
		||||
	return Uint64(key, uint64(val))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uintp constructs a field that carries a *uint. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Uintp(key string, val *uint) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Uint(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uint64 constructs a field with the given key and value.
 | 
			
		||||
func Uint64(key string, val uint64) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.Uint64Type, Integer: int64(val)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uint64p constructs a field that carries a *uint64. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Uint64p(key string, val *uint64) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Uint64(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uint32 constructs a field with the given key and value.
 | 
			
		||||
func Uint32(key string, val uint32) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.Uint32Type, Integer: int64(val)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uint32p constructs a field that carries a *uint32. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Uint32p(key string, val *uint32) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Uint32(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uint16 constructs a field with the given key and value.
 | 
			
		||||
func Uint16(key string, val uint16) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.Uint16Type, Integer: int64(val)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uint16p constructs a field that carries a *uint16. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Uint16p(key string, val *uint16) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Uint16(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uint8 constructs a field with the given key and value.
 | 
			
		||||
func Uint8(key string, val uint8) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.Uint8Type, Integer: int64(val)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uint8p constructs a field that carries a *uint8. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Uint8p(key string, val *uint8) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Uint8(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uintptr constructs a field with the given key and value.
 | 
			
		||||
func Uintptr(key string, val uintptr) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.UintptrType, Integer: int64(val)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uintptrp constructs a field that carries a *uintptr. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Uintptrp(key string, val *uintptr) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Uintptr(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Reflect constructs a field with the given key and an arbitrary object. It uses
 | 
			
		||||
// an encoding-appropriate, reflection-based function to lazily serialize nearly
 | 
			
		||||
// any object into the logging context, but it's relatively slow and
 | 
			
		||||
// allocation-heavy. Outside tests, Any is always a better choice.
 | 
			
		||||
//
 | 
			
		||||
// If encoding fails (e.g., trying to serialize a map[int]string to JSON), Reflect
 | 
			
		||||
// includes the error message in the final log output.
 | 
			
		||||
func Reflect(key string, val interface{}) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.ReflectType, Interface: val}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Namespace creates a named, isolated scope within the logger's context. All
 | 
			
		||||
// subsequent fields will be added to the new namespace.
 | 
			
		||||
//
 | 
			
		||||
// This helps prevent key collisions when injecting loggers into sub-components
 | 
			
		||||
// or third-party libraries.
 | 
			
		||||
func Namespace(key string) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.NamespaceType}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stringer constructs a field with the given key and the output of the value's
 | 
			
		||||
// String method. The Stringer's String method is called lazily.
 | 
			
		||||
func Stringer(key string, val fmt.Stringer) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.StringerType, Interface: val}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Time constructs a Field with the given key and value. The encoder
 | 
			
		||||
// controls how the time is serialized.
 | 
			
		||||
func Time(key string, val time.Time) Field {
 | 
			
		||||
	if val.Before(_minTimeInt64) || val.After(_maxTimeInt64) {
 | 
			
		||||
		return Field{Key: key, Type: zapcore.TimeFullType, Interface: val}
 | 
			
		||||
	}
 | 
			
		||||
	return Field{Key: key, Type: zapcore.TimeType, Integer: val.UnixNano(), Interface: val.Location()}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Timep constructs a field that carries a *time.Time. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Timep(key string, val *time.Time) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Time(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stack constructs a field that stores a stacktrace of the current goroutine
 | 
			
		||||
// under provided key. Keep in mind that taking a stacktrace is eager and
 | 
			
		||||
// expensive (relatively speaking); this function both makes an allocation and
 | 
			
		||||
// takes about two microseconds.
 | 
			
		||||
func Stack(key string) Field {
 | 
			
		||||
	return StackSkip(key, 1) // skip Stack
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StackSkip constructs a field similarly to Stack, but also skips the given
 | 
			
		||||
// number of frames from the top of the stacktrace.
 | 
			
		||||
func StackSkip(key string, skip int) Field {
 | 
			
		||||
	// Returning the stacktrace as a string costs an allocation, but saves us
 | 
			
		||||
	// from expanding the zapcore.Field union struct to include a byte slice. Since
 | 
			
		||||
	// taking a stacktrace is already so expensive (~10us), the extra allocation
 | 
			
		||||
	// is okay.
 | 
			
		||||
	return String(key, takeStacktrace(skip+1)) // skip StackSkip
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Duration constructs a field with the given key and value. The encoder
 | 
			
		||||
// controls how the duration is serialized.
 | 
			
		||||
func Duration(key string, val time.Duration) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.DurationType, Integer: int64(val)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Durationp constructs a field that carries a *time.Duration. The returned Field will safely
 | 
			
		||||
// and explicitly represent `nil` when appropriate.
 | 
			
		||||
func Durationp(key string, val *time.Duration) Field {
 | 
			
		||||
	if val == nil {
 | 
			
		||||
		return nilField(key)
 | 
			
		||||
	}
 | 
			
		||||
	return Duration(key, *val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Object constructs a field with the given key and ObjectMarshaler. It
 | 
			
		||||
// provides a flexible, but still type-safe and efficient, way to add map- or
 | 
			
		||||
// struct-like user-defined types to the logging context. The struct's
 | 
			
		||||
// MarshalLogObject method is called lazily.
 | 
			
		||||
func Object(key string, val zapcore.ObjectMarshaler) Field {
 | 
			
		||||
	return Field{Key: key, Type: zapcore.ObjectMarshalerType, Interface: val}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Inline constructs a Field that is similar to Object, but it
 | 
			
		||||
// will add the elements of the provided ObjectMarshaler to the
 | 
			
		||||
// current namespace.
 | 
			
		||||
func Inline(val zapcore.ObjectMarshaler) Field {
 | 
			
		||||
	return zapcore.Field{
 | 
			
		||||
		Type:      zapcore.InlineMarshalerType,
 | 
			
		||||
		Interface: val,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Any takes a key and an arbitrary value and chooses the best way to represent
 | 
			
		||||
// them as a field, falling back to a reflection-based approach only if
 | 
			
		||||
// necessary.
 | 
			
		||||
//
 | 
			
		||||
// Since byte/uint8 and rune/int32 are aliases, Any can't differentiate between
 | 
			
		||||
// them. To minimize surprises, []byte values are treated as binary blobs, byte
 | 
			
		||||
// values are treated as uint8, and runes are always treated as integers.
 | 
			
		||||
func Any(key string, value interface{}) Field {
 | 
			
		||||
	switch val := value.(type) {
 | 
			
		||||
	case zapcore.ObjectMarshaler:
 | 
			
		||||
		return Object(key, val)
 | 
			
		||||
	case zapcore.ArrayMarshaler:
 | 
			
		||||
		return Array(key, val)
 | 
			
		||||
	case bool:
 | 
			
		||||
		return Bool(key, val)
 | 
			
		||||
	case *bool:
 | 
			
		||||
		return Boolp(key, val)
 | 
			
		||||
	case []bool:
 | 
			
		||||
		return Bools(key, val)
 | 
			
		||||
	case complex128:
 | 
			
		||||
		return Complex128(key, val)
 | 
			
		||||
	case *complex128:
 | 
			
		||||
		return Complex128p(key, val)
 | 
			
		||||
	case []complex128:
 | 
			
		||||
		return Complex128s(key, val)
 | 
			
		||||
	case complex64:
 | 
			
		||||
		return Complex64(key, val)
 | 
			
		||||
	case *complex64:
 | 
			
		||||
		return Complex64p(key, val)
 | 
			
		||||
	case []complex64:
 | 
			
		||||
		return Complex64s(key, val)
 | 
			
		||||
	case float64:
 | 
			
		||||
		return Float64(key, val)
 | 
			
		||||
	case *float64:
 | 
			
		||||
		return Float64p(key, val)
 | 
			
		||||
	case []float64:
 | 
			
		||||
		return Float64s(key, val)
 | 
			
		||||
	case float32:
 | 
			
		||||
		return Float32(key, val)
 | 
			
		||||
	case *float32:
 | 
			
		||||
		return Float32p(key, val)
 | 
			
		||||
	case []float32:
 | 
			
		||||
		return Float32s(key, val)
 | 
			
		||||
	case int:
 | 
			
		||||
		return Int(key, val)
 | 
			
		||||
	case *int:
 | 
			
		||||
		return Intp(key, val)
 | 
			
		||||
	case []int:
 | 
			
		||||
		return Ints(key, val)
 | 
			
		||||
	case int64:
 | 
			
		||||
		return Int64(key, val)
 | 
			
		||||
	case *int64:
 | 
			
		||||
		return Int64p(key, val)
 | 
			
		||||
	case []int64:
 | 
			
		||||
		return Int64s(key, val)
 | 
			
		||||
	case int32:
 | 
			
		||||
		return Int32(key, val)
 | 
			
		||||
	case *int32:
 | 
			
		||||
		return Int32p(key, val)
 | 
			
		||||
	case []int32:
 | 
			
		||||
		return Int32s(key, val)
 | 
			
		||||
	case int16:
 | 
			
		||||
		return Int16(key, val)
 | 
			
		||||
	case *int16:
 | 
			
		||||
		return Int16p(key, val)
 | 
			
		||||
	case []int16:
 | 
			
		||||
		return Int16s(key, val)
 | 
			
		||||
	case int8:
 | 
			
		||||
		return Int8(key, val)
 | 
			
		||||
	case *int8:
 | 
			
		||||
		return Int8p(key, val)
 | 
			
		||||
	case []int8:
 | 
			
		||||
		return Int8s(key, val)
 | 
			
		||||
	case string:
 | 
			
		||||
		return String(key, val)
 | 
			
		||||
	case *string:
 | 
			
		||||
		return Stringp(key, val)
 | 
			
		||||
	case []string:
 | 
			
		||||
		return Strings(key, val)
 | 
			
		||||
	case uint:
 | 
			
		||||
		return Uint(key, val)
 | 
			
		||||
	case *uint:
 | 
			
		||||
		return Uintp(key, val)
 | 
			
		||||
	case []uint:
 | 
			
		||||
		return Uints(key, val)
 | 
			
		||||
	case uint64:
 | 
			
		||||
		return Uint64(key, val)
 | 
			
		||||
	case *uint64:
 | 
			
		||||
		return Uint64p(key, val)
 | 
			
		||||
	case []uint64:
 | 
			
		||||
		return Uint64s(key, val)
 | 
			
		||||
	case uint32:
 | 
			
		||||
		return Uint32(key, val)
 | 
			
		||||
	case *uint32:
 | 
			
		||||
		return Uint32p(key, val)
 | 
			
		||||
	case []uint32:
 | 
			
		||||
		return Uint32s(key, val)
 | 
			
		||||
	case uint16:
 | 
			
		||||
		return Uint16(key, val)
 | 
			
		||||
	case *uint16:
 | 
			
		||||
		return Uint16p(key, val)
 | 
			
		||||
	case []uint16:
 | 
			
		||||
		return Uint16s(key, val)
 | 
			
		||||
	case uint8:
 | 
			
		||||
		return Uint8(key, val)
 | 
			
		||||
	case *uint8:
 | 
			
		||||
		return Uint8p(key, val)
 | 
			
		||||
	case []byte:
 | 
			
		||||
		return Binary(key, val)
 | 
			
		||||
	case uintptr:
 | 
			
		||||
		return Uintptr(key, val)
 | 
			
		||||
	case *uintptr:
 | 
			
		||||
		return Uintptrp(key, val)
 | 
			
		||||
	case []uintptr:
 | 
			
		||||
		return Uintptrs(key, val)
 | 
			
		||||
	case time.Time:
 | 
			
		||||
		return Time(key, val)
 | 
			
		||||
	case *time.Time:
 | 
			
		||||
		return Timep(key, val)
 | 
			
		||||
	case []time.Time:
 | 
			
		||||
		return Times(key, val)
 | 
			
		||||
	case time.Duration:
 | 
			
		||||
		return Duration(key, val)
 | 
			
		||||
	case *time.Duration:
 | 
			
		||||
		return Durationp(key, val)
 | 
			
		||||
	case []time.Duration:
 | 
			
		||||
		return Durations(key, val)
 | 
			
		||||
	case error:
 | 
			
		||||
		return NamedError(key, val)
 | 
			
		||||
	case []error:
 | 
			
		||||
		return Errors(key, val)
 | 
			
		||||
	case fmt.Stringer:
 | 
			
		||||
		return Stringer(key, val)
 | 
			
		||||
	default:
 | 
			
		||||
		return Reflect(key, val)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								vendor/go.uber.org/zap/flag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								vendor/go.uber.org/zap/flag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"flag"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/zapcore"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// LevelFlag uses the standard library's flag.Var to declare a global flag
 | 
			
		||||
// with the specified name, default, and usage guidance. The returned value is
 | 
			
		||||
// a pointer to the value of the flag.
 | 
			
		||||
//
 | 
			
		||||
// If you don't want to use the flag package's global state, you can use any
 | 
			
		||||
// non-nil *Level as a flag.Value with your own *flag.FlagSet.
 | 
			
		||||
func LevelFlag(name string, defaultLevel zapcore.Level, usage string) *zapcore.Level {
 | 
			
		||||
	lvl := defaultLevel
 | 
			
		||||
	flag.Var(&lvl, name, usage)
 | 
			
		||||
	return &lvl
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								vendor/go.uber.org/zap/glide.yaml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								vendor/go.uber.org/zap/glide.yaml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
package: go.uber.org/zap
 | 
			
		||||
license: MIT
 | 
			
		||||
import:
 | 
			
		||||
- package: go.uber.org/atomic
 | 
			
		||||
  version: ^1
 | 
			
		||||
- package: go.uber.org/multierr
 | 
			
		||||
  version: ^1
 | 
			
		||||
testImport:
 | 
			
		||||
- package: github.com/satori/go.uuid
 | 
			
		||||
- package: github.com/sirupsen/logrus
 | 
			
		||||
- package: github.com/apex/log
 | 
			
		||||
  subpackages:
 | 
			
		||||
  - handlers/json
 | 
			
		||||
- package: github.com/go-kit/kit
 | 
			
		||||
  subpackages:
 | 
			
		||||
  - log
 | 
			
		||||
- package: github.com/stretchr/testify
 | 
			
		||||
  subpackages:
 | 
			
		||||
  - assert
 | 
			
		||||
  - require
 | 
			
		||||
- package: gopkg.in/inconshreveable/log15.v2
 | 
			
		||||
- package: github.com/mattn/goveralls
 | 
			
		||||
- package: github.com/pborman/uuid
 | 
			
		||||
- package: github.com/pkg/errors
 | 
			
		||||
- package: github.com/rs/zerolog
 | 
			
		||||
- package: golang.org/x/tools
 | 
			
		||||
  subpackages:
 | 
			
		||||
  - cover
 | 
			
		||||
- package: golang.org/x/lint
 | 
			
		||||
  subpackages:
 | 
			
		||||
  - golint
 | 
			
		||||
- package: github.com/axw/gocov
 | 
			
		||||
  subpackages:
 | 
			
		||||
  - gocov
 | 
			
		||||
							
								
								
									
										168
									
								
								vendor/go.uber.org/zap/global.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								vendor/go.uber.org/zap/global.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,168 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/zapcore"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	_loggerWriterDepth       = 2
 | 
			
		||||
	_programmerErrorTemplate = "You've found a bug in zap! Please file a bug at " +
 | 
			
		||||
		"https://github.com/uber-go/zap/issues/new and reference this error: %v"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_globalMu sync.RWMutex
 | 
			
		||||
	_globalL  = NewNop()
 | 
			
		||||
	_globalS  = _globalL.Sugar()
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// L returns the global Logger, which can be reconfigured with ReplaceGlobals.
 | 
			
		||||
// It's safe for concurrent use.
 | 
			
		||||
func L() *Logger {
 | 
			
		||||
	_globalMu.RLock()
 | 
			
		||||
	l := _globalL
 | 
			
		||||
	_globalMu.RUnlock()
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// S returns the global SugaredLogger, which can be reconfigured with
 | 
			
		||||
// ReplaceGlobals. It's safe for concurrent use.
 | 
			
		||||
func S() *SugaredLogger {
 | 
			
		||||
	_globalMu.RLock()
 | 
			
		||||
	s := _globalS
 | 
			
		||||
	_globalMu.RUnlock()
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ReplaceGlobals replaces the global Logger and SugaredLogger, and returns a
 | 
			
		||||
// function to restore the original values. It's safe for concurrent use.
 | 
			
		||||
func ReplaceGlobals(logger *Logger) func() {
 | 
			
		||||
	_globalMu.Lock()
 | 
			
		||||
	prev := _globalL
 | 
			
		||||
	_globalL = logger
 | 
			
		||||
	_globalS = logger.Sugar()
 | 
			
		||||
	_globalMu.Unlock()
 | 
			
		||||
	return func() { ReplaceGlobals(prev) }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewStdLog returns a *log.Logger which writes to the supplied zap Logger at
 | 
			
		||||
// InfoLevel. To redirect the standard library's package-global logging
 | 
			
		||||
// functions, use RedirectStdLog instead.
 | 
			
		||||
func NewStdLog(l *Logger) *log.Logger {
 | 
			
		||||
	logger := l.WithOptions(AddCallerSkip(_stdLogDefaultDepth + _loggerWriterDepth))
 | 
			
		||||
	f := logger.Info
 | 
			
		||||
	return log.New(&loggerWriter{f}, "" /* prefix */, 0 /* flags */)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewStdLogAt returns *log.Logger which writes to supplied zap logger at
 | 
			
		||||
// required level.
 | 
			
		||||
func NewStdLogAt(l *Logger, level zapcore.Level) (*log.Logger, error) {
 | 
			
		||||
	logger := l.WithOptions(AddCallerSkip(_stdLogDefaultDepth + _loggerWriterDepth))
 | 
			
		||||
	logFunc, err := levelToFunc(logger, level)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return log.New(&loggerWriter{logFunc}, "" /* prefix */, 0 /* flags */), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RedirectStdLog redirects output from the standard library's package-global
 | 
			
		||||
// logger to the supplied logger at InfoLevel. Since zap already handles caller
 | 
			
		||||
// annotations, timestamps, etc., it automatically disables the standard
 | 
			
		||||
// library's annotations and prefixing.
 | 
			
		||||
//
 | 
			
		||||
// It returns a function to restore the original prefix and flags and reset the
 | 
			
		||||
// standard library's output to os.Stderr.
 | 
			
		||||
func RedirectStdLog(l *Logger) func() {
 | 
			
		||||
	f, err := redirectStdLogAt(l, InfoLevel)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		// Can't get here, since passing InfoLevel to redirectStdLogAt always
 | 
			
		||||
		// works.
 | 
			
		||||
		panic(fmt.Sprintf(_programmerErrorTemplate, err))
 | 
			
		||||
	}
 | 
			
		||||
	return f
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RedirectStdLogAt redirects output from the standard library's package-global
 | 
			
		||||
// logger to the supplied logger at the specified level. Since zap already
 | 
			
		||||
// handles caller annotations, timestamps, etc., it automatically disables the
 | 
			
		||||
// standard library's annotations and prefixing.
 | 
			
		||||
//
 | 
			
		||||
// It returns a function to restore the original prefix and flags and reset the
 | 
			
		||||
// standard library's output to os.Stderr.
 | 
			
		||||
func RedirectStdLogAt(l *Logger, level zapcore.Level) (func(), error) {
 | 
			
		||||
	return redirectStdLogAt(l, level)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func redirectStdLogAt(l *Logger, level zapcore.Level) (func(), error) {
 | 
			
		||||
	flags := log.Flags()
 | 
			
		||||
	prefix := log.Prefix()
 | 
			
		||||
	log.SetFlags(0)
 | 
			
		||||
	log.SetPrefix("")
 | 
			
		||||
	logger := l.WithOptions(AddCallerSkip(_stdLogDefaultDepth + _loggerWriterDepth))
 | 
			
		||||
	logFunc, err := levelToFunc(logger, level)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	log.SetOutput(&loggerWriter{logFunc})
 | 
			
		||||
	return func() {
 | 
			
		||||
		log.SetFlags(flags)
 | 
			
		||||
		log.SetPrefix(prefix)
 | 
			
		||||
		log.SetOutput(os.Stderr)
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func levelToFunc(logger *Logger, lvl zapcore.Level) (func(string, ...Field), error) {
 | 
			
		||||
	switch lvl {
 | 
			
		||||
	case DebugLevel:
 | 
			
		||||
		return logger.Debug, nil
 | 
			
		||||
	case InfoLevel:
 | 
			
		||||
		return logger.Info, nil
 | 
			
		||||
	case WarnLevel:
 | 
			
		||||
		return logger.Warn, nil
 | 
			
		||||
	case ErrorLevel:
 | 
			
		||||
		return logger.Error, nil
 | 
			
		||||
	case DPanicLevel:
 | 
			
		||||
		return logger.DPanic, nil
 | 
			
		||||
	case PanicLevel:
 | 
			
		||||
		return logger.Panic, nil
 | 
			
		||||
	case FatalLevel:
 | 
			
		||||
		return logger.Fatal, nil
 | 
			
		||||
	}
 | 
			
		||||
	return nil, fmt.Errorf("unrecognized level: %q", lvl)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type loggerWriter struct {
 | 
			
		||||
	logFunc func(msg string, fields ...Field)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *loggerWriter) Write(p []byte) (int, error) {
 | 
			
		||||
	p = bytes.TrimSpace(p)
 | 
			
		||||
	l.logFunc(string(p))
 | 
			
		||||
	return len(p), nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								vendor/go.uber.org/zap/global_go112.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/go.uber.org/zap/global_go112.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
// Copyright (c) 2019 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.
 | 
			
		||||
 | 
			
		||||
// See #682 for more information.
 | 
			
		||||
// +build go1.12
 | 
			
		||||
 | 
			
		||||
package zap
 | 
			
		||||
 | 
			
		||||
const _stdLogDefaultDepth = 1
 | 
			
		||||
							
								
								
									
										26
									
								
								vendor/go.uber.org/zap/global_prego112.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/go.uber.org/zap/global_prego112.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
// Copyright (c) 2019 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.
 | 
			
		||||
 | 
			
		||||
// See #682 for more information.
 | 
			
		||||
// +build !go1.12
 | 
			
		||||
 | 
			
		||||
package zap
 | 
			
		||||
 | 
			
		||||
const _stdLogDefaultDepth = 2
 | 
			
		||||
							
								
								
									
										132
									
								
								vendor/go.uber.org/zap/http_handler.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								vendor/go.uber.org/zap/http_handler.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/zapcore"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ServeHTTP is a simple JSON endpoint that can report on or change the current
 | 
			
		||||
// logging level.
 | 
			
		||||
//
 | 
			
		||||
// GET
 | 
			
		||||
//
 | 
			
		||||
// The GET request returns a JSON description of the current logging level like:
 | 
			
		||||
//   {"level":"info"}
 | 
			
		||||
//
 | 
			
		||||
// PUT
 | 
			
		||||
//
 | 
			
		||||
// The PUT request changes the logging level. It is perfectly safe to change the
 | 
			
		||||
// logging level while a program is running. Two content types are supported:
 | 
			
		||||
//
 | 
			
		||||
//    Content-Type: application/x-www-form-urlencoded
 | 
			
		||||
//
 | 
			
		||||
// With this content type, the level can be provided through the request body or
 | 
			
		||||
// a query parameter. The log level is URL encoded like:
 | 
			
		||||
//
 | 
			
		||||
//    level=debug
 | 
			
		||||
//
 | 
			
		||||
// The request body takes precedence over the query parameter, if both are
 | 
			
		||||
// specified.
 | 
			
		||||
//
 | 
			
		||||
// This content type is the default for a curl PUT request. Following are two
 | 
			
		||||
// example curl requests that both set the logging level to debug.
 | 
			
		||||
//
 | 
			
		||||
//    curl -X PUT localhost:8080/log/level?level=debug
 | 
			
		||||
//    curl -X PUT localhost:8080/log/level -d level=debug
 | 
			
		||||
//
 | 
			
		||||
// For any other content type, the payload is expected to be JSON encoded and
 | 
			
		||||
// look like:
 | 
			
		||||
//
 | 
			
		||||
//   {"level":"info"}
 | 
			
		||||
//
 | 
			
		||||
// An example curl request could look like this:
 | 
			
		||||
//
 | 
			
		||||
//    curl -X PUT localhost:8080/log/level -H "Content-Type: application/json" -d '{"level":"debug"}'
 | 
			
		||||
//
 | 
			
		||||
func (lvl AtomicLevel) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	type errorResponse struct {
 | 
			
		||||
		Error string `json:"error"`
 | 
			
		||||
	}
 | 
			
		||||
	type payload struct {
 | 
			
		||||
		Level zapcore.Level `json:"level"`
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	enc := json.NewEncoder(w)
 | 
			
		||||
 | 
			
		||||
	switch r.Method {
 | 
			
		||||
	case http.MethodGet:
 | 
			
		||||
		enc.Encode(payload{Level: lvl.Level()})
 | 
			
		||||
	case http.MethodPut:
 | 
			
		||||
		requestedLvl, err := decodePutRequest(r.Header.Get("Content-Type"), r)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			w.WriteHeader(http.StatusBadRequest)
 | 
			
		||||
			enc.Encode(errorResponse{Error: err.Error()})
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		lvl.SetLevel(requestedLvl)
 | 
			
		||||
		enc.Encode(payload{Level: lvl.Level()})
 | 
			
		||||
	default:
 | 
			
		||||
		w.WriteHeader(http.StatusMethodNotAllowed)
 | 
			
		||||
		enc.Encode(errorResponse{
 | 
			
		||||
			Error: "Only GET and PUT are supported.",
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Decodes incoming PUT requests and returns the requested logging level.
 | 
			
		||||
func decodePutRequest(contentType string, r *http.Request) (zapcore.Level, error) {
 | 
			
		||||
	if contentType == "application/x-www-form-urlencoded" {
 | 
			
		||||
		return decodePutURL(r)
 | 
			
		||||
	}
 | 
			
		||||
	return decodePutJSON(r.Body)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func decodePutURL(r *http.Request) (zapcore.Level, error) {
 | 
			
		||||
	lvl := r.FormValue("level")
 | 
			
		||||
	if lvl == "" {
 | 
			
		||||
		return 0, fmt.Errorf("must specify logging level")
 | 
			
		||||
	}
 | 
			
		||||
	var l zapcore.Level
 | 
			
		||||
	if err := l.UnmarshalText([]byte(lvl)); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return l, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func decodePutJSON(body io.Reader) (zapcore.Level, error) {
 | 
			
		||||
	var pld struct {
 | 
			
		||||
		Level *zapcore.Level `json:"level"`
 | 
			
		||||
	}
 | 
			
		||||
	if err := json.NewDecoder(body).Decode(&pld); err != nil {
 | 
			
		||||
		return 0, fmt.Errorf("malformed request body: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	if pld.Level == nil {
 | 
			
		||||
		return 0, fmt.Errorf("must specify logging level")
 | 
			
		||||
	}
 | 
			
		||||
	return *pld.Level, nil
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								vendor/go.uber.org/zap/internal/bufferpool/bufferpool.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								vendor/go.uber.org/zap/internal/bufferpool/bufferpool.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
// 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 bufferpool houses zap's shared internal buffer pool. Third-party
 | 
			
		||||
// packages can recreate the same functionality with buffers.NewPool.
 | 
			
		||||
package bufferpool
 | 
			
		||||
 | 
			
		||||
import "go.uber.org/zap/buffer"
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_pool = buffer.NewPool()
 | 
			
		||||
	// Get retrieves a buffer from the pool, creating one if necessary.
 | 
			
		||||
	Get = _pool.Get
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										44
									
								
								vendor/go.uber.org/zap/internal/color/color.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								vendor/go.uber.org/zap/internal/color/color.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
// 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 color adds coloring functionality for TTY output.
 | 
			
		||||
package color
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
// Foreground colors.
 | 
			
		||||
const (
 | 
			
		||||
	Black Color = iota + 30
 | 
			
		||||
	Red
 | 
			
		||||
	Green
 | 
			
		||||
	Yellow
 | 
			
		||||
	Blue
 | 
			
		||||
	Magenta
 | 
			
		||||
	Cyan
 | 
			
		||||
	White
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Color represents a text color.
 | 
			
		||||
type Color uint8
 | 
			
		||||
 | 
			
		||||
// Add adds the coloring to the given string.
 | 
			
		||||
func (c Color) Add(s string) string {
 | 
			
		||||
	return fmt.Sprintf("\x1b[%dm%s\x1b[0m", uint8(c), s)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										64
									
								
								vendor/go.uber.org/zap/internal/exit/exit.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								vendor/go.uber.org/zap/internal/exit/exit.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
// 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 exit provides stubs so that unit tests can exercise code that calls
 | 
			
		||||
// os.Exit(1).
 | 
			
		||||
package exit
 | 
			
		||||
 | 
			
		||||
import "os"
 | 
			
		||||
 | 
			
		||||
var real = func() { os.Exit(1) }
 | 
			
		||||
 | 
			
		||||
// Exit normally terminates the process by calling os.Exit(1). If the package
 | 
			
		||||
// is stubbed, it instead records a call in the testing spy.
 | 
			
		||||
func Exit() {
 | 
			
		||||
	real()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A StubbedExit is a testing fake for os.Exit.
 | 
			
		||||
type StubbedExit struct {
 | 
			
		||||
	Exited bool
 | 
			
		||||
	prev   func()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stub substitutes a fake for the call to os.Exit(1).
 | 
			
		||||
func Stub() *StubbedExit {
 | 
			
		||||
	s := &StubbedExit{prev: real}
 | 
			
		||||
	real = s.exit
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithStub runs the supplied function with Exit stubbed. It returns the stub
 | 
			
		||||
// used, so that users can test whether the process would have crashed.
 | 
			
		||||
func WithStub(f func()) *StubbedExit {
 | 
			
		||||
	s := Stub()
 | 
			
		||||
	defer s.Unstub()
 | 
			
		||||
	f()
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unstub restores the previous exit function.
 | 
			
		||||
func (se *StubbedExit) Unstub() {
 | 
			
		||||
	real = se.prev
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (se *StubbedExit) exit() {
 | 
			
		||||
	se.Exited = true
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										132
									
								
								vendor/go.uber.org/zap/level.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								vendor/go.uber.org/zap/level.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"go.uber.org/atomic"
 | 
			
		||||
	"go.uber.org/zap/zapcore"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// DebugLevel logs are typically voluminous, and are usually disabled in
 | 
			
		||||
	// production.
 | 
			
		||||
	DebugLevel = zapcore.DebugLevel
 | 
			
		||||
	// InfoLevel is the default logging priority.
 | 
			
		||||
	InfoLevel = zapcore.InfoLevel
 | 
			
		||||
	// WarnLevel logs are more important than Info, but don't need individual
 | 
			
		||||
	// human review.
 | 
			
		||||
	WarnLevel = zapcore.WarnLevel
 | 
			
		||||
	// ErrorLevel logs are high-priority. If an application is running smoothly,
 | 
			
		||||
	// it shouldn't generate any error-level logs.
 | 
			
		||||
	ErrorLevel = zapcore.ErrorLevel
 | 
			
		||||
	// DPanicLevel logs are particularly important errors. In development the
 | 
			
		||||
	// logger panics after writing the message.
 | 
			
		||||
	DPanicLevel = zapcore.DPanicLevel
 | 
			
		||||
	// PanicLevel logs a message, then panics.
 | 
			
		||||
	PanicLevel = zapcore.PanicLevel
 | 
			
		||||
	// FatalLevel logs a message, then calls os.Exit(1).
 | 
			
		||||
	FatalLevel = zapcore.FatalLevel
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// LevelEnablerFunc is a convenient way to implement zapcore.LevelEnabler with
 | 
			
		||||
// an anonymous function.
 | 
			
		||||
//
 | 
			
		||||
// It's particularly useful when splitting log output between different
 | 
			
		||||
// outputs (e.g., standard error and standard out). For sample code, see the
 | 
			
		||||
// package-level AdvancedConfiguration example.
 | 
			
		||||
type LevelEnablerFunc func(zapcore.Level) bool
 | 
			
		||||
 | 
			
		||||
// Enabled calls the wrapped function.
 | 
			
		||||
func (f LevelEnablerFunc) Enabled(lvl zapcore.Level) bool { return f(lvl) }
 | 
			
		||||
 | 
			
		||||
// An AtomicLevel is an atomically changeable, dynamic logging level. It lets
 | 
			
		||||
// you safely change the log level of a tree of loggers (the root logger and
 | 
			
		||||
// any children created by adding context) at runtime.
 | 
			
		||||
//
 | 
			
		||||
// The AtomicLevel itself is an http.Handler that serves a JSON endpoint to
 | 
			
		||||
// alter its level.
 | 
			
		||||
//
 | 
			
		||||
// AtomicLevels must be created with the NewAtomicLevel constructor to allocate
 | 
			
		||||
// their internal atomic pointer.
 | 
			
		||||
type AtomicLevel struct {
 | 
			
		||||
	l *atomic.Int32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewAtomicLevel creates an AtomicLevel with InfoLevel and above logging
 | 
			
		||||
// enabled.
 | 
			
		||||
func NewAtomicLevel() AtomicLevel {
 | 
			
		||||
	return AtomicLevel{
 | 
			
		||||
		l: atomic.NewInt32(int32(InfoLevel)),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewAtomicLevelAt is a convenience function that creates an AtomicLevel
 | 
			
		||||
// and then calls SetLevel with the given level.
 | 
			
		||||
func NewAtomicLevelAt(l zapcore.Level) AtomicLevel {
 | 
			
		||||
	a := NewAtomicLevel()
 | 
			
		||||
	a.SetLevel(l)
 | 
			
		||||
	return a
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Enabled implements the zapcore.LevelEnabler interface, which allows the
 | 
			
		||||
// AtomicLevel to be used in place of traditional static levels.
 | 
			
		||||
func (lvl AtomicLevel) Enabled(l zapcore.Level) bool {
 | 
			
		||||
	return lvl.Level().Enabled(l)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Level returns the minimum enabled log level.
 | 
			
		||||
func (lvl AtomicLevel) Level() zapcore.Level {
 | 
			
		||||
	return zapcore.Level(int8(lvl.l.Load()))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetLevel alters the logging level.
 | 
			
		||||
func (lvl AtomicLevel) SetLevel(l zapcore.Level) {
 | 
			
		||||
	lvl.l.Store(int32(l))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String returns the string representation of the underlying Level.
 | 
			
		||||
func (lvl AtomicLevel) String() string {
 | 
			
		||||
	return lvl.Level().String()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalText unmarshals the text to an AtomicLevel. It uses the same text
 | 
			
		||||
// representations as the static zapcore.Levels ("debug", "info", "warn",
 | 
			
		||||
// "error", "dpanic", "panic", and "fatal").
 | 
			
		||||
func (lvl *AtomicLevel) UnmarshalText(text []byte) error {
 | 
			
		||||
	if lvl.l == nil {
 | 
			
		||||
		lvl.l = &atomic.Int32{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var l zapcore.Level
 | 
			
		||||
	if err := l.UnmarshalText(text); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lvl.SetLevel(l)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalText marshals the AtomicLevel to a byte slice. It uses the same
 | 
			
		||||
// text representation as the static zapcore.Levels ("debug", "info", "warn",
 | 
			
		||||
// "error", "dpanic", "panic", and "fatal").
 | 
			
		||||
func (lvl AtomicLevel) MarshalText() (text []byte, err error) {
 | 
			
		||||
	return lvl.Level().MarshalText()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										348
									
								
								vendor/go.uber.org/zap/logger.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										348
									
								
								vendor/go.uber.org/zap/logger.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,348 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/zapcore"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A Logger provides fast, leveled, structured logging. All methods are safe
 | 
			
		||||
// for concurrent use.
 | 
			
		||||
//
 | 
			
		||||
// The Logger is designed for contexts in which every microsecond and every
 | 
			
		||||
// allocation matters, so its API intentionally favors performance and type
 | 
			
		||||
// safety over brevity. For most applications, the SugaredLogger strikes a
 | 
			
		||||
// better balance between performance and ergonomics.
 | 
			
		||||
type Logger struct {
 | 
			
		||||
	core zapcore.Core
 | 
			
		||||
 | 
			
		||||
	development bool
 | 
			
		||||
	addCaller   bool
 | 
			
		||||
	onFatal     zapcore.CheckWriteAction // default is WriteThenFatal
 | 
			
		||||
 | 
			
		||||
	name        string
 | 
			
		||||
	errorOutput zapcore.WriteSyncer
 | 
			
		||||
 | 
			
		||||
	addStack zapcore.LevelEnabler
 | 
			
		||||
 | 
			
		||||
	callerSkip int
 | 
			
		||||
 | 
			
		||||
	clock zapcore.Clock
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// New constructs a new Logger from the provided zapcore.Core and Options. If
 | 
			
		||||
// the passed zapcore.Core is nil, it falls back to using a no-op
 | 
			
		||||
// implementation.
 | 
			
		||||
//
 | 
			
		||||
// This is the most flexible way to construct a Logger, but also the most
 | 
			
		||||
// verbose. For typical use cases, the highly-opinionated presets
 | 
			
		||||
// (NewProduction, NewDevelopment, and NewExample) or the Config struct are
 | 
			
		||||
// more convenient.
 | 
			
		||||
//
 | 
			
		||||
// For sample code, see the package-level AdvancedConfiguration example.
 | 
			
		||||
func New(core zapcore.Core, options ...Option) *Logger {
 | 
			
		||||
	if core == nil {
 | 
			
		||||
		return NewNop()
 | 
			
		||||
	}
 | 
			
		||||
	log := &Logger{
 | 
			
		||||
		core:        core,
 | 
			
		||||
		errorOutput: zapcore.Lock(os.Stderr),
 | 
			
		||||
		addStack:    zapcore.FatalLevel + 1,
 | 
			
		||||
		clock:       zapcore.DefaultClock,
 | 
			
		||||
	}
 | 
			
		||||
	return log.WithOptions(options...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewNop returns a no-op Logger. It never writes out logs or internal errors,
 | 
			
		||||
// and it never runs user-defined hooks.
 | 
			
		||||
//
 | 
			
		||||
// Using WithOptions to replace the Core or error output of a no-op Logger can
 | 
			
		||||
// re-enable logging.
 | 
			
		||||
func NewNop() *Logger {
 | 
			
		||||
	return &Logger{
 | 
			
		||||
		core:        zapcore.NewNopCore(),
 | 
			
		||||
		errorOutput: zapcore.AddSync(ioutil.Discard),
 | 
			
		||||
		addStack:    zapcore.FatalLevel + 1,
 | 
			
		||||
		clock:       zapcore.DefaultClock,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewProduction builds a sensible production Logger that writes InfoLevel and
 | 
			
		||||
// above logs to standard error as JSON.
 | 
			
		||||
//
 | 
			
		||||
// It's a shortcut for NewProductionConfig().Build(...Option).
 | 
			
		||||
func NewProduction(options ...Option) (*Logger, error) {
 | 
			
		||||
	return NewProductionConfig().Build(options...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewDevelopment builds a development Logger that writes DebugLevel and above
 | 
			
		||||
// logs to standard error in a human-friendly format.
 | 
			
		||||
//
 | 
			
		||||
// It's a shortcut for NewDevelopmentConfig().Build(...Option).
 | 
			
		||||
func NewDevelopment(options ...Option) (*Logger, error) {
 | 
			
		||||
	return NewDevelopmentConfig().Build(options...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewExample builds a Logger that's designed for use in zap's testable
 | 
			
		||||
// examples. It writes DebugLevel and above logs to standard out as JSON, but
 | 
			
		||||
// omits the timestamp and calling function to keep example output
 | 
			
		||||
// short and deterministic.
 | 
			
		||||
func NewExample(options ...Option) *Logger {
 | 
			
		||||
	encoderCfg := zapcore.EncoderConfig{
 | 
			
		||||
		MessageKey:     "msg",
 | 
			
		||||
		LevelKey:       "level",
 | 
			
		||||
		NameKey:        "logger",
 | 
			
		||||
		EncodeLevel:    zapcore.LowercaseLevelEncoder,
 | 
			
		||||
		EncodeTime:     zapcore.ISO8601TimeEncoder,
 | 
			
		||||
		EncodeDuration: zapcore.StringDurationEncoder,
 | 
			
		||||
	}
 | 
			
		||||
	core := zapcore.NewCore(zapcore.NewJSONEncoder(encoderCfg), os.Stdout, DebugLevel)
 | 
			
		||||
	return New(core).WithOptions(options...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sugar wraps the Logger to provide a more ergonomic, but slightly slower,
 | 
			
		||||
// API. Sugaring a Logger is quite inexpensive, so it's reasonable for a
 | 
			
		||||
// single application to use both Loggers and SugaredLoggers, converting
 | 
			
		||||
// between them on the boundaries of performance-sensitive code.
 | 
			
		||||
func (log *Logger) Sugar() *SugaredLogger {
 | 
			
		||||
	core := log.clone()
 | 
			
		||||
	core.callerSkip += 2
 | 
			
		||||
	return &SugaredLogger{core}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Named adds a new path segment to the logger's name. Segments are joined by
 | 
			
		||||
// periods. By default, Loggers are unnamed.
 | 
			
		||||
func (log *Logger) Named(s string) *Logger {
 | 
			
		||||
	if s == "" {
 | 
			
		||||
		return log
 | 
			
		||||
	}
 | 
			
		||||
	l := log.clone()
 | 
			
		||||
	if log.name == "" {
 | 
			
		||||
		l.name = s
 | 
			
		||||
	} else {
 | 
			
		||||
		l.name = strings.Join([]string{l.name, s}, ".")
 | 
			
		||||
	}
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithOptions clones the current Logger, applies the supplied Options, and
 | 
			
		||||
// returns the resulting Logger. It's safe to use concurrently.
 | 
			
		||||
func (log *Logger) WithOptions(opts ...Option) *Logger {
 | 
			
		||||
	c := log.clone()
 | 
			
		||||
	for _, opt := range opts {
 | 
			
		||||
		opt.apply(c)
 | 
			
		||||
	}
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// With creates a child logger and adds structured context to it. Fields added
 | 
			
		||||
// to the child don't affect the parent, and vice versa.
 | 
			
		||||
func (log *Logger) With(fields ...Field) *Logger {
 | 
			
		||||
	if len(fields) == 0 {
 | 
			
		||||
		return log
 | 
			
		||||
	}
 | 
			
		||||
	l := log.clone()
 | 
			
		||||
	l.core = l.core.With(fields)
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Check returns a CheckedEntry if logging a message at the specified level
 | 
			
		||||
// is enabled. It's a completely optional optimization; in high-performance
 | 
			
		||||
// applications, Check can help avoid allocating a slice to hold fields.
 | 
			
		||||
func (log *Logger) Check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry {
 | 
			
		||||
	return log.check(lvl, msg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Debug logs a message at DebugLevel. The message includes any fields passed
 | 
			
		||||
// at the log site, as well as any fields accumulated on the logger.
 | 
			
		||||
func (log *Logger) Debug(msg string, fields ...Field) {
 | 
			
		||||
	if ce := log.check(DebugLevel, msg); ce != nil {
 | 
			
		||||
		ce.Write(fields...)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Info logs a message at InfoLevel. The message includes any fields passed
 | 
			
		||||
// at the log site, as well as any fields accumulated on the logger.
 | 
			
		||||
func (log *Logger) Info(msg string, fields ...Field) {
 | 
			
		||||
	if ce := log.check(InfoLevel, msg); ce != nil {
 | 
			
		||||
		ce.Write(fields...)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Warn logs a message at WarnLevel. The message includes any fields passed
 | 
			
		||||
// at the log site, as well as any fields accumulated on the logger.
 | 
			
		||||
func (log *Logger) Warn(msg string, fields ...Field) {
 | 
			
		||||
	if ce := log.check(WarnLevel, msg); ce != nil {
 | 
			
		||||
		ce.Write(fields...)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Error logs a message at ErrorLevel. The message includes any fields passed
 | 
			
		||||
// at the log site, as well as any fields accumulated on the logger.
 | 
			
		||||
func (log *Logger) Error(msg string, fields ...Field) {
 | 
			
		||||
	if ce := log.check(ErrorLevel, msg); ce != nil {
 | 
			
		||||
		ce.Write(fields...)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DPanic logs a message at DPanicLevel. The message includes any fields
 | 
			
		||||
// passed at the log site, as well as any fields accumulated on the logger.
 | 
			
		||||
//
 | 
			
		||||
// If the logger is in development mode, it then panics (DPanic means
 | 
			
		||||
// "development panic"). This is useful for catching errors that are
 | 
			
		||||
// recoverable, but shouldn't ever happen.
 | 
			
		||||
func (log *Logger) DPanic(msg string, fields ...Field) {
 | 
			
		||||
	if ce := log.check(DPanicLevel, msg); ce != nil {
 | 
			
		||||
		ce.Write(fields...)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Panic logs a message at PanicLevel. The message includes any fields passed
 | 
			
		||||
// at the log site, as well as any fields accumulated on the logger.
 | 
			
		||||
//
 | 
			
		||||
// The logger then panics, even if logging at PanicLevel is disabled.
 | 
			
		||||
func (log *Logger) Panic(msg string, fields ...Field) {
 | 
			
		||||
	if ce := log.check(PanicLevel, msg); ce != nil {
 | 
			
		||||
		ce.Write(fields...)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fatal logs a message at FatalLevel. The message includes any fields passed
 | 
			
		||||
// at the log site, as well as any fields accumulated on the logger.
 | 
			
		||||
//
 | 
			
		||||
// The logger then calls os.Exit(1), even if logging at FatalLevel is
 | 
			
		||||
// disabled.
 | 
			
		||||
func (log *Logger) Fatal(msg string, fields ...Field) {
 | 
			
		||||
	if ce := log.check(FatalLevel, msg); ce != nil {
 | 
			
		||||
		ce.Write(fields...)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sync calls the underlying Core's Sync method, flushing any buffered log
 | 
			
		||||
// entries. Applications should take care to call Sync before exiting.
 | 
			
		||||
func (log *Logger) Sync() error {
 | 
			
		||||
	return log.core.Sync()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Core returns the Logger's underlying zapcore.Core.
 | 
			
		||||
func (log *Logger) Core() zapcore.Core {
 | 
			
		||||
	return log.core
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (log *Logger) clone() *Logger {
 | 
			
		||||
	copy := *log
 | 
			
		||||
	return ©
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry {
 | 
			
		||||
	// check must always be called directly by a method in the Logger interface
 | 
			
		||||
	// (e.g., Check, Info, Fatal).
 | 
			
		||||
	const callerSkipOffset = 2
 | 
			
		||||
 | 
			
		||||
	// Check the level first to reduce the cost of disabled log calls.
 | 
			
		||||
	// Since Panic and higher may exit, we skip the optimization for those levels.
 | 
			
		||||
	if lvl < zapcore.DPanicLevel && !log.core.Enabled(lvl) {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Create basic checked entry thru the core; this will be non-nil if the
 | 
			
		||||
	// log message will actually be written somewhere.
 | 
			
		||||
	ent := zapcore.Entry{
 | 
			
		||||
		LoggerName: log.name,
 | 
			
		||||
		Time:       log.clock.Now(),
 | 
			
		||||
		Level:      lvl,
 | 
			
		||||
		Message:    msg,
 | 
			
		||||
	}
 | 
			
		||||
	ce := log.core.Check(ent, nil)
 | 
			
		||||
	willWrite := ce != nil
 | 
			
		||||
 | 
			
		||||
	// Set up any required terminal behavior.
 | 
			
		||||
	switch ent.Level {
 | 
			
		||||
	case zapcore.PanicLevel:
 | 
			
		||||
		ce = ce.Should(ent, zapcore.WriteThenPanic)
 | 
			
		||||
	case zapcore.FatalLevel:
 | 
			
		||||
		onFatal := log.onFatal
 | 
			
		||||
		// Noop is the default value for CheckWriteAction, and it leads to
 | 
			
		||||
		// continued execution after a Fatal which is unexpected.
 | 
			
		||||
		if onFatal == zapcore.WriteThenNoop {
 | 
			
		||||
			onFatal = zapcore.WriteThenFatal
 | 
			
		||||
		}
 | 
			
		||||
		ce = ce.Should(ent, onFatal)
 | 
			
		||||
	case zapcore.DPanicLevel:
 | 
			
		||||
		if log.development {
 | 
			
		||||
			ce = ce.Should(ent, zapcore.WriteThenPanic)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Only do further annotation if we're going to write this message; checked
 | 
			
		||||
	// entries that exist only for terminal behavior don't benefit from
 | 
			
		||||
	// annotation.
 | 
			
		||||
	if !willWrite {
 | 
			
		||||
		return ce
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Thread the error output through to the CheckedEntry.
 | 
			
		||||
	ce.ErrorOutput = log.errorOutput
 | 
			
		||||
	if log.addCaller {
 | 
			
		||||
		frame, defined := getCallerFrame(log.callerSkip + callerSkipOffset)
 | 
			
		||||
		if !defined {
 | 
			
		||||
			fmt.Fprintf(log.errorOutput, "%v Logger.check error: failed to get caller\n", ent.Time.UTC())
 | 
			
		||||
			log.errorOutput.Sync()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ce.Entry.Caller = zapcore.EntryCaller{
 | 
			
		||||
			Defined:  defined,
 | 
			
		||||
			PC:       frame.PC,
 | 
			
		||||
			File:     frame.File,
 | 
			
		||||
			Line:     frame.Line,
 | 
			
		||||
			Function: frame.Function,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if log.addStack.Enabled(ce.Entry.Level) {
 | 
			
		||||
		ce.Entry.Stack = StackSkip("", log.callerSkip+callerSkipOffset).String
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ce
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getCallerFrame gets caller frame. The argument skip is the number of stack
 | 
			
		||||
// frames to ascend, with 0 identifying the caller of getCallerFrame. The
 | 
			
		||||
// boolean ok is false if it was not possible to recover the information.
 | 
			
		||||
//
 | 
			
		||||
// Note: This implementation is similar to runtime.Caller, but it returns the whole frame.
 | 
			
		||||
func getCallerFrame(skip int) (frame runtime.Frame, ok bool) {
 | 
			
		||||
	const skipOffset = 2 // skip getCallerFrame and Callers
 | 
			
		||||
 | 
			
		||||
	pc := make([]uintptr, 1)
 | 
			
		||||
	numFrames := runtime.Callers(skip+skipOffset, pc)
 | 
			
		||||
	if numFrames < 1 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	frame, _ = runtime.CallersFrames(pc).Next()
 | 
			
		||||
	return frame, frame.PC != 0
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										148
									
								
								vendor/go.uber.org/zap/options.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								vendor/go.uber.org/zap/options.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,148 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/zapcore"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// An Option configures a Logger.
 | 
			
		||||
type Option interface {
 | 
			
		||||
	apply(*Logger)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// optionFunc wraps a func so it satisfies the Option interface.
 | 
			
		||||
type optionFunc func(*Logger)
 | 
			
		||||
 | 
			
		||||
func (f optionFunc) apply(log *Logger) {
 | 
			
		||||
	f(log)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WrapCore wraps or replaces the Logger's underlying zapcore.Core.
 | 
			
		||||
func WrapCore(f func(zapcore.Core) zapcore.Core) Option {
 | 
			
		||||
	return optionFunc(func(log *Logger) {
 | 
			
		||||
		log.core = f(log.core)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Hooks registers functions which will be called each time the Logger writes
 | 
			
		||||
// out an Entry. Repeated use of Hooks is additive.
 | 
			
		||||
//
 | 
			
		||||
// Hooks are useful for simple side effects, like capturing metrics for the
 | 
			
		||||
// number of emitted logs. More complex side effects, including anything that
 | 
			
		||||
// requires access to the Entry's structured fields, should be implemented as
 | 
			
		||||
// a zapcore.Core instead. See zapcore.RegisterHooks for details.
 | 
			
		||||
func Hooks(hooks ...func(zapcore.Entry) error) Option {
 | 
			
		||||
	return optionFunc(func(log *Logger) {
 | 
			
		||||
		log.core = zapcore.RegisterHooks(log.core, hooks...)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fields adds fields to the Logger.
 | 
			
		||||
func Fields(fs ...Field) Option {
 | 
			
		||||
	return optionFunc(func(log *Logger) {
 | 
			
		||||
		log.core = log.core.With(fs)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ErrorOutput sets the destination for errors generated by the Logger. Note
 | 
			
		||||
// that this option only affects internal errors; for sample code that sends
 | 
			
		||||
// error-level logs to a different location from info- and debug-level logs,
 | 
			
		||||
// see the package-level AdvancedConfiguration example.
 | 
			
		||||
//
 | 
			
		||||
// The supplied WriteSyncer must be safe for concurrent use. The Open and
 | 
			
		||||
// zapcore.Lock functions are the simplest ways to protect files with a mutex.
 | 
			
		||||
func ErrorOutput(w zapcore.WriteSyncer) Option {
 | 
			
		||||
	return optionFunc(func(log *Logger) {
 | 
			
		||||
		log.errorOutput = w
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Development puts the logger in development mode, which makes DPanic-level
 | 
			
		||||
// logs panic instead of simply logging an error.
 | 
			
		||||
func Development() Option {
 | 
			
		||||
	return optionFunc(func(log *Logger) {
 | 
			
		||||
		log.development = true
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddCaller configures the Logger to annotate each message with the filename,
 | 
			
		||||
// line number, and function name of zap's caller. See also WithCaller.
 | 
			
		||||
func AddCaller() Option {
 | 
			
		||||
	return WithCaller(true)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithCaller configures the Logger to annotate each message with the filename,
 | 
			
		||||
// line number, and function name of zap's caller, or not, depending on the
 | 
			
		||||
// value of enabled. This is a generalized form of AddCaller.
 | 
			
		||||
func WithCaller(enabled bool) Option {
 | 
			
		||||
	return optionFunc(func(log *Logger) {
 | 
			
		||||
		log.addCaller = enabled
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddCallerSkip increases the number of callers skipped by caller annotation
 | 
			
		||||
// (as enabled by the AddCaller option). When building wrappers around the
 | 
			
		||||
// Logger and SugaredLogger, supplying this Option prevents zap from always
 | 
			
		||||
// reporting the wrapper code as the caller.
 | 
			
		||||
func AddCallerSkip(skip int) Option {
 | 
			
		||||
	return optionFunc(func(log *Logger) {
 | 
			
		||||
		log.callerSkip += skip
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddStacktrace configures the Logger to record a stack trace for all messages at
 | 
			
		||||
// or above a given level.
 | 
			
		||||
func AddStacktrace(lvl zapcore.LevelEnabler) Option {
 | 
			
		||||
	return optionFunc(func(log *Logger) {
 | 
			
		||||
		log.addStack = lvl
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IncreaseLevel increase the level of the logger. It has no effect if
 | 
			
		||||
// the passed in level tries to decrease the level of the logger.
 | 
			
		||||
func IncreaseLevel(lvl zapcore.LevelEnabler) Option {
 | 
			
		||||
	return optionFunc(func(log *Logger) {
 | 
			
		||||
		core, err := zapcore.NewIncreaseLevelCore(log.core, lvl)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Fprintf(log.errorOutput, "failed to IncreaseLevel: %v\n", err)
 | 
			
		||||
		} else {
 | 
			
		||||
			log.core = core
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OnFatal sets the action to take on fatal logs.
 | 
			
		||||
func OnFatal(action zapcore.CheckWriteAction) Option {
 | 
			
		||||
	return optionFunc(func(log *Logger) {
 | 
			
		||||
		log.onFatal = action
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithClock specifies the clock used by the logger to determine the current
 | 
			
		||||
// time for logged entries. Defaults to the system clock with time.Now.
 | 
			
		||||
func WithClock(clock zapcore.Clock) Option {
 | 
			
		||||
	return optionFunc(func(log *Logger) {
 | 
			
		||||
		log.clock = clock
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										161
									
								
								vendor/go.uber.org/zap/sink.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								vendor/go.uber.org/zap/sink.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,161 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/zapcore"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const schemeFile = "file"
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_sinkMutex     sync.RWMutex
 | 
			
		||||
	_sinkFactories map[string]func(*url.URL) (Sink, error) // keyed by scheme
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	resetSinkRegistry()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func resetSinkRegistry() {
 | 
			
		||||
	_sinkMutex.Lock()
 | 
			
		||||
	defer _sinkMutex.Unlock()
 | 
			
		||||
 | 
			
		||||
	_sinkFactories = map[string]func(*url.URL) (Sink, error){
 | 
			
		||||
		schemeFile: newFileSink,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sink defines the interface to write to and close logger destinations.
 | 
			
		||||
type Sink interface {
 | 
			
		||||
	zapcore.WriteSyncer
 | 
			
		||||
	io.Closer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type nopCloserSink struct{ zapcore.WriteSyncer }
 | 
			
		||||
 | 
			
		||||
func (nopCloserSink) Close() error { return nil }
 | 
			
		||||
 | 
			
		||||
type errSinkNotFound struct {
 | 
			
		||||
	scheme string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *errSinkNotFound) Error() string {
 | 
			
		||||
	return fmt.Sprintf("no sink found for scheme %q", e.scheme)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RegisterSink registers a user-supplied factory for all sinks with a
 | 
			
		||||
// particular scheme.
 | 
			
		||||
//
 | 
			
		||||
// All schemes must be ASCII, valid under section 3.1 of RFC 3986
 | 
			
		||||
// (https://tools.ietf.org/html/rfc3986#section-3.1), and must not already
 | 
			
		||||
// have a factory registered. Zap automatically registers a factory for the
 | 
			
		||||
// "file" scheme.
 | 
			
		||||
func RegisterSink(scheme string, factory func(*url.URL) (Sink, error)) error {
 | 
			
		||||
	_sinkMutex.Lock()
 | 
			
		||||
	defer _sinkMutex.Unlock()
 | 
			
		||||
 | 
			
		||||
	if scheme == "" {
 | 
			
		||||
		return errors.New("can't register a sink factory for empty string")
 | 
			
		||||
	}
 | 
			
		||||
	normalized, err := normalizeScheme(scheme)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("%q is not a valid scheme: %v", scheme, err)
 | 
			
		||||
	}
 | 
			
		||||
	if _, ok := _sinkFactories[normalized]; ok {
 | 
			
		||||
		return fmt.Errorf("sink factory already registered for scheme %q", normalized)
 | 
			
		||||
	}
 | 
			
		||||
	_sinkFactories[normalized] = factory
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newSink(rawURL string) (Sink, error) {
 | 
			
		||||
	u, err := url.Parse(rawURL)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("can't parse %q as a URL: %v", rawURL, err)
 | 
			
		||||
	}
 | 
			
		||||
	if u.Scheme == "" {
 | 
			
		||||
		u.Scheme = schemeFile
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_sinkMutex.RLock()
 | 
			
		||||
	factory, ok := _sinkFactories[u.Scheme]
 | 
			
		||||
	_sinkMutex.RUnlock()
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, &errSinkNotFound{u.Scheme}
 | 
			
		||||
	}
 | 
			
		||||
	return factory(u)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newFileSink(u *url.URL) (Sink, error) {
 | 
			
		||||
	if u.User != nil {
 | 
			
		||||
		return nil, fmt.Errorf("user and password not allowed with file URLs: got %v", u)
 | 
			
		||||
	}
 | 
			
		||||
	if u.Fragment != "" {
 | 
			
		||||
		return nil, fmt.Errorf("fragments not allowed with file URLs: got %v", u)
 | 
			
		||||
	}
 | 
			
		||||
	if u.RawQuery != "" {
 | 
			
		||||
		return nil, fmt.Errorf("query parameters not allowed with file URLs: got %v", u)
 | 
			
		||||
	}
 | 
			
		||||
	// Error messages are better if we check hostname and port separately.
 | 
			
		||||
	if u.Port() != "" {
 | 
			
		||||
		return nil, fmt.Errorf("ports not allowed with file URLs: got %v", u)
 | 
			
		||||
	}
 | 
			
		||||
	if hn := u.Hostname(); hn != "" && hn != "localhost" {
 | 
			
		||||
		return nil, fmt.Errorf("file URLs must leave host empty or use localhost: got %v", u)
 | 
			
		||||
	}
 | 
			
		||||
	switch u.Path {
 | 
			
		||||
	case "stdout":
 | 
			
		||||
		return nopCloserSink{os.Stdout}, nil
 | 
			
		||||
	case "stderr":
 | 
			
		||||
		return nopCloserSink{os.Stderr}, nil
 | 
			
		||||
	}
 | 
			
		||||
	return os.OpenFile(u.Path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func normalizeScheme(s string) (string, error) {
 | 
			
		||||
	// https://tools.ietf.org/html/rfc3986#section-3.1
 | 
			
		||||
	s = strings.ToLower(s)
 | 
			
		||||
	if first := s[0]; 'a' > first || 'z' < first {
 | 
			
		||||
		return "", errors.New("must start with a letter")
 | 
			
		||||
	}
 | 
			
		||||
	for i := 1; i < len(s); i++ { // iterate over bytes, not runes
 | 
			
		||||
		c := s[i]
 | 
			
		||||
		switch {
 | 
			
		||||
		case 'a' <= c && c <= 'z':
 | 
			
		||||
			continue
 | 
			
		||||
		case '0' <= c && c <= '9':
 | 
			
		||||
			continue
 | 
			
		||||
		case c == '.' || c == '+' || c == '-':
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		return "", fmt.Errorf("may not contain %q", c)
 | 
			
		||||
	}
 | 
			
		||||
	return s, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										85
									
								
								vendor/go.uber.org/zap/stacktrace.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								vendor/go.uber.org/zap/stacktrace.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/internal/bufferpool"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_stacktracePool = sync.Pool{
 | 
			
		||||
		New: func() interface{} {
 | 
			
		||||
			return newProgramCounters(64)
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func takeStacktrace(skip int) string {
 | 
			
		||||
	buffer := bufferpool.Get()
 | 
			
		||||
	defer buffer.Free()
 | 
			
		||||
	programCounters := _stacktracePool.Get().(*programCounters)
 | 
			
		||||
	defer _stacktracePool.Put(programCounters)
 | 
			
		||||
 | 
			
		||||
	var numFrames int
 | 
			
		||||
	for {
 | 
			
		||||
		// Skip the call to runtime.Callers and takeStacktrace so that the
 | 
			
		||||
		// program counters start at the caller of takeStacktrace.
 | 
			
		||||
		numFrames = runtime.Callers(skip+2, programCounters.pcs)
 | 
			
		||||
		if numFrames < len(programCounters.pcs) {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		// Don't put the too-short counter slice back into the pool; this lets
 | 
			
		||||
		// the pool adjust if we consistently take deep stacktraces.
 | 
			
		||||
		programCounters = newProgramCounters(len(programCounters.pcs) * 2)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	i := 0
 | 
			
		||||
	frames := runtime.CallersFrames(programCounters.pcs[:numFrames])
 | 
			
		||||
 | 
			
		||||
	// Note: On the last iteration, frames.Next() returns false, with a valid
 | 
			
		||||
	// frame, but we ignore this frame. The last frame is a a runtime frame which
 | 
			
		||||
	// adds noise, since it's only either runtime.main or runtime.goexit.
 | 
			
		||||
	for frame, more := frames.Next(); more; frame, more = frames.Next() {
 | 
			
		||||
		if i != 0 {
 | 
			
		||||
			buffer.AppendByte('\n')
 | 
			
		||||
		}
 | 
			
		||||
		i++
 | 
			
		||||
		buffer.AppendString(frame.Function)
 | 
			
		||||
		buffer.AppendByte('\n')
 | 
			
		||||
		buffer.AppendByte('\t')
 | 
			
		||||
		buffer.AppendString(frame.File)
 | 
			
		||||
		buffer.AppendByte(':')
 | 
			
		||||
		buffer.AppendInt(int64(frame.Line))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return buffer.String()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type programCounters struct {
 | 
			
		||||
	pcs []uintptr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newProgramCounters(size int) *programCounters {
 | 
			
		||||
	return &programCounters{make([]uintptr, size)}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										315
									
								
								vendor/go.uber.org/zap/sugar.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										315
									
								
								vendor/go.uber.org/zap/sugar.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,315 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/zapcore"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/multierr"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	_oddNumberErrMsg    = "Ignored key without a value."
 | 
			
		||||
	_nonStringKeyErrMsg = "Ignored key-value pairs with non-string keys."
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A SugaredLogger wraps the base Logger functionality in a slower, but less
 | 
			
		||||
// verbose, API. Any Logger can be converted to a SugaredLogger with its Sugar
 | 
			
		||||
// method.
 | 
			
		||||
//
 | 
			
		||||
// Unlike the Logger, the SugaredLogger doesn't insist on structured logging.
 | 
			
		||||
// For each log level, it exposes three methods: one for loosely-typed
 | 
			
		||||
// structured logging, one for println-style formatting, and one for
 | 
			
		||||
// printf-style formatting. For example, SugaredLoggers can produce InfoLevel
 | 
			
		||||
// output with Infow ("info with" structured context), Info, or Infof.
 | 
			
		||||
type SugaredLogger struct {
 | 
			
		||||
	base *Logger
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Desugar unwraps a SugaredLogger, exposing the original Logger. Desugaring
 | 
			
		||||
// is quite inexpensive, so it's reasonable for a single application to use
 | 
			
		||||
// both Loggers and SugaredLoggers, converting between them on the boundaries
 | 
			
		||||
// of performance-sensitive code.
 | 
			
		||||
func (s *SugaredLogger) Desugar() *Logger {
 | 
			
		||||
	base := s.base.clone()
 | 
			
		||||
	base.callerSkip -= 2
 | 
			
		||||
	return base
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Named adds a sub-scope to the logger's name. See Logger.Named for details.
 | 
			
		||||
func (s *SugaredLogger) Named(name string) *SugaredLogger {
 | 
			
		||||
	return &SugaredLogger{base: s.base.Named(name)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// With adds a variadic number of fields to the logging context. It accepts a
 | 
			
		||||
// mix of strongly-typed Field objects and loosely-typed key-value pairs. When
 | 
			
		||||
// processing pairs, the first element of the pair is used as the field key
 | 
			
		||||
// and the second as the field value.
 | 
			
		||||
//
 | 
			
		||||
// For example,
 | 
			
		||||
//   sugaredLogger.With(
 | 
			
		||||
//     "hello", "world",
 | 
			
		||||
//     "failure", errors.New("oh no"),
 | 
			
		||||
//     Stack(),
 | 
			
		||||
//     "count", 42,
 | 
			
		||||
//     "user", User{Name: "alice"},
 | 
			
		||||
//  )
 | 
			
		||||
// is the equivalent of
 | 
			
		||||
//   unsugared.With(
 | 
			
		||||
//     String("hello", "world"),
 | 
			
		||||
//     String("failure", "oh no"),
 | 
			
		||||
//     Stack(),
 | 
			
		||||
//     Int("count", 42),
 | 
			
		||||
//     Object("user", User{Name: "alice"}),
 | 
			
		||||
//   )
 | 
			
		||||
//
 | 
			
		||||
// Note that the keys in key-value pairs should be strings. In development,
 | 
			
		||||
// passing a non-string key panics. In production, the logger is more
 | 
			
		||||
// forgiving: a separate error is logged, but the key-value pair is skipped
 | 
			
		||||
// and execution continues. Passing an orphaned key triggers similar behavior:
 | 
			
		||||
// panics in development and errors in production.
 | 
			
		||||
func (s *SugaredLogger) With(args ...interface{}) *SugaredLogger {
 | 
			
		||||
	return &SugaredLogger{base: s.base.With(s.sweetenFields(args)...)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Debug uses fmt.Sprint to construct and log a message.
 | 
			
		||||
func (s *SugaredLogger) Debug(args ...interface{}) {
 | 
			
		||||
	s.log(DebugLevel, "", args, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Info uses fmt.Sprint to construct and log a message.
 | 
			
		||||
func (s *SugaredLogger) Info(args ...interface{}) {
 | 
			
		||||
	s.log(InfoLevel, "", args, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Warn uses fmt.Sprint to construct and log a message.
 | 
			
		||||
func (s *SugaredLogger) Warn(args ...interface{}) {
 | 
			
		||||
	s.log(WarnLevel, "", args, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Error uses fmt.Sprint to construct and log a message.
 | 
			
		||||
func (s *SugaredLogger) Error(args ...interface{}) {
 | 
			
		||||
	s.log(ErrorLevel, "", args, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DPanic uses fmt.Sprint to construct and log a message. In development, the
 | 
			
		||||
// logger then panics. (See DPanicLevel for details.)
 | 
			
		||||
func (s *SugaredLogger) DPanic(args ...interface{}) {
 | 
			
		||||
	s.log(DPanicLevel, "", args, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Panic uses fmt.Sprint to construct and log a message, then panics.
 | 
			
		||||
func (s *SugaredLogger) Panic(args ...interface{}) {
 | 
			
		||||
	s.log(PanicLevel, "", args, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fatal uses fmt.Sprint to construct and log a message, then calls os.Exit.
 | 
			
		||||
func (s *SugaredLogger) Fatal(args ...interface{}) {
 | 
			
		||||
	s.log(FatalLevel, "", args, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Debugf uses fmt.Sprintf to log a templated message.
 | 
			
		||||
func (s *SugaredLogger) Debugf(template string, args ...interface{}) {
 | 
			
		||||
	s.log(DebugLevel, template, args, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Infof uses fmt.Sprintf to log a templated message.
 | 
			
		||||
func (s *SugaredLogger) Infof(template string, args ...interface{}) {
 | 
			
		||||
	s.log(InfoLevel, template, args, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Warnf uses fmt.Sprintf to log a templated message.
 | 
			
		||||
func (s *SugaredLogger) Warnf(template string, args ...interface{}) {
 | 
			
		||||
	s.log(WarnLevel, template, args, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Errorf uses fmt.Sprintf to log a templated message.
 | 
			
		||||
func (s *SugaredLogger) Errorf(template string, args ...interface{}) {
 | 
			
		||||
	s.log(ErrorLevel, template, args, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DPanicf uses fmt.Sprintf to log a templated message. In development, the
 | 
			
		||||
// logger then panics. (See DPanicLevel for details.)
 | 
			
		||||
func (s *SugaredLogger) DPanicf(template string, args ...interface{}) {
 | 
			
		||||
	s.log(DPanicLevel, template, args, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Panicf uses fmt.Sprintf to log a templated message, then panics.
 | 
			
		||||
func (s *SugaredLogger) Panicf(template string, args ...interface{}) {
 | 
			
		||||
	s.log(PanicLevel, template, args, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fatalf uses fmt.Sprintf to log a templated message, then calls os.Exit.
 | 
			
		||||
func (s *SugaredLogger) Fatalf(template string, args ...interface{}) {
 | 
			
		||||
	s.log(FatalLevel, template, args, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Debugw logs a message with some additional context. The variadic key-value
 | 
			
		||||
// pairs are treated as they are in With.
 | 
			
		||||
//
 | 
			
		||||
// When debug-level logging is disabled, this is much faster than
 | 
			
		||||
//  s.With(keysAndValues).Debug(msg)
 | 
			
		||||
func (s *SugaredLogger) Debugw(msg string, keysAndValues ...interface{}) {
 | 
			
		||||
	s.log(DebugLevel, msg, nil, keysAndValues)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Infow logs a message with some additional context. The variadic key-value
 | 
			
		||||
// pairs are treated as they are in With.
 | 
			
		||||
func (s *SugaredLogger) Infow(msg string, keysAndValues ...interface{}) {
 | 
			
		||||
	s.log(InfoLevel, msg, nil, keysAndValues)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Warnw logs a message with some additional context. The variadic key-value
 | 
			
		||||
// pairs are treated as they are in With.
 | 
			
		||||
func (s *SugaredLogger) Warnw(msg string, keysAndValues ...interface{}) {
 | 
			
		||||
	s.log(WarnLevel, msg, nil, keysAndValues)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Errorw logs a message with some additional context. The variadic key-value
 | 
			
		||||
// pairs are treated as they are in With.
 | 
			
		||||
func (s *SugaredLogger) Errorw(msg string, keysAndValues ...interface{}) {
 | 
			
		||||
	s.log(ErrorLevel, msg, nil, keysAndValues)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DPanicw logs a message with some additional context. In development, the
 | 
			
		||||
// logger then panics. (See DPanicLevel for details.) The variadic key-value
 | 
			
		||||
// pairs are treated as they are in With.
 | 
			
		||||
func (s *SugaredLogger) DPanicw(msg string, keysAndValues ...interface{}) {
 | 
			
		||||
	s.log(DPanicLevel, msg, nil, keysAndValues)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Panicw logs a message with some additional context, then panics. The
 | 
			
		||||
// variadic key-value pairs are treated as they are in With.
 | 
			
		||||
func (s *SugaredLogger) Panicw(msg string, keysAndValues ...interface{}) {
 | 
			
		||||
	s.log(PanicLevel, msg, nil, keysAndValues)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fatalw logs a message with some additional context, then calls os.Exit. The
 | 
			
		||||
// variadic key-value pairs are treated as they are in With.
 | 
			
		||||
func (s *SugaredLogger) Fatalw(msg string, keysAndValues ...interface{}) {
 | 
			
		||||
	s.log(FatalLevel, msg, nil, keysAndValues)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sync flushes any buffered log entries.
 | 
			
		||||
func (s *SugaredLogger) Sync() error {
 | 
			
		||||
	return s.base.Sync()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *SugaredLogger) log(lvl zapcore.Level, template string, fmtArgs []interface{}, context []interface{}) {
 | 
			
		||||
	// If logging at this level is completely disabled, skip the overhead of
 | 
			
		||||
	// string formatting.
 | 
			
		||||
	if lvl < DPanicLevel && !s.base.Core().Enabled(lvl) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	msg := getMessage(template, fmtArgs)
 | 
			
		||||
	if ce := s.base.Check(lvl, msg); ce != nil {
 | 
			
		||||
		ce.Write(s.sweetenFields(context)...)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getMessage format with Sprint, Sprintf, or neither.
 | 
			
		||||
func getMessage(template string, fmtArgs []interface{}) string {
 | 
			
		||||
	if len(fmtArgs) == 0 {
 | 
			
		||||
		return template
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if template != "" {
 | 
			
		||||
		return fmt.Sprintf(template, fmtArgs...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(fmtArgs) == 1 {
 | 
			
		||||
		if str, ok := fmtArgs[0].(string); ok {
 | 
			
		||||
			return str
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprint(fmtArgs...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *SugaredLogger) sweetenFields(args []interface{}) []Field {
 | 
			
		||||
	if len(args) == 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Allocate enough space for the worst case; if users pass only structured
 | 
			
		||||
	// fields, we shouldn't penalize them with extra allocations.
 | 
			
		||||
	fields := make([]Field, 0, len(args))
 | 
			
		||||
	var invalid invalidPairs
 | 
			
		||||
 | 
			
		||||
	for i := 0; i < len(args); {
 | 
			
		||||
		// This is a strongly-typed field. Consume it and move on.
 | 
			
		||||
		if f, ok := args[i].(Field); ok {
 | 
			
		||||
			fields = append(fields, f)
 | 
			
		||||
			i++
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Make sure this element isn't a dangling key.
 | 
			
		||||
		if i == len(args)-1 {
 | 
			
		||||
			s.base.Error(_oddNumberErrMsg, Any("ignored", args[i]))
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Consume this value and the next, treating them as a key-value pair. If the
 | 
			
		||||
		// key isn't a string, add this pair to the slice of invalid pairs.
 | 
			
		||||
		key, val := args[i], args[i+1]
 | 
			
		||||
		if keyStr, ok := key.(string); !ok {
 | 
			
		||||
			// Subsequent errors are likely, so allocate once up front.
 | 
			
		||||
			if cap(invalid) == 0 {
 | 
			
		||||
				invalid = make(invalidPairs, 0, len(args)/2)
 | 
			
		||||
			}
 | 
			
		||||
			invalid = append(invalid, invalidPair{i, key, val})
 | 
			
		||||
		} else {
 | 
			
		||||
			fields = append(fields, Any(keyStr, val))
 | 
			
		||||
		}
 | 
			
		||||
		i += 2
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If we encountered any invalid key-value pairs, log an error.
 | 
			
		||||
	if len(invalid) > 0 {
 | 
			
		||||
		s.base.Error(_nonStringKeyErrMsg, Array("invalid", invalid))
 | 
			
		||||
	}
 | 
			
		||||
	return fields
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type invalidPair struct {
 | 
			
		||||
	position   int
 | 
			
		||||
	key, value interface{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p invalidPair) MarshalLogObject(enc zapcore.ObjectEncoder) error {
 | 
			
		||||
	enc.AddInt64("position", int64(p.position))
 | 
			
		||||
	Any("key", p.key).AddTo(enc)
 | 
			
		||||
	Any("value", p.value).AddTo(enc)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type invalidPairs []invalidPair
 | 
			
		||||
 | 
			
		||||
func (ps invalidPairs) MarshalLogArray(enc zapcore.ArrayEncoder) error {
 | 
			
		||||
	var err error
 | 
			
		||||
	for i := range ps {
 | 
			
		||||
		err = multierr.Append(err, enc.AppendObject(ps[i]))
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								vendor/go.uber.org/zap/time.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/go.uber.org/zap/time.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
// 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"
 | 
			
		||||
 | 
			
		||||
func timeToMillis(t time.Time) int64 {
 | 
			
		||||
	return t.UnixNano() / int64(time.Millisecond)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										99
									
								
								vendor/go.uber.org/zap/writer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								vendor/go.uber.org/zap/writer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/zapcore"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/multierr"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Open is a high-level wrapper that takes a variadic number of URLs, opens or
 | 
			
		||||
// creates each of the specified resources, and combines them into a locked
 | 
			
		||||
// WriteSyncer. It also returns any error encountered and a function to close
 | 
			
		||||
// any opened files.
 | 
			
		||||
//
 | 
			
		||||
// Passing no URLs returns a no-op WriteSyncer. Zap handles URLs without a
 | 
			
		||||
// scheme and URLs with the "file" scheme. Third-party code may register
 | 
			
		||||
// factories for other schemes using RegisterSink.
 | 
			
		||||
//
 | 
			
		||||
// URLs with the "file" scheme must use absolute paths on the local
 | 
			
		||||
// filesystem. No user, password, port, fragments, or query parameters are
 | 
			
		||||
// allowed, and the hostname must be empty or "localhost".
 | 
			
		||||
//
 | 
			
		||||
// Since it's common to write logs to the local filesystem, URLs without a
 | 
			
		||||
// scheme (e.g., "/var/log/foo.log") are treated as local file paths. Without
 | 
			
		||||
// a scheme, the special paths "stdout" and "stderr" are interpreted as
 | 
			
		||||
// os.Stdout and os.Stderr. When specified without a scheme, relative file
 | 
			
		||||
// paths also work.
 | 
			
		||||
func Open(paths ...string) (zapcore.WriteSyncer, func(), error) {
 | 
			
		||||
	writers, close, err := open(paths)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	writer := CombineWriteSyncers(writers...)
 | 
			
		||||
	return writer, close, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func open(paths []string) ([]zapcore.WriteSyncer, func(), error) {
 | 
			
		||||
	writers := make([]zapcore.WriteSyncer, 0, len(paths))
 | 
			
		||||
	closers := make([]io.Closer, 0, len(paths))
 | 
			
		||||
	close := func() {
 | 
			
		||||
		for _, c := range closers {
 | 
			
		||||
			c.Close()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var openErr error
 | 
			
		||||
	for _, path := range paths {
 | 
			
		||||
		sink, err := newSink(path)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			openErr = multierr.Append(openErr, fmt.Errorf("couldn't open sink %q: %v", path, err))
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		writers = append(writers, sink)
 | 
			
		||||
		closers = append(closers, sink)
 | 
			
		||||
	}
 | 
			
		||||
	if openErr != nil {
 | 
			
		||||
		close()
 | 
			
		||||
		return writers, nil, openErr
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return writers, close, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CombineWriteSyncers is a utility that combines multiple WriteSyncers into a
 | 
			
		||||
// single, locked WriteSyncer. If no inputs are supplied, it returns a no-op
 | 
			
		||||
// WriteSyncer.
 | 
			
		||||
//
 | 
			
		||||
// It's provided purely as a convenience; the result is no different from
 | 
			
		||||
// using zapcore.NewMultiWriteSyncer and zapcore.Lock individually.
 | 
			
		||||
func CombineWriteSyncers(writers ...zapcore.WriteSyncer) zapcore.WriteSyncer {
 | 
			
		||||
	if len(writers) == 0 {
 | 
			
		||||
		return zapcore.AddSync(ioutil.Discard)
 | 
			
		||||
	}
 | 
			
		||||
	return zapcore.Lock(zapcore.NewMultiWriteSyncer(writers...))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										188
									
								
								vendor/go.uber.org/zap/zapcore/buffered_write_syncer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								vendor/go.uber.org/zap/zapcore/buffered_write_syncer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,188 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/multierr"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// _defaultBufferSize specifies the default size used by Buffer.
 | 
			
		||||
	_defaultBufferSize = 256 * 1024 // 256 kB
 | 
			
		||||
 | 
			
		||||
	// _defaultFlushInterval specifies the default flush interval for
 | 
			
		||||
	// Buffer.
 | 
			
		||||
	_defaultFlushInterval = 30 * time.Second
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A BufferedWriteSyncer is a WriteSyncer that buffers writes in-memory before
 | 
			
		||||
// flushing them to a wrapped WriteSyncer after reaching some limit, or at some
 | 
			
		||||
// fixed interval--whichever comes first.
 | 
			
		||||
//
 | 
			
		||||
// BufferedWriteSyncer is safe for concurrent use. You don't need to use
 | 
			
		||||
// zapcore.Lock for WriteSyncers with BufferedWriteSyncer.
 | 
			
		||||
type BufferedWriteSyncer struct {
 | 
			
		||||
	// WS is the WriteSyncer around which BufferedWriteSyncer will buffer
 | 
			
		||||
	// writes.
 | 
			
		||||
	//
 | 
			
		||||
	// This field is required.
 | 
			
		||||
	WS WriteSyncer
 | 
			
		||||
 | 
			
		||||
	// Size specifies the maximum amount of data the writer will buffered
 | 
			
		||||
	// before flushing.
 | 
			
		||||
	//
 | 
			
		||||
	// Defaults to 256 kB if unspecified.
 | 
			
		||||
	Size int
 | 
			
		||||
 | 
			
		||||
	// FlushInterval specifies how often the writer should flush data if
 | 
			
		||||
	// there have been no writes.
 | 
			
		||||
	//
 | 
			
		||||
	// Defaults to 30 seconds if unspecified.
 | 
			
		||||
	FlushInterval time.Duration
 | 
			
		||||
 | 
			
		||||
	// Clock, if specified, provides control of the source of time for the
 | 
			
		||||
	// writer.
 | 
			
		||||
	//
 | 
			
		||||
	// Defaults to the system clock.
 | 
			
		||||
	Clock Clock
 | 
			
		||||
 | 
			
		||||
	// unexported fields for state
 | 
			
		||||
	mu          sync.Mutex
 | 
			
		||||
	initialized bool // whether initialize() has run
 | 
			
		||||
	stopped     bool // whether Stop() has run
 | 
			
		||||
	writer      *bufio.Writer
 | 
			
		||||
	ticker      *time.Ticker
 | 
			
		||||
	stop        chan struct{} // closed when flushLoop should stop
 | 
			
		||||
	done        chan struct{} // closed when flushLoop has stopped
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *BufferedWriteSyncer) initialize() {
 | 
			
		||||
	size := s.Size
 | 
			
		||||
	if size == 0 {
 | 
			
		||||
		size = _defaultBufferSize
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	flushInterval := s.FlushInterval
 | 
			
		||||
	if flushInterval == 0 {
 | 
			
		||||
		flushInterval = _defaultFlushInterval
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s.Clock == nil {
 | 
			
		||||
		s.Clock = DefaultClock
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.ticker = s.Clock.NewTicker(flushInterval)
 | 
			
		||||
	s.writer = bufio.NewWriterSize(s.WS, size)
 | 
			
		||||
	s.stop = make(chan struct{})
 | 
			
		||||
	s.done = make(chan struct{})
 | 
			
		||||
	s.initialized = true
 | 
			
		||||
	go s.flushLoop()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Write writes log data into buffer syncer directly, multiple Write calls will be batched,
 | 
			
		||||
// and log data will be flushed to disk when the buffer is full or periodically.
 | 
			
		||||
func (s *BufferedWriteSyncer) Write(bs []byte) (int, error) {
 | 
			
		||||
	s.mu.Lock()
 | 
			
		||||
	defer s.mu.Unlock()
 | 
			
		||||
 | 
			
		||||
	if !s.initialized {
 | 
			
		||||
		s.initialize()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// To avoid partial writes from being flushed, we manually flush the existing buffer if:
 | 
			
		||||
	// * The current write doesn't fit into the buffer fully, and
 | 
			
		||||
	// * The buffer is not empty (since bufio will not split large writes when the buffer is empty)
 | 
			
		||||
	if len(bs) > s.writer.Available() && s.writer.Buffered() > 0 {
 | 
			
		||||
		if err := s.writer.Flush(); err != nil {
 | 
			
		||||
			return 0, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return s.writer.Write(bs)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sync flushes buffered log data into disk directly.
 | 
			
		||||
func (s *BufferedWriteSyncer) Sync() error {
 | 
			
		||||
	s.mu.Lock()
 | 
			
		||||
	defer s.mu.Unlock()
 | 
			
		||||
 | 
			
		||||
	var err error
 | 
			
		||||
	if s.initialized {
 | 
			
		||||
		err = s.writer.Flush()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return multierr.Append(err, s.WS.Sync())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// flushLoop flushes the buffer at the configured interval until Stop is
 | 
			
		||||
// called.
 | 
			
		||||
func (s *BufferedWriteSyncer) flushLoop() {
 | 
			
		||||
	defer close(s.done)
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		select {
 | 
			
		||||
		case <-s.ticker.C:
 | 
			
		||||
			// we just simply ignore error here
 | 
			
		||||
			// because the underlying bufio writer stores any errors
 | 
			
		||||
			// and we return any error from Sync() as part of the close
 | 
			
		||||
			_ = s.Sync()
 | 
			
		||||
		case <-s.stop:
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stop closes the buffer, cleans up background goroutines, and flushes
 | 
			
		||||
// remaining unwritten data.
 | 
			
		||||
func (s *BufferedWriteSyncer) Stop() (err error) {
 | 
			
		||||
	var stopped bool
 | 
			
		||||
 | 
			
		||||
	// Critical section.
 | 
			
		||||
	func() {
 | 
			
		||||
		s.mu.Lock()
 | 
			
		||||
		defer s.mu.Unlock()
 | 
			
		||||
 | 
			
		||||
		if !s.initialized {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		stopped = s.stopped
 | 
			
		||||
		if stopped {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		s.stopped = true
 | 
			
		||||
 | 
			
		||||
		s.ticker.Stop()
 | 
			
		||||
		close(s.stop) // tell flushLoop to stop
 | 
			
		||||
		<-s.done      // and wait until it has
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	// Don't call Sync on consecutive Stops.
 | 
			
		||||
	if !stopped {
 | 
			
		||||
		err = s.Sync()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								vendor/go.uber.org/zap/zapcore/clock.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								vendor/go.uber.org/zap/zapcore/clock.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DefaultClock is the default clock used by Zap in operations that require
 | 
			
		||||
// time. This clock uses the system clock for all operations.
 | 
			
		||||
var DefaultClock = systemClock{}
 | 
			
		||||
 | 
			
		||||
// Clock is a source of time for logged entries.
 | 
			
		||||
type Clock interface {
 | 
			
		||||
	// Now returns the current local time.
 | 
			
		||||
	Now() time.Time
 | 
			
		||||
 | 
			
		||||
	// NewTicker returns *time.Ticker that holds a channel
 | 
			
		||||
	// that delivers "ticks" of a clock.
 | 
			
		||||
	NewTicker(time.Duration) *time.Ticker
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// systemClock implements default Clock that uses system time.
 | 
			
		||||
type systemClock struct{}
 | 
			
		||||
 | 
			
		||||
func (systemClock) Now() time.Time {
 | 
			
		||||
	return time.Now()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (systemClock) NewTicker(duration time.Duration) *time.Ticker {
 | 
			
		||||
	return time.NewTicker(duration)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										161
									
								
								vendor/go.uber.org/zap/zapcore/console_encoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								vendor/go.uber.org/zap/zapcore/console_encoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,161 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/buffer"
 | 
			
		||||
	"go.uber.org/zap/internal/bufferpool"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _sliceEncoderPool = sync.Pool{
 | 
			
		||||
	New: func() interface{} {
 | 
			
		||||
		return &sliceArrayEncoder{elems: make([]interface{}, 0, 2)}
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getSliceEncoder() *sliceArrayEncoder {
 | 
			
		||||
	return _sliceEncoderPool.Get().(*sliceArrayEncoder)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func putSliceEncoder(e *sliceArrayEncoder) {
 | 
			
		||||
	e.elems = e.elems[:0]
 | 
			
		||||
	_sliceEncoderPool.Put(e)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type consoleEncoder struct {
 | 
			
		||||
	*jsonEncoder
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewConsoleEncoder creates an encoder whose output is designed for human -
 | 
			
		||||
// rather than machine - consumption. It serializes the core log entry data
 | 
			
		||||
// (message, level, timestamp, etc.) in a plain-text format and leaves the
 | 
			
		||||
// structured context as JSON.
 | 
			
		||||
//
 | 
			
		||||
// Note that although the console encoder doesn't use the keys specified in the
 | 
			
		||||
// encoder configuration, it will omit any element whose key is set to the empty
 | 
			
		||||
// string.
 | 
			
		||||
func NewConsoleEncoder(cfg EncoderConfig) Encoder {
 | 
			
		||||
	if cfg.ConsoleSeparator == "" {
 | 
			
		||||
		// Use a default delimiter of '\t' for backwards compatibility
 | 
			
		||||
		cfg.ConsoleSeparator = "\t"
 | 
			
		||||
	}
 | 
			
		||||
	return consoleEncoder{newJSONEncoder(cfg, true)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c consoleEncoder) Clone() Encoder {
 | 
			
		||||
	return consoleEncoder{c.jsonEncoder.Clone().(*jsonEncoder)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c consoleEncoder) EncodeEntry(ent Entry, fields []Field) (*buffer.Buffer, error) {
 | 
			
		||||
	line := bufferpool.Get()
 | 
			
		||||
 | 
			
		||||
	// We don't want the entry's metadata to be quoted and escaped (if it's
 | 
			
		||||
	// encoded as strings), which means that we can't use the JSON encoder. The
 | 
			
		||||
	// simplest option is to use the memory encoder and fmt.Fprint.
 | 
			
		||||
	//
 | 
			
		||||
	// If this ever becomes a performance bottleneck, we can implement
 | 
			
		||||
	// ArrayEncoder for our plain-text format.
 | 
			
		||||
	arr := getSliceEncoder()
 | 
			
		||||
	if c.TimeKey != "" && c.EncodeTime != nil {
 | 
			
		||||
		c.EncodeTime(ent.Time, arr)
 | 
			
		||||
	}
 | 
			
		||||
	if c.LevelKey != "" && c.EncodeLevel != nil {
 | 
			
		||||
		c.EncodeLevel(ent.Level, arr)
 | 
			
		||||
	}
 | 
			
		||||
	if ent.LoggerName != "" && c.NameKey != "" {
 | 
			
		||||
		nameEncoder := c.EncodeName
 | 
			
		||||
 | 
			
		||||
		if nameEncoder == nil {
 | 
			
		||||
			// Fall back to FullNameEncoder for backward compatibility.
 | 
			
		||||
			nameEncoder = FullNameEncoder
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		nameEncoder(ent.LoggerName, arr)
 | 
			
		||||
	}
 | 
			
		||||
	if ent.Caller.Defined {
 | 
			
		||||
		if c.CallerKey != "" && c.EncodeCaller != nil {
 | 
			
		||||
			c.EncodeCaller(ent.Caller, arr)
 | 
			
		||||
		}
 | 
			
		||||
		if c.FunctionKey != "" {
 | 
			
		||||
			arr.AppendString(ent.Caller.Function)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for i := range arr.elems {
 | 
			
		||||
		if i > 0 {
 | 
			
		||||
			line.AppendString(c.ConsoleSeparator)
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Fprint(line, arr.elems[i])
 | 
			
		||||
	}
 | 
			
		||||
	putSliceEncoder(arr)
 | 
			
		||||
 | 
			
		||||
	// Add the message itself.
 | 
			
		||||
	if c.MessageKey != "" {
 | 
			
		||||
		c.addSeparatorIfNecessary(line)
 | 
			
		||||
		line.AppendString(ent.Message)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add any structured context.
 | 
			
		||||
	c.writeContext(line, fields)
 | 
			
		||||
 | 
			
		||||
	// If there's no stacktrace key, honor that; this allows users to force
 | 
			
		||||
	// single-line output.
 | 
			
		||||
	if ent.Stack != "" && c.StacktraceKey != "" {
 | 
			
		||||
		line.AppendByte('\n')
 | 
			
		||||
		line.AppendString(ent.Stack)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c.LineEnding != "" {
 | 
			
		||||
		line.AppendString(c.LineEnding)
 | 
			
		||||
	} else {
 | 
			
		||||
		line.AppendString(DefaultLineEnding)
 | 
			
		||||
	}
 | 
			
		||||
	return line, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c consoleEncoder) writeContext(line *buffer.Buffer, extra []Field) {
 | 
			
		||||
	context := c.jsonEncoder.Clone().(*jsonEncoder)
 | 
			
		||||
	defer func() {
 | 
			
		||||
		// putJSONEncoder assumes the buffer is still used, but we write out the buffer so
 | 
			
		||||
		// we can free it.
 | 
			
		||||
		context.buf.Free()
 | 
			
		||||
		putJSONEncoder(context)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	addFields(context, extra)
 | 
			
		||||
	context.closeOpenNamespaces()
 | 
			
		||||
	if context.buf.Len() == 0 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.addSeparatorIfNecessary(line)
 | 
			
		||||
	line.AppendByte('{')
 | 
			
		||||
	line.Write(context.buf.Bytes())
 | 
			
		||||
	line.AppendByte('}')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c consoleEncoder) addSeparatorIfNecessary(line *buffer.Buffer) {
 | 
			
		||||
	if line.Len() > 0 {
 | 
			
		||||
		line.AppendString(c.ConsoleSeparator)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										113
									
								
								vendor/go.uber.org/zap/zapcore/core.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								vendor/go.uber.org/zap/zapcore/core.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
// Core is a minimal, fast logger interface. It's designed for library authors
 | 
			
		||||
// to wrap in a more user-friendly API.
 | 
			
		||||
type Core interface {
 | 
			
		||||
	LevelEnabler
 | 
			
		||||
 | 
			
		||||
	// With adds structured context to the Core.
 | 
			
		||||
	With([]Field) Core
 | 
			
		||||
	// Check determines whether the supplied Entry should be logged (using the
 | 
			
		||||
	// embedded LevelEnabler and possibly some extra logic). If the entry
 | 
			
		||||
	// should be logged, the Core adds itself to the CheckedEntry and returns
 | 
			
		||||
	// the result.
 | 
			
		||||
	//
 | 
			
		||||
	// Callers must use Check before calling Write.
 | 
			
		||||
	Check(Entry, *CheckedEntry) *CheckedEntry
 | 
			
		||||
	// Write serializes the Entry and any Fields supplied at the log site and
 | 
			
		||||
	// writes them to their destination.
 | 
			
		||||
	//
 | 
			
		||||
	// If called, Write should always log the Entry and Fields; it should not
 | 
			
		||||
	// replicate the logic of Check.
 | 
			
		||||
	Write(Entry, []Field) error
 | 
			
		||||
	// Sync flushes buffered logs (if any).
 | 
			
		||||
	Sync() error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type nopCore struct{}
 | 
			
		||||
 | 
			
		||||
// NewNopCore returns a no-op Core.
 | 
			
		||||
func NewNopCore() Core                                        { return nopCore{} }
 | 
			
		||||
func (nopCore) Enabled(Level) bool                            { return false }
 | 
			
		||||
func (n nopCore) With([]Field) Core                           { return n }
 | 
			
		||||
func (nopCore) Check(_ Entry, ce *CheckedEntry) *CheckedEntry { return ce }
 | 
			
		||||
func (nopCore) Write(Entry, []Field) error                    { return nil }
 | 
			
		||||
func (nopCore) Sync() error                                   { return nil }
 | 
			
		||||
 | 
			
		||||
// NewCore creates a Core that writes logs to a WriteSyncer.
 | 
			
		||||
func NewCore(enc Encoder, ws WriteSyncer, enab LevelEnabler) Core {
 | 
			
		||||
	return &ioCore{
 | 
			
		||||
		LevelEnabler: enab,
 | 
			
		||||
		enc:          enc,
 | 
			
		||||
		out:          ws,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ioCore struct {
 | 
			
		||||
	LevelEnabler
 | 
			
		||||
	enc Encoder
 | 
			
		||||
	out WriteSyncer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *ioCore) With(fields []Field) Core {
 | 
			
		||||
	clone := c.clone()
 | 
			
		||||
	addFields(clone.enc, fields)
 | 
			
		||||
	return clone
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *ioCore) Check(ent Entry, ce *CheckedEntry) *CheckedEntry {
 | 
			
		||||
	if c.Enabled(ent.Level) {
 | 
			
		||||
		return ce.AddCore(ent, c)
 | 
			
		||||
	}
 | 
			
		||||
	return ce
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *ioCore) Write(ent Entry, fields []Field) error {
 | 
			
		||||
	buf, err := c.enc.EncodeEntry(ent, fields)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	_, err = c.out.Write(buf.Bytes())
 | 
			
		||||
	buf.Free()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if ent.Level > ErrorLevel {
 | 
			
		||||
		// Since we may be crashing the program, sync the output. Ignore Sync
 | 
			
		||||
		// errors, pending a clean solution to issue #370.
 | 
			
		||||
		c.Sync()
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *ioCore) Sync() error {
 | 
			
		||||
	return c.out.Sync()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *ioCore) clone() *ioCore {
 | 
			
		||||
	return &ioCore{
 | 
			
		||||
		LevelEnabler: c.LevelEnabler,
 | 
			
		||||
		enc:          c.enc.Clone(),
 | 
			
		||||
		out:          c.out,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								vendor/go.uber.org/zap/zapcore/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								vendor/go.uber.org/zap/zapcore/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
// 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 zapcore defines and implements the low-level interfaces upon which
 | 
			
		||||
// zap is built. By providing alternate implementations of these interfaces,
 | 
			
		||||
// external packages can extend zap's capabilities.
 | 
			
		||||
package zapcore // import "go.uber.org/zap/zapcore"
 | 
			
		||||
							
								
								
									
										443
									
								
								vendor/go.uber.org/zap/zapcore/encoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										443
									
								
								vendor/go.uber.org/zap/zapcore/encoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,443 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/buffer"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DefaultLineEnding defines the default line ending when writing logs.
 | 
			
		||||
// Alternate line endings specified in EncoderConfig can override this
 | 
			
		||||
// behavior.
 | 
			
		||||
const DefaultLineEnding = "\n"
 | 
			
		||||
 | 
			
		||||
// OmitKey defines the key to use when callers want to remove a key from log output.
 | 
			
		||||
const OmitKey = ""
 | 
			
		||||
 | 
			
		||||
// A LevelEncoder serializes a Level to a primitive type.
 | 
			
		||||
type LevelEncoder func(Level, PrimitiveArrayEncoder)
 | 
			
		||||
 | 
			
		||||
// LowercaseLevelEncoder serializes a Level to a lowercase string. For example,
 | 
			
		||||
// InfoLevel is serialized to "info".
 | 
			
		||||
func LowercaseLevelEncoder(l Level, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	enc.AppendString(l.String())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LowercaseColorLevelEncoder serializes a Level to a lowercase string and adds coloring.
 | 
			
		||||
// For example, InfoLevel is serialized to "info" and colored blue.
 | 
			
		||||
func LowercaseColorLevelEncoder(l Level, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	s, ok := _levelToLowercaseColorString[l]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		s = _unknownLevelColor.Add(l.String())
 | 
			
		||||
	}
 | 
			
		||||
	enc.AppendString(s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CapitalLevelEncoder serializes a Level to an all-caps string. For example,
 | 
			
		||||
// InfoLevel is serialized to "INFO".
 | 
			
		||||
func CapitalLevelEncoder(l Level, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	enc.AppendString(l.CapitalString())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CapitalColorLevelEncoder serializes a Level to an all-caps string and adds color.
 | 
			
		||||
// For example, InfoLevel is serialized to "INFO" and colored blue.
 | 
			
		||||
func CapitalColorLevelEncoder(l Level, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	s, ok := _levelToCapitalColorString[l]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		s = _unknownLevelColor.Add(l.CapitalString())
 | 
			
		||||
	}
 | 
			
		||||
	enc.AppendString(s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalText unmarshals text to a LevelEncoder. "capital" is unmarshaled to
 | 
			
		||||
// CapitalLevelEncoder, "coloredCapital" is unmarshaled to CapitalColorLevelEncoder,
 | 
			
		||||
// "colored" is unmarshaled to LowercaseColorLevelEncoder, and anything else
 | 
			
		||||
// is unmarshaled to LowercaseLevelEncoder.
 | 
			
		||||
func (e *LevelEncoder) UnmarshalText(text []byte) error {
 | 
			
		||||
	switch string(text) {
 | 
			
		||||
	case "capital":
 | 
			
		||||
		*e = CapitalLevelEncoder
 | 
			
		||||
	case "capitalColor":
 | 
			
		||||
		*e = CapitalColorLevelEncoder
 | 
			
		||||
	case "color":
 | 
			
		||||
		*e = LowercaseColorLevelEncoder
 | 
			
		||||
	default:
 | 
			
		||||
		*e = LowercaseLevelEncoder
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A TimeEncoder serializes a time.Time to a primitive type.
 | 
			
		||||
type TimeEncoder func(time.Time, PrimitiveArrayEncoder)
 | 
			
		||||
 | 
			
		||||
// EpochTimeEncoder serializes a time.Time to a floating-point number of seconds
 | 
			
		||||
// since the Unix epoch.
 | 
			
		||||
func EpochTimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	nanos := t.UnixNano()
 | 
			
		||||
	sec := float64(nanos) / float64(time.Second)
 | 
			
		||||
	enc.AppendFloat64(sec)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// EpochMillisTimeEncoder serializes a time.Time to a floating-point number of
 | 
			
		||||
// milliseconds since the Unix epoch.
 | 
			
		||||
func EpochMillisTimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	nanos := t.UnixNano()
 | 
			
		||||
	millis := float64(nanos) / float64(time.Millisecond)
 | 
			
		||||
	enc.AppendFloat64(millis)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// EpochNanosTimeEncoder serializes a time.Time to an integer number of
 | 
			
		||||
// nanoseconds since the Unix epoch.
 | 
			
		||||
func EpochNanosTimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	enc.AppendInt64(t.UnixNano())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func encodeTimeLayout(t time.Time, layout string, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	type appendTimeEncoder interface {
 | 
			
		||||
		AppendTimeLayout(time.Time, string)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if enc, ok := enc.(appendTimeEncoder); ok {
 | 
			
		||||
		enc.AppendTimeLayout(t, layout)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	enc.AppendString(t.Format(layout))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ISO8601TimeEncoder serializes a time.Time to an ISO8601-formatted string
 | 
			
		||||
// with millisecond precision.
 | 
			
		||||
//
 | 
			
		||||
// If enc supports AppendTimeLayout(t time.Time,layout string), it's used
 | 
			
		||||
// instead of appending a pre-formatted string value.
 | 
			
		||||
func ISO8601TimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	encodeTimeLayout(t, "2006-01-02T15:04:05.000Z0700", enc)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RFC3339TimeEncoder serializes a time.Time to an RFC3339-formatted string.
 | 
			
		||||
//
 | 
			
		||||
// If enc supports AppendTimeLayout(t time.Time,layout string), it's used
 | 
			
		||||
// instead of appending a pre-formatted string value.
 | 
			
		||||
func RFC3339TimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	encodeTimeLayout(t, time.RFC3339, enc)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RFC3339NanoTimeEncoder serializes a time.Time to an RFC3339-formatted string
 | 
			
		||||
// with nanosecond precision.
 | 
			
		||||
//
 | 
			
		||||
// If enc supports AppendTimeLayout(t time.Time,layout string), it's used
 | 
			
		||||
// instead of appending a pre-formatted string value.
 | 
			
		||||
func RFC3339NanoTimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	encodeTimeLayout(t, time.RFC3339Nano, enc)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TimeEncoderOfLayout returns TimeEncoder which serializes a time.Time using
 | 
			
		||||
// given layout.
 | 
			
		||||
func TimeEncoderOfLayout(layout string) TimeEncoder {
 | 
			
		||||
	return func(t time.Time, enc PrimitiveArrayEncoder) {
 | 
			
		||||
		encodeTimeLayout(t, layout, enc)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalText unmarshals text to a TimeEncoder.
 | 
			
		||||
// "rfc3339nano" and "RFC3339Nano" are unmarshaled to RFC3339NanoTimeEncoder.
 | 
			
		||||
// "rfc3339" and "RFC3339" are unmarshaled to RFC3339TimeEncoder.
 | 
			
		||||
// "iso8601" and "ISO8601" are unmarshaled to ISO8601TimeEncoder.
 | 
			
		||||
// "millis" is unmarshaled to EpochMillisTimeEncoder.
 | 
			
		||||
// "nanos" is unmarshaled to EpochNanosEncoder.
 | 
			
		||||
// Anything else is unmarshaled to EpochTimeEncoder.
 | 
			
		||||
func (e *TimeEncoder) UnmarshalText(text []byte) error {
 | 
			
		||||
	switch string(text) {
 | 
			
		||||
	case "rfc3339nano", "RFC3339Nano":
 | 
			
		||||
		*e = RFC3339NanoTimeEncoder
 | 
			
		||||
	case "rfc3339", "RFC3339":
 | 
			
		||||
		*e = RFC3339TimeEncoder
 | 
			
		||||
	case "iso8601", "ISO8601":
 | 
			
		||||
		*e = ISO8601TimeEncoder
 | 
			
		||||
	case "millis":
 | 
			
		||||
		*e = EpochMillisTimeEncoder
 | 
			
		||||
	case "nanos":
 | 
			
		||||
		*e = EpochNanosTimeEncoder
 | 
			
		||||
	default:
 | 
			
		||||
		*e = EpochTimeEncoder
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalYAML unmarshals YAML to a TimeEncoder.
 | 
			
		||||
// If value is an object with a "layout" field, it will be unmarshaled to  TimeEncoder with given layout.
 | 
			
		||||
//     timeEncoder:
 | 
			
		||||
//       layout: 06/01/02 03:04pm
 | 
			
		||||
// If value is string, it uses UnmarshalText.
 | 
			
		||||
//     timeEncoder: iso8601
 | 
			
		||||
func (e *TimeEncoder) UnmarshalYAML(unmarshal func(interface{}) error) error {
 | 
			
		||||
	var o struct {
 | 
			
		||||
		Layout string `json:"layout" yaml:"layout"`
 | 
			
		||||
	}
 | 
			
		||||
	if err := unmarshal(&o); err == nil {
 | 
			
		||||
		*e = TimeEncoderOfLayout(o.Layout)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var s string
 | 
			
		||||
	if err := unmarshal(&s); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return e.UnmarshalText([]byte(s))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalJSON unmarshals JSON to a TimeEncoder as same way UnmarshalYAML does.
 | 
			
		||||
func (e *TimeEncoder) UnmarshalJSON(data []byte) error {
 | 
			
		||||
	return e.UnmarshalYAML(func(v interface{}) error {
 | 
			
		||||
		return json.Unmarshal(data, v)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A DurationEncoder serializes a time.Duration to a primitive type.
 | 
			
		||||
type DurationEncoder func(time.Duration, PrimitiveArrayEncoder)
 | 
			
		||||
 | 
			
		||||
// SecondsDurationEncoder serializes a time.Duration to a floating-point number of seconds elapsed.
 | 
			
		||||
func SecondsDurationEncoder(d time.Duration, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	enc.AppendFloat64(float64(d) / float64(time.Second))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NanosDurationEncoder serializes a time.Duration to an integer number of
 | 
			
		||||
// nanoseconds elapsed.
 | 
			
		||||
func NanosDurationEncoder(d time.Duration, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	enc.AppendInt64(int64(d))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MillisDurationEncoder serializes a time.Duration to an integer number of
 | 
			
		||||
// milliseconds elapsed.
 | 
			
		||||
func MillisDurationEncoder(d time.Duration, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	enc.AppendInt64(d.Nanoseconds() / 1e6)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StringDurationEncoder serializes a time.Duration using its built-in String
 | 
			
		||||
// method.
 | 
			
		||||
func StringDurationEncoder(d time.Duration, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	enc.AppendString(d.String())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalText unmarshals text to a DurationEncoder. "string" is unmarshaled
 | 
			
		||||
// to StringDurationEncoder, and anything else is unmarshaled to
 | 
			
		||||
// NanosDurationEncoder.
 | 
			
		||||
func (e *DurationEncoder) UnmarshalText(text []byte) error {
 | 
			
		||||
	switch string(text) {
 | 
			
		||||
	case "string":
 | 
			
		||||
		*e = StringDurationEncoder
 | 
			
		||||
	case "nanos":
 | 
			
		||||
		*e = NanosDurationEncoder
 | 
			
		||||
	case "ms":
 | 
			
		||||
		*e = MillisDurationEncoder
 | 
			
		||||
	default:
 | 
			
		||||
		*e = SecondsDurationEncoder
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A CallerEncoder serializes an EntryCaller to a primitive type.
 | 
			
		||||
type CallerEncoder func(EntryCaller, PrimitiveArrayEncoder)
 | 
			
		||||
 | 
			
		||||
// FullCallerEncoder serializes a caller in /full/path/to/package/file:line
 | 
			
		||||
// format.
 | 
			
		||||
func FullCallerEncoder(caller EntryCaller, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	// TODO: consider using a byte-oriented API to save an allocation.
 | 
			
		||||
	enc.AppendString(caller.String())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ShortCallerEncoder serializes a caller in package/file:line format, trimming
 | 
			
		||||
// all but the final directory from the full path.
 | 
			
		||||
func ShortCallerEncoder(caller EntryCaller, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	// TODO: consider using a byte-oriented API to save an allocation.
 | 
			
		||||
	enc.AppendString(caller.TrimmedPath())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalText unmarshals text to a CallerEncoder. "full" is unmarshaled to
 | 
			
		||||
// FullCallerEncoder and anything else is unmarshaled to ShortCallerEncoder.
 | 
			
		||||
func (e *CallerEncoder) UnmarshalText(text []byte) error {
 | 
			
		||||
	switch string(text) {
 | 
			
		||||
	case "full":
 | 
			
		||||
		*e = FullCallerEncoder
 | 
			
		||||
	default:
 | 
			
		||||
		*e = ShortCallerEncoder
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A NameEncoder serializes a period-separated logger name to a primitive
 | 
			
		||||
// type.
 | 
			
		||||
type NameEncoder func(string, PrimitiveArrayEncoder)
 | 
			
		||||
 | 
			
		||||
// FullNameEncoder serializes the logger name as-is.
 | 
			
		||||
func FullNameEncoder(loggerName string, enc PrimitiveArrayEncoder) {
 | 
			
		||||
	enc.AppendString(loggerName)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalText unmarshals text to a NameEncoder. Currently, everything is
 | 
			
		||||
// unmarshaled to FullNameEncoder.
 | 
			
		||||
func (e *NameEncoder) UnmarshalText(text []byte) error {
 | 
			
		||||
	switch string(text) {
 | 
			
		||||
	case "full":
 | 
			
		||||
		*e = FullNameEncoder
 | 
			
		||||
	default:
 | 
			
		||||
		*e = FullNameEncoder
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// An EncoderConfig allows users to configure the concrete encoders supplied by
 | 
			
		||||
// zapcore.
 | 
			
		||||
type EncoderConfig struct {
 | 
			
		||||
	// Set the keys used for each log entry. If any key is empty, that portion
 | 
			
		||||
	// of the entry is omitted.
 | 
			
		||||
	MessageKey    string `json:"messageKey" yaml:"messageKey"`
 | 
			
		||||
	LevelKey      string `json:"levelKey" yaml:"levelKey"`
 | 
			
		||||
	TimeKey       string `json:"timeKey" yaml:"timeKey"`
 | 
			
		||||
	NameKey       string `json:"nameKey" yaml:"nameKey"`
 | 
			
		||||
	CallerKey     string `json:"callerKey" yaml:"callerKey"`
 | 
			
		||||
	FunctionKey   string `json:"functionKey" yaml:"functionKey"`
 | 
			
		||||
	StacktraceKey string `json:"stacktraceKey" yaml:"stacktraceKey"`
 | 
			
		||||
	LineEnding    string `json:"lineEnding" yaml:"lineEnding"`
 | 
			
		||||
	// Configure the primitive representations of common complex types. For
 | 
			
		||||
	// example, some users may want all time.Times serialized as floating-point
 | 
			
		||||
	// seconds since epoch, while others may prefer ISO8601 strings.
 | 
			
		||||
	EncodeLevel    LevelEncoder    `json:"levelEncoder" yaml:"levelEncoder"`
 | 
			
		||||
	EncodeTime     TimeEncoder     `json:"timeEncoder" yaml:"timeEncoder"`
 | 
			
		||||
	EncodeDuration DurationEncoder `json:"durationEncoder" yaml:"durationEncoder"`
 | 
			
		||||
	EncodeCaller   CallerEncoder   `json:"callerEncoder" yaml:"callerEncoder"`
 | 
			
		||||
	// Unlike the other primitive type encoders, EncodeName is optional. The
 | 
			
		||||
	// zero value falls back to FullNameEncoder.
 | 
			
		||||
	EncodeName NameEncoder `json:"nameEncoder" yaml:"nameEncoder"`
 | 
			
		||||
	// Configures the field separator used by the console encoder. Defaults
 | 
			
		||||
	// to tab.
 | 
			
		||||
	ConsoleSeparator string `json:"consoleSeparator" yaml:"consoleSeparator"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ObjectEncoder is a strongly-typed, encoding-agnostic interface for adding a
 | 
			
		||||
// map- or struct-like object to the logging context. Like maps, ObjectEncoders
 | 
			
		||||
// aren't safe for concurrent use (though typical use shouldn't require locks).
 | 
			
		||||
type ObjectEncoder interface {
 | 
			
		||||
	// Logging-specific marshalers.
 | 
			
		||||
	AddArray(key string, marshaler ArrayMarshaler) error
 | 
			
		||||
	AddObject(key string, marshaler ObjectMarshaler) error
 | 
			
		||||
 | 
			
		||||
	// Built-in types.
 | 
			
		||||
	AddBinary(key string, value []byte)     // for arbitrary bytes
 | 
			
		||||
	AddByteString(key string, value []byte) // for UTF-8 encoded bytes
 | 
			
		||||
	AddBool(key string, value bool)
 | 
			
		||||
	AddComplex128(key string, value complex128)
 | 
			
		||||
	AddComplex64(key string, value complex64)
 | 
			
		||||
	AddDuration(key string, value time.Duration)
 | 
			
		||||
	AddFloat64(key string, value float64)
 | 
			
		||||
	AddFloat32(key string, value float32)
 | 
			
		||||
	AddInt(key string, value int)
 | 
			
		||||
	AddInt64(key string, value int64)
 | 
			
		||||
	AddInt32(key string, value int32)
 | 
			
		||||
	AddInt16(key string, value int16)
 | 
			
		||||
	AddInt8(key string, value int8)
 | 
			
		||||
	AddString(key, value string)
 | 
			
		||||
	AddTime(key string, value time.Time)
 | 
			
		||||
	AddUint(key string, value uint)
 | 
			
		||||
	AddUint64(key string, value uint64)
 | 
			
		||||
	AddUint32(key string, value uint32)
 | 
			
		||||
	AddUint16(key string, value uint16)
 | 
			
		||||
	AddUint8(key string, value uint8)
 | 
			
		||||
	AddUintptr(key string, value uintptr)
 | 
			
		||||
 | 
			
		||||
	// AddReflected uses reflection to serialize arbitrary objects, so it can be
 | 
			
		||||
	// slow and allocation-heavy.
 | 
			
		||||
	AddReflected(key string, value interface{}) error
 | 
			
		||||
	// OpenNamespace opens an isolated namespace where all subsequent fields will
 | 
			
		||||
	// be added. Applications can use namespaces to prevent key collisions when
 | 
			
		||||
	// injecting loggers into sub-components or third-party libraries.
 | 
			
		||||
	OpenNamespace(key string)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ArrayEncoder is a strongly-typed, encoding-agnostic interface for adding
 | 
			
		||||
// array-like objects to the logging context. Of note, it supports mixed-type
 | 
			
		||||
// arrays even though they aren't typical in Go. Like slices, ArrayEncoders
 | 
			
		||||
// aren't safe for concurrent use (though typical use shouldn't require locks).
 | 
			
		||||
type ArrayEncoder interface {
 | 
			
		||||
	// Built-in types.
 | 
			
		||||
	PrimitiveArrayEncoder
 | 
			
		||||
 | 
			
		||||
	// Time-related types.
 | 
			
		||||
	AppendDuration(time.Duration)
 | 
			
		||||
	AppendTime(time.Time)
 | 
			
		||||
 | 
			
		||||
	// Logging-specific marshalers.
 | 
			
		||||
	AppendArray(ArrayMarshaler) error
 | 
			
		||||
	AppendObject(ObjectMarshaler) error
 | 
			
		||||
 | 
			
		||||
	// AppendReflected uses reflection to serialize arbitrary objects, so it's
 | 
			
		||||
	// slow and allocation-heavy.
 | 
			
		||||
	AppendReflected(value interface{}) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PrimitiveArrayEncoder is the subset of the ArrayEncoder interface that deals
 | 
			
		||||
// only in Go's built-in types. It's included only so that Duration- and
 | 
			
		||||
// TimeEncoders cannot trigger infinite recursion.
 | 
			
		||||
type PrimitiveArrayEncoder interface {
 | 
			
		||||
	// Built-in types.
 | 
			
		||||
	AppendBool(bool)
 | 
			
		||||
	AppendByteString([]byte) // for UTF-8 encoded bytes
 | 
			
		||||
	AppendComplex128(complex128)
 | 
			
		||||
	AppendComplex64(complex64)
 | 
			
		||||
	AppendFloat64(float64)
 | 
			
		||||
	AppendFloat32(float32)
 | 
			
		||||
	AppendInt(int)
 | 
			
		||||
	AppendInt64(int64)
 | 
			
		||||
	AppendInt32(int32)
 | 
			
		||||
	AppendInt16(int16)
 | 
			
		||||
	AppendInt8(int8)
 | 
			
		||||
	AppendString(string)
 | 
			
		||||
	AppendUint(uint)
 | 
			
		||||
	AppendUint64(uint64)
 | 
			
		||||
	AppendUint32(uint32)
 | 
			
		||||
	AppendUint16(uint16)
 | 
			
		||||
	AppendUint8(uint8)
 | 
			
		||||
	AppendUintptr(uintptr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Encoder is a format-agnostic interface for all log entry marshalers. Since
 | 
			
		||||
// log encoders don't need to support the same wide range of use cases as
 | 
			
		||||
// general-purpose marshalers, it's possible to make them faster and
 | 
			
		||||
// lower-allocation.
 | 
			
		||||
//
 | 
			
		||||
// Implementations of the ObjectEncoder interface's methods can, of course,
 | 
			
		||||
// freely modify the receiver. However, the Clone and EncodeEntry methods will
 | 
			
		||||
// be called concurrently and shouldn't modify the receiver.
 | 
			
		||||
type Encoder interface {
 | 
			
		||||
	ObjectEncoder
 | 
			
		||||
 | 
			
		||||
	// Clone copies the encoder, ensuring that adding fields to the copy doesn't
 | 
			
		||||
	// affect the original.
 | 
			
		||||
	Clone() Encoder
 | 
			
		||||
 | 
			
		||||
	// EncodeEntry encodes an entry and fields, along with any accumulated
 | 
			
		||||
	// context, into a byte buffer and returns it. Any fields that are empty,
 | 
			
		||||
	// including fields on the `Entry` type, should be omitted.
 | 
			
		||||
	EncodeEntry(Entry, []Field) (*buffer.Buffer, error)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										262
									
								
								vendor/go.uber.org/zap/zapcore/entry.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								vendor/go.uber.org/zap/zapcore/entry.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,262 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/internal/bufferpool"
 | 
			
		||||
	"go.uber.org/zap/internal/exit"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/multierr"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_cePool = sync.Pool{New: func() interface{} {
 | 
			
		||||
		// Pre-allocate some space for cores.
 | 
			
		||||
		return &CheckedEntry{
 | 
			
		||||
			cores: make([]Core, 4),
 | 
			
		||||
		}
 | 
			
		||||
	}}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func getCheckedEntry() *CheckedEntry {
 | 
			
		||||
	ce := _cePool.Get().(*CheckedEntry)
 | 
			
		||||
	ce.reset()
 | 
			
		||||
	return ce
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func putCheckedEntry(ce *CheckedEntry) {
 | 
			
		||||
	if ce == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	_cePool.Put(ce)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewEntryCaller makes an EntryCaller from the return signature of
 | 
			
		||||
// runtime.Caller.
 | 
			
		||||
func NewEntryCaller(pc uintptr, file string, line int, ok bool) EntryCaller {
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return EntryCaller{}
 | 
			
		||||
	}
 | 
			
		||||
	return EntryCaller{
 | 
			
		||||
		PC:      pc,
 | 
			
		||||
		File:    file,
 | 
			
		||||
		Line:    line,
 | 
			
		||||
		Defined: true,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// EntryCaller represents the caller of a logging function.
 | 
			
		||||
type EntryCaller struct {
 | 
			
		||||
	Defined  bool
 | 
			
		||||
	PC       uintptr
 | 
			
		||||
	File     string
 | 
			
		||||
	Line     int
 | 
			
		||||
	Function string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String returns the full path and line number of the caller.
 | 
			
		||||
func (ec EntryCaller) String() string {
 | 
			
		||||
	return ec.FullPath()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FullPath returns a /full/path/to/package/file:line description of the
 | 
			
		||||
// caller.
 | 
			
		||||
func (ec EntryCaller) FullPath() string {
 | 
			
		||||
	if !ec.Defined {
 | 
			
		||||
		return "undefined"
 | 
			
		||||
	}
 | 
			
		||||
	buf := bufferpool.Get()
 | 
			
		||||
	buf.AppendString(ec.File)
 | 
			
		||||
	buf.AppendByte(':')
 | 
			
		||||
	buf.AppendInt(int64(ec.Line))
 | 
			
		||||
	caller := buf.String()
 | 
			
		||||
	buf.Free()
 | 
			
		||||
	return caller
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TrimmedPath returns a package/file:line description of the caller,
 | 
			
		||||
// preserving only the leaf directory name and file name.
 | 
			
		||||
func (ec EntryCaller) TrimmedPath() string {
 | 
			
		||||
	if !ec.Defined {
 | 
			
		||||
		return "undefined"
 | 
			
		||||
	}
 | 
			
		||||
	// nb. To make sure we trim the path correctly on Windows too, we
 | 
			
		||||
	// counter-intuitively need to use '/' and *not* os.PathSeparator here,
 | 
			
		||||
	// because the path given originates from Go stdlib, specifically
 | 
			
		||||
	// runtime.Caller() which (as of Mar/17) returns forward slashes even on
 | 
			
		||||
	// Windows.
 | 
			
		||||
	//
 | 
			
		||||
	// See https://github.com/golang/go/issues/3335
 | 
			
		||||
	// and https://github.com/golang/go/issues/18151
 | 
			
		||||
	//
 | 
			
		||||
	// for discussion on the issue on Go side.
 | 
			
		||||
	//
 | 
			
		||||
	// Find the last separator.
 | 
			
		||||
	//
 | 
			
		||||
	idx := strings.LastIndexByte(ec.File, '/')
 | 
			
		||||
	if idx == -1 {
 | 
			
		||||
		return ec.FullPath()
 | 
			
		||||
	}
 | 
			
		||||
	// Find the penultimate separator.
 | 
			
		||||
	idx = strings.LastIndexByte(ec.File[:idx], '/')
 | 
			
		||||
	if idx == -1 {
 | 
			
		||||
		return ec.FullPath()
 | 
			
		||||
	}
 | 
			
		||||
	buf := bufferpool.Get()
 | 
			
		||||
	// Keep everything after the penultimate separator.
 | 
			
		||||
	buf.AppendString(ec.File[idx+1:])
 | 
			
		||||
	buf.AppendByte(':')
 | 
			
		||||
	buf.AppendInt(int64(ec.Line))
 | 
			
		||||
	caller := buf.String()
 | 
			
		||||
	buf.Free()
 | 
			
		||||
	return caller
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// An Entry represents a complete log message. The entry's structured context
 | 
			
		||||
// is already serialized, but the log level, time, message, and call site
 | 
			
		||||
// information are available for inspection and modification. Any fields left
 | 
			
		||||
// empty will be omitted when encoding.
 | 
			
		||||
//
 | 
			
		||||
// Entries are pooled, so any functions that accept them MUST be careful not to
 | 
			
		||||
// retain references to them.
 | 
			
		||||
type Entry struct {
 | 
			
		||||
	Level      Level
 | 
			
		||||
	Time       time.Time
 | 
			
		||||
	LoggerName string
 | 
			
		||||
	Message    string
 | 
			
		||||
	Caller     EntryCaller
 | 
			
		||||
	Stack      string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CheckWriteAction indicates what action to take after a log entry is
 | 
			
		||||
// processed. Actions are ordered in increasing severity.
 | 
			
		||||
type CheckWriteAction uint8
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// WriteThenNoop indicates that nothing special needs to be done. It's the
 | 
			
		||||
	// default behavior.
 | 
			
		||||
	WriteThenNoop CheckWriteAction = iota
 | 
			
		||||
	// WriteThenGoexit runs runtime.Goexit after Write.
 | 
			
		||||
	WriteThenGoexit
 | 
			
		||||
	// WriteThenPanic causes a panic after Write.
 | 
			
		||||
	WriteThenPanic
 | 
			
		||||
	// WriteThenFatal causes a fatal os.Exit after Write.
 | 
			
		||||
	WriteThenFatal
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CheckedEntry is an Entry together with a collection of Cores that have
 | 
			
		||||
// already agreed to log it.
 | 
			
		||||
//
 | 
			
		||||
// CheckedEntry references should be created by calling AddCore or Should on a
 | 
			
		||||
// nil *CheckedEntry. References are returned to a pool after Write, and MUST
 | 
			
		||||
// NOT be retained after calling their Write method.
 | 
			
		||||
type CheckedEntry struct {
 | 
			
		||||
	Entry
 | 
			
		||||
	ErrorOutput WriteSyncer
 | 
			
		||||
	dirty       bool // best-effort detection of pool misuse
 | 
			
		||||
	should      CheckWriteAction
 | 
			
		||||
	cores       []Core
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ce *CheckedEntry) reset() {
 | 
			
		||||
	ce.Entry = Entry{}
 | 
			
		||||
	ce.ErrorOutput = nil
 | 
			
		||||
	ce.dirty = false
 | 
			
		||||
	ce.should = WriteThenNoop
 | 
			
		||||
	for i := range ce.cores {
 | 
			
		||||
		// don't keep references to cores
 | 
			
		||||
		ce.cores[i] = nil
 | 
			
		||||
	}
 | 
			
		||||
	ce.cores = ce.cores[:0]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Write writes the entry to the stored Cores, returns any errors, and returns
 | 
			
		||||
// the CheckedEntry reference to a pool for immediate re-use. Finally, it
 | 
			
		||||
// executes any required CheckWriteAction.
 | 
			
		||||
func (ce *CheckedEntry) Write(fields ...Field) {
 | 
			
		||||
	if ce == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ce.dirty {
 | 
			
		||||
		if ce.ErrorOutput != nil {
 | 
			
		||||
			// Make a best effort to detect unsafe re-use of this CheckedEntry.
 | 
			
		||||
			// If the entry is dirty, log an internal error; because the
 | 
			
		||||
			// CheckedEntry is being used after it was returned to the pool,
 | 
			
		||||
			// the message may be an amalgamation from multiple call sites.
 | 
			
		||||
			fmt.Fprintf(ce.ErrorOutput, "%v Unsafe CheckedEntry re-use near Entry %+v.\n", ce.Time, ce.Entry)
 | 
			
		||||
			ce.ErrorOutput.Sync()
 | 
			
		||||
		}
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	ce.dirty = true
 | 
			
		||||
 | 
			
		||||
	var err error
 | 
			
		||||
	for i := range ce.cores {
 | 
			
		||||
		err = multierr.Append(err, ce.cores[i].Write(ce.Entry, fields))
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil && ce.ErrorOutput != nil {
 | 
			
		||||
		fmt.Fprintf(ce.ErrorOutput, "%v write error: %v\n", ce.Time, err)
 | 
			
		||||
		ce.ErrorOutput.Sync()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	should, msg := ce.should, ce.Message
 | 
			
		||||
	putCheckedEntry(ce)
 | 
			
		||||
 | 
			
		||||
	switch should {
 | 
			
		||||
	case WriteThenPanic:
 | 
			
		||||
		panic(msg)
 | 
			
		||||
	case WriteThenFatal:
 | 
			
		||||
		exit.Exit()
 | 
			
		||||
	case WriteThenGoexit:
 | 
			
		||||
		runtime.Goexit()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddCore adds a Core that has agreed to log this CheckedEntry. It's intended to be
 | 
			
		||||
// used by Core.Check implementations, and is safe to call on nil CheckedEntry
 | 
			
		||||
// references.
 | 
			
		||||
func (ce *CheckedEntry) AddCore(ent Entry, core Core) *CheckedEntry {
 | 
			
		||||
	if ce == nil {
 | 
			
		||||
		ce = getCheckedEntry()
 | 
			
		||||
		ce.Entry = ent
 | 
			
		||||
	}
 | 
			
		||||
	ce.cores = append(ce.cores, core)
 | 
			
		||||
	return ce
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Should sets this CheckedEntry's CheckWriteAction, which controls whether a
 | 
			
		||||
// Core will panic or fatal after writing this log entry. Like AddCore, it's
 | 
			
		||||
// safe to call on nil CheckedEntry references.
 | 
			
		||||
func (ce *CheckedEntry) Should(ent Entry, should CheckWriteAction) *CheckedEntry {
 | 
			
		||||
	if ce == nil {
 | 
			
		||||
		ce = getCheckedEntry()
 | 
			
		||||
		ce.Entry = ent
 | 
			
		||||
	}
 | 
			
		||||
	ce.should = should
 | 
			
		||||
	return ce
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										132
									
								
								vendor/go.uber.org/zap/zapcore/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								vendor/go.uber.org/zap/zapcore/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
package zapcore
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Encodes the given error into fields of an object. A field with the given
 | 
			
		||||
// name is added for the error message.
 | 
			
		||||
//
 | 
			
		||||
// If the error implements fmt.Formatter, a field with the name ${key}Verbose
 | 
			
		||||
// is also added with the full verbose error message.
 | 
			
		||||
//
 | 
			
		||||
// Finally, if the error implements errorGroup (from go.uber.org/multierr) or
 | 
			
		||||
// causer (from github.com/pkg/errors), a ${key}Causes field is added with an
 | 
			
		||||
// array of objects containing the errors this error was comprised of.
 | 
			
		||||
//
 | 
			
		||||
//  {
 | 
			
		||||
//    "error": err.Error(),
 | 
			
		||||
//    "errorVerbose": fmt.Sprintf("%+v", err),
 | 
			
		||||
//    "errorCauses": [
 | 
			
		||||
//      ...
 | 
			
		||||
//    ],
 | 
			
		||||
//  }
 | 
			
		||||
func encodeError(key string, err error, enc ObjectEncoder) (retErr error) {
 | 
			
		||||
	// Try to capture panics (from nil references or otherwise) when calling
 | 
			
		||||
	// the Error() method
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if rerr := recover(); rerr != nil {
 | 
			
		||||
			// If it's a nil pointer, just say "<nil>". The likeliest causes are a
 | 
			
		||||
			// error that fails to guard against nil or a nil pointer for a
 | 
			
		||||
			// value receiver, and in either case, "<nil>" is a nice result.
 | 
			
		||||
			if v := reflect.ValueOf(err); v.Kind() == reflect.Ptr && v.IsNil() {
 | 
			
		||||
				enc.AddString(key, "<nil>")
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			retErr = fmt.Errorf("PANIC=%v", rerr)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	basic := err.Error()
 | 
			
		||||
	enc.AddString(key, basic)
 | 
			
		||||
 | 
			
		||||
	switch e := err.(type) {
 | 
			
		||||
	case errorGroup:
 | 
			
		||||
		return enc.AddArray(key+"Causes", errArray(e.Errors()))
 | 
			
		||||
	case fmt.Formatter:
 | 
			
		||||
		verbose := fmt.Sprintf("%+v", e)
 | 
			
		||||
		if verbose != basic {
 | 
			
		||||
			// This is a rich error type, like those produced by
 | 
			
		||||
			// github.com/pkg/errors.
 | 
			
		||||
			enc.AddString(key+"Verbose", verbose)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type errorGroup interface {
 | 
			
		||||
	// Provides read-only access to the underlying list of errors, preferably
 | 
			
		||||
	// without causing any allocs.
 | 
			
		||||
	Errors() []error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Note that errArray 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 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 ArrayEncoder) error {
 | 
			
		||||
	return arr.AppendObject(e)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *errArrayElem) MarshalLogObject(enc ObjectEncoder) error {
 | 
			
		||||
	return encodeError("error", e.err, enc)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *errArrayElem) Free() {
 | 
			
		||||
	e.err = nil
 | 
			
		||||
	_errArrayElemPool.Put(e)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										233
									
								
								vendor/go.uber.org/zap/zapcore/field.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								vendor/go.uber.org/zap/zapcore/field.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,233 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"math"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A FieldType indicates which member of the Field union struct should be used
 | 
			
		||||
// and how it should be serialized.
 | 
			
		||||
type FieldType uint8
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// UnknownType is the default field type. Attempting to add it to an encoder will panic.
 | 
			
		||||
	UnknownType FieldType = iota
 | 
			
		||||
	// ArrayMarshalerType indicates that the field carries an ArrayMarshaler.
 | 
			
		||||
	ArrayMarshalerType
 | 
			
		||||
	// ObjectMarshalerType indicates that the field carries an ObjectMarshaler.
 | 
			
		||||
	ObjectMarshalerType
 | 
			
		||||
	// BinaryType indicates that the field carries an opaque binary blob.
 | 
			
		||||
	BinaryType
 | 
			
		||||
	// BoolType indicates that the field carries a bool.
 | 
			
		||||
	BoolType
 | 
			
		||||
	// ByteStringType indicates that the field carries UTF-8 encoded bytes.
 | 
			
		||||
	ByteStringType
 | 
			
		||||
	// Complex128Type indicates that the field carries a complex128.
 | 
			
		||||
	Complex128Type
 | 
			
		||||
	// Complex64Type indicates that the field carries a complex128.
 | 
			
		||||
	Complex64Type
 | 
			
		||||
	// DurationType indicates that the field carries a time.Duration.
 | 
			
		||||
	DurationType
 | 
			
		||||
	// Float64Type indicates that the field carries a float64.
 | 
			
		||||
	Float64Type
 | 
			
		||||
	// Float32Type indicates that the field carries a float32.
 | 
			
		||||
	Float32Type
 | 
			
		||||
	// Int64Type indicates that the field carries an int64.
 | 
			
		||||
	Int64Type
 | 
			
		||||
	// Int32Type indicates that the field carries an int32.
 | 
			
		||||
	Int32Type
 | 
			
		||||
	// Int16Type indicates that the field carries an int16.
 | 
			
		||||
	Int16Type
 | 
			
		||||
	// Int8Type indicates that the field carries an int8.
 | 
			
		||||
	Int8Type
 | 
			
		||||
	// StringType indicates that the field carries a string.
 | 
			
		||||
	StringType
 | 
			
		||||
	// TimeType indicates that the field carries a time.Time that is
 | 
			
		||||
	// representable by a UnixNano() stored as an int64.
 | 
			
		||||
	TimeType
 | 
			
		||||
	// TimeFullType indicates that the field carries a time.Time stored as-is.
 | 
			
		||||
	TimeFullType
 | 
			
		||||
	// Uint64Type indicates that the field carries a uint64.
 | 
			
		||||
	Uint64Type
 | 
			
		||||
	// Uint32Type indicates that the field carries a uint32.
 | 
			
		||||
	Uint32Type
 | 
			
		||||
	// Uint16Type indicates that the field carries a uint16.
 | 
			
		||||
	Uint16Type
 | 
			
		||||
	// Uint8Type indicates that the field carries a uint8.
 | 
			
		||||
	Uint8Type
 | 
			
		||||
	// UintptrType indicates that the field carries a uintptr.
 | 
			
		||||
	UintptrType
 | 
			
		||||
	// ReflectType indicates that the field carries an interface{}, which should
 | 
			
		||||
	// be serialized using reflection.
 | 
			
		||||
	ReflectType
 | 
			
		||||
	// NamespaceType signals the beginning of an isolated namespace. All
 | 
			
		||||
	// subsequent fields should be added to the new namespace.
 | 
			
		||||
	NamespaceType
 | 
			
		||||
	// StringerType indicates that the field carries a fmt.Stringer.
 | 
			
		||||
	StringerType
 | 
			
		||||
	// ErrorType indicates that the field carries an error.
 | 
			
		||||
	ErrorType
 | 
			
		||||
	// SkipType indicates that the field is a no-op.
 | 
			
		||||
	SkipType
 | 
			
		||||
 | 
			
		||||
	// InlineMarshalerType indicates that the field carries an ObjectMarshaler
 | 
			
		||||
	// that should be inlined.
 | 
			
		||||
	InlineMarshalerType
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A Field is a marshaling operation used to add a key-value pair to a logger's
 | 
			
		||||
// context. Most fields are lazily marshaled, so it's inexpensive to add fields
 | 
			
		||||
// to disabled debug-level log statements.
 | 
			
		||||
type Field struct {
 | 
			
		||||
	Key       string
 | 
			
		||||
	Type      FieldType
 | 
			
		||||
	Integer   int64
 | 
			
		||||
	String    string
 | 
			
		||||
	Interface interface{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddTo exports a field through the ObjectEncoder interface. It's primarily
 | 
			
		||||
// useful to library authors, and shouldn't be necessary in most applications.
 | 
			
		||||
func (f Field) AddTo(enc ObjectEncoder) {
 | 
			
		||||
	var err error
 | 
			
		||||
 | 
			
		||||
	switch f.Type {
 | 
			
		||||
	case ArrayMarshalerType:
 | 
			
		||||
		err = enc.AddArray(f.Key, f.Interface.(ArrayMarshaler))
 | 
			
		||||
	case ObjectMarshalerType:
 | 
			
		||||
		err = enc.AddObject(f.Key, f.Interface.(ObjectMarshaler))
 | 
			
		||||
	case InlineMarshalerType:
 | 
			
		||||
		err = f.Interface.(ObjectMarshaler).MarshalLogObject(enc)
 | 
			
		||||
	case BinaryType:
 | 
			
		||||
		enc.AddBinary(f.Key, f.Interface.([]byte))
 | 
			
		||||
	case BoolType:
 | 
			
		||||
		enc.AddBool(f.Key, f.Integer == 1)
 | 
			
		||||
	case ByteStringType:
 | 
			
		||||
		enc.AddByteString(f.Key, f.Interface.([]byte))
 | 
			
		||||
	case Complex128Type:
 | 
			
		||||
		enc.AddComplex128(f.Key, f.Interface.(complex128))
 | 
			
		||||
	case Complex64Type:
 | 
			
		||||
		enc.AddComplex64(f.Key, f.Interface.(complex64))
 | 
			
		||||
	case DurationType:
 | 
			
		||||
		enc.AddDuration(f.Key, time.Duration(f.Integer))
 | 
			
		||||
	case Float64Type:
 | 
			
		||||
		enc.AddFloat64(f.Key, math.Float64frombits(uint64(f.Integer)))
 | 
			
		||||
	case Float32Type:
 | 
			
		||||
		enc.AddFloat32(f.Key, math.Float32frombits(uint32(f.Integer)))
 | 
			
		||||
	case Int64Type:
 | 
			
		||||
		enc.AddInt64(f.Key, f.Integer)
 | 
			
		||||
	case Int32Type:
 | 
			
		||||
		enc.AddInt32(f.Key, int32(f.Integer))
 | 
			
		||||
	case Int16Type:
 | 
			
		||||
		enc.AddInt16(f.Key, int16(f.Integer))
 | 
			
		||||
	case Int8Type:
 | 
			
		||||
		enc.AddInt8(f.Key, int8(f.Integer))
 | 
			
		||||
	case StringType:
 | 
			
		||||
		enc.AddString(f.Key, f.String)
 | 
			
		||||
	case TimeType:
 | 
			
		||||
		if f.Interface != nil {
 | 
			
		||||
			enc.AddTime(f.Key, time.Unix(0, f.Integer).In(f.Interface.(*time.Location)))
 | 
			
		||||
		} else {
 | 
			
		||||
			// Fall back to UTC if location is nil.
 | 
			
		||||
			enc.AddTime(f.Key, time.Unix(0, f.Integer))
 | 
			
		||||
		}
 | 
			
		||||
	case TimeFullType:
 | 
			
		||||
		enc.AddTime(f.Key, f.Interface.(time.Time))
 | 
			
		||||
	case Uint64Type:
 | 
			
		||||
		enc.AddUint64(f.Key, uint64(f.Integer))
 | 
			
		||||
	case Uint32Type:
 | 
			
		||||
		enc.AddUint32(f.Key, uint32(f.Integer))
 | 
			
		||||
	case Uint16Type:
 | 
			
		||||
		enc.AddUint16(f.Key, uint16(f.Integer))
 | 
			
		||||
	case Uint8Type:
 | 
			
		||||
		enc.AddUint8(f.Key, uint8(f.Integer))
 | 
			
		||||
	case UintptrType:
 | 
			
		||||
		enc.AddUintptr(f.Key, uintptr(f.Integer))
 | 
			
		||||
	case ReflectType:
 | 
			
		||||
		err = enc.AddReflected(f.Key, f.Interface)
 | 
			
		||||
	case NamespaceType:
 | 
			
		||||
		enc.OpenNamespace(f.Key)
 | 
			
		||||
	case StringerType:
 | 
			
		||||
		err = encodeStringer(f.Key, f.Interface, enc)
 | 
			
		||||
	case ErrorType:
 | 
			
		||||
		err = encodeError(f.Key, f.Interface.(error), enc)
 | 
			
		||||
	case SkipType:
 | 
			
		||||
		break
 | 
			
		||||
	default:
 | 
			
		||||
		panic(fmt.Sprintf("unknown field type: %v", f))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		enc.AddString(fmt.Sprintf("%sError", f.Key), err.Error())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Equals returns whether two fields are equal. For non-primitive types such as
 | 
			
		||||
// errors, marshalers, or reflect types, it uses reflect.DeepEqual.
 | 
			
		||||
func (f Field) Equals(other Field) bool {
 | 
			
		||||
	if f.Type != other.Type {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if f.Key != other.Key {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch f.Type {
 | 
			
		||||
	case BinaryType, ByteStringType:
 | 
			
		||||
		return bytes.Equal(f.Interface.([]byte), other.Interface.([]byte))
 | 
			
		||||
	case ArrayMarshalerType, ObjectMarshalerType, ErrorType, ReflectType:
 | 
			
		||||
		return reflect.DeepEqual(f.Interface, other.Interface)
 | 
			
		||||
	default:
 | 
			
		||||
		return f == other
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func addFields(enc ObjectEncoder, fields []Field) {
 | 
			
		||||
	for i := range fields {
 | 
			
		||||
		fields[i].AddTo(enc)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func encodeStringer(key string, stringer interface{}, enc ObjectEncoder) (retErr error) {
 | 
			
		||||
	// Try to capture panics (from nil references or otherwise) when calling
 | 
			
		||||
	// the String() method, similar to https://golang.org/src/fmt/print.go#L540
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if err := recover(); err != nil {
 | 
			
		||||
			// If it's a nil pointer, just say "<nil>". The likeliest causes are a
 | 
			
		||||
			// Stringer that fails to guard against nil or a nil pointer for a
 | 
			
		||||
			// value receiver, and in either case, "<nil>" is a nice result.
 | 
			
		||||
			if v := reflect.ValueOf(stringer); v.Kind() == reflect.Ptr && v.IsNil() {
 | 
			
		||||
				enc.AddString(key, "<nil>")
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			retErr = fmt.Errorf("PANIC=%v", err)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	enc.AddString(key, stringer.(fmt.Stringer).String())
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										68
									
								
								vendor/go.uber.org/zap/zapcore/hook.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								vendor/go.uber.org/zap/zapcore/hook.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import "go.uber.org/multierr"
 | 
			
		||||
 | 
			
		||||
type hooked struct {
 | 
			
		||||
	Core
 | 
			
		||||
	funcs []func(Entry) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RegisterHooks wraps a Core and runs a collection of user-defined callback
 | 
			
		||||
// hooks each time a message is logged. Execution of the callbacks is blocking.
 | 
			
		||||
//
 | 
			
		||||
// This offers users an easy way to register simple callbacks (e.g., metrics
 | 
			
		||||
// collection) without implementing the full Core interface.
 | 
			
		||||
func RegisterHooks(core Core, hooks ...func(Entry) error) Core {
 | 
			
		||||
	funcs := append([]func(Entry) error{}, hooks...)
 | 
			
		||||
	return &hooked{
 | 
			
		||||
		Core:  core,
 | 
			
		||||
		funcs: funcs,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *hooked) Check(ent Entry, ce *CheckedEntry) *CheckedEntry {
 | 
			
		||||
	// Let the wrapped Core decide whether to log this message or not. This
 | 
			
		||||
	// also gives the downstream a chance to register itself directly with the
 | 
			
		||||
	// CheckedEntry.
 | 
			
		||||
	if downstream := h.Core.Check(ent, ce); downstream != nil {
 | 
			
		||||
		return downstream.AddCore(ent, h)
 | 
			
		||||
	}
 | 
			
		||||
	return ce
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *hooked) With(fields []Field) Core {
 | 
			
		||||
	return &hooked{
 | 
			
		||||
		Core:  h.Core.With(fields),
 | 
			
		||||
		funcs: h.funcs,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *hooked) Write(ent Entry, _ []Field) error {
 | 
			
		||||
	// Since our downstream had a chance to register itself directly with the
 | 
			
		||||
	// CheckedMessage, we don't need to call it here.
 | 
			
		||||
	var err error
 | 
			
		||||
	for i := range h.funcs {
 | 
			
		||||
		err = multierr.Append(err, h.funcs[i](ent))
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								vendor/go.uber.org/zap/zapcore/increase_level.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								vendor/go.uber.org/zap/zapcore/increase_level.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
type levelFilterCore struct {
 | 
			
		||||
	core  Core
 | 
			
		||||
	level LevelEnabler
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewIncreaseLevelCore creates a core that can be used to increase the level of
 | 
			
		||||
// an existing Core. It cannot be used to decrease the logging level, as it acts
 | 
			
		||||
// as a filter before calling the underlying core. If level decreases the log level,
 | 
			
		||||
// an error is returned.
 | 
			
		||||
func NewIncreaseLevelCore(core Core, level LevelEnabler) (Core, error) {
 | 
			
		||||
	for l := _maxLevel; l >= _minLevel; l-- {
 | 
			
		||||
		if !core.Enabled(l) && level.Enabled(l) {
 | 
			
		||||
			return nil, fmt.Errorf("invalid increase level, as level %q is allowed by increased level, but not by existing core", l)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &levelFilterCore{core, level}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *levelFilterCore) Enabled(lvl Level) bool {
 | 
			
		||||
	return c.level.Enabled(lvl)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *levelFilterCore) With(fields []Field) Core {
 | 
			
		||||
	return &levelFilterCore{c.core.With(fields), c.level}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *levelFilterCore) Check(ent Entry, ce *CheckedEntry) *CheckedEntry {
 | 
			
		||||
	if !c.Enabled(ent.Level) {
 | 
			
		||||
		return ce
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c.core.Check(ent, ce)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *levelFilterCore) Write(ent Entry, fields []Field) error {
 | 
			
		||||
	return c.core.Write(ent, fields)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *levelFilterCore) Sync() error {
 | 
			
		||||
	return c.core.Sync()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										542
									
								
								vendor/go.uber.org/zap/zapcore/json_encoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										542
									
								
								vendor/go.uber.org/zap/zapcore/json_encoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,542 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/base64"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"math"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/zap/buffer"
 | 
			
		||||
	"go.uber.org/zap/internal/bufferpool"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// For JSON-escaping; see jsonEncoder.safeAddString below.
 | 
			
		||||
const _hex = "0123456789abcdef"
 | 
			
		||||
 | 
			
		||||
var _jsonPool = sync.Pool{New: func() interface{} {
 | 
			
		||||
	return &jsonEncoder{}
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
func getJSONEncoder() *jsonEncoder {
 | 
			
		||||
	return _jsonPool.Get().(*jsonEncoder)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func putJSONEncoder(enc *jsonEncoder) {
 | 
			
		||||
	if enc.reflectBuf != nil {
 | 
			
		||||
		enc.reflectBuf.Free()
 | 
			
		||||
	}
 | 
			
		||||
	enc.EncoderConfig = nil
 | 
			
		||||
	enc.buf = nil
 | 
			
		||||
	enc.spaced = false
 | 
			
		||||
	enc.openNamespaces = 0
 | 
			
		||||
	enc.reflectBuf = nil
 | 
			
		||||
	enc.reflectEnc = nil
 | 
			
		||||
	_jsonPool.Put(enc)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type jsonEncoder struct {
 | 
			
		||||
	*EncoderConfig
 | 
			
		||||
	buf            *buffer.Buffer
 | 
			
		||||
	spaced         bool // include spaces after colons and commas
 | 
			
		||||
	openNamespaces int
 | 
			
		||||
 | 
			
		||||
	// for encoding generic values by reflection
 | 
			
		||||
	reflectBuf *buffer.Buffer
 | 
			
		||||
	reflectEnc *json.Encoder
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewJSONEncoder creates a fast, low-allocation JSON encoder. The encoder
 | 
			
		||||
// appropriately escapes all field keys and values.
 | 
			
		||||
//
 | 
			
		||||
// Note that the encoder doesn't deduplicate keys, so it's possible to produce
 | 
			
		||||
// a message like
 | 
			
		||||
//   {"foo":"bar","foo":"baz"}
 | 
			
		||||
// This is permitted by the JSON specification, but not encouraged. Many
 | 
			
		||||
// libraries will ignore duplicate key-value pairs (typically keeping the last
 | 
			
		||||
// pair) when unmarshaling, but users should attempt to avoid adding duplicate
 | 
			
		||||
// keys.
 | 
			
		||||
func NewJSONEncoder(cfg EncoderConfig) Encoder {
 | 
			
		||||
	return newJSONEncoder(cfg, false)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newJSONEncoder(cfg EncoderConfig, spaced bool) *jsonEncoder {
 | 
			
		||||
	return &jsonEncoder{
 | 
			
		||||
		EncoderConfig: &cfg,
 | 
			
		||||
		buf:           bufferpool.Get(),
 | 
			
		||||
		spaced:        spaced,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddArray(key string, arr ArrayMarshaler) error {
 | 
			
		||||
	enc.addKey(key)
 | 
			
		||||
	return enc.AppendArray(arr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddObject(key string, obj ObjectMarshaler) error {
 | 
			
		||||
	enc.addKey(key)
 | 
			
		||||
	return enc.AppendObject(obj)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddBinary(key string, val []byte) {
 | 
			
		||||
	enc.AddString(key, base64.StdEncoding.EncodeToString(val))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddByteString(key string, val []byte) {
 | 
			
		||||
	enc.addKey(key)
 | 
			
		||||
	enc.AppendByteString(val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddBool(key string, val bool) {
 | 
			
		||||
	enc.addKey(key)
 | 
			
		||||
	enc.AppendBool(val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddComplex128(key string, val complex128) {
 | 
			
		||||
	enc.addKey(key)
 | 
			
		||||
	enc.AppendComplex128(val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddDuration(key string, val time.Duration) {
 | 
			
		||||
	enc.addKey(key)
 | 
			
		||||
	enc.AppendDuration(val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddFloat64(key string, val float64) {
 | 
			
		||||
	enc.addKey(key)
 | 
			
		||||
	enc.AppendFloat64(val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddFloat32(key string, val float32) {
 | 
			
		||||
	enc.addKey(key)
 | 
			
		||||
	enc.AppendFloat32(val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddInt64(key string, val int64) {
 | 
			
		||||
	enc.addKey(key)
 | 
			
		||||
	enc.AppendInt64(val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) resetReflectBuf() {
 | 
			
		||||
	if enc.reflectBuf == nil {
 | 
			
		||||
		enc.reflectBuf = bufferpool.Get()
 | 
			
		||||
		enc.reflectEnc = json.NewEncoder(enc.reflectBuf)
 | 
			
		||||
 | 
			
		||||
		// For consistency with our custom JSON encoder.
 | 
			
		||||
		enc.reflectEnc.SetEscapeHTML(false)
 | 
			
		||||
	} else {
 | 
			
		||||
		enc.reflectBuf.Reset()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var nullLiteralBytes = []byte("null")
 | 
			
		||||
 | 
			
		||||
// Only invoke the standard JSON encoder if there is actually something to
 | 
			
		||||
// encode; otherwise write JSON null literal directly.
 | 
			
		||||
func (enc *jsonEncoder) encodeReflected(obj interface{}) ([]byte, error) {
 | 
			
		||||
	if obj == nil {
 | 
			
		||||
		return nullLiteralBytes, nil
 | 
			
		||||
	}
 | 
			
		||||
	enc.resetReflectBuf()
 | 
			
		||||
	if err := enc.reflectEnc.Encode(obj); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	enc.reflectBuf.TrimNewline()
 | 
			
		||||
	return enc.reflectBuf.Bytes(), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddReflected(key string, obj interface{}) error {
 | 
			
		||||
	valueBytes, err := enc.encodeReflected(obj)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	enc.addKey(key)
 | 
			
		||||
	_, err = enc.buf.Write(valueBytes)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) OpenNamespace(key string) {
 | 
			
		||||
	enc.addKey(key)
 | 
			
		||||
	enc.buf.AppendByte('{')
 | 
			
		||||
	enc.openNamespaces++
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddString(key, val string) {
 | 
			
		||||
	enc.addKey(key)
 | 
			
		||||
	enc.AppendString(val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddTime(key string, val time.Time) {
 | 
			
		||||
	enc.addKey(key)
 | 
			
		||||
	enc.AppendTime(val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddUint64(key string, val uint64) {
 | 
			
		||||
	enc.addKey(key)
 | 
			
		||||
	enc.AppendUint64(val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AppendArray(arr ArrayMarshaler) error {
 | 
			
		||||
	enc.addElementSeparator()
 | 
			
		||||
	enc.buf.AppendByte('[')
 | 
			
		||||
	err := arr.MarshalLogArray(enc)
 | 
			
		||||
	enc.buf.AppendByte(']')
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AppendObject(obj ObjectMarshaler) error {
 | 
			
		||||
	enc.addElementSeparator()
 | 
			
		||||
	enc.buf.AppendByte('{')
 | 
			
		||||
	err := obj.MarshalLogObject(enc)
 | 
			
		||||
	enc.buf.AppendByte('}')
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AppendBool(val bool) {
 | 
			
		||||
	enc.addElementSeparator()
 | 
			
		||||
	enc.buf.AppendBool(val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AppendByteString(val []byte) {
 | 
			
		||||
	enc.addElementSeparator()
 | 
			
		||||
	enc.buf.AppendByte('"')
 | 
			
		||||
	enc.safeAddByteString(val)
 | 
			
		||||
	enc.buf.AppendByte('"')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AppendComplex128(val complex128) {
 | 
			
		||||
	enc.addElementSeparator()
 | 
			
		||||
	// Cast to a platform-independent, fixed-size type.
 | 
			
		||||
	r, i := float64(real(val)), float64(imag(val))
 | 
			
		||||
	enc.buf.AppendByte('"')
 | 
			
		||||
	// Because we're always in a quoted string, we can use strconv without
 | 
			
		||||
	// special-casing NaN and +/-Inf.
 | 
			
		||||
	enc.buf.AppendFloat(r, 64)
 | 
			
		||||
	// If imaginary part is less than 0, minus (-) sign is added by default
 | 
			
		||||
	// by AppendFloat.
 | 
			
		||||
	if i >= 0 {
 | 
			
		||||
		enc.buf.AppendByte('+')
 | 
			
		||||
	}
 | 
			
		||||
	enc.buf.AppendFloat(i, 64)
 | 
			
		||||
	enc.buf.AppendByte('i')
 | 
			
		||||
	enc.buf.AppendByte('"')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AppendDuration(val time.Duration) {
 | 
			
		||||
	cur := enc.buf.Len()
 | 
			
		||||
	if e := enc.EncodeDuration; e != nil {
 | 
			
		||||
		e(val, enc)
 | 
			
		||||
	}
 | 
			
		||||
	if cur == enc.buf.Len() {
 | 
			
		||||
		// User-supplied EncodeDuration is a no-op. Fall back to nanoseconds to keep
 | 
			
		||||
		// JSON valid.
 | 
			
		||||
		enc.AppendInt64(int64(val))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AppendInt64(val int64) {
 | 
			
		||||
	enc.addElementSeparator()
 | 
			
		||||
	enc.buf.AppendInt(val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AppendReflected(val interface{}) error {
 | 
			
		||||
	valueBytes, err := enc.encodeReflected(val)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	enc.addElementSeparator()
 | 
			
		||||
	_, err = enc.buf.Write(valueBytes)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AppendString(val string) {
 | 
			
		||||
	enc.addElementSeparator()
 | 
			
		||||
	enc.buf.AppendByte('"')
 | 
			
		||||
	enc.safeAddString(val)
 | 
			
		||||
	enc.buf.AppendByte('"')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AppendTimeLayout(time time.Time, layout string) {
 | 
			
		||||
	enc.addElementSeparator()
 | 
			
		||||
	enc.buf.AppendByte('"')
 | 
			
		||||
	enc.buf.AppendTime(time, layout)
 | 
			
		||||
	enc.buf.AppendByte('"')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AppendTime(val time.Time) {
 | 
			
		||||
	cur := enc.buf.Len()
 | 
			
		||||
	if e := enc.EncodeTime; e != nil {
 | 
			
		||||
		e(val, enc)
 | 
			
		||||
	}
 | 
			
		||||
	if cur == enc.buf.Len() {
 | 
			
		||||
		// User-supplied EncodeTime is a no-op. Fall back to nanos since epoch to keep
 | 
			
		||||
		// output JSON valid.
 | 
			
		||||
		enc.AppendInt64(val.UnixNano())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AppendUint64(val uint64) {
 | 
			
		||||
	enc.addElementSeparator()
 | 
			
		||||
	enc.buf.AppendUint(val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) AddComplex64(k string, v complex64) { enc.AddComplex128(k, complex128(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AddInt(k string, v int)             { enc.AddInt64(k, int64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AddInt32(k string, v int32)         { enc.AddInt64(k, int64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AddInt16(k string, v int16)         { enc.AddInt64(k, int64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AddInt8(k string, v int8)           { enc.AddInt64(k, int64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AddUint(k string, v uint)           { enc.AddUint64(k, uint64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AddUint32(k string, v uint32)       { enc.AddUint64(k, uint64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AddUint16(k string, v uint16)       { enc.AddUint64(k, uint64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AddUint8(k string, v uint8)         { enc.AddUint64(k, uint64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AddUintptr(k string, v uintptr)     { enc.AddUint64(k, uint64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AppendComplex64(v complex64)        { enc.AppendComplex128(complex128(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AppendFloat64(v float64)            { enc.appendFloat(v, 64) }
 | 
			
		||||
func (enc *jsonEncoder) AppendFloat32(v float32)            { enc.appendFloat(float64(v), 32) }
 | 
			
		||||
func (enc *jsonEncoder) AppendInt(v int)                    { enc.AppendInt64(int64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AppendInt32(v int32)                { enc.AppendInt64(int64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AppendInt16(v int16)                { enc.AppendInt64(int64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AppendInt8(v int8)                  { enc.AppendInt64(int64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AppendUint(v uint)                  { enc.AppendUint64(uint64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AppendUint32(v uint32)              { enc.AppendUint64(uint64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AppendUint16(v uint16)              { enc.AppendUint64(uint64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AppendUint8(v uint8)                { enc.AppendUint64(uint64(v)) }
 | 
			
		||||
func (enc *jsonEncoder) AppendUintptr(v uintptr)            { enc.AppendUint64(uint64(v)) }
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) Clone() Encoder {
 | 
			
		||||
	clone := enc.clone()
 | 
			
		||||
	clone.buf.Write(enc.buf.Bytes())
 | 
			
		||||
	return clone
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) clone() *jsonEncoder {
 | 
			
		||||
	clone := getJSONEncoder()
 | 
			
		||||
	clone.EncoderConfig = enc.EncoderConfig
 | 
			
		||||
	clone.spaced = enc.spaced
 | 
			
		||||
	clone.openNamespaces = enc.openNamespaces
 | 
			
		||||
	clone.buf = bufferpool.Get()
 | 
			
		||||
	return clone
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) EncodeEntry(ent Entry, fields []Field) (*buffer.Buffer, error) {
 | 
			
		||||
	final := enc.clone()
 | 
			
		||||
	final.buf.AppendByte('{')
 | 
			
		||||
 | 
			
		||||
	if final.LevelKey != "" {
 | 
			
		||||
		final.addKey(final.LevelKey)
 | 
			
		||||
		cur := final.buf.Len()
 | 
			
		||||
		final.EncodeLevel(ent.Level, final)
 | 
			
		||||
		if cur == final.buf.Len() {
 | 
			
		||||
			// User-supplied EncodeLevel was a no-op. Fall back to strings to keep
 | 
			
		||||
			// output JSON valid.
 | 
			
		||||
			final.AppendString(ent.Level.String())
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if final.TimeKey != "" {
 | 
			
		||||
		final.AddTime(final.TimeKey, ent.Time)
 | 
			
		||||
	}
 | 
			
		||||
	if ent.LoggerName != "" && final.NameKey != "" {
 | 
			
		||||
		final.addKey(final.NameKey)
 | 
			
		||||
		cur := final.buf.Len()
 | 
			
		||||
		nameEncoder := final.EncodeName
 | 
			
		||||
 | 
			
		||||
		// if no name encoder provided, fall back to FullNameEncoder for backwards
 | 
			
		||||
		// compatibility
 | 
			
		||||
		if nameEncoder == nil {
 | 
			
		||||
			nameEncoder = FullNameEncoder
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		nameEncoder(ent.LoggerName, final)
 | 
			
		||||
		if cur == final.buf.Len() {
 | 
			
		||||
			// User-supplied EncodeName was a no-op. Fall back to strings to
 | 
			
		||||
			// keep output JSON valid.
 | 
			
		||||
			final.AppendString(ent.LoggerName)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if ent.Caller.Defined {
 | 
			
		||||
		if final.CallerKey != "" {
 | 
			
		||||
			final.addKey(final.CallerKey)
 | 
			
		||||
			cur := final.buf.Len()
 | 
			
		||||
			final.EncodeCaller(ent.Caller, final)
 | 
			
		||||
			if cur == final.buf.Len() {
 | 
			
		||||
				// User-supplied EncodeCaller was a no-op. Fall back to strings to
 | 
			
		||||
				// keep output JSON valid.
 | 
			
		||||
				final.AppendString(ent.Caller.String())
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if final.FunctionKey != "" {
 | 
			
		||||
			final.addKey(final.FunctionKey)
 | 
			
		||||
			final.AppendString(ent.Caller.Function)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if final.MessageKey != "" {
 | 
			
		||||
		final.addKey(enc.MessageKey)
 | 
			
		||||
		final.AppendString(ent.Message)
 | 
			
		||||
	}
 | 
			
		||||
	if enc.buf.Len() > 0 {
 | 
			
		||||
		final.addElementSeparator()
 | 
			
		||||
		final.buf.Write(enc.buf.Bytes())
 | 
			
		||||
	}
 | 
			
		||||
	addFields(final, fields)
 | 
			
		||||
	final.closeOpenNamespaces()
 | 
			
		||||
	if ent.Stack != "" && final.StacktraceKey != "" {
 | 
			
		||||
		final.AddString(final.StacktraceKey, ent.Stack)
 | 
			
		||||
	}
 | 
			
		||||
	final.buf.AppendByte('}')
 | 
			
		||||
	if final.LineEnding != "" {
 | 
			
		||||
		final.buf.AppendString(final.LineEnding)
 | 
			
		||||
	} else {
 | 
			
		||||
		final.buf.AppendString(DefaultLineEnding)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret := final.buf
 | 
			
		||||
	putJSONEncoder(final)
 | 
			
		||||
	return ret, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) truncate() {
 | 
			
		||||
	enc.buf.Reset()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) closeOpenNamespaces() {
 | 
			
		||||
	for i := 0; i < enc.openNamespaces; i++ {
 | 
			
		||||
		enc.buf.AppendByte('}')
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) addKey(key string) {
 | 
			
		||||
	enc.addElementSeparator()
 | 
			
		||||
	enc.buf.AppendByte('"')
 | 
			
		||||
	enc.safeAddString(key)
 | 
			
		||||
	enc.buf.AppendByte('"')
 | 
			
		||||
	enc.buf.AppendByte(':')
 | 
			
		||||
	if enc.spaced {
 | 
			
		||||
		enc.buf.AppendByte(' ')
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) addElementSeparator() {
 | 
			
		||||
	last := enc.buf.Len() - 1
 | 
			
		||||
	if last < 0 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	switch enc.buf.Bytes()[last] {
 | 
			
		||||
	case '{', '[', ':', ',', ' ':
 | 
			
		||||
		return
 | 
			
		||||
	default:
 | 
			
		||||
		enc.buf.AppendByte(',')
 | 
			
		||||
		if enc.spaced {
 | 
			
		||||
			enc.buf.AppendByte(' ')
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) appendFloat(val float64, bitSize int) {
 | 
			
		||||
	enc.addElementSeparator()
 | 
			
		||||
	switch {
 | 
			
		||||
	case math.IsNaN(val):
 | 
			
		||||
		enc.buf.AppendString(`"NaN"`)
 | 
			
		||||
	case math.IsInf(val, 1):
 | 
			
		||||
		enc.buf.AppendString(`"+Inf"`)
 | 
			
		||||
	case math.IsInf(val, -1):
 | 
			
		||||
		enc.buf.AppendString(`"-Inf"`)
 | 
			
		||||
	default:
 | 
			
		||||
		enc.buf.AppendFloat(val, bitSize)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// safeAddString JSON-escapes a string and appends it to the internal buffer.
 | 
			
		||||
// Unlike the standard library's encoder, it doesn't attempt to protect the
 | 
			
		||||
// user from browser vulnerabilities or JSONP-related problems.
 | 
			
		||||
func (enc *jsonEncoder) safeAddString(s string) {
 | 
			
		||||
	for i := 0; i < len(s); {
 | 
			
		||||
		if enc.tryAddRuneSelf(s[i]) {
 | 
			
		||||
			i++
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		r, size := utf8.DecodeRuneInString(s[i:])
 | 
			
		||||
		if enc.tryAddRuneError(r, size) {
 | 
			
		||||
			i++
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		enc.buf.AppendString(s[i : i+size])
 | 
			
		||||
		i += size
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// safeAddByteString is no-alloc equivalent of safeAddString(string(s)) for s []byte.
 | 
			
		||||
func (enc *jsonEncoder) safeAddByteString(s []byte) {
 | 
			
		||||
	for i := 0; i < len(s); {
 | 
			
		||||
		if enc.tryAddRuneSelf(s[i]) {
 | 
			
		||||
			i++
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		r, size := utf8.DecodeRune(s[i:])
 | 
			
		||||
		if enc.tryAddRuneError(r, size) {
 | 
			
		||||
			i++
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		enc.buf.Write(s[i : i+size])
 | 
			
		||||
		i += size
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// tryAddRuneSelf appends b if it is valid UTF-8 character represented in a single byte.
 | 
			
		||||
func (enc *jsonEncoder) tryAddRuneSelf(b byte) bool {
 | 
			
		||||
	if b >= utf8.RuneSelf {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if 0x20 <= b && b != '\\' && b != '"' {
 | 
			
		||||
		enc.buf.AppendByte(b)
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	switch b {
 | 
			
		||||
	case '\\', '"':
 | 
			
		||||
		enc.buf.AppendByte('\\')
 | 
			
		||||
		enc.buf.AppendByte(b)
 | 
			
		||||
	case '\n':
 | 
			
		||||
		enc.buf.AppendByte('\\')
 | 
			
		||||
		enc.buf.AppendByte('n')
 | 
			
		||||
	case '\r':
 | 
			
		||||
		enc.buf.AppendByte('\\')
 | 
			
		||||
		enc.buf.AppendByte('r')
 | 
			
		||||
	case '\t':
 | 
			
		||||
		enc.buf.AppendByte('\\')
 | 
			
		||||
		enc.buf.AppendByte('t')
 | 
			
		||||
	default:
 | 
			
		||||
		// Encode bytes < 0x20, except for the escape sequences above.
 | 
			
		||||
		enc.buf.AppendString(`\u00`)
 | 
			
		||||
		enc.buf.AppendByte(_hex[b>>4])
 | 
			
		||||
		enc.buf.AppendByte(_hex[b&0xF])
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (enc *jsonEncoder) tryAddRuneError(r rune, size int) bool {
 | 
			
		||||
	if r == utf8.RuneError && size == 1 {
 | 
			
		||||
		enc.buf.AppendString(`\ufffd`)
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										175
									
								
								vendor/go.uber.org/zap/zapcore/level.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								vendor/go.uber.org/zap/zapcore/level.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,175 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var errUnmarshalNilLevel = errors.New("can't unmarshal a nil *Level")
 | 
			
		||||
 | 
			
		||||
// A Level is a logging priority. Higher levels are more important.
 | 
			
		||||
type Level int8
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// DebugLevel logs are typically voluminous, and are usually disabled in
 | 
			
		||||
	// production.
 | 
			
		||||
	DebugLevel Level = iota - 1
 | 
			
		||||
	// InfoLevel is the default logging priority.
 | 
			
		||||
	InfoLevel
 | 
			
		||||
	// WarnLevel logs are more important than Info, but don't need individual
 | 
			
		||||
	// human review.
 | 
			
		||||
	WarnLevel
 | 
			
		||||
	// ErrorLevel logs are high-priority. If an application is running smoothly,
 | 
			
		||||
	// it shouldn't generate any error-level logs.
 | 
			
		||||
	ErrorLevel
 | 
			
		||||
	// DPanicLevel logs are particularly important errors. In development the
 | 
			
		||||
	// logger panics after writing the message.
 | 
			
		||||
	DPanicLevel
 | 
			
		||||
	// PanicLevel logs a message, then panics.
 | 
			
		||||
	PanicLevel
 | 
			
		||||
	// FatalLevel logs a message, then calls os.Exit(1).
 | 
			
		||||
	FatalLevel
 | 
			
		||||
 | 
			
		||||
	_minLevel = DebugLevel
 | 
			
		||||
	_maxLevel = FatalLevel
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// String returns a lower-case ASCII representation of the log level.
 | 
			
		||||
func (l Level) String() string {
 | 
			
		||||
	switch l {
 | 
			
		||||
	case DebugLevel:
 | 
			
		||||
		return "debug"
 | 
			
		||||
	case InfoLevel:
 | 
			
		||||
		return "info"
 | 
			
		||||
	case WarnLevel:
 | 
			
		||||
		return "warn"
 | 
			
		||||
	case ErrorLevel:
 | 
			
		||||
		return "error"
 | 
			
		||||
	case DPanicLevel:
 | 
			
		||||
		return "dpanic"
 | 
			
		||||
	case PanicLevel:
 | 
			
		||||
		return "panic"
 | 
			
		||||
	case FatalLevel:
 | 
			
		||||
		return "fatal"
 | 
			
		||||
	default:
 | 
			
		||||
		return fmt.Sprintf("Level(%d)", l)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CapitalString returns an all-caps ASCII representation of the log level.
 | 
			
		||||
func (l Level) CapitalString() string {
 | 
			
		||||
	// Printing levels in all-caps is common enough that we should export this
 | 
			
		||||
	// functionality.
 | 
			
		||||
	switch l {
 | 
			
		||||
	case DebugLevel:
 | 
			
		||||
		return "DEBUG"
 | 
			
		||||
	case InfoLevel:
 | 
			
		||||
		return "INFO"
 | 
			
		||||
	case WarnLevel:
 | 
			
		||||
		return "WARN"
 | 
			
		||||
	case ErrorLevel:
 | 
			
		||||
		return "ERROR"
 | 
			
		||||
	case DPanicLevel:
 | 
			
		||||
		return "DPANIC"
 | 
			
		||||
	case PanicLevel:
 | 
			
		||||
		return "PANIC"
 | 
			
		||||
	case FatalLevel:
 | 
			
		||||
		return "FATAL"
 | 
			
		||||
	default:
 | 
			
		||||
		return fmt.Sprintf("LEVEL(%d)", l)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalText marshals the Level to text. Note that the text representation
 | 
			
		||||
// drops the -Level suffix (see example).
 | 
			
		||||
func (l Level) MarshalText() ([]byte, error) {
 | 
			
		||||
	return []byte(l.String()), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalText unmarshals text to a level. Like MarshalText, UnmarshalText
 | 
			
		||||
// expects the text representation of a Level to drop the -Level suffix (see
 | 
			
		||||
// example).
 | 
			
		||||
//
 | 
			
		||||
// In particular, this makes it easy to configure logging levels using YAML,
 | 
			
		||||
// TOML, or JSON files.
 | 
			
		||||
func (l *Level) UnmarshalText(text []byte) error {
 | 
			
		||||
	if l == nil {
 | 
			
		||||
		return errUnmarshalNilLevel
 | 
			
		||||
	}
 | 
			
		||||
	if !l.unmarshalText(text) && !l.unmarshalText(bytes.ToLower(text)) {
 | 
			
		||||
		return fmt.Errorf("unrecognized level: %q", text)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *Level) unmarshalText(text []byte) bool {
 | 
			
		||||
	switch string(text) {
 | 
			
		||||
	case "debug", "DEBUG":
 | 
			
		||||
		*l = DebugLevel
 | 
			
		||||
	case "info", "INFO", "": // make the zero value useful
 | 
			
		||||
		*l = InfoLevel
 | 
			
		||||
	case "warn", "WARN":
 | 
			
		||||
		*l = WarnLevel
 | 
			
		||||
	case "error", "ERROR":
 | 
			
		||||
		*l = ErrorLevel
 | 
			
		||||
	case "dpanic", "DPANIC":
 | 
			
		||||
		*l = DPanicLevel
 | 
			
		||||
	case "panic", "PANIC":
 | 
			
		||||
		*l = PanicLevel
 | 
			
		||||
	case "fatal", "FATAL":
 | 
			
		||||
		*l = FatalLevel
 | 
			
		||||
	default:
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set sets the level for the flag.Value interface.
 | 
			
		||||
func (l *Level) Set(s string) error {
 | 
			
		||||
	return l.UnmarshalText([]byte(s))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get gets the level for the flag.Getter interface.
 | 
			
		||||
func (l *Level) Get() interface{} {
 | 
			
		||||
	return *l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Enabled returns true if the given level is at or above this level.
 | 
			
		||||
func (l Level) Enabled(lvl Level) bool {
 | 
			
		||||
	return lvl >= l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LevelEnabler decides whether a given logging level is enabled when logging a
 | 
			
		||||
// message.
 | 
			
		||||
//
 | 
			
		||||
// Enablers are intended to be used to implement deterministic filters;
 | 
			
		||||
// concerns like sampling are better implemented as a Core.
 | 
			
		||||
//
 | 
			
		||||
// Each concrete Level value implements a static LevelEnabler which returns
 | 
			
		||||
// true for itself and all higher logging levels. For example WarnLevel.Enabled()
 | 
			
		||||
// will return true for WarnLevel, ErrorLevel, DPanicLevel, PanicLevel, and
 | 
			
		||||
// FatalLevel, but return false for InfoLevel and DebugLevel.
 | 
			
		||||
type LevelEnabler interface {
 | 
			
		||||
	Enabled(Level) bool
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								vendor/go.uber.org/zap/zapcore/level_strings.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								vendor/go.uber.org/zap/zapcore/level_strings.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import "go.uber.org/zap/internal/color"
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_levelToColor = map[Level]color.Color{
 | 
			
		||||
		DebugLevel:  color.Magenta,
 | 
			
		||||
		InfoLevel:   color.Blue,
 | 
			
		||||
		WarnLevel:   color.Yellow,
 | 
			
		||||
		ErrorLevel:  color.Red,
 | 
			
		||||
		DPanicLevel: color.Red,
 | 
			
		||||
		PanicLevel:  color.Red,
 | 
			
		||||
		FatalLevel:  color.Red,
 | 
			
		||||
	}
 | 
			
		||||
	_unknownLevelColor = color.Red
 | 
			
		||||
 | 
			
		||||
	_levelToLowercaseColorString = make(map[Level]string, len(_levelToColor))
 | 
			
		||||
	_levelToCapitalColorString   = make(map[Level]string, len(_levelToColor))
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	for level, color := range _levelToColor {
 | 
			
		||||
		_levelToLowercaseColorString[level] = color.Add(level.String())
 | 
			
		||||
		_levelToCapitalColorString[level] = color.Add(level.CapitalString())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								vendor/go.uber.org/zap/zapcore/marshaler.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								vendor/go.uber.org/zap/zapcore/marshaler.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
// ObjectMarshaler allows user-defined types to efficiently add themselves to the
 | 
			
		||||
// logging context, and to selectively omit information which shouldn't be
 | 
			
		||||
// included in logs (e.g., passwords).
 | 
			
		||||
//
 | 
			
		||||
// Note: ObjectMarshaler is only used when zap.Object is used or when
 | 
			
		||||
// passed directly to zap.Any. It is not used when reflection-based
 | 
			
		||||
// encoding is used.
 | 
			
		||||
type ObjectMarshaler interface {
 | 
			
		||||
	MarshalLogObject(ObjectEncoder) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ObjectMarshalerFunc is a type adapter that turns a function into an
 | 
			
		||||
// ObjectMarshaler.
 | 
			
		||||
type ObjectMarshalerFunc func(ObjectEncoder) error
 | 
			
		||||
 | 
			
		||||
// MarshalLogObject calls the underlying function.
 | 
			
		||||
func (f ObjectMarshalerFunc) MarshalLogObject(enc ObjectEncoder) error {
 | 
			
		||||
	return f(enc)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ArrayMarshaler allows user-defined types to efficiently add themselves to the
 | 
			
		||||
// logging context, and to selectively omit information which shouldn't be
 | 
			
		||||
// included in logs (e.g., passwords).
 | 
			
		||||
//
 | 
			
		||||
// Note: ArrayMarshaler is only used when zap.Array is used or when
 | 
			
		||||
// passed directly to zap.Any. It is not used when reflection-based
 | 
			
		||||
// encoding is used.
 | 
			
		||||
type ArrayMarshaler interface {
 | 
			
		||||
	MarshalLogArray(ArrayEncoder) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ArrayMarshalerFunc is a type adapter that turns a function into an
 | 
			
		||||
// ArrayMarshaler.
 | 
			
		||||
type ArrayMarshalerFunc func(ArrayEncoder) error
 | 
			
		||||
 | 
			
		||||
// MarshalLogArray calls the underlying function.
 | 
			
		||||
func (f ArrayMarshalerFunc) MarshalLogArray(enc ArrayEncoder) error {
 | 
			
		||||
	return f(enc)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										179
									
								
								vendor/go.uber.org/zap/zapcore/memory_encoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								vendor/go.uber.org/zap/zapcore/memory_encoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,179 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import "time"
 | 
			
		||||
 | 
			
		||||
// MapObjectEncoder is an ObjectEncoder backed by a simple
 | 
			
		||||
// map[string]interface{}. It's not fast enough for production use, but it's
 | 
			
		||||
// helpful in tests.
 | 
			
		||||
type MapObjectEncoder struct {
 | 
			
		||||
	// Fields contains the entire encoded log context.
 | 
			
		||||
	Fields map[string]interface{}
 | 
			
		||||
	// cur is a pointer to the namespace we're currently writing to.
 | 
			
		||||
	cur map[string]interface{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewMapObjectEncoder creates a new map-backed ObjectEncoder.
 | 
			
		||||
func NewMapObjectEncoder() *MapObjectEncoder {
 | 
			
		||||
	m := make(map[string]interface{})
 | 
			
		||||
	return &MapObjectEncoder{
 | 
			
		||||
		Fields: m,
 | 
			
		||||
		cur:    m,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddArray implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddArray(key string, v ArrayMarshaler) error {
 | 
			
		||||
	arr := &sliceArrayEncoder{elems: make([]interface{}, 0)}
 | 
			
		||||
	err := v.MarshalLogArray(arr)
 | 
			
		||||
	m.cur[key] = arr.elems
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddObject implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddObject(k string, v ObjectMarshaler) error {
 | 
			
		||||
	newMap := NewMapObjectEncoder()
 | 
			
		||||
	m.cur[k] = newMap.Fields
 | 
			
		||||
	return v.MarshalLogObject(newMap)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddBinary implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddBinary(k string, v []byte) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddByteString implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddByteString(k string, v []byte) { m.cur[k] = string(v) }
 | 
			
		||||
 | 
			
		||||
// AddBool implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddBool(k string, v bool) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddDuration implements ObjectEncoder.
 | 
			
		||||
func (m MapObjectEncoder) AddDuration(k string, v time.Duration) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddComplex128 implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddComplex128(k string, v complex128) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddComplex64 implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddComplex64(k string, v complex64) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddFloat64 implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddFloat64(k string, v float64) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddFloat32 implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddFloat32(k string, v float32) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddInt implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddInt(k string, v int) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddInt64 implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddInt64(k string, v int64) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddInt32 implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddInt32(k string, v int32) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddInt16 implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddInt16(k string, v int16) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddInt8 implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddInt8(k string, v int8) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddString implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddString(k string, v string) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddTime implements ObjectEncoder.
 | 
			
		||||
func (m MapObjectEncoder) AddTime(k string, v time.Time) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddUint implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddUint(k string, v uint) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddUint64 implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddUint64(k string, v uint64) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddUint32 implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddUint32(k string, v uint32) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddUint16 implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddUint16(k string, v uint16) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddUint8 implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddUint8(k string, v uint8) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddUintptr implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddUintptr(k string, v uintptr) { m.cur[k] = v }
 | 
			
		||||
 | 
			
		||||
// AddReflected implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) AddReflected(k string, v interface{}) error {
 | 
			
		||||
	m.cur[k] = v
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OpenNamespace implements ObjectEncoder.
 | 
			
		||||
func (m *MapObjectEncoder) OpenNamespace(k string) {
 | 
			
		||||
	ns := make(map[string]interface{})
 | 
			
		||||
	m.cur[k] = ns
 | 
			
		||||
	m.cur = ns
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// sliceArrayEncoder is an ArrayEncoder backed by a simple []interface{}. Like
 | 
			
		||||
// the MapObjectEncoder, it's not designed for production use.
 | 
			
		||||
type sliceArrayEncoder struct {
 | 
			
		||||
	elems []interface{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *sliceArrayEncoder) AppendArray(v ArrayMarshaler) error {
 | 
			
		||||
	enc := &sliceArrayEncoder{}
 | 
			
		||||
	err := v.MarshalLogArray(enc)
 | 
			
		||||
	s.elems = append(s.elems, enc.elems)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *sliceArrayEncoder) AppendObject(v ObjectMarshaler) error {
 | 
			
		||||
	m := NewMapObjectEncoder()
 | 
			
		||||
	err := v.MarshalLogObject(m)
 | 
			
		||||
	s.elems = append(s.elems, m.Fields)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *sliceArrayEncoder) AppendReflected(v interface{}) error {
 | 
			
		||||
	s.elems = append(s.elems, v)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *sliceArrayEncoder) AppendBool(v bool)              { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendByteString(v []byte)      { s.elems = append(s.elems, string(v)) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendComplex128(v complex128)  { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendComplex64(v complex64)    { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendDuration(v time.Duration) { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendFloat64(v float64)        { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendFloat32(v float32)        { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendInt(v int)                { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendInt64(v int64)            { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendInt32(v int32)            { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendInt16(v int16)            { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendInt8(v int8)              { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendString(v string)          { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendTime(v time.Time)         { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendUint(v uint)              { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendUint64(v uint64)          { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendUint32(v uint32)          { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendUint16(v uint16)          { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendUint8(v uint8)            { s.elems = append(s.elems, v) }
 | 
			
		||||
func (s *sliceArrayEncoder) AppendUintptr(v uintptr)        { s.elems = append(s.elems, v) }
 | 
			
		||||
							
								
								
									
										210
									
								
								vendor/go.uber.org/zap/zapcore/sampler.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								vendor/go.uber.org/zap/zapcore/sampler.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,210 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/atomic"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	_numLevels        = _maxLevel - _minLevel + 1
 | 
			
		||||
	_countersPerLevel = 4096
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type counter struct {
 | 
			
		||||
	resetAt atomic.Int64
 | 
			
		||||
	counter atomic.Uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type counters [_numLevels][_countersPerLevel]counter
 | 
			
		||||
 | 
			
		||||
func newCounters() *counters {
 | 
			
		||||
	return &counters{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cs *counters) get(lvl Level, key string) *counter {
 | 
			
		||||
	i := lvl - _minLevel
 | 
			
		||||
	j := fnv32a(key) % _countersPerLevel
 | 
			
		||||
	return &cs[i][j]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// fnv32a, adapted from "hash/fnv", but without a []byte(string) alloc
 | 
			
		||||
func fnv32a(s string) uint32 {
 | 
			
		||||
	const (
 | 
			
		||||
		offset32 = 2166136261
 | 
			
		||||
		prime32  = 16777619
 | 
			
		||||
	)
 | 
			
		||||
	hash := uint32(offset32)
 | 
			
		||||
	for i := 0; i < len(s); i++ {
 | 
			
		||||
		hash ^= uint32(s[i])
 | 
			
		||||
		hash *= prime32
 | 
			
		||||
	}
 | 
			
		||||
	return hash
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *counter) IncCheckReset(t time.Time, tick time.Duration) uint64 {
 | 
			
		||||
	tn := t.UnixNano()
 | 
			
		||||
	resetAfter := c.resetAt.Load()
 | 
			
		||||
	if resetAfter > tn {
 | 
			
		||||
		return c.counter.Inc()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.counter.Store(1)
 | 
			
		||||
 | 
			
		||||
	newResetAfter := tn + tick.Nanoseconds()
 | 
			
		||||
	if !c.resetAt.CAS(resetAfter, newResetAfter) {
 | 
			
		||||
		// We raced with another goroutine trying to reset, and it also reset
 | 
			
		||||
		// the counter to 1, so we need to reincrement the counter.
 | 
			
		||||
		return c.counter.Inc()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SamplingDecision is a decision represented as a bit field made by sampler.
 | 
			
		||||
// More decisions may be added in the future.
 | 
			
		||||
type SamplingDecision uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// LogDropped indicates that the Sampler dropped a log entry.
 | 
			
		||||
	LogDropped SamplingDecision = 1 << iota
 | 
			
		||||
	// LogSampled indicates that the Sampler sampled a log entry.
 | 
			
		||||
	LogSampled
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// optionFunc wraps a func so it satisfies the SamplerOption interface.
 | 
			
		||||
type optionFunc func(*sampler)
 | 
			
		||||
 | 
			
		||||
func (f optionFunc) apply(s *sampler) {
 | 
			
		||||
	f(s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SamplerOption configures a Sampler.
 | 
			
		||||
type SamplerOption interface {
 | 
			
		||||
	apply(*sampler)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// nopSamplingHook is the default hook used by sampler.
 | 
			
		||||
func nopSamplingHook(Entry, SamplingDecision) {}
 | 
			
		||||
 | 
			
		||||
// SamplerHook registers a function  which will be called when Sampler makes a
 | 
			
		||||
// decision.
 | 
			
		||||
//
 | 
			
		||||
// This hook may be used to get visibility into the performance of the sampler.
 | 
			
		||||
// For example, use it to track metrics of dropped versus sampled logs.
 | 
			
		||||
//
 | 
			
		||||
//  var dropped atomic.Int64
 | 
			
		||||
//  zapcore.SamplerHook(func(ent zapcore.Entry, dec zapcore.SamplingDecision) {
 | 
			
		||||
//    if dec&zapcore.LogDropped > 0 {
 | 
			
		||||
//      dropped.Inc()
 | 
			
		||||
//    }
 | 
			
		||||
//  })
 | 
			
		||||
func SamplerHook(hook func(entry Entry, dec SamplingDecision)) SamplerOption {
 | 
			
		||||
	return optionFunc(func(s *sampler) {
 | 
			
		||||
		s.hook = hook
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSamplerWithOptions creates a Core that samples incoming entries, which
 | 
			
		||||
// caps the CPU and I/O load of logging while attempting to preserve a
 | 
			
		||||
// representative subset of your logs.
 | 
			
		||||
//
 | 
			
		||||
// Zap samples by logging the first N entries with a given level and message
 | 
			
		||||
// each tick. If more Entries with the same level and message are seen during
 | 
			
		||||
// the same interval, every Mth message is logged and the rest are dropped.
 | 
			
		||||
//
 | 
			
		||||
// Sampler can be configured to report sampling decisions with the SamplerHook
 | 
			
		||||
// option.
 | 
			
		||||
//
 | 
			
		||||
// Keep in mind that zap's sampling implementation is optimized for speed over
 | 
			
		||||
// absolute precision; under load, each tick may be slightly over- or
 | 
			
		||||
// under-sampled.
 | 
			
		||||
func NewSamplerWithOptions(core Core, tick time.Duration, first, thereafter int, opts ...SamplerOption) Core {
 | 
			
		||||
	s := &sampler{
 | 
			
		||||
		Core:       core,
 | 
			
		||||
		tick:       tick,
 | 
			
		||||
		counts:     newCounters(),
 | 
			
		||||
		first:      uint64(first),
 | 
			
		||||
		thereafter: uint64(thereafter),
 | 
			
		||||
		hook:       nopSamplingHook,
 | 
			
		||||
	}
 | 
			
		||||
	for _, opt := range opts {
 | 
			
		||||
		opt.apply(s)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type sampler struct {
 | 
			
		||||
	Core
 | 
			
		||||
 | 
			
		||||
	counts            *counters
 | 
			
		||||
	tick              time.Duration
 | 
			
		||||
	first, thereafter uint64
 | 
			
		||||
	hook              func(Entry, SamplingDecision)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSampler creates a Core that samples incoming entries, which
 | 
			
		||||
// caps the CPU and I/O load of logging while attempting to preserve a
 | 
			
		||||
// representative subset of your logs.
 | 
			
		||||
//
 | 
			
		||||
// Zap samples by logging the first N entries with a given level and message
 | 
			
		||||
// each tick. If more Entries with the same level and message are seen during
 | 
			
		||||
// the same interval, every Mth message is logged and the rest are dropped.
 | 
			
		||||
//
 | 
			
		||||
// Keep in mind that zap's sampling implementation is optimized for speed over
 | 
			
		||||
// absolute precision; under load, each tick may be slightly over- or
 | 
			
		||||
// under-sampled.
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: use NewSamplerWithOptions.
 | 
			
		||||
func NewSampler(core Core, tick time.Duration, first, thereafter int) Core {
 | 
			
		||||
	return NewSamplerWithOptions(core, tick, first, thereafter)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *sampler) With(fields []Field) Core {
 | 
			
		||||
	return &sampler{
 | 
			
		||||
		Core:       s.Core.With(fields),
 | 
			
		||||
		tick:       s.tick,
 | 
			
		||||
		counts:     s.counts,
 | 
			
		||||
		first:      s.first,
 | 
			
		||||
		thereafter: s.thereafter,
 | 
			
		||||
		hook:       s.hook,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *sampler) Check(ent Entry, ce *CheckedEntry) *CheckedEntry {
 | 
			
		||||
	if !s.Enabled(ent.Level) {
 | 
			
		||||
		return ce
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ent.Level >= _minLevel && ent.Level <= _maxLevel {
 | 
			
		||||
		counter := s.counts.get(ent.Level, ent.Message)
 | 
			
		||||
		n := counter.IncCheckReset(ent.Time, s.tick)
 | 
			
		||||
		if n > s.first && (n-s.first)%s.thereafter != 0 {
 | 
			
		||||
			s.hook(ent, LogDropped)
 | 
			
		||||
			return ce
 | 
			
		||||
		}
 | 
			
		||||
		s.hook(ent, LogSampled)
 | 
			
		||||
	}
 | 
			
		||||
	return s.Core.Check(ent, ce)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										81
									
								
								vendor/go.uber.org/zap/zapcore/tee.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								vendor/go.uber.org/zap/zapcore/tee.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import "go.uber.org/multierr"
 | 
			
		||||
 | 
			
		||||
type multiCore []Core
 | 
			
		||||
 | 
			
		||||
// NewTee creates a Core that duplicates log entries into two or more
 | 
			
		||||
// underlying Cores.
 | 
			
		||||
//
 | 
			
		||||
// Calling it with a single Core returns the input unchanged, and calling
 | 
			
		||||
// it with no input returns a no-op Core.
 | 
			
		||||
func NewTee(cores ...Core) Core {
 | 
			
		||||
	switch len(cores) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		return NewNopCore()
 | 
			
		||||
	case 1:
 | 
			
		||||
		return cores[0]
 | 
			
		||||
	default:
 | 
			
		||||
		return multiCore(cores)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (mc multiCore) With(fields []Field) Core {
 | 
			
		||||
	clone := make(multiCore, len(mc))
 | 
			
		||||
	for i := range mc {
 | 
			
		||||
		clone[i] = mc[i].With(fields)
 | 
			
		||||
	}
 | 
			
		||||
	return clone
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (mc multiCore) Enabled(lvl Level) bool {
 | 
			
		||||
	for i := range mc {
 | 
			
		||||
		if mc[i].Enabled(lvl) {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (mc multiCore) Check(ent Entry, ce *CheckedEntry) *CheckedEntry {
 | 
			
		||||
	for i := range mc {
 | 
			
		||||
		ce = mc[i].Check(ent, ce)
 | 
			
		||||
	}
 | 
			
		||||
	return ce
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (mc multiCore) Write(ent Entry, fields []Field) error {
 | 
			
		||||
	var err error
 | 
			
		||||
	for i := range mc {
 | 
			
		||||
		err = multierr.Append(err, mc[i].Write(ent, fields))
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (mc multiCore) Sync() error {
 | 
			
		||||
	var err error
 | 
			
		||||
	for i := range mc {
 | 
			
		||||
		err = multierr.Append(err, mc[i].Sync())
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										122
									
								
								vendor/go.uber.org/zap/zapcore/write_syncer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								vendor/go.uber.org/zap/zapcore/write_syncer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,122 @@
 | 
			
		||||
// 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 zapcore
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.uber.org/multierr"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A WriteSyncer is an io.Writer that can also flush any buffered data. Note
 | 
			
		||||
// that *os.File (and thus, os.Stderr and os.Stdout) implement WriteSyncer.
 | 
			
		||||
type WriteSyncer interface {
 | 
			
		||||
	io.Writer
 | 
			
		||||
	Sync() error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddSync converts an io.Writer to a WriteSyncer. It attempts to be
 | 
			
		||||
// intelligent: if the concrete type of the io.Writer implements WriteSyncer,
 | 
			
		||||
// we'll use the existing Sync method. If it doesn't, we'll add a no-op Sync.
 | 
			
		||||
func AddSync(w io.Writer) WriteSyncer {
 | 
			
		||||
	switch w := w.(type) {
 | 
			
		||||
	case WriteSyncer:
 | 
			
		||||
		return w
 | 
			
		||||
	default:
 | 
			
		||||
		return writerWrapper{w}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type lockedWriteSyncer struct {
 | 
			
		||||
	sync.Mutex
 | 
			
		||||
	ws WriteSyncer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Lock wraps a WriteSyncer in a mutex to make it safe for concurrent use. In
 | 
			
		||||
// particular, *os.Files must be locked before use.
 | 
			
		||||
func Lock(ws WriteSyncer) WriteSyncer {
 | 
			
		||||
	if _, ok := ws.(*lockedWriteSyncer); ok {
 | 
			
		||||
		// no need to layer on another lock
 | 
			
		||||
		return ws
 | 
			
		||||
	}
 | 
			
		||||
	return &lockedWriteSyncer{ws: ws}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *lockedWriteSyncer) Write(bs []byte) (int, error) {
 | 
			
		||||
	s.Lock()
 | 
			
		||||
	n, err := s.ws.Write(bs)
 | 
			
		||||
	s.Unlock()
 | 
			
		||||
	return n, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *lockedWriteSyncer) Sync() error {
 | 
			
		||||
	s.Lock()
 | 
			
		||||
	err := s.ws.Sync()
 | 
			
		||||
	s.Unlock()
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type writerWrapper struct {
 | 
			
		||||
	io.Writer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (w writerWrapper) Sync() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type multiWriteSyncer []WriteSyncer
 | 
			
		||||
 | 
			
		||||
// NewMultiWriteSyncer creates a WriteSyncer that duplicates its writes
 | 
			
		||||
// and sync calls, much like io.MultiWriter.
 | 
			
		||||
func NewMultiWriteSyncer(ws ...WriteSyncer) WriteSyncer {
 | 
			
		||||
	if len(ws) == 1 {
 | 
			
		||||
		return ws[0]
 | 
			
		||||
	}
 | 
			
		||||
	return multiWriteSyncer(ws)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// See https://golang.org/src/io/multi.go
 | 
			
		||||
// When not all underlying syncers write the same number of bytes,
 | 
			
		||||
// the smallest number is returned even though Write() is called on
 | 
			
		||||
// all of them.
 | 
			
		||||
func (ws multiWriteSyncer) Write(p []byte) (int, error) {
 | 
			
		||||
	var writeErr error
 | 
			
		||||
	nWritten := 0
 | 
			
		||||
	for _, w := range ws {
 | 
			
		||||
		n, err := w.Write(p)
 | 
			
		||||
		writeErr = multierr.Append(writeErr, err)
 | 
			
		||||
		if nWritten == 0 && n != 0 {
 | 
			
		||||
			nWritten = n
 | 
			
		||||
		} else if n < nWritten {
 | 
			
		||||
			nWritten = n
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nWritten, writeErr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ws multiWriteSyncer) Sync() error {
 | 
			
		||||
	var err error
 | 
			
		||||
	for _, w := range ws {
 | 
			
		||||
		err = multierr.Append(err, w.Sync())
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
// Copyright 2020 The Go Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// Package unsafeheader contains header declarations for the Go runtime's
 | 
			
		||||
// slice and string implementations.
 | 
			
		||||
//
 | 
			
		||||
// This package allows x/sys to use types equivalent to
 | 
			
		||||
// reflect.SliceHeader and reflect.StringHeader without introducing
 | 
			
		||||
// a dependency on the (relatively heavy) "reflect" package.
 | 
			
		||||
package unsafeheader
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Slice is the runtime representation of a slice.
 | 
			
		||||
// It cannot be used safely or portably and its representation may change in a later release.
 | 
			
		||||
type Slice struct {
 | 
			
		||||
	Data unsafe.Pointer
 | 
			
		||||
	Len  int
 | 
			
		||||
	Cap  int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String is the runtime representation of a string.
 | 
			
		||||
// It cannot be used safely or portably and its representation may change in a later release.
 | 
			
		||||
type String struct {
 | 
			
		||||
	Data unsafe.Pointer
 | 
			
		||||
	Len  int
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								vendor/golang.org/x/sys/unix/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/golang.org/x/sys/unix/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -89,7 +89,7 @@ constants.
 | 
			
		||||
 | 
			
		||||
Adding new syscall numbers is mostly done by running the build on a sufficiently
 | 
			
		||||
new installation of the target OS (or updating the source checkouts for the
 | 
			
		||||
new build system). However, depending on the OS, you make need to update the
 | 
			
		||||
new build system). However, depending on the OS, you may need to update the
 | 
			
		||||
parsing in mksysnum.
 | 
			
		||||
 | 
			
		||||
### mksyscall.go
 | 
			
		||||
@@ -163,7 +163,7 @@ The merge is performed in the following steps:
 | 
			
		||||
 | 
			
		||||
## Generated files
 | 
			
		||||
 | 
			
		||||
### `zerror_${GOOS}_${GOARCH}.go`
 | 
			
		||||
### `zerrors_${GOOS}_${GOARCH}.go`
 | 
			
		||||
 | 
			
		||||
A file containing all of the system's generated error numbers, error strings,
 | 
			
		||||
signal numbers, and constants. Generated by `mkerrors.sh` (see above).
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/golang.org/x/sys/unix/aliases.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/golang.org/x/sys/unix/aliases.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -2,7 +2,8 @@
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 | 
			
		||||
//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9
 | 
			
		||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
 | 
			
		||||
// +build go1.9
 | 
			
		||||
 | 
			
		||||
package unix
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -2,7 +2,8 @@
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build !gccgo
 | 
			
		||||
//go:build gc
 | 
			
		||||
// +build gc
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
// Copyright 2009 The Go Authors. All rights reserved.
 | 
			
		||||
// Copyright 2021 The Go Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build !gccgo
 | 
			
		||||
//go:build (darwin || freebsd || netbsd || openbsd) && gc
 | 
			
		||||
// +build darwin freebsd netbsd openbsd
 | 
			
		||||
// +build gc
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// System call support for 386, Darwin
 | 
			
		||||
//
 | 
			
		||||
// System call support for 386 BSD
 | 
			
		||||
 | 
			
		||||
// Just jump to package syscall's implementation for all these functions.
 | 
			
		||||
// The runtime may know about them.
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
// Copyright 2009 The Go Authors. All rights reserved.
 | 
			
		||||
// Copyright 2021 The Go Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build !gccgo
 | 
			
		||||
//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && gc
 | 
			
		||||
// +build darwin dragonfly freebsd netbsd openbsd
 | 
			
		||||
// +build gc
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// System call support for AMD64, Darwin
 | 
			
		||||
//
 | 
			
		||||
// System call support for AMD64 BSD
 | 
			
		||||
 | 
			
		||||
// Just jump to package syscall's implementation for all these functions.
 | 
			
		||||
// The runtime may know about them.
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user