planetscale 0.1.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.buildkite/pipeline.yml +21 -0
  3. data/.github/workflows/ci.yml +5 -6
  4. data/.github/workflows/gem-push.yml +4 -3
  5. data/.licenses/go/github.com/planetscale/planetscale-go/planetscale.dep.yml +56 -3
  6. data/.licenses/go/github.com/planetscale/sql-proxy/proxy.dep.yml +205 -172
  7. data/.licenses/go/go.uber.org/zap.dep.yml +1 -1
  8. data/.licenses/go/go.uber.org/zap/buffer.dep.yml +1 -1
  9. data/.licenses/go/go.uber.org/zap/internal/bufferpool.dep.yml +1 -1
  10. data/.licenses/go/go.uber.org/zap/internal/color.dep.yml +1 -1
  11. data/.licenses/go/go.uber.org/zap/internal/exit.dep.yml +1 -1
  12. data/.licenses/go/go.uber.org/zap/zapcore.dep.yml +1 -1
  13. data/README.md +9 -8
  14. data/controller.go +23 -10
  15. data/go.mod +3 -3
  16. data/go.sum +24 -23
  17. data/lib/generators/planetscale/install_generator.rb +8 -6
  18. data/lib/planetscale.rb +12 -12
  19. data/lib/planetscale/version.rb +1 -1
  20. data/planetscale.gemspec +1 -1
  21. data/proxy/planetscale-darwin.h +95 -0
  22. data/proxy/planetscale-darwin.so +0 -0
  23. data/proxy/planetscale-linux.h +95 -0
  24. data/proxy/planetscale-linux.so +0 -0
  25. data/vendor/github.com/planetscale/planetscale-go/LICENSE +202 -0
  26. data/vendor/github.com/planetscale/planetscale-go/planetscale/audit_logs.go +136 -0
  27. data/vendor/github.com/planetscale/planetscale-go/planetscale/branches.go +6 -12
  28. data/vendor/github.com/planetscale/planetscale-go/planetscale/certs.go +40 -16
  29. data/vendor/github.com/planetscale/planetscale-go/planetscale/client.go +13 -6
  30. data/vendor/github.com/planetscale/planetscale-go/planetscale/databases.go +2 -0
  31. data/vendor/github.com/planetscale/planetscale-go/planetscale/organizations.go +25 -0
  32. data/vendor/github.com/planetscale/planetscale-go/planetscale/regions.go +52 -0
  33. data/vendor/github.com/planetscale/planetscale-go/planetscale/service_tokens.go +1 -1
  34. data/vendor/github.com/planetscale/sql-proxy/LICENSE +202 -0
  35. data/vendor/github.com/planetscale/sql-proxy/proxy/client.go +17 -8
  36. data/vendor/go.uber.org/zap/CHANGELOG.md +60 -0
  37. data/vendor/go.uber.org/zap/CONTRIBUTING.md +0 -6
  38. data/vendor/go.uber.org/zap/FAQ.md +8 -0
  39. data/vendor/go.uber.org/zap/Makefile +13 -3
  40. data/vendor/go.uber.org/zap/README.md +4 -4
  41. data/vendor/go.uber.org/zap/buffer/buffer.go +18 -0
  42. data/vendor/go.uber.org/zap/field.go +10 -0
  43. data/vendor/go.uber.org/zap/go.mod +7 -6
  44. data/vendor/go.uber.org/zap/go.sum +25 -27
  45. data/vendor/go.uber.org/zap/http_handler.go +75 -24
  46. data/vendor/go.uber.org/zap/logger.go +11 -7
  47. data/vendor/go.uber.org/zap/options.go +8 -0
  48. data/vendor/go.uber.org/zap/sugar.go +21 -10
  49. data/vendor/go.uber.org/zap/zapcore/buffered_write_syncer.go +188 -0
  50. data/vendor/go.uber.org/zap/zapcore/clock.go +50 -0
  51. data/vendor/go.uber.org/zap/zapcore/console_encoder.go +1 -1
  52. data/vendor/go.uber.org/zap/zapcore/entry.go +2 -2
  53. data/vendor/go.uber.org/zap/zapcore/error.go +18 -1
  54. data/vendor/go.uber.org/zap/zapcore/field.go +7 -1
  55. data/vendor/go.uber.org/zap/zapcore/write_syncer.go +1 -2
  56. data/vendor/modules.txt +3 -3
  57. metadata +20 -10
  58. 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
- CACert *x509.Certificate
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
- rootCertPool.AddCert(cert.CACert)
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
@@ -25,12 +25,6 @@ git remote add upstream https://github.com/uber-go/zap.git
25
25
  git fetch upstream
26
26
  ```
27
27
 
28
- Install zap's dependencies:
29
-
30
- ```
31
- make dependencies
32
- ```
33
-
34
28
  Make sure that the tests and the linters pass:
35
29
 
36
30
  ```
@@ -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://godoc.org/go.uber.org/zap?status.svg
127
- [doc]: https://godoc.org/go.uber.org/zap
128
- [ci-img]: https://travis-ci.com/uber-go/zap.svg?branch=master
129
- [ci]: https://travis-ci.com/uber-go/zap
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.4.0
8
- go.uber.org/atomic v1.6.0
9
- go.uber.org/multierr v1.5.0
10
- golang.org/x/lint v0.0.0-20190930215403-16217165b5de
11
- gopkg.in/yaml.v2 v2.2.2
12
- honnef.co/go/tools v0.0.1-2019.2.3
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/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
2
- github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
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/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
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
- go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
24
- go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
25
- go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
26
- go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
27
- go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
28
- go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
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/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
43
- golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c h1:IGkKhmfzcztjm6gYkykvu/NiS8kaqbCWAEWWAyf8J5U=
44
- golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
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
- honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
56
- honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
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 requests return a JSON description of the current logging level. PUT
35
- // requests change the logging level and expect a payload like:
35
+ // GET
36
+ //
37
+ // The GET request returns a JSON description of the current logging level like:
36
38
  // {"level":"info"}
37
39
  //
38
- // It's perfectly safe to change the logging level while a program is running.
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 *zapcore.Level `json:"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
- current := lvl.Level()
53
- enc.Encode(payload{Level: &current})
54
-
82
+ enc.Encode(payload{Level: lvl.Level()})
55
83
  case http.MethodPut:
56
- var req payload
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: errmess})
87
+ enc.Encode(errorResponse{Error: err.Error()})
69
88
  return
70
89
  }
71
-
72
- lvl.SetLevel(*req.Level)
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
+ }