planetscale 0.1.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.buildkite/pipeline.yml +21 -0
- data/.github/workflows/ci.yml +5 -6
- data/.github/workflows/gem-push.yml +4 -3
- data/.licenses/go/github.com/planetscale/planetscale-go/planetscale.dep.yml +56 -3
- data/.licenses/go/github.com/planetscale/sql-proxy/proxy.dep.yml +205 -172
- data/.licenses/go/go.uber.org/zap.dep.yml +1 -1
- data/.licenses/go/go.uber.org/zap/buffer.dep.yml +1 -1
- data/.licenses/go/go.uber.org/zap/internal/bufferpool.dep.yml +1 -1
- data/.licenses/go/go.uber.org/zap/internal/color.dep.yml +1 -1
- data/.licenses/go/go.uber.org/zap/internal/exit.dep.yml +1 -1
- data/.licenses/go/go.uber.org/zap/zapcore.dep.yml +1 -1
- data/README.md +9 -8
- data/controller.go +23 -10
- data/go.mod +3 -3
- data/go.sum +24 -23
- data/lib/generators/planetscale/install_generator.rb +8 -6
- data/lib/planetscale.rb +12 -12
- data/lib/planetscale/version.rb +1 -1
- data/planetscale.gemspec +1 -1
- data/proxy/planetscale-darwin.h +95 -0
- data/proxy/planetscale-darwin.so +0 -0
- data/proxy/planetscale-linux.h +95 -0
- data/proxy/planetscale-linux.so +0 -0
- data/vendor/github.com/planetscale/planetscale-go/LICENSE +202 -0
- data/vendor/github.com/planetscale/planetscale-go/planetscale/audit_logs.go +136 -0
- data/vendor/github.com/planetscale/planetscale-go/planetscale/branches.go +6 -12
- data/vendor/github.com/planetscale/planetscale-go/planetscale/certs.go +40 -16
- data/vendor/github.com/planetscale/planetscale-go/planetscale/client.go +13 -6
- data/vendor/github.com/planetscale/planetscale-go/planetscale/databases.go +2 -0
- data/vendor/github.com/planetscale/planetscale-go/planetscale/organizations.go +25 -0
- data/vendor/github.com/planetscale/planetscale-go/planetscale/regions.go +52 -0
- data/vendor/github.com/planetscale/planetscale-go/planetscale/service_tokens.go +1 -1
- data/vendor/github.com/planetscale/sql-proxy/LICENSE +202 -0
- data/vendor/github.com/planetscale/sql-proxy/proxy/client.go +17 -8
- data/vendor/go.uber.org/zap/CHANGELOG.md +60 -0
- data/vendor/go.uber.org/zap/CONTRIBUTING.md +0 -6
- data/vendor/go.uber.org/zap/FAQ.md +8 -0
- data/vendor/go.uber.org/zap/Makefile +13 -3
- data/vendor/go.uber.org/zap/README.md +4 -4
- data/vendor/go.uber.org/zap/buffer/buffer.go +18 -0
- data/vendor/go.uber.org/zap/field.go +10 -0
- data/vendor/go.uber.org/zap/go.mod +7 -6
- data/vendor/go.uber.org/zap/go.sum +25 -27
- data/vendor/go.uber.org/zap/http_handler.go +75 -24
- data/vendor/go.uber.org/zap/logger.go +11 -7
- data/vendor/go.uber.org/zap/options.go +8 -0
- data/vendor/go.uber.org/zap/sugar.go +21 -10
- data/vendor/go.uber.org/zap/zapcore/buffered_write_syncer.go +188 -0
- data/vendor/go.uber.org/zap/zapcore/clock.go +50 -0
- data/vendor/go.uber.org/zap/zapcore/console_encoder.go +1 -1
- data/vendor/go.uber.org/zap/zapcore/entry.go +2 -2
- data/vendor/go.uber.org/zap/zapcore/error.go +18 -1
- data/vendor/go.uber.org/zap/zapcore/field.go +7 -1
- data/vendor/go.uber.org/zap/zapcore/write_syncer.go +1 -2
- data/vendor/modules.txt +3 -3
- metadata +20 -10
- data/vendor/go.uber.org/zap/.travis.yml +0 -23
@@ -20,12 +20,17 @@ const (
|
|
20
20
|
keepAlivePeriod = time.Minute
|
21
21
|
)
|
22
22
|
|
23
|
+
// CertError represents a Cert operation error.
|
24
|
+
type CertError struct{ msg string }
|
25
|
+
|
26
|
+
func (c *CertError) Error() string { return c.msg }
|
27
|
+
|
23
28
|
// Cert represents the client certificate key pair in the root certiciate
|
24
29
|
// authority that the client uses to verify server certificates.
|
25
30
|
|
26
31
|
type Cert struct {
|
27
32
|
ClientCert tls.Certificate
|
28
|
-
|
33
|
+
CACerts []*x509.Certificate
|
29
34
|
RemoteAddr string
|
30
35
|
Ports RemotePorts
|
31
36
|
}
|
@@ -119,12 +124,6 @@ func NewClient(opts Options) (*Client, error) {
|
|
119
124
|
c.log = logger
|
120
125
|
}
|
121
126
|
|
122
|
-
// cache the certs for the given instance(s)
|
123
|
-
_, _, err := c.clientCerts(context.Background(), opts.Instance)
|
124
|
-
if err != nil {
|
125
|
-
c.log.Error("couldn't retrieve TLS certificate for the client", zap.Error(err))
|
126
|
-
}
|
127
|
-
|
128
127
|
return c, nil
|
129
128
|
}
|
130
129
|
|
@@ -137,6 +136,13 @@ type Conn struct {
|
|
137
136
|
// Run runs the proxy. It listens to the configured localhost address and
|
138
137
|
// proxies the connection over a TLS tunnel to the remote DB instance.
|
139
138
|
func (c *Client) Run(ctx context.Context) error {
|
139
|
+
// cache the certs for the given instance. This will also validate the
|
140
|
+
// input and ensure to exit early.
|
141
|
+
_, _, err := c.clientCerts(context.Background(), c.instance)
|
142
|
+
if err != nil {
|
143
|
+
return &CertError{msg: err.Error()}
|
144
|
+
}
|
145
|
+
|
140
146
|
c.log.Info("ready for new connections")
|
141
147
|
l, err := c.getListener()
|
142
148
|
if err != nil {
|
@@ -335,7 +341,9 @@ func (c *Client) clientCerts(ctx context.Context, instance string) (*tls.Config,
|
|
335
341
|
}
|
336
342
|
|
337
343
|
rootCertPool := x509.NewCertPool()
|
338
|
-
|
344
|
+
for _, caCert := range cert.CACerts {
|
345
|
+
rootCertPool.AddCert(caCert)
|
346
|
+
}
|
339
347
|
|
340
348
|
serverName := fmt.Sprintf("%s.%s.%s.%s", s[2], s[1], s[0], cert.RemoteAddr)
|
341
349
|
fullAddr := fmt.Sprintf("%s:%d", serverName, cert.Ports.Proxy)
|
@@ -343,6 +351,7 @@ func (c *Client) clientCerts(ctx context.Context, instance string) (*tls.Config,
|
|
343
351
|
cfg := &tls.Config{
|
344
352
|
ServerName: serverName,
|
345
353
|
Certificates: []tls.Certificate{cert.ClientCert},
|
354
|
+
MinVersion: tls.VersionTLS12,
|
346
355
|
RootCAs: rootCertPool,
|
347
356
|
// Set InsecureSkipVerify to skip the default validation we are
|
348
357
|
// replacing. This will not disable VerifyConnection.
|
@@ -1,5 +1,56 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.18.1 (28 Jun 2021)
|
4
|
+
|
5
|
+
Bugfixes:
|
6
|
+
* [#974][]: Fix nil dereference in logger constructed by `zap.NewNop`.
|
7
|
+
|
8
|
+
[#974]: https://github.com/uber-go/zap/pull/974
|
9
|
+
|
10
|
+
## 1.18.0 (28 Jun 2021)
|
11
|
+
|
12
|
+
Enhancements:
|
13
|
+
* [#961][]: Add `zapcore.BufferedWriteSyncer`, a new `WriteSyncer` that buffers
|
14
|
+
messages in-memory and flushes them periodically.
|
15
|
+
* [#971][]: Add `zapio.Writer` to use a Zap logger as an `io.Writer`.
|
16
|
+
* [#897][]: Add `zap.WithClock` option to control the source of time via the
|
17
|
+
new `zapcore.Clock` interface.
|
18
|
+
* [#949][]: Avoid panicking in `zap.SugaredLogger` when arguments of `*w`
|
19
|
+
methods don't match expectations.
|
20
|
+
* [#943][]: Add support for filtering by level or arbitrary matcher function to
|
21
|
+
`zaptest/observer`.
|
22
|
+
* [#691][]: Comply with `io.StringWriter` and `io.ByteWriter` in Zap's
|
23
|
+
`buffer.Buffer`.
|
24
|
+
|
25
|
+
Thanks to @atrn0, @ernado, @heyanfu, @hnlq715, @zchee
|
26
|
+
for their contributions to this release.
|
27
|
+
|
28
|
+
[#691]: https://github.com/uber-go/zap/pull/691
|
29
|
+
[#897]: https://github.com/uber-go/zap/pull/897
|
30
|
+
[#943]: https://github.com/uber-go/zap/pull/943
|
31
|
+
[#949]: https://github.com/uber-go/zap/pull/949
|
32
|
+
[#961]: https://github.com/uber-go/zap/pull/961
|
33
|
+
[#971]: https://github.com/uber-go/zap/pull/971
|
34
|
+
|
35
|
+
## 1.17.0 (25 May 2021)
|
36
|
+
|
37
|
+
Bugfixes:
|
38
|
+
* [#867][]: Encode `<nil>` for nil `error` instead of a panic.
|
39
|
+
* [#931][], [#936][]: Update minimum version constraints to address
|
40
|
+
vulnerabilities in dependencies.
|
41
|
+
|
42
|
+
Enhancements:
|
43
|
+
* [#865][]: Improve alignment of fields of the Logger struct, reducing its
|
44
|
+
size from 96 to 80 bytes.
|
45
|
+
* [#881][]: Support `grpclog.LoggerV2` in zapgrpc.
|
46
|
+
* [#903][]: Support URL-encoded POST requests to the AtomicLevel HTTP handler
|
47
|
+
with the `application/x-www-form-urlencoded` content type.
|
48
|
+
* [#912][]: Support multi-field encoding with `zap.Inline`.
|
49
|
+
* [#913][]: Speed up SugaredLogger for calls with a single string.
|
50
|
+
* [#928][]: Add support for filtering by field name to `zaptest/observer`.
|
51
|
+
|
52
|
+
Thanks to @ash2k, @FMLS, @jimmystewpot, @Oncilla, @tsoslow, @tylitianrui, @withshubh, and @wziww for their contributions to this release.
|
53
|
+
|
3
54
|
## 1.16.0 (1 Sep 2020)
|
4
55
|
|
5
56
|
Bugfixes:
|
@@ -430,3 +481,12 @@ upgrade to the upcoming stable release.
|
|
430
481
|
[#854]: https://github.com/uber-go/zap/pull/854
|
431
482
|
[#861]: https://github.com/uber-go/zap/pull/861
|
432
483
|
[#862]: https://github.com/uber-go/zap/pull/862
|
484
|
+
[#865]: https://github.com/uber-go/zap/pull/865
|
485
|
+
[#867]: https://github.com/uber-go/zap/pull/867
|
486
|
+
[#881]: https://github.com/uber-go/zap/pull/881
|
487
|
+
[#903]: https://github.com/uber-go/zap/pull/903
|
488
|
+
[#912]: https://github.com/uber-go/zap/pull/912
|
489
|
+
[#913]: https://github.com/uber-go/zap/pull/913
|
490
|
+
[#928]: https://github.com/uber-go/zap/pull/928
|
491
|
+
[#931]: https://github.com/uber-go/zap/pull/931
|
492
|
+
[#936]: https://github.com/uber-go/zap/pull/936
|
@@ -27,6 +27,13 @@ abstraction, and it lets us add methods without introducing breaking changes.
|
|
27
27
|
Your applications should define and depend upon an interface that includes
|
28
28
|
just the methods you use.
|
29
29
|
|
30
|
+
### Why are some of my logs missing?
|
31
|
+
|
32
|
+
Logs are dropped intentionally by zap when sampling is enabled. The production
|
33
|
+
configuration (as returned by `NewProductionConfig()` enables sampling which will
|
34
|
+
cause repeated logs within a second to be sampled. See more details on why sampling
|
35
|
+
is enabled in [Why sample application logs](https://github.com/uber-go/zap/blob/master/FAQ.md#why-sample-application-logs).
|
36
|
+
|
30
37
|
### Why sample application logs?
|
31
38
|
|
32
39
|
Applications often experience runs of errors, either because of a bug or
|
@@ -150,6 +157,7 @@ We're aware of the following extensions, but haven't used them ourselves:
|
|
150
157
|
| `github.com/fgrosse/zaptest` | Ginkgo |
|
151
158
|
| `github.com/blendle/zapdriver` | Stackdriver |
|
152
159
|
| `github.com/moul/zapgorm` | Gorm |
|
160
|
+
| `github.com/moul/zapfilter` | Advanced filtering rules |
|
153
161
|
|
154
162
|
[go-proverbs]: https://go-proverbs.github.io/
|
155
163
|
[import-path]: https://golang.org/cmd/go/#hdr-Remote_import_paths
|
@@ -7,7 +7,7 @@ BENCH_FLAGS ?= -cpuprofile=cpu.pprof -memprofile=mem.pprof -benchmem
|
|
7
7
|
# Directories containing independent Go modules.
|
8
8
|
#
|
9
9
|
# We track coverage only for the main module.
|
10
|
-
MODULE_DIRS = . ./benchmarks
|
10
|
+
MODULE_DIRS = . ./benchmarks ./zapgrpc/internal/test
|
11
11
|
|
12
12
|
# Many Go tools take file globs or directories as arguments instead of packages.
|
13
13
|
GO_FILES := $(shell \
|
@@ -33,12 +33,18 @@ lint: $(GOLINT) $(STATICCHECK)
|
|
33
33
|
@echo "Checking for license headers..."
|
34
34
|
@./checklicense.sh | tee -a lint.log
|
35
35
|
@[ ! -s lint.log ]
|
36
|
+
@echo "Checking 'go mod tidy'..."
|
37
|
+
@make tidy
|
38
|
+
@if ! git diff --quiet; then \
|
39
|
+
echo "'go mod tidy' resulted in changes or working tree is dirty:"; \
|
40
|
+
git --no-pager diff; \
|
41
|
+
fi
|
36
42
|
|
37
43
|
$(GOLINT):
|
38
|
-
go install golang.org/x/lint/golint
|
44
|
+
cd tools && go install golang.org/x/lint/golint
|
39
45
|
|
40
46
|
$(STATICCHECK):
|
41
|
-
go install honnef.co/go/tools/cmd/staticcheck
|
47
|
+
cd tools && go install honnef.co/go/tools/cmd/staticcheck
|
42
48
|
|
43
49
|
.PHONY: test
|
44
50
|
test:
|
@@ -61,3 +67,7 @@ bench:
|
|
61
67
|
updatereadme:
|
62
68
|
rm -f README.md
|
63
69
|
cat .readme.tmpl | go run internal/readme/readme.go > README.md
|
70
|
+
|
71
|
+
.PHONY: tidy
|
72
|
+
tidy:
|
73
|
+
@$(foreach dir,$(MODULE_DIRS),(cd $(dir) && go mod tidy) &&) true
|
@@ -123,10 +123,10 @@ Released under the [MIT License](LICENSE.txt).
|
|
123
123
|
benchmarking against slightly older versions of other packages. Versions are
|
124
124
|
pinned in the [benchmarks/go.mod][] file. [↩](#anchor-versions)
|
125
125
|
|
126
|
-
[doc-img]: https://
|
127
|
-
[doc]: https://
|
128
|
-
[ci-img]: https://
|
129
|
-
[ci]: https://
|
126
|
+
[doc-img]: https://pkg.go.dev/badge/go.uber.org/zap
|
127
|
+
[doc]: https://pkg.go.dev/go.uber.org/zap
|
128
|
+
[ci-img]: https://github.com/uber-go/zap/actions/workflows/go.yml/badge.svg
|
129
|
+
[ci]: https://github.com/uber-go/zap/actions/workflows/go.yml
|
130
130
|
[cov-img]: https://codecov.io/gh/uber-go/zap/branch/master/graph/badge.svg
|
131
131
|
[cov]: https://codecov.io/gh/uber-go/zap
|
132
132
|
[benchmarking suite]: https://github.com/uber-go/zap/tree/master/benchmarks
|
@@ -106,6 +106,24 @@ func (b *Buffer) Write(bs []byte) (int, error) {
|
|
106
106
|
return len(bs), nil
|
107
107
|
}
|
108
108
|
|
109
|
+
// WriteByte writes a single byte to the Buffer.
|
110
|
+
//
|
111
|
+
// Error returned is always nil, function signature is compatible
|
112
|
+
// with bytes.Buffer and bufio.Writer
|
113
|
+
func (b *Buffer) WriteByte(v byte) error {
|
114
|
+
b.AppendByte(v)
|
115
|
+
return nil
|
116
|
+
}
|
117
|
+
|
118
|
+
// WriteString writes a string to the Buffer.
|
119
|
+
//
|
120
|
+
// Error returned is always nil, function signature is compatible
|
121
|
+
// with bytes.Buffer and bufio.Writer
|
122
|
+
func (b *Buffer) WriteString(s string) (int, error) {
|
123
|
+
b.AppendString(s)
|
124
|
+
return len(s), nil
|
125
|
+
}
|
126
|
+
|
109
127
|
// TrimNewline trims any final "\n" byte from the end of the buffer.
|
110
128
|
func (b *Buffer) TrimNewline() {
|
111
129
|
if i := len(b.bs) - 1; i >= 0 {
|
@@ -400,6 +400,16 @@ func Object(key string, val zapcore.ObjectMarshaler) Field {
|
|
400
400
|
return Field{Key: key, Type: zapcore.ObjectMarshalerType, Interface: val}
|
401
401
|
}
|
402
402
|
|
403
|
+
// Inline constructs a Field that is similar to Object, but it
|
404
|
+
// will add the elements of the provided ObjectMarshaler to the
|
405
|
+
// current namespace.
|
406
|
+
func Inline(val zapcore.ObjectMarshaler) Field {
|
407
|
+
return zapcore.Field{
|
408
|
+
Type: zapcore.InlineMarshalerType,
|
409
|
+
Interface: val,
|
410
|
+
}
|
411
|
+
}
|
412
|
+
|
403
413
|
// Any takes a key and an arbitrary value and chooses the best way to represent
|
404
414
|
// them as a field, falling back to a reflection-based approach only if
|
405
415
|
// necessary.
|
@@ -3,11 +3,12 @@ module go.uber.org/zap
|
|
3
3
|
go 1.13
|
4
4
|
|
5
5
|
require (
|
6
|
+
github.com/benbjohnson/clock v1.1.0
|
6
7
|
github.com/pkg/errors v0.8.1
|
7
|
-
github.com/stretchr/testify v1.
|
8
|
-
go.uber.org/atomic v1.
|
9
|
-
go.uber.org/
|
10
|
-
|
11
|
-
gopkg.in/yaml.v2 v2.2.
|
12
|
-
|
8
|
+
github.com/stretchr/testify v1.7.0
|
9
|
+
go.uber.org/atomic v1.7.0
|
10
|
+
go.uber.org/goleak v1.1.10
|
11
|
+
go.uber.org/multierr v1.6.0
|
12
|
+
gopkg.in/yaml.v2 v2.2.8
|
13
|
+
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
13
14
|
)
|
@@ -1,13 +1,11 @@
|
|
1
|
-
github.com/
|
2
|
-
github.com/
|
3
|
-
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
1
|
+
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
2
|
+
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
4
3
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
5
4
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
6
5
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
7
|
-
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
8
|
-
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
9
6
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
10
7
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
8
|
+
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
|
11
9
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
12
10
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
13
11
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
@@ -15,42 +13,42 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
|
15
13
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
16
14
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
17
15
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
18
|
-
github.com/
|
16
|
+
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
19
17
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
20
18
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
21
|
-
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
22
19
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
23
|
-
|
24
|
-
|
25
|
-
go.uber.org/
|
26
|
-
go.uber.org/
|
27
|
-
go.uber.org/
|
28
|
-
go.uber.org/
|
20
|
+
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
21
|
+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
22
|
+
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
23
|
+
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
24
|
+
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
|
25
|
+
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
26
|
+
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
27
|
+
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
28
|
+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
29
29
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
30
|
-
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
31
30
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
32
31
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
33
|
-
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
34
32
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
35
|
-
golang.org/x/net v0.0.0-
|
33
|
+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
36
34
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
35
|
+
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
37
36
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
37
|
+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
38
38
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
39
|
-
golang.org/x/
|
39
|
+
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
40
40
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
41
41
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
42
|
-
golang.org/x/tools v0.0.0-
|
43
|
-
golang.org/x/tools v0.0.0-
|
44
|
-
golang.org/x/
|
45
|
-
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
|
46
|
-
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
42
|
+
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11 h1:Yq9t9jnGoR+dBuitxdo9l6Q7xh/zOyNnYUtDKaQ3x0E=
|
43
|
+
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
44
|
+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
|
47
45
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
48
|
-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
49
46
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
50
47
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
51
48
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
52
|
-
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
53
|
-
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
54
49
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
55
|
-
|
56
|
-
|
50
|
+
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
51
|
+
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
52
|
+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
53
|
+
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
54
|
+
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
@@ -23,6 +23,7 @@ package zap
|
|
23
23
|
import (
|
24
24
|
"encoding/json"
|
25
25
|
"fmt"
|
26
|
+
"io"
|
26
27
|
"net/http"
|
27
28
|
|
28
29
|
"go.uber.org/zap/zapcore"
|
@@ -31,47 +32,63 @@ import (
|
|
31
32
|
// ServeHTTP is a simple JSON endpoint that can report on or change the current
|
32
33
|
// logging level.
|
33
34
|
//
|
34
|
-
// GET
|
35
|
-
//
|
35
|
+
// GET
|
36
|
+
//
|
37
|
+
// The GET request returns a JSON description of the current logging level like:
|
36
38
|
// {"level":"info"}
|
37
39
|
//
|
38
|
-
//
|
40
|
+
// PUT
|
41
|
+
//
|
42
|
+
// The PUT request changes the logging level. It is perfectly safe to change the
|
43
|
+
// logging level while a program is running. Two content types are supported:
|
44
|
+
//
|
45
|
+
// Content-Type: application/x-www-form-urlencoded
|
46
|
+
//
|
47
|
+
// With this content type, the level can be provided through the request body or
|
48
|
+
// a query parameter. The log level is URL encoded like:
|
49
|
+
//
|
50
|
+
// level=debug
|
51
|
+
//
|
52
|
+
// The request body takes precedence over the query parameter, if both are
|
53
|
+
// specified.
|
54
|
+
//
|
55
|
+
// This content type is the default for a curl PUT request. Following are two
|
56
|
+
// example curl requests that both set the logging level to debug.
|
57
|
+
//
|
58
|
+
// curl -X PUT localhost:8080/log/level?level=debug
|
59
|
+
// curl -X PUT localhost:8080/log/level -d level=debug
|
60
|
+
//
|
61
|
+
// For any other content type, the payload is expected to be JSON encoded and
|
62
|
+
// look like:
|
63
|
+
//
|
64
|
+
// {"level":"info"}
|
65
|
+
//
|
66
|
+
// An example curl request could look like this:
|
67
|
+
//
|
68
|
+
// curl -X PUT localhost:8080/log/level -H "Content-Type: application/json" -d '{"level":"debug"}'
|
69
|
+
//
|
39
70
|
func (lvl AtomicLevel) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
40
71
|
type errorResponse struct {
|
41
72
|
Error string `json:"error"`
|
42
73
|
}
|
43
74
|
type payload struct {
|
44
|
-
Level
|
75
|
+
Level zapcore.Level `json:"level"`
|
45
76
|
}
|
46
77
|
|
47
78
|
enc := json.NewEncoder(w)
|
48
79
|
|
49
80
|
switch r.Method {
|
50
|
-
|
51
81
|
case http.MethodGet:
|
52
|
-
|
53
|
-
enc.Encode(payload{Level: ¤t})
|
54
|
-
|
82
|
+
enc.Encode(payload{Level: lvl.Level()})
|
55
83
|
case http.MethodPut:
|
56
|
-
|
57
|
-
|
58
|
-
if errmess := func() string {
|
59
|
-
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
60
|
-
return fmt.Sprintf("Request body must be well-formed JSON: %v", err)
|
61
|
-
}
|
62
|
-
if req.Level == nil {
|
63
|
-
return "Must specify a logging level."
|
64
|
-
}
|
65
|
-
return ""
|
66
|
-
}(); errmess != "" {
|
84
|
+
requestedLvl, err := decodePutRequest(r.Header.Get("Content-Type"), r)
|
85
|
+
if err != nil {
|
67
86
|
w.WriteHeader(http.StatusBadRequest)
|
68
|
-
enc.Encode(errorResponse{Error:
|
87
|
+
enc.Encode(errorResponse{Error: err.Error()})
|
69
88
|
return
|
70
89
|
}
|
71
|
-
|
72
|
-
|
73
|
-
enc.Encode(req)
|
74
|
-
|
90
|
+
lvl.SetLevel(requestedLvl)
|
91
|
+
enc.Encode(payload{Level: lvl.Level()})
|
75
92
|
default:
|
76
93
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
77
94
|
enc.Encode(errorResponse{
|
@@ -79,3 +96,37 @@ func (lvl AtomicLevel) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
79
96
|
})
|
80
97
|
}
|
81
98
|
}
|
99
|
+
|
100
|
+
// Decodes incoming PUT requests and returns the requested logging level.
|
101
|
+
func decodePutRequest(contentType string, r *http.Request) (zapcore.Level, error) {
|
102
|
+
if contentType == "application/x-www-form-urlencoded" {
|
103
|
+
return decodePutURL(r)
|
104
|
+
}
|
105
|
+
return decodePutJSON(r.Body)
|
106
|
+
}
|
107
|
+
|
108
|
+
func decodePutURL(r *http.Request) (zapcore.Level, error) {
|
109
|
+
lvl := r.FormValue("level")
|
110
|
+
if lvl == "" {
|
111
|
+
return 0, fmt.Errorf("must specify logging level")
|
112
|
+
}
|
113
|
+
var l zapcore.Level
|
114
|
+
if err := l.UnmarshalText([]byte(lvl)); err != nil {
|
115
|
+
return 0, err
|
116
|
+
}
|
117
|
+
return l, nil
|
118
|
+
}
|
119
|
+
|
120
|
+
func decodePutJSON(body io.Reader) (zapcore.Level, error) {
|
121
|
+
var pld struct {
|
122
|
+
Level *zapcore.Level `json:"level"`
|
123
|
+
}
|
124
|
+
if err := json.NewDecoder(body).Decode(&pld); err != nil {
|
125
|
+
return 0, fmt.Errorf("malformed request body: %v", err)
|
126
|
+
}
|
127
|
+
if pld.Level == nil {
|
128
|
+
return 0, fmt.Errorf("must specify logging level")
|
129
|
+
}
|
130
|
+
return *pld.Level, nil
|
131
|
+
|
132
|
+
}
|