Repository: go-kratos/kratos
Pull request #2472 (2022-10-24 18:44:35)

build(deps): bump github.com/hashicorp/consul/api from 1.14.0 to 1.15.3 in /contrib/config/consul
Bumps [github.com/hashicorp/consul/api](https://github.com/hashicorp/consul) from 1.14.0 to 1.15.3.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/hashicorp/consul/blob/main/CHANGELOG.md">github.com/hashicorp/consul/api's changelog</a>.</em></p>
<blockquote>
<h2>1.13.3 (October 19, 2022)</h2>
<p>FEATURES:</p>
<ul>
<li>agent: Added a new config option <code>rpc_client_timeout</code> to tune timeouts for client RPC requests [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14965">GH-14965</a>]</li>
<li>config-entry(ingress-gateway): Added support for <code>max_connections</code> for upstream clusters [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14749">GH-14749</a>]</li>
</ul>
<p>IMPROVEMENTS:</p>
<ul>
<li>connect/ca: Log a warning message instead of erroring when attempting to update the intermediate pki mount when using the Vault provider. [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/15035">GH-15035</a>]</li>
<li>connect: Added gateway options to Envoy proxy config for enabling tcp keepalives on terminating gateway upstreams and mesh gateways in remote datacenters. [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14800">GH-14800</a>]</li>
<li>connect: Bump Envoy 1.20 to 1.20.7, 1.21 to 1.21.5 and 1.22 to 1.22.5 [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14828">GH-14828</a>]</li>
<li>licensing: <strong>(Enterprise Only)</strong> Consul Enterprise production licenses do not degrade or terminate Consul upon expiration. They will only fail when trying to upgrade to a newer version of Consul. Evaluation licenses still terminate. [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/1990">GH-1990</a>]</li>
</ul>
<p>BUG FIXES:</p>
<ul>
<li>agent: avoid leaking the alias check runner goroutine when the check is de-registered [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14935">GH-14935</a>]</li>
<li>ca: fix a masked bug in leaf cert generation that would not be notified of root cert rotation after the first one [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/15005">GH-15005</a>]</li>
<li>cache: prevent goroutine leak in agent cache [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14908">GH-14908</a>]</li>
<li>checks: Fixed a bug that prevented registration of UDP health checks from agent configuration files, such as service definition files with embedded health check definitions. [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14885">GH-14885</a>]</li>
<li>connect: Fixed a bug where transparent proxy does not correctly spawn listeners for upstreams to service-resolvers. [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14751">GH-14751</a>]</li>
<li>snapshot-agent: <strong>(Enterprise only)</strong> Fix a bug when a session is not found in Consul, which leads the agent to panic.</li>
</ul>
<h2>1.12.6 (October 19, 2022)</h2>
<p>FEATURES:</p>
<ul>
<li>agent: Added a new config option <code>rpc_client_timeout</code> to tune timeouts for client RPC requests [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14965">GH-14965</a>]</li>
<li>agent: Added information about build date alongside other version information for Consul. Extended /agent/self endpoint and <code>consul version</code> commands
to report this. Agent also reports build date in log on startup. [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/13357">GH-13357</a>]</li>
<li>config-entry(ingress-gateway): Added support for <code>max_connections</code> for upstream clusters [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14749">GH-14749</a>]</li>
</ul>
<p>IMPROVEMENTS:</p>
<ul>
<li>connect/ca: Log a warning message instead of erroring when attempting to update the intermediate pki mount when using the Vault provider. [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/15035">GH-15035</a>]</li>
<li>connect: Added gateway options to Envoy proxy config for enabling tcp keepalives on terminating gateway upstreams and mesh gateways in remote datacenters. [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14800">GH-14800</a>]</li>
<li>connect: Bump Envoy 1.20 to 1.20.7, 1.21 to 1.21.5 and 1.22 to 1.22.5 [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14829">GH-14829</a>]</li>
<li>licensing: <strong>(Enterprise Only)</strong> Consul Enterprise production licenses do not degrade or terminate Consul upon expiration. They will only fail when trying to upgrade to a newer version of Consul. Evaluation licenses still terminate. [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/1990">GH-1990</a>]</li>
</ul>
<p>BUG FIXES:</p>
<ul>
<li>agent: avoid leaking the alias check runner goroutine when the check is de-registered [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14935">GH-14935</a>]</li>
<li>ca: fix a masked bug in leaf cert generation that would not be notified of root cert rotation after the first one [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/15005">GH-15005</a>]</li>
<li>cache: prevent goroutine leak in agent cache [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14908">GH-14908</a>]</li>
<li>connect: Fixed a bug where transparent proxy does not correctly spawn listeners for upstreams to service-resolvers. [<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14751">GH-14751</a>]</li>
<li>snapshot-agent: <strong>(Enterprise only)</strong> Fix a bug when a session is not found in Consul, which leads the agent to panic.</li>
</ul>
<h2>1.11.11 (October 19, 2022)</h2>
<p>FEATURES:</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/hashicorp/consul/commit/19a8c3734adb79a1839cfd1760e13b812bdaa49b"><code>19a8c37</code></a> Uncomment api go.mod replace.</li>
<li><a href="https://github.com/hashicorp/consul/commit/b29e5894f2322c9294b1f03c9b264ae2e6ae0eb0"><code>b29e589</code></a> Stage 1.13.3</li>
<li><a href="https://github.com/hashicorp/consul/commit/b8e43784c9cd96679e1a59443c19b169d904db14"><code>b8e4378</code></a> backport of commit a548634862b3ec7a0e6aa4b4ad4b271056351158 (<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/15058">#15058</a>)</li>
<li><a href="https://github.com/hashicorp/consul/commit/9de04ef8d7493e68db56ab06542b187b1172ef4a"><code>9de04ef</code></a> backport of commit d122108992b6facf4ad02931772c09e96ab53237 (<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/15049">#15049</a>)</li>
<li><a href="https://github.com/hashicorp/consul/commit/d4a20c272555405a7e71cab3b67e65633999a25c"><code>d4a20c2</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/15040">#15040</a> from hashicorp/backport/kisunji/NET-1092/evenly-das...</li>
<li><a href="https://github.com/hashicorp/consul/commit/8e729690629ec79db3cbf7629c00fc80252e78ff"><code>8e72969</code></a> Fix imports</li>
<li><a href="https://github.com/hashicorp/consul/commit/ddf010deaa60154d29ca7c9857eaf7fbd7e697d1"><code>ddf010d</code></a> Remove unused methods from template</li>
<li><a href="https://github.com/hashicorp/consul/commit/262760a71dcc30118f6b9c0c1c4c661259e57a57"><code>262760a</code></a> Refactor client RPC timeouts (<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/14965">#14965</a>)</li>
<li><a href="https://github.com/hashicorp/consul/commit/9206f8940ee5cf74651a4ed9eb5917051a37a353"><code>9206f89</code></a> Backport of test: possibly fix flaky TestEnvoy/case-ingress-gateway-multiple-...</li>
<li><a href="https://github.com/hashicorp/consul/commit/10f9d8edfd5d6bdcc8637f1772d8ee335957fbdc"><code>10f9d8e</code></a> backport of commit 52957fcb179026c5fa82f84076fe4f5a6d5c4287 (<a href="https://github-redirect.dependabot.com/hashicorp/consul/issues/15031">#15031</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/hashicorp/consul/compare/api/v1.14.0...api/v1.15.3">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/hashicorp/consul/api&package-manager=go_modules&previous-version=1.14.0&new-version=1.15.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/app.go b/app.go
index e3d81ffb..436be294 100644
--- a/app.go
+++ b/app.go
@@ -89,8 +89,15 @@ func (a *App) Run() error {
 	a.mu.Lock()
 	a.instance = instance
 	a.mu.Unlock()
-	eg, ctx := errgroup.WithContext(NewContext(a.ctx, a))
+	sctx := NewContext(a.ctx, a)
+	eg, ctx := errgroup.WithContext(sctx)
 	wg := sync.WaitGroup{}
+
+	for _, fn := range a.opts.beforeStart {
+		if err = fn(sctx); err != nil {
+			return err
+		}
+	}
 	for _, srv := range a.opts.servers {
 		srv := srv
 		eg.Go(func() error {
@@ -102,17 +109,23 @@ func (a *App) Run() error {
 		wg.Add(1)
 		eg.Go(func() error {
 			wg.Done() // here is to ensure server start has begun running before register, so defer is not needed
-			return srv.Start(NewContext(a.opts.ctx, a))
+			return srv.Start(sctx)
 		})
 	}
 	wg.Wait()
 	if a.opts.registrar != nil {
 		rctx, rcancel := context.WithTimeout(ctx, a.opts.registrarTimeout)
 		defer rcancel()
-		if err := a.opts.registrar.Register(rctx, instance); err != nil {
+		if err = a.opts.registrar.Register(rctx, instance); err != nil {
+			return err
+		}
+	}
+	for _, fn := range a.opts.afterStart {
+		if err = fn(sctx); err != nil {
 			return err
 		}
 	}
+
 	c := make(chan os.Signal, 1)
 	signal.Notify(c, a.opts.sigs...)
 	eg.Go(func() error {
@@ -123,28 +136,36 @@ func (a *App) Run() error {
 			return a.Stop()
 		}
 	})
-	if err := eg.Wait(); err != nil && !errors.Is(err, context.Canceled) {
+	if err = eg.Wait(); err != nil && !errors.Is(err, context.Canceled) {
 		return err
 	}
-	return nil
+	for _, fn := range a.opts.afterStop {
+		err = fn(sctx)
+	}
+	return err
 }
 
 // Stop gracefully stops the application.
-func (a *App) Stop() error {
+func (a *App) Stop() (err error) {
+	sctx := NewContext(a.ctx, a)
+	for _, fn := range a.opts.beforeStop {
+		err = fn(sctx)
+	}
+
 	a.mu.Lock()
 	instance := a.instance
 	a.mu.Unlock()
 	if a.opts.registrar != nil && instance != nil {
 		ctx, cancel := context.WithTimeout(NewContext(a.ctx, a), a.opts.registrarTimeout)
 		defer cancel()
-		if err := a.opts.registrar.Deregister(ctx, instance); err != nil {
+		if err = a.opts.registrar.Deregister(ctx, instance); err != nil {
 			return err
 		}
 	}
 	if a.cancel != nil {
 		a.cancel()
 	}
-	return nil
+	return err
 }
 
 func (a *App) buildInstance() (*registry.ServiceInstance, error) {
diff --git a/config/config.go b/config/config.go
index 126a6379..9efc9024 100644
--- a/config/config.go
+++ b/config/config.go
@@ -15,13 +15,13 @@ import (
 	"github.com/go-kratos/kratos/v2/log"
 )
 
+var _ Config = (*config)(nil)
+
 var (
 	// ErrNotFound is key not found.
 	ErrNotFound = errors.New("key not found")
 	// ErrTypeAssert is type assert error.
 	ErrTypeAssert = errors.New("type assert error")
-
-	_ Config = (*config)(nil)
 )
 
 // Observer is config observer.
@@ -44,7 +44,7 @@ type config struct {
 	watchers  []Watcher
 }
 
-// New new a config with options.
+// New a config with options.
 func New(opts ...Option) Config {
 	o := options{
 		decoder:  defaultDecoder,
@@ -62,11 +62,11 @@ func New(opts ...Option) Config {
 func (c *config) watch(w Watcher) {
 	for {
 		kvs, err := w.Next()
-		if errors.Is(err, context.Canceled) {
-			log.Infof("watcher's ctx cancel : %v", err)
-			return
-		}
 		if err != nil {
+			if errors.Is(err, context.Canceled) {
+				log.Infof("watcher's ctx cancel : %v", err)
+				return
+			}
 			time.Sleep(time.Second)
 			log.Errorf("failed to watch next config: %v", err)
 			continue
diff --git a/config/env/env.go b/config/env/env.go
index 30e011b9..cdd30e1b 100644
--- a/config/env/env.go
+++ b/config/env/env.go
@@ -19,11 +19,11 @@ func (e *env) Load() (kv []*config.KeyValue, err error) {
 	return e.load(os.Environ()), nil
 }
 
-func (e *env) load(envStrings []string) []*config.KeyValue {
+func (e *env) load(envs []string) []*config.KeyValue {
 	var kv []*config.KeyValue
-	for _, envstr := range envStrings {
+	for _, env := range envs {
 		var k, v string
-		subs := strings.SplitN(envstr, "=", 2) //nolint:gomnd
+		subs := strings.SplitN(env, "=", 2) //nolint:gomnd
 		k = subs[0]
 		if len(subs) > 1 {
 			v = subs[1]
diff --git a/config/env/watcher.go b/config/env/watcher.go
index 2ea02931..84e7932e 100644
--- a/config/env/watcher.go
+++ b/config/env/watcher.go
@@ -6,13 +6,13 @@ import (
 	"github.com/go-kratos/kratos/v2/config"
 )
 
+var _ config.Watcher = (*watcher)(nil)
+
 type watcher struct {
 	ctx    context.Context
 	cancel context.CancelFunc
 }
 
-var _ config.Watcher = (*watcher)(nil)
-
 func NewWatcher() (config.Watcher, error) {
 	ctx, cancel := context.WithCancel(context.Background())
 	return &watcher{ctx: ctx, cancel: cancel}, nil
diff --git a/config/file/watcher.go b/config/file/watcher.go
index ea309fa8..1f067d1a 100644
--- a/config/file/watcher.go
+++ b/config/file/watcher.go
@@ -10,6 +10,8 @@ import (
 	"github.com/go-kratos/kratos/v2/config"
 )
 
+var _ config.Watcher = (*watcher)(nil)
+
 type watcher struct {
 	f  *file
 	fw *fsnotify.Watcher
@@ -18,8 +20,6 @@ type watcher struct {
 	cancel context.CancelFunc
 }
 
-var _ config.Watcher = (*watcher)(nil)
-
 func newWatcher(f *file) (config.Watcher, error) {
 	fw, err := fsnotify.NewWatcher()
 	if err != nil {
diff --git a/config/reader.go b/config/reader.go
index 6858a0f6..2202de6b 100644
--- a/config/reader.go
+++ b/config/reader.go
@@ -8,11 +8,11 @@ import (
 	"strings"
 	"sync"
 
-	"github.com/go-kratos/kratos/v2/log"
-
 	"github.com/imdario/mergo"
 	"google.golang.org/protobuf/encoding/protojson"
 	"google.golang.org/protobuf/proto"
+
+	"github.com/go-kratos/kratos/v2/log"
 )
 
 // Reader is config reader.
@@ -38,9 +38,7 @@ func newReader(opts options) Reader {
 }
 
 func (r *reader) Merge(kvs ...*KeyValue) error {
-	r.lock.Lock()
-	merged, err := cloneMap(r.values)
-	r.lock.Unlock()
+	merged, err := r.cloneMap()
 	if err != nil {
 		return err
 	}
@@ -79,6 +77,12 @@ func (r *reader) Resolve() error {
 	return r.opts.resolver(r.values)
 }
 
+func (r *reader) cloneMap() (map[string]interface{}, error) {
+	r.lock.Lock()
+	defer r.lock.Unlock()
+	return cloneMap(r.values)
+}
+
 func cloneMap(src map[string]interface{}) (map[string]interface{}, error) {
 	// https://gist.github.com/soroushjp/0ec92102641ddfc3ad5515ca76405f4d
 	var buf bytes.Buffer
@@ -90,12 +94,12 @@ func cloneMap(src map[string]interface{}) (map[string]interface{}, error) {
 	if err != nil {
 		return nil, err
 	}
-	var copy map[string]interface{}
-	err = dec.Decode(&copy)
+	var clone map[string]interface{}
+	err = dec.Decode(&clone)
 	if err != nil {
 		return nil, err
 	}
-	return copy, nil
+	return clone, nil
 }
 
 func convertMap(src interface{}) interface{} {
diff --git a/config/value.go b/config/value.go
index 9f6234f5..11de2e89 100644
--- a/config/value.go
+++ b/config/value.go
@@ -1,7 +1,7 @@
 package config
 
 import (
-	stdjson "encoding/json"
+	"encoding/json"
 	"fmt"
 	"reflect"
 	"strconv"
@@ -10,7 +10,7 @@ import (
 
 	"google.golang.org/protobuf/proto"
 
-	"github.com/go-kratos/kratos/v2/encoding/json"
+	kratosjson "github.com/go-kratos/kratos/v2/encoding/json"
 )
 
 var (
@@ -36,6 +36,10 @@ type atomicValue struct {
 	atomic.Value
 }
 
+func (v *atomicValue) typeAssertError() error {
+	return fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load()))
+}
+
 func (v *atomicValue) Bool() (bool, error) {
 	switch val := v.Load().(type) {
 	case bool:
@@ -43,7 +47,7 @@ func (v *atomicValue) Bool() (bool, error) {
 	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, string:
 		return strconv.ParseBool(fmt.Sprint(val))
 	}
-	return false, fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load()))
+	return false, v.typeAssertError()
 }
 
 func (v *atomicValue) Int() (int64, error) {
@@ -73,35 +77,37 @@ func (v *atomicValue) Int() (int64, error) {
 	case float64:
 		return int64(val), nil
 	case string:
-		return strconv.ParseInt(val, 10, 64) //nolint:gomnd
+		return strconv.ParseInt(val, 10, 64)
 	}
-	return 0, fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load()))
+	return 0, v.typeAssertError()
 }
 
 func (v *atomicValue) Slice() ([]Value, error) {
-	if vals, ok := v.Load().([]interface{}); ok {
-		var slices []Value
-		for _, val := range vals {
-			a := &atomicValue{}
-			a.Store(val)
-			slices = append(slices, a)
-		}
-		return slices, nil
+	vals, ok := v.Load().([]interface{})
+	if !ok {
+		return nil, v.typeAssertError()
 	}
-	return nil, fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load()))
+	slices := make([]Value, 0, len(vals))
+	for _, val := range vals {
+		a := new(atomicValue)
+		a.Store(val)
+		slices = append(slices, a)
+	}
+	return slices, nil
 }
 
 func (v *atomicValue) Map() (map[string]Value, error) {
-	if vals, ok := v.Load().(map[string]interface{}); ok {
-		m := make(map[string]Value, len(vals))
-		for key, val := range vals {
-			a := new(atomicValue)
-			a.Store(val)
-			m[key] = a
-		}
-		return m, nil
+	vals, ok := v.Load().(map[string]interface{})
+	if !ok {
+		return nil, v.typeAssertError()
+	}
+	m := make(map[string]Value, len(vals))
+	for key, val := range vals {
+		a := new(atomicValue)
+		a.Store(val)
+		m[key] = a
 	}
-	return nil, fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load()))
+	return m, nil
 }
 
 func (v *atomicValue) Float() (float64, error) {
@@ -131,9 +137,9 @@ func (v *atomicValue) Float() (float64, error) {
 	case float64:
 		return val, nil
 	case string:
-		return strconv.ParseFloat(val, 64) //nolint:gomnd
+		return strconv.ParseFloat(val, 64)
 	}
-	return 0.0, fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load()))
+	return 0.0, v.typeAssertError()
 }
 
 func (v *atomicValue) String() (string, error) {
@@ -147,7 +153,7 @@ func (v *atomicValue) String() (string, error) {
 	case fmt.Stringer:
 		return val.String(), nil
 	}
-	return "", fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load()))
+	return "", v.typeAssertError()
 }
 
 func (v *atomicValue) Duration() (time.Duration, error) {
@@ -159,14 +165,14 @@ func (v *atomicValue) Duration() (time.Duration, error) {
 }
 
 func (v *atomicValue) Scan(obj interface{}) error {
-	data, err := stdjson.Marshal(v.Load())
+	data, err := json.Marshal(v.Load())
 	if err != nil {
 		return err
 	}
 	if pb, ok := obj.(proto.Message); ok {
-		return json.UnmarshalOptions.Unmarshal(data, pb)
+		return kratosjson.UnmarshalOptions.Unmarshal(data, pb)
 	}
-	return stdjson.Unmarshal(data, obj)
+	return json.Unmarshal(data, obj)
 }
 
 type errValue struct {
diff --git a/contrib/config/consul/go.mod b/contrib/config/consul/go.mod
index 49e23b74..25d459c6 100644
--- a/contrib/config/consul/go.mod
+++ b/contrib/config/consul/go.mod
@@ -4,7 +4,7 @@ go 1.15
 
 require (
 	github.com/go-kratos/kratos/v2 v2.4.0
-	github.com/hashicorp/consul/api v1.14.0
+	github.com/hashicorp/consul/api v1.15.3
 )
 
 replace github.com/go-kratos/kratos/v2 => ../../../
diff --git a/contrib/config/consul/go.sum b/contrib/config/consul/go.sum
index 25fbdf7f..b6e682aa 100644
--- a/contrib/config/consul/go.sum
+++ b/contrib/config/consul/go.sum
@@ -91,10 +91,10 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
 github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
-github.com/hashicorp/consul/api v1.14.0 h1:Y64GIJ8hYTu+tuGekwO4G4ardXoiCivX9wv1iP/kihk=
-github.com/hashicorp/consul/api v1.14.0/go.mod h1:bcaw5CSZ7NE9qfOfKCI1xb7ZKjzu/MyvQkCLTfqLqxQ=
-github.com/hashicorp/consul/sdk v0.10.0 h1:rGLEh2AWK4K0KCMvqWAz2EYxQqgciIfMagWZ0nVe5MI=
-github.com/hashicorp/consul/sdk v0.10.0/go.mod h1:yPkX5Q6CsxTFMjQQDJwzeNmUUF5NUGGbrDsv9wTb8cw=
+github.com/hashicorp/consul/api v1.15.3 h1:WYONYL2rxTXtlekAqblR2SCdJsizMDIj/uXb5wNy9zU=
+github.com/hashicorp/consul/api v1.15.3/go.mod h1:/g/qgcoBcEXALCNZgRRisyTW0nY86++L0KbeAMXYCeY=
+github.com/hashicorp/consul/sdk v0.11.0 h1:HRzj8YSCln2yGgCumN5CL8lYlD3gBurnervJRJAZyC4=
+github.com/hashicorp/consul/sdk v0.11.0/go.mod h1:yPkX5Q6CsxTFMjQQDJwzeNmUUF5NUGGbrDsv9wTb8cw=
 github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
 github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
diff --git a/contrib/log/aliyun/go.mod b/contrib/log/aliyun/go.mod
index 1c7b5fa8..54abe05f 100644
--- a/contrib/log/aliyun/go.mod
+++ b/contrib/log/aliyun/go.mod
@@ -3,7 +3,7 @@ module github.com/go-kratos/kratos/contrib/log/aliyun/v2
 go 1.16
 
 require (
-	github.com/aliyun/aliyun-log-go-sdk v0.1.39
+	github.com/aliyun/aliyun-log-go-sdk v0.1.40
 	github.com/go-kratos/kratos/v2 v2.5.2
 	google.golang.org/protobuf v1.28.1
 )
diff --git a/contrib/log/aliyun/go.sum b/contrib/log/aliyun/go.sum
index ab2ac488..0b42927b 100644
--- a/contrib/log/aliyun/go.sum
+++ b/contrib/log/aliyun/go.sum
@@ -12,8 +12,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/aliyun/aliyun-log-go-sdk v0.1.39 h1:oVLVcRbtOhE4a1D4HhO3OYPR6wMADl3ldcbVeFrRL8Y=
-github.com/aliyun/aliyun-log-go-sdk v0.1.39/go.mod h1:1QQ59pEJiVVXqKgbHcU6FWIgxT5RKBt+CT8AiQ2bEts=
+github.com/aliyun/aliyun-log-go-sdk v0.1.40 h1:GNlRoTe9Fi7dfhIMHAnb+b5837/fIw8lqs1DRqaU1CM=
+github.com/aliyun/aliyun-log-go-sdk v0.1.40/go.mod h1:1QQ59pEJiVVXqKgbHcU6FWIgxT5RKBt+CT8AiQ2bEts=
 github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
diff --git a/contrib/metrics/datadog/go.mod b/contrib/metrics/datadog/go.mod
index 42d43453..aebfd094 100644
--- a/contrib/metrics/datadog/go.mod
+++ b/contrib/metrics/datadog/go.mod
@@ -4,8 +4,11 @@ go 1.16
 
 require (
 	github.com/DataDog/datadog-go v4.8.3+incompatible
-	github.com/Microsoft/go-winio v0.5.2 // indirect
 	github.com/go-kratos/kratos/v2 v2.5.2
 )
 
+require (
+	github.com/Microsoft/go-winio v0.5.2 // indirect
+)
+
 replace github.com/go-kratos/kratos/v2 => ../../../
diff --git a/contrib/metrics/prometheus/go.mod b/contrib/metrics/prometheus/go.mod
index 4a31ccad..0b925f11 100644
--- a/contrib/metrics/prometheus/go.mod
+++ b/contrib/metrics/prometheus/go.mod
@@ -4,7 +4,7 @@ go 1.16
 
 require (
 	github.com/go-kratos/kratos/v2 v2.5.2
-	github.com/prometheus/client_golang v1.12.2
+	github.com/prometheus/client_golang v1.13.1
 	github.com/prometheus/common v0.37.0
 )
 
diff --git a/contrib/metrics/prometheus/go.sum b/contrib/metrics/prometheus/go.sum
index 559a32af..d40e7b4f 100644
--- a/contrib/metrics/prometheus/go.sum
+++ b/contrib/metrics/prometheus/go.sum
@@ -129,8 +129,9 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
 github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
+github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
+github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@@ -186,8 +187,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn
 github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
 github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
 github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
-github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34=
-github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
+github.com/prometheus/client_golang v1.13.1 h1:3gMjIY2+/hzmqhtUC/aQNYldJA6DtH3CgQvwS+02K1c=
+github.com/prometheus/client_golang v1.13.1/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -203,8 +204,9 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
 github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
+github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
+github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
 github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/shirou/gopsutil/v3 v3.21.8/go.mod h1:YWp/H8Qs5fVmf17v7JNZzA0mPJ+mS2e9JdiUF9LlKzQ=
@@ -319,6 +321,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/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-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -364,8 +367,9 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -422,7 +426,6 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
 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/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
 google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
@@ -506,8 +509,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
 google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
+google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/contrib/registry/etcd/go.mod b/contrib/registry/etcd/go.mod
index c4c072ec..f6ae3437 100644
--- a/contrib/registry/etcd/go.mod
+++ b/contrib/registry/etcd/go.mod
@@ -5,7 +5,7 @@ go 1.16
 require (
 	github.com/go-kratos/kratos/v2 v2.5.2
 	go.etcd.io/etcd/client/v3 v3.5.4
-	google.golang.org/grpc v1.46.2
+	google.golang.org/grpc v1.50.1
 )
 
 replace github.com/go-kratos/kratos/v2 => ../../../
diff --git a/contrib/registry/etcd/go.sum b/contrib/registry/etcd/go.sum
index e847ccab..36c78cdc 100644
--- a/contrib/registry/etcd/go.sum
+++ b/contrib/registry/etcd/go.sum
@@ -268,8 +268,9 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp
 google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
 google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ=
 google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY=
+google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
diff --git a/contrib/registry/polaris/go.mod b/contrib/registry/polaris/go.mod
index f70157cc..256ed425 100644
--- a/contrib/registry/polaris/go.mod
+++ b/contrib/registry/polaris/go.mod
@@ -4,7 +4,7 @@ go 1.16
 
 require (
 	github.com/go-kratos/kratos/v2 v2.5.2
-	github.com/polarismesh/polaris-go v1.1.0
+	github.com/polarismesh/polaris-go v1.2.0
 )
 
 replace github.com/go-kratos/kratos/v2 => ../../../
diff --git a/contrib/registry/polaris/go.sum b/contrib/registry/polaris/go.sum
index 6205e994..77f73a2e 100644
--- a/contrib/registry/polaris/go.sum
+++ b/contrib/registry/polaris/go.sum
@@ -60,22 +60,21 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
-github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
+github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
 github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
-github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -213,8 +212,8 @@ 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=
-github.com/polarismesh/polaris-go v1.1.0 h1:nFvn3q3XaVFhzF7pBnIySrN0ZZBwvbbYXC5r2DpsQN0=
-github.com/polarismesh/polaris-go v1.1.0/go.mod h1:tquawfjEKp1W3ffNJQSzhfditjjoZ7tvhOCElN7Efzs=
+github.com/polarismesh/polaris-go v1.2.0 h1:GIWvUno4DB0PD3HC7bHmTCeG+a54neMrVvNPiRXJUtc=
+github.com/polarismesh/polaris-go v1.2.0/go.mod h1:HsN0ierETIujHpmnnYJ3qkwQw4QGAECuHvBZTDaw1tI=
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
 github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
@@ -275,12 +274,12 @@ go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48
 go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
 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/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
+go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
 go.uber.org/multierr v1.6.0 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=
+go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
+go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
 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-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -349,8 +348,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210917221730-978cfadd31cf h1:R150MpwJIv1MpS0N/pc+NhTM8ajzvlmxlY5OYsrevXQ=
-golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
+golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -409,19 +408,24 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60=
+golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -524,6 +528,7 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
 google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20220504150022-98cd25cafc72/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
 google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd h1:e0TwkXOdbnH/1x5rc5MZ/VYyiZ4v+RdVfrGMqEwT68I=
 google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -540,7 +545,6 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
 google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
 google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
 google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
 google.golang.org/grpc v1.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ=
 google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
diff --git a/encoding/form/form.go b/encoding/form/form.go
index 823aeb8f..ba0447e4 100644
--- a/encoding/form/form.go
+++ b/encoding/form/form.go
@@ -4,10 +4,10 @@ import (
 	"net/url"
 	"reflect"
 
-	"github.com/go-kratos/kratos/v2/encoding"
-
 	"github.com/go-playground/form/v4"
 	"google.golang.org/protobuf/proto"
+
+	"github.com/go-kratos/kratos/v2/encoding"
 )
 
 const (
@@ -70,7 +70,8 @@ func (c codec) Unmarshal(data []byte, v interface{}) error {
 	}
 	if m, ok := v.(proto.Message); ok {
 		return DecodeValues(m, vs)
-	} else if m, ok := reflect.Indirect(reflect.ValueOf(v)).Interface().(proto.Message); ok {
+	}
+	if m, ok := rv.Interface().(proto.Message); ok {
 		return DecodeValues(m, vs)
 	}
 
diff --git a/encoding/form/proto_decode.go b/encoding/form/proto_decode.go
index fcf46d46..1620162b 100644
--- a/encoding/form/proto_decode.go
+++ b/encoding/form/proto_decode.go
@@ -10,13 +10,12 @@ import (
 	"time"
 
 	"google.golang.org/protobuf/encoding/protojson"
-	"google.golang.org/protobuf/types/known/structpb"
-
 	"google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/reflect/protoreflect"
 	"google.golang.org/protobuf/reflect/protoregistry"
 	"google.golang.org/protobuf/types/known/durationpb"
 	"google.golang.org/protobuf/types/known/fieldmaskpb"
+	"google.golang.org/protobuf/types/known/structpb"
 	"google.golang.org/protobuf/types/known/timestamppb"
 	"google.golang.org/protobuf/types/known/wrapperspb"
 )
@@ -122,15 +121,13 @@ func populateRepeatedField(fd protoreflect.FieldDescriptor, list protoreflect.Li
 }
 
 func populateMapField(fd protoreflect.FieldDescriptor, mp protoreflect.Map, fieldPath []string, values []string) error {
-	flen := len(fieldPath)
-	vlen := len(values)
 	// post sub key.
-	nkey := flen - 1
+	nkey := len(fieldPath) - 1
 	key, err := parseField(fd.MapKey(), fieldPath[nkey])
 	if err != nil {
 		return fmt.Errorf("parsing map key %q: %w", fd.FullName().Name(), err)
 	}
-	vkey := vlen - 1
+	vkey := len(values) - 1
 	value, err := parseField(fd.MapValue(), values[vkey])
 	if err != nil {
 		return fmt.Errorf("parsing map value %q: %w", fd.FullName().Name(), err)
diff --git a/log/filter.go b/log/filter.go
index ab572377..993fa926 100644
--- a/log/filter.go
+++ b/log/filter.go
@@ -64,20 +64,18 @@ func (f *Filter) Log(level Level, keyvals ...interface{}) error {
 	if level < f.level {
 		return nil
 	}
-	// fkv is used to provide a slice to contains both logger.prefix and keyvals for filter
-	var fkv []interface{}
+	// prefixkv contains the slice of arguments defined as prefixes during the log initialization
+	var prefixkv []interface{}
 	l, ok := f.logger.(*logger)
 	if ok && len(l.prefix) > 0 {
-		fkv = make([]interface{}, 0, len(l.prefix)+len(keyvals))
-		fkv = append(fkv, l.prefix...)
-		fkv = append(fkv, keyvals...)
+		prefixkv = make([]interface{}, 0, len(l.prefix))
+		prefixkv = append(prefixkv, l.prefix...)
 	}
-	if !ok {
-		fkv = keyvals
-	}
-	if f.filter != nil && f.filter(level, fkv...) {
+
+	if f.filter != nil && (f.filter(level, prefixkv...) || f.filter(level, keyvals...)) {
 		return nil
 	}
+
 	if len(f.key) > 0 || len(f.value) > 0 {
 		for i := 0; i < len(keyvals); i += 2 {
 			v := i + 1
diff --git a/options.go b/options.go
index 8f9e9a55..5e337a38 100644
--- a/options.go
+++ b/options.go
@@ -30,6 +30,12 @@ type options struct {
 	registrarTimeout time.Duration
 	stopTimeout      time.Duration
 	servers          []transport.Server
+
+	// Before and After funcs
+	beforeStart []func(context.Context) error
+	beforeStop  []func(context.Context) error
+	afterStart  []func(context.Context) error
+	afterStop   []func(context.Context) error
 }
 
 // ID with service id.
@@ -91,3 +97,33 @@ func RegistrarTimeout(t time.Duration) Option {
 func StopTimeout(t time.Duration) Option {
 	return func(o *options) { o.stopTimeout = t }
 }
+
+// Before and Afters
+
+// BeforeStart run funcs before app starts
+func BeforeStart(fn func(context.Context) error) Option {
+	return func(o *options) {
+		o.beforeStart = append(o.beforeStart, fn)
+	}
+}
+
+// BeforeStop run funcs before app stops
+func BeforeStop(fn func(context.Context) error) Option {
+	return func(o *options) {
+		o.beforeStop = append(o.beforeStop, fn)
+	}
+}
+
+// AfterStart run funcs after app starts
+func AfterStart(fn func(context.Context) error) Option {
+	return func(o *options) {
+		o.afterStart = append(o.afterStart, fn)
+	}
+}
+
+// AfterStop run funcs after app stops
+func AfterStop(fn func(context.Context) error) Option {
+	return func(o *options) {
+		o.afterStop = append(o.afterStop, fn)
+	}
+}


Test patch:
diff --git a/app_test.go b/app_test.go
index 2b8c8c9d..92a2ca29 100644
--- a/app_test.go
+++ b/app_test.go
@@ -47,6 +47,22 @@ func TestApp(t *testing.T) {
 		Name("kratos"),
 		Version("v1.0.0"),
 		Server(hs, gs),
+		BeforeStart(func(_ context.Context) error {
+			t.Log("BeforeStart...")
+			return nil
+		}),
+		BeforeStop(func(_ context.Context) error {
+			t.Log("BeforeStop...")
+			return nil
+		}),
+		AfterStart(func(_ context.Context) error {
+			t.Log("AfterStart...")
+			return nil
+		}),
+		AfterStop(func(_ context.Context) error {
+			t.Log("AfterStop...")
+			return nil
+		}),
 		Registrar(&mockRegistry{service: make(map[string]*registry.ServiceInstance)}),
 	)
 	time.AfterFunc(time.Second, func() {
diff --git a/config/config_test.go b/config/config_test.go
index 5699dec1..9a166b00 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -2,7 +2,6 @@ package config
 
 import (
 	"errors"
-	"reflect"
 	"testing"
 )
 
@@ -124,7 +123,7 @@ func TestConfig(t *testing.T) {
 	)
 	err = c.Close()
 	if err != nil {
-		t.Fatal("t is not nil")
+		t.Fatal(err)
 	}
 
 	jSource := newTestJSONSource(_testJSON)
@@ -139,21 +138,21 @@ func TestConfig(t *testing.T) {
 
 	err = cf.Load()
 	if err != nil {
-		t.Fatal("t is not nil")
+		t.Fatal(err)
 	}
 
-	val, err := cf.Value("data.database.driver").String()
+	driver, err := cf.Value("data.database.driver").String()
 	if err != nil {
-		t.Fatal("t is not nil")
+		t.Fatal(err)
 	}
-	if !reflect.DeepEqual(databaseDriver, val) {
-		t.Fatal(`databaseDriver is not equal to val`)
+	if databaseDriver != driver {
+		t.Fatal("databaseDriver is not equal to val")
 	}
 
 	err = cf.Watch("endpoints", func(key string, value Value) {
 	})
 	if err != nil {
-		t.Fatal("t is not nil")
+		t.Fatal(err)
 	}
 
 	jSource.sig <- struct{}{}
@@ -162,24 +161,24 @@ func TestConfig(t *testing.T) {
 	var testConf testConfigStruct
 	err = cf.Scan(&testConf)
 	if err != nil {
-		t.Fatal("t is not nil")
+		t.Fatal(err)
 	}
-	if !reflect.DeepEqual(httpAddr, testConf.Server.HTTP.Addr) {
-		t.Fatal(`httpAddr is not equal to testConf.Server.HTTP.Addr`)
+	if httpAddr != testConf.Server.HTTP.Addr {
+		t.Errorf("testConf.Server.HTTP.Addr want: %s, got: %s", httpAddr, testConf.Server.HTTP.Addr)
 	}
-	if !reflect.DeepEqual(httpTimeout, testConf.Server.HTTP.Timeout) {
-		t.Fatal(`httpTimeout is not equal to testConf.Server.HTTP.Timeout`)
+	if httpTimeout != testConf.Server.HTTP.Timeout {
+		t.Errorf("testConf.Server.HTTP.Timeout want: %.1f, got: %.1f", httpTimeout, testConf.Server.HTTP.Timeout)
 	}
-	if !reflect.DeepEqual(true, testConf.Server.HTTP.EnableSSL) {
-		t.Fatal(`testConf.Server.HTTP.EnableSSL is not equal to true`)
+	if !testConf.Server.HTTP.EnableSSL {
+		t.Error("testConf.Server.HTTP.EnableSSL is not equal to true")
 	}
-	if !reflect.DeepEqual(grpcPort, testConf.Server.GRPC.Port) {
-		t.Fatal(`grpcPort is not equal to testConf.Server.GRPC.Port`)
+	if grpcPort != testConf.Server.GRPC.Port {
+		t.Errorf("testConf.Server.GRPC.Port want: %d, got: %d", grpcPort, testConf.Server.GRPC.Port)
 	}
-	if !reflect.DeepEqual(endpoint1, testConf.Endpoints[0]) {
-		t.Fatal(`endpoint1 is not equal to testConf.Endpoints[0]`)
+	if endpoint1 != testConf.Endpoints[0] {
+		t.Errorf("testConf.Endpoints[0] want: %s, got: %s", endpoint1, testConf.Endpoints[0])
 	}
-	if !reflect.DeepEqual(len(testConf.Endpoints), 2) {
-		t.Fatal(`len(testConf.Endpoints) is not equal to 2`)
+	if len(testConf.Endpoints) != 2 {
+		t.Error("len(testConf.Endpoints) is not equal to 2")
 	}
 }
diff --git a/config/file/file_test.go b/config/file/file_test.go
index 0eb2b24f..ac6ad843 100644
--- a/config/file/file_test.go
+++ b/config/file/file_test.go
@@ -121,10 +121,10 @@ func testWatchFile(t *testing.T, path string) {
 	}
 	kvs, err := watch.Next()
 	if err != nil {
-		t.Errorf(`watch.Next() error(%v)`, err)
+		t.Errorf("watch.Next() error(%v)", err)
 	}
 	if !reflect.DeepEqual(string(kvs[0].Value), _testJSONUpdate) {
-		t.Errorf(`string(kvs[0].Value(%v) is  not equal to _testJSONUpdate(%v)`, kvs[0].Value, _testJSONUpdate)
+		t.Errorf("string(kvs[0].Value(%v) is  not equal to _testJSONUpdate(%v)", kvs[0].Value, _testJSONUpdate)
 	}
 
 	newFilepath := filepath.Join(filepath.Dir(path), "test1.json")
@@ -133,15 +133,15 @@ func testWatchFile(t *testing.T, path string) {
 	}
 	kvs, err = watch.Next()
 	if err == nil {
-		t.Errorf(`watch.Next() error(%v)`, err)
+		t.Errorf("watch.Next() error(%v)", err)
 	}
 	if kvs != nil {
-		t.Errorf(`watch.Next() error(%v)`, err)
+		t.Errorf("watch.Next() error(%v)", err)
 	}
 
 	err = watch.Stop()
 	if err != nil {
-		t.Errorf(`watch.Stop() error(%v)`, err)
+		t.Errorf("watch.Stop() error(%v)", err)
 	}
 
 	if err := os.Rename(newFilepath, path); err != nil {
@@ -171,10 +171,10 @@ func testWatchDir(t *testing.T, path, file string) {
 
 	kvs, err := watch.Next()
 	if err != nil {
-		t.Errorf(`watch.Next() error(%v)`, err)
+		t.Errorf("watch.Next() error(%v)", err)
 	}
 	if !reflect.DeepEqual(string(kvs[0].Value), _testJSONUpdate) {
-		t.Errorf(`string(kvs[0].Value(%v) is  not equal to _testJSONUpdate(%v)`, kvs[0].Value, _testJSONUpdate)
+		t.Errorf("string(kvs[0].Value(%s) is  not equal to _testJSONUpdate(%v)", kvs[0].Value, _testJSONUpdate)
 	}
 }
 
diff --git a/config/file/format_test.go b/config/file/format_test.go
index 509a9837..75185cc6 100644
--- a/config/file/format_test.go
+++ b/config/file/format_test.go
@@ -1,6 +1,8 @@
 package file
 
-import "testing"
+import (
+	"testing"
+)
 
 func TestFormat(t *testing.T) {
 	tests := []struct {
diff --git a/config/options_test.go b/config/options_test.go
index 51e8b48e..c8cd2bf8 100644
--- a/config/options_test.go
+++ b/config/options_test.go
@@ -15,7 +15,7 @@ func TestDefaultDecoder(t *testing.T) {
 	target := make(map[string]interface{})
 	err := defaultDecoder(src, target)
 	if err != nil {
-		t.Fatal("err is not nil")
+		t.Fatal(err)
 	}
 	if !reflect.DeepEqual(target, map[string]interface{}{"service": []byte("config")}) {
 		t.Fatal(`target is not equal to map[string]interface{}{"service": "config"}`)
@@ -29,7 +29,7 @@ func TestDefaultDecoder(t *testing.T) {
 	target = make(map[string]interface{})
 	err = defaultDecoder(src, target)
 	if err != nil {
-		t.Fatal("err is not nil")
+		t.Fatal(err)
 	}
 	if !reflect.DeepEqual(map[string]interface{}{
 		"service": map[string]interface{}{
@@ -150,7 +150,7 @@ func TestDefaultResolver(t *testing.T) {
 		t.Run(test.name, func(t *testing.T) {
 			err := defaultResolver(data)
 			if err != nil {
-				t.Fatal(`err is not nil`)
+				t.Fatal(err)
 			}
 			rd := reader{
 				values: data,
@@ -161,25 +161,25 @@ func TestDefaultResolver(t *testing.T) {
 				case int:
 					if actual, err = v.Int(); err == nil {
 						if !reflect.DeepEqual(test.expect.(int), int(actual.(int64))) {
-							t.Fatal(`expect is not equal to actual`)
+							t.Fatal("expect is not equal to actual")
 						}
 					}
 				case string:
 					if actual, err = v.String(); err == nil {
 						if !reflect.DeepEqual(test.expect, actual) {
-							t.Fatal(`expect is not equal to actual`)
+							t.Fatal("expect is not equal to actual")
 						}
 					}
 				case bool:
 					if actual, err = v.Bool(); err == nil {
 						if !reflect.DeepEqual(test.expect, actual) {
-							t.Fatal(`expect is not equal to actual`)
+							t.Fatal("expect is not equal to actual")
 						}
 					}
 				case float64:
 					if actual, err = v.Float(); err == nil {
 						if !reflect.DeepEqual(test.expect, actual) {
-							t.Fatal(`expect is not equal to actual`)
+							t.Fatal("expect is not equal to actual")
 						}
 					}
 				default:
diff --git a/config/reader_test.go b/config/reader_test.go
index 15f8f617..11b2d990 100644
--- a/config/reader_test.go
+++ b/config/reader_test.go
@@ -29,7 +29,7 @@ func TestReader_Merge(t *testing.T) {
 		Format: "json",
 	})
 	if err == nil {
-		t.Fatal(`err is nil`)
+		t.Fatal("err is nil")
 	}
 
 	err = r.Merge(&KeyValue{
@@ -38,15 +38,15 @@ func TestReader_Merge(t *testing.T) {
 		Format: "json",
 	})
 	if err != nil {
-		t.Fatal(`err is not nil`)
+		t.Fatal(err)
 	}
 	vv, ok := r.Value("nice")
 	if !ok {
-		t.Fatal(`ok is false`)
+		t.Fatal("ok is false")
 	}
 	vvv, err := vv.String()
 	if err != nil {
-		t.Fatal(`err is not nil`)
+		t.Fatal(err)
 	}
 	if vvv != "boat" {
 		t.Fatal(`vvv is not equal to "boat"`)
@@ -58,18 +58,18 @@ func TestReader_Merge(t *testing.T) {
 		Format: "json",
 	})
 	if err != nil {
-		t.Fatal(`err is not nil`)
+		t.Fatal(err)
 	}
 	vv, ok = r.Value("x")
 	if !ok {
-		t.Fatal(`ok is false`)
+		t.Fatal("ok is false")
 	}
 	vvx, err := vv.Int()
 	if err != nil {
-		t.Fatal(`err is not nil`)
+		t.Fatal(err)
 	}
-	if int64(2) != vvx {
-		t.Fatal(`vvx is not equal to 2`)
+	if vvx != 2 {
+		t.Fatal("vvx is not equal to 2")
 	}
 }
 
@@ -118,27 +118,27 @@ a:
 			r := newReader(opts)
 			err := r.Merge(&test.kv)
 			if err != nil {
-				t.Fatal(`err is not nil`)
+				t.Fatal(err)
 			}
 			vv, ok := r.Value("a.b.X")
 			if !ok {
-				t.Fatal(`ok is false`)
+				t.Fatal("ok is false")
 			}
 			vvv, err := vv.Int()
 			if err != nil {
-				t.Fatal(`err is not nil`)
+				t.Fatal(err)
 			}
 			if int64(1) != vvv {
-				t.Fatal(`vvv is not equal to 1`)
+				t.Fatal("vvv is not equal to 1")
 			}
 
 			vv, ok = r.Value("a.b.Y")
 			if !ok {
-				t.Fatal(`ok is false`)
+				t.Fatal("ok is false")
 			}
 			vvy, err := vv.String()
 			if err != nil {
-				t.Fatal(`err is not nil`)
+				t.Fatal(err)
 			}
 			if vvy != "lol" {
 				t.Fatal(`vvy is not equal to "lol"`)
@@ -146,29 +146,29 @@ a:
 
 			vv, ok = r.Value("a.b.z")
 			if !ok {
-				t.Fatal(`ok is false`)
+				t.Fatal("ok is false")
 			}
 			vvz, err := vv.Bool()
 			if err != nil {
-				t.Fatal(`err is not nil`)
+				t.Fatal(err)
 			}
 			if !vvz {
-				t.Fatal(`vvz is not equal to true`)
+				t.Fatal("vvz is not equal to true")
 			}
 
 			_, ok = r.Value("aasasdg=234l.asdfk,")
 			if ok {
-				t.Fatal(`ok is true`)
+				t.Fatal("ok is true")
 			}
 
 			_, ok = r.Value("aas......asdg=234l.asdfk,")
 			if ok {
-				t.Fatal(`ok is true`)
+				t.Fatal("ok is true")
 			}
 
 			_, ok = r.Value("a.b.Y.")
 			if ok {
-				t.Fatal(`ok is true`)
+				t.Fatal("ok is true")
 			}
 		})
 	}
@@ -192,11 +192,11 @@ func TestReader_Source(t *testing.T) {
 		Format: "json",
 	})
 	if err != nil {
-		t.Fatal(`err is not nil`)
+		t.Fatal(err)
 	}
 	b, err := r.Source()
 	if err != nil {
-		t.Fatal(`err is not nil`)
+		t.Fatal(err)
 	}
 	if !reflect.DeepEqual([]byte(`{"a":{"b":{"X":1}}}`), b) {
 		t.Fatal("[]byte(`{\"a\":{\"b\":{\"X\":1}}}`) is not equal to b")
diff --git a/config/value_test.go b/config/value_test.go
index 68558bf8..df771757 100644
--- a/config/value_test.go
+++ b/config/value_test.go
@@ -6,17 +6,17 @@ import (
 	"time"
 )
 
-func Test_atomicValue_Bool(t *testing.T) {
+func TestAtomicValue_Bool(t *testing.T) {
 	vlist := []interface{}{"1", "t", "T", "true", "TRUE", "True", true, 1, int32(1)}
 	for _, x := range vlist {
 		v := atomicValue{}
 		v.Store(x)
 		b, err := v.Bool()
 		if err != nil {
-			t.Fatal(`err is not nil`)
+			t.Fatal(err)
 		}
 		if !b {
-			t.Fatal(`b is not equal to true`)
+			t.Fatal("b is not equal to true")
 		}
 	}
 
@@ -26,10 +26,10 @@ func Test_atomicValue_Bool(t *testing.T) {
 		v.Store(x)
 		b, err := v.Bool()
 		if err != nil {
-			t.Fatal(`err is not nil`)
+			t.Fatal(err)
 		}
 		if b {
-			t.Fatal(`b is not equal to false`)
+			t.Fatal("b is not equal to false")
 		}
 	}
 
@@ -39,22 +39,22 @@ func Test_atomicValue_Bool(t *testing.T) {
 		v.Store(x)
 		_, err := v.Bool()
 		if err == nil {
-			t.Fatal(`err is nil`)
+			t.Fatal("err is nil")
 		}
 	}
 }
 
-func Test_atomicValue_Int(t *testing.T) {
+func TestAtomicValue_Int(t *testing.T) {
 	vlist := []interface{}{"123123", float64(123123), int64(123123), int32(123123), 123123}
 	for _, x := range vlist {
 		v := atomicValue{}
 		v.Store(x)
 		b, err := v.Int()
 		if err != nil {
-			t.Fatal(`err is not nil`)
+			t.Fatal(err)
 		}
 		if b != 123123 {
-			t.Fatal(`b is not equal to 123123`)
+			t.Fatal("b is not equal to 123123")
 		}
 	}
 
@@ -64,22 +64,22 @@ func Test_atomicValue_Int(t *testing.T) {
 		v.Store(x)
 		_, err := v.Int()
 		if err == nil {
-			t.Fatal(`err is nil`)
+			t.Fatal("err is nil")
 		}
 	}
 }
 
-func Test_atomicValue_Float(t *testing.T) {
+func TestAtomicValue_Float(t *testing.T) {
 	vlist := []interface{}{"123123.1", 123123.1}
 	for _, x := range vlist {
 		v := atomicValue{}
 		v.Store(x)
 		b, err := v.Float()
 		if err != nil {
-			t.Fatal(`err is not nil`)
+			t.Fatal(err)
 		}
 		if b != 123123.1 {
-			t.Fatal(`b is not equal to 123123.1`)
+			t.Fatal("b is not equal to 123123.1")
 		}
 	}
 
@@ -89,7 +89,7 @@ func Test_atomicValue_Float(t *testing.T) {
 		v.Store(x)
 		_, err := v.Float()
 		if err == nil {
-			t.Fatal(`err is nil`)
+			t.Fatal("err is nil")
 		}
 	}
 }
@@ -103,17 +103,17 @@ func (t ts) String() string {
 	return fmt.Sprintf("%s%d", t.Name, t.Age)
 }
 
-func Test_atomicValue_String(t *testing.T) {
+func TestAtomicValue_String(t *testing.T) {
 	vlist := []interface{}{"1", float64(1), int64(1), 1, int64(1)}
 	for _, x := range vlist {
 		v := atomicValue{}
 		v.Store(x)
 		b, err := v.String()
 		if err != nil {
-			t.Fatal(`err is not nil`)
+			t.Fatal(err)
 		}
 		if b != "1" {
-			t.Fatal(`b is not equal to 1`)
+			t.Fatal("b is not equal to 1")
 		}
 	}
 
@@ -121,7 +121,7 @@ func Test_atomicValue_String(t *testing.T) {
 	v.Store(true)
 	b, err := v.String()
 	if err != nil {
-		t.Fatal(`err is not nil`)
+		t.Fatal(err)
 	}
 	if b != "true" {
 		t.Fatal(`b is not equal to "true"`)
@@ -134,48 +134,48 @@ func Test_atomicValue_String(t *testing.T) {
 	})
 	b, err = v.String()
 	if err != nil {
-		t.Fatal(`err is not nil`)
+		t.Fatal(err)
 	}
 	if b != "test10" {
 		t.Fatal(`b is not equal to "test10"`)
 	}
 }
 
-func Test_atomicValue_Duration(t *testing.T) {
+func TestAtomicValue_Duration(t *testing.T) {
 	vlist := []interface{}{int64(5)}
 	for _, x := range vlist {
 		v := atomicValue{}
 		v.Store(x)
 		b, err := v.Duration()
 		if err != nil {
-			t.Fatal(`err is not nil`)
+			t.Fatal(err)
 		}
 		if b != time.Duration(5) {
-			t.Fatal(`b is not equal to time.Duration(5)`)
+			t.Fatal("b is not equal to time.Duration(5)")
 		}
 	}
 }
 
-func Test_atomicValue_Slice(t *testing.T) {
+func TestAtomicValue_Slice(t *testing.T) {
 	vlist := []interface{}{int64(5)}
 	v := atomicValue{}
 	v.Store(vlist)
 	slices, err := v.Slice()
 	if err != nil {
-		t.Fatal(`err is not nil`)
+		t.Fatal(err)
 	}
 	for _, v := range slices {
 		b, err := v.Duration()
 		if err != nil {
-			t.Fatal(`err is not nil`)
+			t.Fatal(err)
 		}
 		if b != time.Duration(5) {
-			t.Fatal(`b is not equal to time.Duration(5)`)
+			t.Fatal("b is not equal to time.Duration(5)")
 		}
 	}
 }
 
-func Test_atomicValue_Map(t *testing.T) {
+func TestAtomicValue_Map(t *testing.T) {
 	vlist := make(map[string]interface{})
 	vlist["5"] = int64(5)
 	vlist["text"] = "text"
@@ -183,21 +183,21 @@ func Test_atomicValue_Map(t *testing.T) {
 	v.Store(vlist)
 	m, err := v.Map()
 	if err != nil {
-		t.Fatal(`err is not nil`)
+		t.Fatal(err)
 	}
 	for k, v := range m {
 		if k == "5" {
 			b, err := v.Duration()
 			if err != nil {
-				t.Fatal(`err is not nil`)
+				t.Fatal(err)
 			}
 			if b != time.Duration(5) {
-				t.Fatal(`b is not equal to time.Duration(5)`)
+				t.Fatal("b is not equal to time.Duration(5)")
 			}
 		} else {
 			b, err := v.String()
 			if err != nil {
-				t.Fatal(`err is not nil`)
+				t.Fatal(err)
 			}
 			if b != "text" {
 				t.Fatal(`b is not equal to "text"`)
@@ -206,20 +206,19 @@ func Test_atomicValue_Map(t *testing.T) {
 	}
 }
 
-func Test_atomicValue_Scan(t *testing.T) {
-	var err error
+func TestAtomicValue_Scan(t *testing.T) {
 	v := atomicValue{}
-	err = v.Scan(&struct {
+	err := v.Scan(&struct {
 		A string `json:"a"`
 	}{"a"})
 	if err != nil {
-		t.Fatal(`err is not nil`)
+		t.Fatal(err)
 	}
 
 	err = v.Scan(&struct {
 		A string `json:"a"`
 	}{"a"})
 	if err != nil {
-		t.Fatal(`err is not nil`)
+		t.Fatal(err)
 	}
 }
diff --git a/contrib/log/aliyun/aliyun_test.go b/contrib/log/aliyun/aliyun_test.go
index c4bfde48..e3e224ad 100644
--- a/contrib/log/aliyun/aliyun_test.go
+++ b/contrib/log/aliyun/aliyun_test.go
@@ -116,21 +116,22 @@ func TestToString(t *testing.T) {
 		{"float64", 6.66, "6.66"},
 		{"max float64", math.MaxFloat64, "179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, //nolint:lll
 		{"float32", float32(6.66), "6.66"},
-		{"max float32", math.MaxFloat32, "340282346638528860000000000000000000000"},
-		{"int", int(math.MaxInt64), "9223372036854775807"},
+		{"max float32", float32(math.MaxFloat32), "340282350000000000000000000000000000000"},
+		{"int", math.MaxInt64, "9223372036854775807"},
 		{"uint", uint(math.MaxUint64), "18446744073709551615"},
-		{"int8", math.MaxInt8, "127"},
-		{"uint8", math.MaxUint8, "255"},
-		{"int16", math.MaxInt16, "32767"},
-		{"uint16", math.MaxUint16, "65535"},
-		{"int32", math.MaxInt32, "2147483647"},
-		{"uint32", math.MaxUint32, "4294967295"},
-		{"int64", math.MaxInt64, "9223372036854775807"},
+		{"int8", int8(math.MaxInt8), "127"},
+		{"uint8", uint8(math.MaxUint8), "255"},
+		{"int16", int16(math.MaxInt16), "32767"},
+		{"uint16", uint16(math.MaxUint16), "65535"},
+		{"int32", int32(math.MaxInt32), "2147483647"},
+		{"uint32", uint32(math.MaxUint32), "4294967295"},
+		{"int64", int64(math.MaxInt64), "9223372036854775807"},
 		{"uint64", uint64(math.MaxUint64), "18446744073709551615"},
 		{"string", "abc", "abc"},
 		{"bool", false, "false"},
 		{"[]byte", []byte("abc"), "abc"},
 		{"struct", struct{ Name string }{}, `{"Name":""}`},
+		{"nil", nil, ""},
 	}
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
diff --git a/contrib/log/tencent/tencent_test.go b/contrib/log/tencent/tencent_test.go
index 76bc13bd..df1fe367 100644
--- a/contrib/log/tencent/tencent_test.go
+++ b/contrib/log/tencent/tencent_test.go
@@ -120,21 +120,22 @@ func TestToString(t *testing.T) {
 		{"float64", 6.66, "6.66"},
 		{"max float64", math.MaxFloat64, "179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, //nolint:lll
 		{"float32", float32(6.66), "6.66"},
-		{"max float32", math.MaxFloat32, "340282346638528860000000000000000000000"},
-		{"int", int(math.MaxInt64), "9223372036854775807"},
+		{"max float32", float32(math.MaxFloat32), "340282350000000000000000000000000000000"},
+		{"int", math.MaxInt64, "9223372036854775807"},
 		{"uint", uint(math.MaxUint64), "18446744073709551615"},
-		{"int8", math.MaxInt8, "127"},
-		{"uint8", math.MaxUint8, "255"},
-		{"int16", math.MaxInt16, "32767"},
-		{"uint16", math.MaxUint16, "65535"},
-		{"int32", math.MaxInt32, "2147483647"},
-		{"uint32", math.MaxUint32, "4294967295"},
-		{"int64", math.MaxInt64, "9223372036854775807"},
+		{"int8", int8(math.MaxInt8), "127"},
+		{"uint8", uint8(math.MaxUint8), "255"},
+		{"int16", int16(math.MaxInt16), "32767"},
+		{"uint16", uint16(math.MaxUint16), "65535"},
+		{"int32", int32(math.MaxInt32), "2147483647"},
+		{"uint32", uint32(math.MaxUint32), "4294967295"},
+		{"int64", int64(math.MaxInt64), "9223372036854775807"},
 		{"uint64", uint64(math.MaxUint64), "18446744073709551615"},
 		{"string", "abc", "abc"},
 		{"bool", false, "false"},
 		{"[]byte", []byte("abc"), "abc"},
 		{"struct", struct{ Name string }{}, `{"Name":""}`},
+		{"nil", nil, ""},
 	}
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
diff --git a/encoding/form/form_test.go b/encoding/form/form_test.go
index ddd053cd..647d1edc 100644
--- a/encoding/form/form_test.go
+++ b/encoding/form/form_test.go
@@ -26,14 +26,12 @@ type TestModel struct {
 	Name string `json:"name"`
 }
 
-const contentType = "x-www-form-urlencoded"
-
 func TestFormCodecMarshal(t *testing.T) {
 	req := &LoginRequest{
 		Username: "kratos",
 		Password: "kratos_pwd",
 	}
-	content, err := encoding.GetCodec(contentType).Marshal(req)
+	content, err := encoding.GetCodec(Name).Marshal(req)
 	if err != nil {
 		t.Errorf("marshal error: %v", err)
 	}
@@ -45,7 +43,7 @@ func TestFormCodecMarshal(t *testing.T) {
 		Username: "kratos",
 		Password: "",
 	}
-	content, err = encoding.GetCodec(contentType).Marshal(req)
+	content, err = encoding.GetCodec(Name).Marshal(req)
 	if err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
 	}
@@ -57,7 +55,7 @@ func TestFormCodecMarshal(t *testing.T) {
 		ID:   1,
 		Name: "kratos",
 	}
-	content, err = encoding.GetCodec(contentType).Marshal(m)
+	content, err = encoding.GetCodec(Name).Marshal(m)
 	t.Log(string(content))
 	if err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
@@ -72,13 +70,13 @@ func TestFormCodecUnmarshal(t *testing.T) {
 		Username: "kratos",
 		Password: "kratos_pwd",
 	}
-	content, err := encoding.GetCodec(contentType).Marshal(req)
+	content, err := encoding.GetCodec(Name).Marshal(req)
 	if err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
 	}
 
 	bindReq := new(LoginRequest)
-	err = encoding.GetCodec(contentType).Unmarshal(content, bindReq)
+	err = encoding.GetCodec(Name).Unmarshal(content, bindReq)
 	if err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
 	}
@@ -119,7 +117,7 @@ func TestProtoEncodeDecode(t *testing.T) {
 		String_:   &wrapperspb.StringValue{Value: "go-kratos"},
 		Bytes:     &wrapperspb.BytesValue{Value: []byte("123")},
 	}
-	content, err := encoding.GetCodec(contentType).Marshal(in)
+	content, err := encoding.GetCodec(Name).Marshal(in)
 	if err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
 	}
@@ -130,7 +128,7 @@ func TestProtoEncodeDecode(t *testing.T) {
 		t.Errorf("rawpath is not equal to %v", string(content))
 	}
 	in2 := &complex.Complex{}
-	err = encoding.GetCodec(contentType).Unmarshal(content, in2)
+	err = encoding.GetCodec(Name).Unmarshal(content, in2)
 	if err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
 	}
@@ -163,7 +161,7 @@ func TestProtoEncodeDecode(t *testing.T) {
 func TestDecodeStructPb(t *testing.T) {
 	req := new(ectest.StructPb)
 	query := `data={"name":"kratos"}&data_list={"name1": "kratos"}&data_list={"name2": "go-kratos"}`
-	if err := encoding.GetCodec(contentType).Unmarshal([]byte(query), req); err != nil {
+	if err := encoding.GetCodec(Name).Unmarshal([]byte(query), req); err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
 	}
 	if !reflect.DeepEqual("kratos", req.Data.GetFields()["name"].GetStringValue()) {
@@ -186,7 +184,7 @@ func TestDecodeBytesValuePb(t *testing.T) {
 	val := base64.URLEncoding.EncodeToString([]byte(url))
 	content := "bytes=" + val
 	in2 := &complex.Complex{}
-	if err := encoding.GetCodec(contentType).Unmarshal([]byte(content), in2); err != nil {
+	if err := encoding.GetCodec(Name).Unmarshal([]byte(content), in2); err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
 	}
 	if !reflect.DeepEqual(url, string(in2.Bytes.Value)) {
diff --git a/encoding/form/proto_decode_test.go b/encoding/form/proto_decode_test.go
new file mode 100644
index 00000000..fbe23433
--- /dev/null
+++ b/encoding/form/proto_decode_test.go
@@ -0,0 +1,217 @@
+package form
+
+import (
+	"fmt"
+	"net/url"
+	"reflect"
+	"strconv"
+	"testing"
+
+	"google.golang.org/protobuf/reflect/protoreflect"
+
+	"github.com/go-kratos/kratos/v2/internal/testdata/complex"
+)
+
+func TestDecodeValues(t *testing.T) {
+	form, err := url.ParseQuery("a=19&age=18&b=true&bool=false&byte=MTIz&bytes=MTIz&count=3&d=22.22&double=12.33&duration=" +
+		"2m0.000000022s&field=1%2C2&float=12.34&id=2233&int32=32&int64=64&numberOne=2233&price=11.23&sex=woman&simples=3344&" +
+		"simples=5566&string=go-kratos&timestamp=1970-01-01T00%3A00%3A20.000000002Z&uint32=32&uint64=64&very_simple.component=5566")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	comp := &complex.Complex{}
+	err = DecodeValues(comp, form)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if comp.Id != int64(2233) {
+		t.Errorf("want %v, got %v", int64(2233), comp.Id)
+	}
+	if comp.NoOne != "2233" {
+		t.Errorf("want %v, got %v", "2233", comp.NoOne)
+	}
+	if comp.Simple == nil {
+		t.Fatalf("want %v, got %v", nil, comp.Simple)
+	}
+	if comp.Simple.Component != "5566" {
+		t.Errorf("want %v, got %v", "5566", comp.Simple.Component)
+	}
+	if len(comp.Simples) != 2 {
+		t.Fatalf("want %v, got %v", 2, len(comp.Simples))
+	}
+	if comp.Simples[0] != "3344" {
+		t.Errorf("want %v, got %v", "3344", comp.Simples[0])
+	}
+	if comp.Simples[1] != "5566" {
+		t.Errorf("want %v, got %v", "5566", comp.Simples[1])
+	}
+}
+
+func TestGetFieldDescriptor(t *testing.T) {
+	comp := &complex.Complex{}
+
+	field := getFieldDescriptor(comp.ProtoReflect(), "id")
+	if field.Kind() != protoreflect.Int64Kind {
+		t.Errorf("want: %d, got: %d", protoreflect.Int64Kind, field.Kind())
+	}
+
+	field = getFieldDescriptor(comp.ProtoReflect(), "simples")
+	if field.Kind() != protoreflect.StringKind {
+		t.Errorf("want: %d, got: %d", protoreflect.StringKind, field.Kind())
+	}
+}
+
+func TestPopulateRepeatedField(t *testing.T) {
+	query, err := url.ParseQuery("simples=3344&simples=5566")
+	if err != nil {
+		t.Fatal(err)
+	}
+	comp := &complex.Complex{}
+	field := getFieldDescriptor(comp.ProtoReflect(), "simples")
+
+	err = populateRepeatedField(field, comp.ProtoReflect().Mutable(field).List(), query["simples"])
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !reflect.DeepEqual([]string{"3344", "5566"}, comp.GetSimples()) {
+		t.Errorf("want: %v, got: %v", []string{"3344", "5566"}, comp.GetSimples())
+	}
+}
+
+func TestPopulateMapField(t *testing.T) {
+	query, err := url.ParseQuery("map%5Bkratos%5D=https://go-kratos.dev/")
+	if err != nil {
+		t.Fatal(err)
+	}
+	comp := &complex.Complex{}
+	field := getFieldDescriptor(comp.ProtoReflect(), "map")
+	// Fill the comp map field with the url query values
+	err = populateMapField(field, comp.ProtoReflect().Mutable(field).Map(), []string{"kratos"}, query["map[kratos]"])
+	if err != nil {
+		t.Fatal(err)
+	}
+	// Get the comp map field value
+	if query["map[kratos]"][0] != comp.Map["kratos"] {
+		t.Errorf("want: %s, got: %s", query["map[kratos]"], comp.Map["kratos"])
+	}
+}
+
+func TestParseField(t *testing.T) {
+	tests := []struct {
+		name                    string
+		fieldName               string
+		protoReflectKind        protoreflect.Kind
+		value                   string
+		targetProtoReflectValue protoreflect.Value
+		targetErr               error
+	}{
+		{
+			name:                    "BoolKind",
+			fieldName:               "b",
+			protoReflectKind:        protoreflect.BoolKind,
+			value:                   "true",
+			targetProtoReflectValue: protoreflect.ValueOfBool(true),
+			targetErr:               nil,
+		},
+		{
+			name:                    "BoolKind",
+			fieldName:               "b",
+			protoReflectKind:        protoreflect.BoolKind,
+			value:                   "a",
+			targetProtoReflectValue: protoreflect.Value{},
+			targetErr:               &strconv.NumError{Func: "ParseBool", Num: "a", Err: strconv.ErrSyntax},
+		},
+		{
+			name:                    "EnumKind",
+			fieldName:               "sex",
+			protoReflectKind:        protoreflect.EnumKind,
+			value:                   "1",
+			targetProtoReflectValue: protoreflect.ValueOfEnum(1),
+			targetErr:               nil,
+		},
+		{
+			name:                    "EnumKind",
+			fieldName:               "sex",
+			protoReflectKind:        protoreflect.EnumKind,
+			value:                   "2",
+			targetProtoReflectValue: protoreflect.Value{},
+			targetErr:               fmt.Errorf("%q is not a valid value", "2"),
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			comp := &complex.Complex{}
+			field := getFieldDescriptor(comp.ProtoReflect(), test.fieldName)
+			if test.protoReflectKind != field.Kind() {
+				t.Fatalf("want: %d, got: %d", test.protoReflectKind, field.Kind())
+			}
+			val, err := parseField(field, test.value)
+			if !reflect.DeepEqual(test.targetErr, err) {
+				t.Fatalf("want: %s, got: %s", test.targetErr, err)
+			}
+			if !reflect.DeepEqual(test.targetProtoReflectValue, val) {
+				t.Errorf("want: %s, got: %s", test.targetProtoReflectValue, val)
+			}
+		})
+	}
+}
+
+func TestJsonSnakeCase(t *testing.T) {
+	tests := []struct {
+		camelCase string
+		snakeCase string
+	}{
+		{
+			"userId", "user_id",
+		},
+		{
+			"user", "user",
+		},
+		{
+			"userIdAndUsername", "user_id_and_username",
+		},
+		{
+			"", "",
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.camelCase, func(t *testing.T) {
+			snake := jsonSnakeCase(test.camelCase)
+			if snake != test.snakeCase {
+				t.Errorf("want: %s, got: %s", test.snakeCase, snake)
+			}
+		})
+	}
+}
+
+func TestIsASCIIUpper(t *testing.T) {
+	tests := []struct {
+		b     byte
+		upper bool
+	}{
+		{
+			'A', true,
+		},
+		{
+			'a', false,
+		},
+		{
+			',', false,
+		},
+		{
+			'1', false,
+		},
+		{
+			' ', false,
+		},
+	}
+	for _, test := range tests {
+		t.Run(string(test.b), func(t *testing.T) {
+			upper := isASCIIUpper(test.b)
+			if test.upper != upper {
+				t.Errorf("'%s' is not ascii upper", string(test.b))
+			}
+		})
+	}
+}
diff --git a/log/filter_test.go b/log/filter_test.go
index d3c8d548..3e36deac 100644
--- a/log/filter_test.go
+++ b/log/filter_test.go
@@ -102,13 +102,19 @@ func TestFilterFuncWitchLoggerPrefix(t *testing.T) {
 			want:   "",
 		},
 		{
+			// Filtered value
 			logger: NewFilter(With(NewStdLogger(buf), "caller", "caller"), FilterFunc(testFilterFuncWithLoggerPrefix)),
-			want:   "INFO caller=caller msg=msg\n",
+			want:   "INFO caller=caller msg=msg filtered=***\n",
+		},
+		{
+			// NO prefix
+			logger: NewFilter(With(NewStdLogger(buf)), FilterFunc(testFilterFuncWithLoggerPrefix)),
+			want:   "INFO msg=msg filtered=***\n",
 		},
 	}
 
 	for _, tt := range tests {
-		err := tt.logger.Log(LevelInfo, "msg", "msg")
+		err := tt.logger.Log(LevelInfo, "msg", "msg", "filtered", "true")
 		if err != nil {
 			t.Fatal("err should be nil")
 		}
@@ -128,6 +134,9 @@ func testFilterFuncWithLoggerPrefix(level Level, keyvals ...interface{}) bool {
 		if keyvals[i] == "prefix" {
 			return true
 		}
+		if keyvals[i] == "filtered" {
+			keyvals[i+1] = fuzzyStr
+		}
 	}
 	return false
 }
diff --git a/options_test.go b/options_test.go
index 438de3d8..60600173 100644
--- a/options_test.go
+++ b/options_test.go
@@ -152,3 +152,39 @@ func TestStopTimeout(t *testing.T) {
 		t.Fatal("o.stopTimeout is not equal to v")
 	}
 }
+
+func TestBeforeStart(t *testing.T) {
+	o := &options{}
+	v := func(_ context.Context) error {
+		t.Log("BeforeStart...")
+		return nil
+	}
+	BeforeStart(v)(o)
+}
+
+func TestBeforeStop(t *testing.T) {
+	o := &options{}
+	v := func(_ context.Context) error {
+		t.Log("BeforeStop...")
+		return nil
+	}
+	BeforeStop(v)(o)
+}
+
+func TestAfterStart(t *testing.T) {
+	o := &options{}
+	v := func(_ context.Context) error {
+		t.Log("AfterStart...")
+		return nil
+	}
+	AfterStart(v)(o)
+}
+
+func TestAfterStop(t *testing.T) {
+	o := &options{}
+	v := func(_ context.Context) error {
+		t.Log("AfterStop...")
+		return nil
+	}
+	AfterStop(v)(o)
+}