Repository: go-kratos/kratos
Pull request #2373 (2022-09-11 14:48:01)

test(log): add toString unit test
<!--
🎉 Thanks for sending a pull request to Kratos! Here are some tips for you:

1. If this is your first time contributing to Kratos, please read our contribution guide: https://go-kratos.dev/en/docs/community/contribution/
2. Ensure you have added or ran the appropriate tests and lint for your PR, please use `make lint` and `make test` before filing your PR, use `make clean` to tidy your go mod.
3. If the PR is unfinished, you may need to mark it as a WIP(Work In Progress) PR or draft PR
4. Please use a semantic commits format title, such as `<type>[optional scope]: <description>`, see: https://go-kratos.dev/docs/community/contribution#type
5. at the same time, please note that similar work should be submitted in one PR as far as possible to reduce the workload of reviewers. Do not split a work into multiple PR unless it should.
-->

<!--
🎉 感谢您向 Kratos 发送 PR 请求！以下是一些提示：
如果这是你第一次为 Kratos 贡献，请阅读我们的贡献指南：https://go-kratos.dev/en/docs/community/contribution/
2、确保您已经为您的 PR 添加或运行了适当的测试和lint，请在提交PR之前使用“make lint”和“make test”，使用“make clean”整理您的 go.mod。
3、如果请购单未完成，您可能需要将其标记为 WIP（在制品）PR 或 draft PR
4、请使用语义提交格式标题，如“<类型>[可选范围]：<说明>`，请参阅：https://go-kratos.dev/docs/community/contribution#type
5. 同时请注意，同类的工作请尽量在一个PR中提交，以减轻 review 者的工作负担，不要把一项工作拆分成很多个PR，除非它应该这样做。
-->

<!--
-->

#### Description (what this PR does / why we need it):
<!--
* The description should include the motivation for this PR or contrast this with previous behavior
-->


#### Which issue(s) this PR fixes (resolves / be part of):
<!--
* Automatically closes linked issue when PR is merged.
* If your PR is not fully resolved the issue, please use `part of #<issue number>` instead.

Usage: `fixes/resolves #<issue number>`, or `fixes/resolves (paste link of issue)`.
-->
part of https://github.com/go-kratos/kratos/issues/2354

#### Other special notes for the reviewers:
<!--
* Somethings that need extra attention for the reviewers
* Some additional notes, TODO list, etc.
-->


codecov-commenter: # [Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2373?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) Report
> Merging [#2373](https://codecov.io/gh/go-kratos/kratos/pull/2373?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) (3241974) into [main](https://codecov.io/gh/go-kratos/kratos/commit/f2a33929d0bb3364fe02352689b1b5c79fa6f66f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) (f2a3392) will **not change** coverage.
> The diff coverage is `n/a`.

```diff
@@           Coverage Diff           @@
##             main    #2373   +/-   ##
=======================================
  Coverage   85.28%   85.28%           
=======================================
  Files          88       88           
  Lines        3778     3778           
=======================================
  Hits         3222     3222           
  Misses        391      391           
  Partials      165      165           
```



Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos)


Patch:
diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md
index c8cc2f81..eeaf2427 100644
--- a/.github/ISSUE_TEMPLATE/feature-request.md
+++ b/.github/ISSUE_TEMPLATE/feature-request.md
@@ -43,7 +43,7 @@ example:
 ### Requirements description of the feature
 <!--
 example:
-    The event interface should be added to Kratos. The interface should contain subscribers and publishers, and the message body should contain key value heade
+    The event interface should be added to Kratos. The interface should contain subscribers and publishers, and the message body should contain key value head
 -->
 ### References
 <!--
diff --git a/.gitignore b/.gitignore
index 0384a2c2..260c599e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,7 +3,6 @@
 *.exe
 *.exe~
 *.dll
-*.so
 *.dylib
 
 # Test binary, built with `go test -c`
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4048a5df..b0f9ceca 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,7 +1,7 @@
 The kratos community wants to be helped by a wide range of developers, so you'd like to take a few minutes to read this guide before you mention the problem or pull request.
 
-## Reportings Bug or Fixing Bugs
-We use github issues to manage issues. If you want to submit , first make sure you've searched for existing issues, pull requests and read our [FAQ](https://go-kratos.dev/docs/intro/faq).
+## Reporting Bug or Fixing Bugs
+We use GitHub issues to manage issues. If you want to submit , first make sure you've searched for existing issues, pull requests and read our [FAQ](https://go-kratos.dev/docs/intro/faq).
 
 When submitting a bug report, use the issue template we provide to clearly describe the problems encountered and how to reproduce, and if convenient it is best to provide a minimal reproduce repository.
 
@@ -16,9 +16,9 @@ After the function is implemented, a merge request will be initiated to associat
 After the merge is completed, Close all issues.
 
 ## How to submit code
-If you've never submitted code on github, follow these steps:
+If you've never submitted code on GitHub, follow these steps:
 
-- First, please fork items to your github account
+- First, please fork items to your GitHub account
 - Then create a new feature branch based on the main branch and name it features such as feature-log 
 - Write code
 - Submit code to the far end branch
diff --git a/api/metadata/server.go b/api/metadata/server.go
index 96f0e1e6..39e468ec 100644
--- a/api/metadata/server.go
+++ b/api/metadata/server.go
@@ -9,7 +9,6 @@ import (
 	"io"
 	"sync"
 
-	"github.com/go-kratos/kratos/v2/log"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
@@ -18,6 +17,8 @@ import (
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	"google.golang.org/protobuf/reflect/protoregistry"
 	dpb "google.golang.org/protobuf/types/descriptorpb"
+
+	"github.com/go-kratos/kratos/v2/log"
 )
 
 // Server is api meta server
diff --git a/cmd/kratos/internal/project/add.go b/cmd/kratos/internal/project/add.go
index f4c1b88c..9f30bfcb 100644
--- a/cmd/kratos/internal/project/add.go
+++ b/cmd/kratos/internal/project/add.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/AlecAivazis/survey/v2"
 	"github.com/fatih/color"
+
 	"github.com/go-kratos/kratos/cmd/kratos/v2/internal/base"
 )
 
diff --git a/cmd/kratos/internal/project/project.go b/cmd/kratos/internal/project/project.go
index 8ea7f2a9..271ad373 100644
--- a/cmd/kratos/internal/project/project.go
+++ b/cmd/kratos/internal/project/project.go
@@ -9,8 +9,9 @@ import (
 	"time"
 
 	"github.com/AlecAivazis/survey/v2"
-	"github.com/go-kratos/kratos/cmd/kratos/v2/internal/base"
 	"github.com/spf13/cobra"
+
+	"github.com/go-kratos/kratos/cmd/kratos/v2/internal/base"
 )
 
 // CmdNew represents the new command.
diff --git a/cmd/protoc-gen-go-errors/errors.go b/cmd/protoc-gen-go-errors/errors.go
index 6a097330..522c2968 100644
--- a/cmd/protoc-gen-go-errors/errors.go
+++ b/cmd/protoc-gen-go-errors/errors.go
@@ -8,9 +8,10 @@ import (
 	"golang.org/x/text/cases"
 	"golang.org/x/text/language"
 
-	"github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2/errors"
 	"google.golang.org/protobuf/compiler/protogen"
 	"google.golang.org/protobuf/proto"
+
+	"github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2/errors"
 )
 
 const (
diff --git a/cmd/protoc-gen-go-http/http.go b/cmd/protoc-gen-go-http/http.go
index cebbb6b1..d8827722 100644
--- a/cmd/protoc-gen-go-http/http.go
+++ b/cmd/protoc-gen-go-http/http.go
@@ -255,8 +255,8 @@ func camelCaseVars(s string) string {
 // drop the underscore and convert the letter to upper case.
 // There is a remote possibility of this rewrite causing a name collision,
 // but it's so remote we're prepared to pretend it's nonexistent - since the
-// C++ generator lowercases names, it's extremely unlikely to have two fields
-// with different capitalizations.
+// C++ generator lowercase names, it's extremely unlikely to have two fields
+// with different capitalization.
 // In short, _my_field_name_2 becomes XMyFieldName_2.
 func camelCase(s string) string {
 	if s == "" {
diff --git a/config/file/watcher.go b/config/file/watcher.go
index 4c00b046..ea309fa8 100644
--- a/config/file/watcher.go
+++ b/config/file/watcher.go
@@ -6,6 +6,7 @@ import (
 	"path/filepath"
 
 	"github.com/fsnotify/fsnotify"
+
 	"github.com/go-kratos/kratos/v2/config"
 )
 
diff --git a/contrib/config/apollo/apollo.go b/contrib/config/apollo/apollo.go
index 5f868bab..259ed1a9 100644
--- a/contrib/config/apollo/apollo.go
+++ b/contrib/config/apollo/apollo.go
@@ -10,6 +10,7 @@ import (
 	"github.com/apolloconfig/agollo/v4/constant"
 	apolloConfig "github.com/apolloconfig/agollo/v4/env/config"
 	"github.com/apolloconfig/agollo/v4/extension"
+
 	"github.com/go-kratos/kratos/v2/encoding"
 )
 
diff --git a/contrib/config/consul/config.go b/contrib/config/consul/config.go
index f42611e0..dca8a88e 100644
--- a/contrib/config/consul/config.go
+++ b/contrib/config/consul/config.go
@@ -6,8 +6,9 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/go-kratos/kratos/v2/config"
 	"github.com/hashicorp/consul/api"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 // Option is etcd config option.
diff --git a/contrib/config/consul/watcher.go b/contrib/config/consul/watcher.go
index baee9ef6..5c70d6f8 100644
--- a/contrib/config/consul/watcher.go
+++ b/contrib/config/consul/watcher.go
@@ -3,9 +3,10 @@ package consul
 import (
 	"context"
 
-	"github.com/go-kratos/kratos/v2/config"
 	"github.com/hashicorp/consul/api"
 	"github.com/hashicorp/consul/api/watch"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 type watcher struct {
diff --git a/contrib/config/etcd/README.md b/contrib/config/etcd/README.md
index c6f3f1bd..d7668745 100644
--- a/contrib/config/etcd/README.md
+++ b/contrib/config/etcd/README.md
@@ -10,7 +10,7 @@ import (
 	"google.golang.org/grpc"
 )
 
-// create a etcd client
+// create an etcd client
 client, err := clientv3.New(clientv3.Config{
     Endpoints:   []string{"127.0.0.1:2379"},
     DialTimeout: time.Second,
diff --git a/contrib/config/etcd/config.go b/contrib/config/etcd/config.go
index 37059e10..76045a58 100644
--- a/contrib/config/etcd/config.go
+++ b/contrib/config/etcd/config.go
@@ -6,8 +6,9 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/go-kratos/kratos/v2/config"
 	clientv3 "go.etcd.io/etcd/client/v3"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 // Option is etcd config option.
diff --git a/contrib/config/etcd/watcher.go b/contrib/config/etcd/watcher.go
index 388c2dd8..dd2ea911 100644
--- a/contrib/config/etcd/watcher.go
+++ b/contrib/config/etcd/watcher.go
@@ -3,8 +3,9 @@ package etcd
 import (
 	"context"
 
-	"github.com/go-kratos/kratos/v2/config"
 	clientv3 "go.etcd.io/etcd/client/v3"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 type watcher struct {
diff --git a/contrib/config/kubernetes/config.go b/contrib/config/kubernetes/config.go
index c66b837f..12026fe8 100644
--- a/contrib/config/kubernetes/config.go
+++ b/contrib/config/kubernetes/config.go
@@ -7,12 +7,13 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/go-kratos/kratos/v2/config"
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/clientcmd"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 // Option is kubernetes option.
diff --git a/contrib/config/kubernetes/watcher.go b/contrib/config/kubernetes/watcher.go
index 87872b8d..c13a8a7e 100644
--- a/contrib/config/kubernetes/watcher.go
+++ b/contrib/config/kubernetes/watcher.go
@@ -4,10 +4,11 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/go-kratos/kratos/v2/config"
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/watch"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 type watcher struct {
diff --git a/contrib/config/nacos/watcher.go b/contrib/config/nacos/watcher.go
index e190b688..fd528af7 100644
--- a/contrib/config/nacos/watcher.go
+++ b/contrib/config/nacos/watcher.go
@@ -5,8 +5,9 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/go-kratos/kratos/v2/config"
 	"github.com/nacos-group/nacos-sdk-go/vo"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 type Watcher struct {
diff --git a/contrib/log/aliyun/aliyun.go b/contrib/log/aliyun/aliyun.go
index 53fdefde..a5e57ca6 100644
--- a/contrib/log/aliyun/aliyun.go
+++ b/contrib/log/aliyun/aliyun.go
@@ -7,11 +7,12 @@ import (
 
 	sls "github.com/aliyun/aliyun-log-go-sdk"
 	"github.com/aliyun/aliyun-log-go-sdk/producer"
-	log "github.com/go-kratos/kratos/v2/log"
 	"google.golang.org/protobuf/proto"
+
+	log "github.com/go-kratos/kratos/v2/log"
 )
 
-// Log see more detail https://github.com/aliyun/aliyun-log-go-sdk
+// Logger see more detail https://github.com/aliyun/aliyun-log-go-sdk
 type Logger interface {
 	log.Logger
 	GetProducer() *producer.Producer
@@ -126,7 +127,7 @@ func NewAliyunLog(options ...Option) Logger {
 	}
 }
 
-// toString 任意类型转string
+// toString convert any type to string
 func toString(v interface{}) string {
 	var key string
 	if v == nil {
@@ -159,6 +160,8 @@ func toString(v interface{}) string {
 		key = strconv.FormatUint(v, 10)
 	case string:
 		key = v
+	case bool:
+		key = strconv.FormatBool(v)
 	case []byte:
 		key = string(v)
 	default:
diff --git a/contrib/log/fluent/fluent.go b/contrib/log/fluent/fluent.go
index 07a15b86..86e86993 100644
--- a/contrib/log/fluent/fluent.go
+++ b/contrib/log/fluent/fluent.go
@@ -8,6 +8,7 @@ import (
 	"time"
 
 	"github.com/fluent/fluent-logger-golang/fluent"
+
 	"github.com/go-kratos/kratos/v2/log"
 )
 
diff --git a/contrib/log/logrus/go.mod b/contrib/log/logrus/go.mod
index aa1f5946..c41e4ecc 100644
--- a/contrib/log/logrus/go.mod
+++ b/contrib/log/logrus/go.mod
@@ -5,7 +5,6 @@ go 1.16
 require (
 	github.com/go-kratos/kratos/v2 v2.5.0
 	github.com/sirupsen/logrus v1.8.1
-	github.com/stretchr/testify v1.7.1
 )
 
 replace github.com/go-kratos/kratos/v2 => ../../../
diff --git a/contrib/log/logrus/go.sum b/contrib/log/logrus/go.sum
index 129b0363..c8ee9b37 100644
--- a/contrib/log/logrus/go.sum
+++ b/contrib/log/logrus/go.sum
@@ -154,7 +154,6 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
 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/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/contrib/log/logrus/logrus.go b/contrib/log/logrus/logrus.go
index b08ba6e1..6fda38c5 100644
--- a/contrib/log/logrus/logrus.go
+++ b/contrib/log/logrus/logrus.go
@@ -1,8 +1,9 @@
 package logrus
 
 import (
-	"github.com/go-kratos/kratos/v2/log"
 	"github.com/sirupsen/logrus"
+
+	"github.com/go-kratos/kratos/v2/log"
 )
 
 var _ log.Logger = (*Logger)(nil)
diff --git a/contrib/log/tencent/tencent.go b/contrib/log/tencent/tencent.go
index 5d7267f2..40cc98cd 100644
--- a/contrib/log/tencent/tencent.go
+++ b/contrib/log/tencent/tencent.go
@@ -6,9 +6,10 @@ import (
 	"strconv"
 	"time"
 
-	log "github.com/go-kratos/kratos/v2/log"
 	cls "github.com/tencentcloud/tencentcloud-cls-sdk-go"
 	"google.golang.org/protobuf/proto"
+
+	log "github.com/go-kratos/kratos/v2/log"
 )
 
 type Logger interface {
diff --git a/contrib/log/zap/zap.go b/contrib/log/zap/zap.go
index 5929c486..511381f9 100644
--- a/contrib/log/zap/zap.go
+++ b/contrib/log/zap/zap.go
@@ -3,8 +3,9 @@ package zap
 import (
 	"fmt"
 
-	"github.com/go-kratos/kratos/v2/log"
 	"go.uber.org/zap"
+
+	"github.com/go-kratos/kratos/v2/log"
 )
 
 var _ log.Logger = (*Logger)(nil)
diff --git a/contrib/metrics/datadog/options.go b/contrib/metrics/datadog/options.go
index d07d418f..ffb9bd80 100644
--- a/contrib/metrics/datadog/options.go
+++ b/contrib/metrics/datadog/options.go
@@ -2,7 +2,7 @@ package datadog
 
 import "github.com/DataDog/datadog-go/statsd"
 
-// Option is doatadog option.
+// Option is datadog option.
 type Option func(*options)
 
 type options struct {
diff --git a/contrib/metrics/prometheus/counter.go b/contrib/metrics/prometheus/counter.go
index 8b90beab..5873c017 100644
--- a/contrib/metrics/prometheus/counter.go
+++ b/contrib/metrics/prometheus/counter.go
@@ -1,8 +1,9 @@
 package prometheus
 
 import (
-	"github.com/go-kratos/kratos/v2/metrics"
 	"github.com/prometheus/client_golang/prometheus"
+
+	"github.com/go-kratos/kratos/v2/metrics"
 )
 
 var _ metrics.Counter = (*counter)(nil)
diff --git a/contrib/metrics/prometheus/gauge.go b/contrib/metrics/prometheus/gauge.go
index 6df11d69..25750b6c 100644
--- a/contrib/metrics/prometheus/gauge.go
+++ b/contrib/metrics/prometheus/gauge.go
@@ -1,8 +1,9 @@
 package prometheus
 
 import (
-	"github.com/go-kratos/kratos/v2/metrics"
 	"github.com/prometheus/client_golang/prometheus"
+
+	"github.com/go-kratos/kratos/v2/metrics"
 )
 
 var _ metrics.Gauge = (*gauge)(nil)
diff --git a/contrib/metrics/prometheus/histogram.go b/contrib/metrics/prometheus/histogram.go
index 81b3b281..a0245d73 100644
--- a/contrib/metrics/prometheus/histogram.go
+++ b/contrib/metrics/prometheus/histogram.go
@@ -1,8 +1,9 @@
 package prometheus
 
 import (
-	"github.com/go-kratos/kratos/v2/metrics"
 	"github.com/prometheus/client_golang/prometheus"
+
+	"github.com/go-kratos/kratos/v2/metrics"
 )
 
 var _ metrics.Observer = (*histogram)(nil)
diff --git a/contrib/metrics/prometheus/summary.go b/contrib/metrics/prometheus/summary.go
index d8bcad91..25969edf 100644
--- a/contrib/metrics/prometheus/summary.go
+++ b/contrib/metrics/prometheus/summary.go
@@ -1,8 +1,9 @@
 package prometheus
 
 import (
-	"github.com/go-kratos/kratos/v2/metrics"
 	"github.com/prometheus/client_golang/prometheus"
+
+	"github.com/go-kratos/kratos/v2/metrics"
 )
 
 var _ metrics.Observer = (*summary)(nil)
diff --git a/contrib/registry/consul/client.go b/contrib/registry/consul/client.go
index 1b39975a..c1364bb3 100644
--- a/contrib/registry/consul/client.go
+++ b/contrib/registry/consul/client.go
@@ -132,6 +132,8 @@ func (c *Client) Register(_ context.Context, svc *registry.ServiceInstance, enab
 				Timeout:                        "5s",
 			})
 		}
+		// custom checks
+		asr.Checks = append(asr.Checks, c.serviceChecks...)
 	}
 	if c.heartbeat {
 		asr.Checks = append(asr.Checks, &api.AgentServiceCheck{
@@ -141,9 +143,6 @@ func (c *Client) Register(_ context.Context, svc *registry.ServiceInstance, enab
 		})
 	}
 
-	// custom checks
-	asr.Checks = append(asr.Checks, c.serviceChecks...)
-
 	err := c.cli.Agent().ServiceRegister(asr)
 	if err != nil {
 		return err
@@ -173,7 +172,7 @@ func (c *Client) Register(_ context.Context, svc *registry.ServiceInstance, enab
 	return nil
 }
 
-// Deregister deregister service by service ID
+// Deregister service by service ID
 func (c *Client) Deregister(_ context.Context, serviceID string) error {
 	c.cancel()
 	return c.cli.Agent().ServiceDeregister(serviceID)
diff --git a/contrib/registry/discovery/discovery.go b/contrib/registry/discovery/discovery.go
index dfff0a97..f439b0ca 100644
--- a/contrib/registry/discovery/discovery.go
+++ b/contrib/registry/discovery/discovery.go
@@ -10,9 +10,10 @@ import (
 	"sync/atomic"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/log"
 	"github.com/go-resty/resty/v2"
 	"github.com/pkg/errors"
+
+	"github.com/go-kratos/kratos/v2/log"
 )
 
 type Discovery struct {
@@ -308,7 +309,7 @@ func (d *Discovery) cancel(ins *discoveryInstance) (err error) {
 func (d *Discovery) broadcast(apps map[string]*disInstancesInfo) {
 	for appID, v := range apps {
 		var count int
-		// v maybe nil in old version(less than v1.1) Discovery,check incase of panic
+		// v maybe nil in old version(less than v1.1) Discovery, check in case of panic
 		if v == nil {
 			continue
 		}
diff --git a/contrib/registry/etcd/registry.go b/contrib/registry/etcd/registry.go
index 945b76a0..5592f62d 100644
--- a/contrib/registry/etcd/registry.go
+++ b/contrib/registry/etcd/registry.go
@@ -6,8 +6,9 @@ import (
 	"math/rand"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	clientv3 "go.etcd.io/etcd/client/v3"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 var (
@@ -153,7 +154,7 @@ func (r *Registry) heartBeat(ctx context.Context, leaseID clientv3.LeaseID, key
 	for {
 		if curLeaseID == 0 {
 			// try to registerWithKV
-			retreat := []int{}
+			var retreat []int
 			for retryCnt := 0; retryCnt < r.opts.maxRetry; retryCnt++ {
 				if ctx.Err() != nil {
 					return
diff --git a/contrib/registry/etcd/watcher.go b/contrib/registry/etcd/watcher.go
index a5bf63c4..0e531a99 100644
--- a/contrib/registry/etcd/watcher.go
+++ b/contrib/registry/etcd/watcher.go
@@ -3,8 +3,9 @@ package etcd
 import (
 	"context"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	clientv3 "go.etcd.io/etcd/client/v3"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 var _ registry.Watcher = (*watcher)(nil)
diff --git a/contrib/registry/eureka/eureka.go b/contrib/registry/eureka/eureka.go
index ee82d850..a5c1201e 100644
--- a/contrib/registry/eureka/eureka.go
+++ b/contrib/registry/eureka/eureka.go
@@ -28,7 +28,7 @@ func NewAPI(ctx context.Context, client *Client, refreshInterval time.Duration)
 		refreshInterval: refreshInterval,
 	}
 
-	// 首次广播一次
+	// it is required to broadcast for the first time
 	e.broadcast()
 
 	go e.refresh(ctx)
@@ -93,7 +93,7 @@ func (e *API) Register(ctx context.Context, serviceName string, endpoints ...End
 	return nil
 }
 
-// Deregister 中的ctx 和 register ctx 是同一个
+// Deregister ctx is the same as register ctx
 func (e *API) Deregister(ctx context.Context, endpoints []Endpoint) error {
 	for _, ep := range endpoints {
 		if err := e.cli.Deregister(ctx, ep.AppID, ep.InstanceID); err != nil {
@@ -121,7 +121,7 @@ func (e *API) GetService(ctx context.Context, serverName string) []Instance {
 		return ins
 	}
 
-	// 如果不再allinstances 中可以尝试再单独获取一次
+	// if not in allInstances of API, you can try to obtain it separately again
 	return e.cli.FetchAppUpInstances(ctx, appID)
 }
 
diff --git a/contrib/registry/kubernetes/registry.go b/contrib/registry/kubernetes/registry.go
index 6f08157d..987ef1e1 100644
--- a/contrib/registry/kubernetes/registry.go
+++ b/contrib/registry/kubernetes/registry.go
@@ -11,7 +11,6 @@ import (
 	"strings"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	jsoniter "github.com/json-iterator/go"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -21,6 +20,8 @@ import (
 	"k8s.io/client-go/kubernetes"
 	listerv1 "k8s.io/client-go/listers/core/v1"
 	"k8s.io/client-go/tools/cache"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 // Defines the key name of specific fields
@@ -299,7 +300,7 @@ func (iter *Iterator) Next() ([]*registry.ServiceInstance, error) {
 	}
 }
 
-// Close is used to close the iterator
+// Stop is used to close the iterator
 func (iter *Iterator) Stop() error {
 	select {
 	case <-iter.stopCh:
diff --git a/contrib/registry/nacos/registry.go b/contrib/registry/nacos/registry.go
index 088cb8c2..1a3722b8 100644
--- a/contrib/registry/nacos/registry.go
+++ b/contrib/registry/nacos/registry.go
@@ -2,6 +2,7 @@ package nacos
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"net"
 	"net/url"
@@ -14,6 +15,8 @@ import (
 	"github.com/go-kratos/kratos/v2/registry"
 )
 
+var ErrServiceInstanceNameEmpty = errors.New("kratos/nacos: ServiceInstance.Name can not be empty")
+
 var (
 	_ registry.Registrar = (*Registry)(nil)
 	_ registry.Discovery = (*Registry)(nil)
@@ -82,7 +85,7 @@ func New(cli naming_client.INamingClient, opts ...Option) (r *Registry) {
 // Register the registration.
 func (r *Registry) Register(_ context.Context, si *registry.ServiceInstance) error {
 	if si.Name == "" {
-		return fmt.Errorf("kratos/nacos: serviceInstance.name can not be empty")
+		return ErrServiceInstanceNameEmpty
 	}
 	for _, endpoint := range si.Endpoints {
 		u, err := url.Parse(endpoint)
diff --git a/contrib/registry/nacos/watcher.go b/contrib/registry/nacos/watcher.go
index c5d652fc..78b4fc21 100644
--- a/contrib/registry/nacos/watcher.go
+++ b/contrib/registry/nacos/watcher.go
@@ -4,10 +4,11 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	"github.com/nacos-group/nacos-sdk-go/clients/naming_client"
 	"github.com/nacos-group/nacos-sdk-go/model"
 	"github.com/nacos-group/nacos-sdk-go/vo"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 var _ registry.Watcher = (*watcher)(nil)
diff --git a/contrib/registry/servicecomb/go.mod b/contrib/registry/servicecomb/go.mod
index 43661281..b5cb1c42 100644
--- a/contrib/registry/servicecomb/go.mod
+++ b/contrib/registry/servicecomb/go.mod
@@ -7,9 +7,5 @@ require (
 	github.com/go-chassis/sc-client v0.6.1-0.20210615014358-a45e9090c751
 	github.com/go-kratos/kratos/v2 v2.3.1
 	github.com/gofrs/uuid v4.2.0+incompatible
-)
-
-require (
-	github.com/stretchr/testify v1.7.1
 	golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4
 )
diff --git a/contrib/registry/servicecomb/go.sum b/contrib/registry/servicecomb/go.sum
index 738943db..015d1508 100644
--- a/contrib/registry/servicecomb/go.sum
+++ b/contrib/registry/servicecomb/go.sum
@@ -137,9 +137,7 @@ github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+
 github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
 github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
 github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
-github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
 github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
-github.com/go-playground/form/v4 v4.2.0 h1:N1wh+Goz61e6w66vo8vJkQt+uwZSoLz50kZPJWR8eic=
 github.com/go-playground/form/v4 v4.2.0/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U=
 github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
@@ -204,7 +202,6 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
 github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
-github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -219,7 +216,6 @@ github.com/google/go-cmp v0.5.2/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/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -229,14 +225,12 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
 github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
 github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
 github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
 github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
@@ -302,11 +296,9 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
 github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
-github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
 github.com/little-cui/etcdadpt v0.3.2/go.mod h1:HnRRpIrVEVNWobkiCvG2EHLWKKZ+L047EcI29ma2zA4=
@@ -548,7 +540,6 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4=
 golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -589,7 +580,6 @@ golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7w
 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-20210816074244-15123e1e1f71/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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -597,7 +587,6 @@ 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 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 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=
@@ -636,7 +625,6 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
 google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
@@ -660,7 +648,6 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfG
 google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
 google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
-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=
 google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -674,7 +661,6 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG
 google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
 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/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=
@@ -688,12 +674,10 @@ 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=
 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=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
diff --git a/contrib/registry/servicecomb/registry.go b/contrib/registry/servicecomb/registry.go
index 7dd388c9..7a532396 100644
--- a/contrib/registry/servicecomb/registry.go
+++ b/contrib/registry/servicecomb/registry.go
@@ -7,7 +7,6 @@ import (
 	"time"
 
 	"github.com/go-chassis/cari/discovery"
-	pb "github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/cari/pkg/errsvc"
 	"github.com/go-chassis/sc-client"
 
@@ -114,7 +113,7 @@ func (r *Registry) Register(_ context.Context, svcIns *registry.ServiceInstance)
 			return parseErr
 		}
 		// 若错误码显示服务未注册，直接返回
-		if svcErr.Code != pb.ErrServiceAlreadyExists {
+		if svcErr.Code != discovery.ErrServiceAlreadyExists {
 			return err
 		}
 		sid, err = r.cli.GetMicroServiceID(appID, ms.ServiceName, ms.Version, ms.Environment)
diff --git a/contrib/registry/zookeeper/watcher.go b/contrib/registry/zookeeper/watcher.go
index f2009675..ddb98a84 100644
--- a/contrib/registry/zookeeper/watcher.go
+++ b/contrib/registry/zookeeper/watcher.go
@@ -6,8 +6,9 @@ import (
 	"path"
 	"sync/atomic"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	"github.com/go-zookeeper/zk"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 var _ registry.Watcher = (*watcher)(nil)
diff --git a/encoding/form/form.go b/encoding/form/form.go
index 77c4237b..823aeb8f 100644
--- a/encoding/form/form.go
+++ b/encoding/form/form.go
@@ -17,10 +17,13 @@ const (
 	nullStr = "null"
 )
 
+var (
+	encoder = form.NewEncoder()
+	decoder = form.NewDecoder()
+)
+
 func init() {
-	decoder := form.NewDecoder()
 	decoder.SetTagName("json")
-	encoder := form.NewEncoder()
 	encoder.SetTagName("json")
 	encoding.RegisterCodec(codec{encoder: encoder, decoder: decoder})
 }
diff --git a/encoding/form/proto_decode.go b/encoding/form/proto_decode.go
index 2856bef5..47affee1 100644
--- a/encoding/form/proto_decode.go
+++ b/encoding/form/proto_decode.go
@@ -52,7 +52,7 @@ func populateFieldValues(v protoreflect.Message, fieldPath []string, values []st
 
 		if fd.Message() == nil || fd.Cardinality() == protoreflect.Repeated {
 			if fd.IsMap() && len(fieldPath) > 1 {
-				// post sub field
+				// post subfield
 				return populateMapField(fd, v.Mutable(fd).Map(), []string{fieldPath[1]}, values)
 			}
 			return fmt.Errorf("invalid path: %q is not a message", fieldName)
diff --git a/encoding/form/proto_encode.go b/encoding/form/proto_encode.go
index 449fca0d..28ebb0bc 100644
--- a/encoding/form/proto_encode.go
+++ b/encoding/form/proto_encode.go
@@ -14,16 +14,19 @@ import (
 )
 
 // EncodeValues encode a message into url values.
-func EncodeValues(msg proto.Message) (url.Values, error) {
+func EncodeValues(msg interface{}) (url.Values, error) {
 	if msg == nil || (reflect.ValueOf(msg).Kind() == reflect.Ptr && reflect.ValueOf(msg).IsNil()) {
 		return url.Values{}, nil
 	}
-	u := make(url.Values)
-	err := encodeByField(u, "", msg.ProtoReflect())
-	if err != nil {
-		return nil, err
+	if v, ok := msg.(proto.Message); ok {
+		u := make(url.Values)
+		err := encodeByField(u, "", v.ProtoReflect())
+		if err != nil {
+			return nil, err
+		}
+		return u, nil
 	}
-	return u, nil
+	return encoder.Encode(msg)
 }
 
 func encodeByField(u url.Values, path string, m protoreflect.Message) (finalErr error) {
diff --git a/encoding/json/json.go b/encoding/json/json.go
index d5e020b7..c1982190 100644
--- a/encoding/json/json.go
+++ b/encoding/json/json.go
@@ -4,9 +4,10 @@ import (
 	"encoding/json"
 	"reflect"
 
-	"github.com/go-kratos/kratos/v2/encoding"
 	"google.golang.org/protobuf/encoding/protojson"
 	"google.golang.org/protobuf/proto"
+
+	"github.com/go-kratos/kratos/v2/encoding"
 )
 
 // Name is the name registered for the json codec.
diff --git a/encoding/yaml/yaml.go b/encoding/yaml/yaml.go
index b2f885f0..1364b24c 100644
--- a/encoding/yaml/yaml.go
+++ b/encoding/yaml/yaml.go
@@ -1,8 +1,9 @@
 package yaml
 
 import (
-	"github.com/go-kratos/kratos/v2/encoding"
 	"gopkg.in/yaml.v3"
+
+	"github.com/go-kratos/kratos/v2/encoding"
 )
 
 // Name is the name registered for the yaml codec.
diff --git a/errors/errors.go b/errors/errors.go
index fd95ff3b..caf31cd3 100644
--- a/errors/errors.go
+++ b/errors/errors.go
@@ -4,9 +4,10 @@ import (
 	"errors"
 	"fmt"
 
-	httpstatus "github.com/go-kratos/kratos/v2/transport/http/status"
 	"google.golang.org/genproto/googleapis/rpc/errdetails"
 	"google.golang.org/grpc/status"
+
+	httpstatus "github.com/go-kratos/kratos/v2/transport/http/status"
 )
 
 const (
diff --git a/errors/types.go b/errors/types.go
index e3d033b0..6a57f32a 100644
--- a/errors/types.go
+++ b/errors/types.go
@@ -17,7 +17,7 @@ func Unauthorized(reason, message string) *Error {
 	return New(401, reason, message)
 }
 
-// IsUnauthorized determines if err is an error which indicates a Unauthorized error.
+// IsUnauthorized determines if err is an error which indicates an Unauthorized error.
 // It supports wrapped errors.
 func IsUnauthorized(err error) bool {
 	return Code(err) == 401
@@ -67,18 +67,18 @@ func IsInternalServer(err error) bool {
 	return Code(err) == 500
 }
 
-// ServiceUnavailable new ServiceUnavailable error that is mapped to a HTTP 503 response.
+// ServiceUnavailable new ServiceUnavailable error that is mapped to an HTTP 503 response.
 func ServiceUnavailable(reason, message string) *Error {
 	return New(503, reason, message)
 }
 
-// IsServiceUnavailable determines if err is an error which indicates a Unavailable error.
+// IsServiceUnavailable determines if err is an error which indicates an Unavailable error.
 // It supports wrapped errors.
 func IsServiceUnavailable(err error) bool {
 	return Code(err) == 503
 }
 
-// GatewayTimeout new GatewayTimeout error that is mapped to a HTTP 504 response.
+// GatewayTimeout new GatewayTimeout error that is mapped to an HTTP 504 response.
 func GatewayTimeout(reason, message string) *Error {
 	return New(504, reason, message)
 }
@@ -89,7 +89,7 @@ func IsGatewayTimeout(err error) bool {
 	return Code(err) == 504
 }
 
-// ClientClosed new ClientClosed error that is mapped to a HTTP 499 response.
+// ClientClosed new ClientClosed error that is mapped to an HTTP 499 response.
 func ClientClosed(reason, message string) *Error {
 	return New(499, reason, message)
 }
diff --git a/internal/group/group.go b/internal/group/group.go
index bb9d0568..c97496d1 100644
--- a/internal/group/group.go
+++ b/internal/group/group.go
@@ -33,7 +33,7 @@ func (g *Group) Get(key string) interface{} {
 	}
 	g.RUnlock()
 
-	// slowpath for group don`t have specified key value
+	// slow path for group don`t have specified key value
 	g.Lock()
 	defer g.Unlock()
 	v, ok = g.vals[key]
diff --git a/log/helper_writer.go b/log/helper_writer.go
index 5ab45802..4d5e68b8 100644
--- a/log/helper_writer.go
+++ b/log/helper_writer.go
@@ -9,7 +9,7 @@ type writerWrapper struct {
 
 type WriterOptionFn func(w *writerWrapper)
 
-// WithWriteLevel set writerWrapper level.
+// WithWriterLevel set writerWrapper level.
 func WithWriterLevel(level Level) WriterOptionFn {
 	return func(w *writerWrapper) {
 		w.level = level
diff --git a/middleware/circuitbreaker/circuitbreaker.go b/middleware/circuitbreaker/circuitbreaker.go
index 1b4fa08f..31433ee7 100644
--- a/middleware/circuitbreaker/circuitbreaker.go
+++ b/middleware/circuitbreaker/circuitbreaker.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/go-kratos/aegis/circuitbreaker"
 	"github.com/go-kratos/aegis/circuitbreaker/sre"
+
 	"github.com/go-kratos/kratos/v2/errors"
 	"github.com/go-kratos/kratos/v2/internal/group"
 	"github.com/go-kratos/kratos/v2/middleware"
@@ -46,8 +47,8 @@ func Client(opts ...Option) middleware.Middleware {
 			breaker := opt.group.Get(info.Operation()).(circuitbreaker.CircuitBreaker)
 			if err := breaker.Allow(); err != nil {
 				// rejected
-				// NOTE: when client reject requets locally,
-				// continue add counter let the drop ratio higher.
+				// NOTE: when client reject requests locally,
+				// continue to add counter let the drop ratio higher.
 				breaker.MarkFailed()
 				return nil, ErrNotAllowed
 			}
diff --git a/middleware/logging/logging.go b/middleware/logging/logging.go
index d050da9a..6f292242 100644
--- a/middleware/logging/logging.go
+++ b/middleware/logging/logging.go
@@ -47,7 +47,7 @@ func Server(logger log.Logger) middleware.Middleware {
 	}
 }
 
-// Client is an client logging middleware.
+// Client is a client logging middleware.
 func Client(logger log.Logger) middleware.Middleware {
 	return func(handler middleware.Handler) middleware.Handler {
 		return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
diff --git a/middleware/ratelimit/ratelimit.go b/middleware/ratelimit/ratelimit.go
index 5bfae27b..23f21753 100644
--- a/middleware/ratelimit/ratelimit.go
+++ b/middleware/ratelimit/ratelimit.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/go-kratos/aegis/ratelimit"
 	"github.com/go-kratos/aegis/ratelimit/bbr"
+
 	"github.com/go-kratos/kratos/v2/errors"
 	"github.com/go-kratos/kratos/v2/middleware"
 )
diff --git a/middleware/tracing/metadata.go b/middleware/tracing/metadata.go
index 01e51132..7ad82806 100644
--- a/middleware/tracing/metadata.go
+++ b/middleware/tracing/metadata.go
@@ -3,9 +3,10 @@ package tracing
 import (
 	"context"
 
+	"go.opentelemetry.io/otel/propagation"
+
 	"github.com/go-kratos/kratos/v2"
 	"github.com/go-kratos/kratos/v2/metadata"
-	"go.opentelemetry.io/otel/propagation"
 )
 
 const serviceHeader = "x-md-service-name"
diff --git a/middleware/tracing/span.go b/middleware/tracing/span.go
index 38bb35f4..7edb914e 100644
--- a/middleware/tracing/span.go
+++ b/middleware/tracing/span.go
@@ -18,10 +18,12 @@ import (
 )
 
 func setClientSpan(ctx context.Context, span trace.Span, m interface{}) {
-	attrs := []attribute.KeyValue{}
-	var remote string
-	var operation string
-	var rpcKind string
+	var (
+		attrs     []attribute.KeyValue
+		remote    string
+		operation string
+		rpcKind   string
+	)
 	tr, ok := transport.FromClientContext(ctx)
 	if ok {
 		operation = tr.Operation()
diff --git a/middleware/tracing/tracer.go b/middleware/tracing/tracer.go
index cf9115bb..798994f8 100644
--- a/middleware/tracing/tracer.go
+++ b/middleware/tracing/tracer.go
@@ -4,13 +4,14 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/go-kratos/kratos/v2/errors"
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/codes"
 	"go.opentelemetry.io/otel/propagation"
 	"go.opentelemetry.io/otel/trace"
 	"google.golang.org/protobuf/proto"
+
+	"github.com/go-kratos/kratos/v2/errors"
 )
 
 // Tracer is otel span tracer
diff --git a/middleware/tracing/tracing.go b/middleware/tracing/tracing.go
index 167725f4..b89ce0a2 100644
--- a/middleware/tracing/tracing.go
+++ b/middleware/tracing/tracing.go
@@ -5,10 +5,11 @@ import (
 
 	"github.com/go-kratos/kratos/v2/log"
 
-	"github.com/go-kratos/kratos/v2/middleware"
-	"github.com/go-kratos/kratos/v2/transport"
 	"go.opentelemetry.io/otel/propagation"
 	"go.opentelemetry.io/otel/trace"
+
+	"github.com/go-kratos/kratos/v2/middleware"
+	"github.com/go-kratos/kratos/v2/transport"
 )
 
 // Option is tracing option.
diff --git a/registry/registry.go b/registry/registry.go
index 84df37b6..7046bafc 100644
--- a/registry/registry.go
+++ b/registry/registry.go
@@ -39,7 +39,7 @@ type ServiceInstance struct {
 	Version string `json:"version"`
 	// Metadata is the kv pair metadata associated with the service instance.
 	Metadata map[string]string `json:"metadata"`
-	// Endpoints is endpoint addresses of the service instance.
+	// Endpoints are endpoint addresses of the service instance.
 	// schema:
 	//   http://127.0.0.1:8000?isSecure=false
 	//   grpc://127.0.0.1:9000?isSecure=false
diff --git a/selector/default_node.go b/selector/default_node.go
index 186629e7..3554a3a1 100644
--- a/selector/default_node.go
+++ b/selector/default_node.go
@@ -6,6 +6,8 @@ import (
 	"github.com/go-kratos/kratos/v2/registry"
 )
 
+var _ Node = (*DefaultNode)(nil)
+
 // DefaultNode is selector node
 type DefaultNode struct {
 	scheme   string
diff --git a/selector/default_selector.go b/selector/default_selector.go
index 247af2e9..83b1ce9e 100644
--- a/selector/default_selector.go
+++ b/selector/default_selector.go
@@ -5,6 +5,11 @@ import (
 	"sync/atomic"
 )
 
+var (
+	_ Rebalancer = (*Default)(nil)
+	_ Builder    = (*DefaultBuilder)(nil)
+)
+
 // Default is composite selector.
 type Default struct {
 	NodeBuilder WeightedNodeBuilder
diff --git a/selector/node/direct/direct.go b/selector/node/direct/direct.go
index 62b30ed7..d32fc314 100644
--- a/selector/node/direct/direct.go
+++ b/selector/node/direct/direct.go
@@ -13,8 +13,8 @@ const (
 )
 
 var (
-	_ selector.WeightedNode        = &Node{}
-	_ selector.WeightedNodeBuilder = &Builder{}
+	_ selector.WeightedNode        = (*Node)(nil)
+	_ selector.WeightedNodeBuilder = (*Builder)(nil)
 )
 
 // Node is endpoint instance
diff --git a/selector/node/ewma/node.go b/selector/node/ewma/node.go
index 1707f108..4fed4aaa 100644
--- a/selector/node/ewma/node.go
+++ b/selector/node/ewma/node.go
@@ -21,8 +21,8 @@ const (
 )
 
 var (
-	_ selector.WeightedNode        = &Node{}
-	_ selector.WeightedNodeBuilder = &Builder{}
+	_ selector.WeightedNode        = (*Node)(nil)
+	_ selector.WeightedNodeBuilder = (*Builder)(nil)
 )
 
 // Node is endpoint instance
diff --git a/selector/random/random.go b/selector/random/random.go
index 3af52d41..1ab7c979 100644
--- a/selector/random/random.go
+++ b/selector/random/random.go
@@ -24,7 +24,7 @@ type options struct{}
 // Balancer is a random balancer.
 type Balancer struct{}
 
-// New an random selector.
+// New a random selector.
 func New(opts ...Option) selector.Selector {
 	return NewBuilder(opts...).Build()
 }
diff --git a/transport/grpc/balancer.go b/transport/grpc/balancer.go
index 2047eb0d..948b736b 100644
--- a/transport/grpc/balancer.go
+++ b/transport/grpc/balancer.go
@@ -87,7 +87,7 @@ func (p *balancerPicker) Pick(info balancer.PickInfo) (balancer.PickResult, erro
 	}, nil
 }
 
-// Trailer is a grpc trailder MD.
+// Trailer is a grpc trailer MD.
 type Trailer metadata.MD
 
 // Get get a grpc trailer value.
diff --git a/transport/grpc/codec.go b/transport/grpc/codec.go
index 19670bba..231f114f 100644
--- a/transport/grpc/codec.go
+++ b/transport/grpc/codec.go
@@ -3,10 +3,11 @@ package grpc
 import (
 	"fmt"
 
-	enc "github.com/go-kratos/kratos/v2/encoding"
-	"github.com/go-kratos/kratos/v2/encoding/json"
 	"google.golang.org/grpc/encoding"
 	"google.golang.org/protobuf/proto"
+
+	enc "github.com/go-kratos/kratos/v2/encoding"
+	"github.com/go-kratos/kratos/v2/encoding/json"
 )
 
 func init() {
diff --git a/transport/grpc/interceptor.go b/transport/grpc/interceptor.go
index ccd83ea6..6cc33154 100644
--- a/transport/grpc/interceptor.go
+++ b/transport/grpc/interceptor.go
@@ -3,11 +3,12 @@ package grpc
 import (
 	"context"
 
+	"google.golang.org/grpc"
+	grpcmd "google.golang.org/grpc/metadata"
+
 	ic "github.com/go-kratos/kratos/v2/internal/context"
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/transport"
-	"google.golang.org/grpc"
-	grpcmd "google.golang.org/grpc/metadata"
 )
 
 // unaryServerInterceptor is a gRPC unary server interceptor
diff --git a/transport/grpc/transport.go b/transport/grpc/transport.go
index 866228d1..50ca5c91 100644
--- a/transport/grpc/transport.go
+++ b/transport/grpc/transport.go
@@ -1,9 +1,10 @@
 package grpc
 
 import (
+	"google.golang.org/grpc/metadata"
+
 	"github.com/go-kratos/kratos/v2/selector"
 	"github.com/go-kratos/kratos/v2/transport"
-	"google.golang.org/grpc/metadata"
 )
 
 var _ transport.Transporter = (*Transport)(nil)
diff --git a/transport/http/binding/encode.go b/transport/http/binding/encode.go
index 3129bbe5..9bcdbeef 100644
--- a/transport/http/binding/encode.go
+++ b/transport/http/binding/encode.go
@@ -1,75 +1,47 @@
 package binding
 
 import (
-	"fmt"
 	"reflect"
 	"regexp"
-	"strings"
 
 	"github.com/go-kratos/kratos/v2/encoding/form"
-
 	"google.golang.org/protobuf/proto"
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 )
 
-var reg = regexp.MustCompile(`/{[\\.\w]+}`)
+var reg = regexp.MustCompile(`{[\\.\w]+}`)
 
 // EncodeURL encode proto message to url path.
-func EncodeURL(pathTemplate string, msg proto.Message, needQuery bool) string {
+func EncodeURL(pathTemplate string, msg interface{}, needQuery bool) string {
 	if msg == nil || (reflect.ValueOf(msg).Kind() == reflect.Ptr && reflect.ValueOf(msg).IsNil()) {
 		return pathTemplate
 	}
+	queryParams, _ := form.EncodeValues(msg)
 	pathParams := make(map[string]struct{})
 	path := reg.ReplaceAllStringFunc(pathTemplate, func(in string) string {
 		// it's unreachable because the reg means that must have more than one char in {}
 		//if len(in) < 4 { //nolint:gomnd // **  explain the 4 number here :-) **
 		//	return in
 		//}
-		key := in[2 : len(in)-1]
-		vars := strings.Split(key, ".")
-		value, err := getValueByField(msg.ProtoReflect(), vars)
-		if err != nil {
-			return in
-		}
+		key := in[1 : len(in)-1]
+		value := queryParams.Get(key)
 		pathParams[key] = struct{}{}
-		return "/" + value
+		return value
 	})
 	if !needQuery {
-		if query := form.EncodeFieldMask(msg.ProtoReflect()); query != "" {
-			return path + "?" + query
+		if v, ok := msg.(proto.Message); ok {
+			if query := form.EncodeFieldMask(v.ProtoReflect()); query != "" {
+				return path + "?" + query
+			}
 		}
 		return path
 	}
-	u, err := form.EncodeValues(msg)
-	if err == nil && len(u) > 0 {
+	if len(queryParams) > 0 {
 		for key := range pathParams {
-			delete(u, key)
+			delete(queryParams, key)
 		}
-		query := u.Encode()
-		if query != "" {
+		if query := queryParams.Encode(); query != "" {
 			path += "?" + query
 		}
 	}
 	return path
 }
-
-func getValueByField(v protoreflect.Message, fieldPath []string) (string, error) {
-	var fd protoreflect.FieldDescriptor
-	for i, fieldName := range fieldPath {
-		fields := v.Descriptor().Fields()
-		if fd = fields.ByJSONName(fieldName); fd == nil {
-			fd = fields.ByName(protoreflect.Name(fieldName))
-			if fd == nil {
-				return "", fmt.Errorf("field path not found: %q", fieldName)
-			}
-		}
-		if i == len(fieldPath)-1 {
-			break
-		}
-		if fd.Message() == nil || fd.Cardinality() == protoreflect.Repeated {
-			return "", fmt.Errorf("invalid path: %q is not a message", fieldName)
-		}
-		v = v.Get(fd).Message()
-	}
-	return form.EncodeField(fd, v.Get(fd))
-}
diff --git a/transport/http/client.go b/transport/http/client.go
index c0ad5ee3..de9a3138 100644
--- a/transport/http/client.go
+++ b/transport/http/client.go
@@ -196,7 +196,7 @@ func NewClient(ctx context.Context, opts ...ClientOption) (*Client, error) {
 	}, nil
 }
 
-// Invoke makes an rpc call procedure for remote service.
+// Invoke makes a rpc call procedure for remote service.
 func (client *Client) Invoke(ctx context.Context, method, path string, args interface{}, reply interface{}, opts ...CallOption) error {
 	var (
 		contentType string
diff --git a/transport/http/context.go b/transport/http/context.go
index f65e03fb..347d7f2b 100644
--- a/transport/http/context.go
+++ b/transport/http/context.go
@@ -9,10 +9,11 @@ import (
 	"net/url"
 	"time"
 
+	"github.com/gorilla/mux"
+
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/transport"
 	"github.com/go-kratos/kratos/v2/transport/http/binding"
-	"github.com/gorilla/mux"
 )
 
 var _ Context = (*wrapper)(nil)
diff --git a/transport/http/filter.go b/transport/http/filter.go
index ba7602f3..43bec807 100644
--- a/transport/http/filter.go
+++ b/transport/http/filter.go
@@ -2,7 +2,7 @@ package http
 
 import "net/http"
 
-// FilterFunc is a function which receives an http.Handler and returns another http.Handler.
+// FilterFunc is a function which receives a http.Handler and returns another http.Handler.
 type FilterFunc func(http.Handler) http.Handler
 
 // FilterChain returns a FilterFunc that specifies the chained handler for HTTP Router.
diff --git a/transport/http/status/status.go b/transport/http/status/status.go
index 2f6a717f..bab99304 100644
--- a/transport/http/status/status.go
+++ b/transport/http/status/status.go
@@ -27,7 +27,7 @@ type statusConverter struct{}
 // DefaultConverter default converter.
 var DefaultConverter Converter = statusConverter{}
 
-// ToGRPCCode converts a HTTP error code into the corresponding gRPC response status.
+// ToGRPCCode converts an HTTP error code into the corresponding gRPC response status.
 // See: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
 func (c statusConverter) ToGRPCCode(code int) codes.Code {
 	switch code {


Test patch:
diff --git a/app_test.go b/app_test.go
index aa0a5ef7..2b8c8c9d 100644
--- a/app_test.go
+++ b/app_test.go
@@ -2,7 +2,7 @@ package kratos
 
 import (
 	"context"
-	"fmt"
+	"errors"
 	"net/url"
 	"reflect"
 	"sync"
@@ -21,7 +21,7 @@ type mockRegistry struct {
 
 func (r *mockRegistry) Register(ctx context.Context, service *registry.ServiceInstance) error {
 	if service == nil || service.ID == "" {
-		return fmt.Errorf("no service id")
+		return errors.New("no service id")
 	}
 	r.lk.Lock()
 	defer r.lk.Unlock()
@@ -34,7 +34,7 @@ func (r *mockRegistry) Deregister(ctx context.Context, service *registry.Service
 	r.lk.Lock()
 	defer r.lk.Unlock()
 	if r.service[service.ID] == nil {
-		return fmt.Errorf("deregister service not found")
+		return errors.New("deregister service not found")
 	}
 	delete(r.service, service.ID)
 	return nil
diff --git a/config/reader_test.go b/config/reader_test.go
index f2ac1444..15f8f617 100644
--- a/config/reader_test.go
+++ b/config/reader_test.go
@@ -132,9 +132,6 @@ a:
 				t.Fatal(`vvv is not equal to 1`)
 			}
 
-			if err != nil {
-				t.Fatal(`err is not nil`)
-			}
 			vv, ok = r.Value("a.b.Y")
 			if !ok {
 				t.Fatal(`ok is false`)
@@ -147,9 +144,6 @@ a:
 				t.Fatal(`vvy is not equal to "lol"`)
 			}
 
-			if err != nil {
-				t.Fatal(`err is not nil`)
-			}
 			vv, ok = r.Value("a.b.z")
 			if !ok {
 				t.Fatal(`ok is false`)
diff --git a/contrib/config/consul/config_test.go b/contrib/config/consul/config_test.go
index a82a2036..adb3c27c 100644
--- a/contrib/config/consul/config_test.go
+++ b/contrib/config/consul/config_test.go
@@ -5,8 +5,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/config"
 	"github.com/hashicorp/consul/api"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 const testPath = "kratos/test/config"
diff --git a/contrib/config/polaris/config_test.go b/contrib/config/polaris/config_test.go
index bf8b6fd6..9559174f 100644
--- a/contrib/config/polaris/config_test.go
+++ b/contrib/config/polaris/config_test.go
@@ -26,13 +26,13 @@ var (
 func makeJSONRequest(uri string, data string, method string, headers map[string]string) ([]byte, error) {
 	client := http.Client{}
 	req, err := http.NewRequest(method, uri, strings.NewReader(data))
+	if err != nil {
+		return nil, err
+	}
 	req.Header.Add("Content-Type", "application/json")
 	for k, v := range headers {
 		req.Header.Add(k, v)
 	}
-	if err != nil {
-		return nil, err
-	}
 	res, err := client.Do(req)
 	if err != nil {
 		return nil, err
diff --git a/contrib/log/aliyun/aliyun_test.go b/contrib/log/aliyun/aliyun_test.go
index 1ceafc32..a5e1f080 100644
--- a/contrib/log/aliyun/aliyun_test.go
+++ b/contrib/log/aliyun/aliyun_test.go
@@ -1,6 +1,7 @@
 package aliyun
 
 import (
+	"math"
 	"testing"
 
 	"github.com/go-kratos/kratos/v2/log"
@@ -92,4 +93,39 @@ func TestLog(t *testing.T) {
 	if err != nil {
 		t.Errorf("Log() returns error:%v", err)
 	}
+	err = logger.Log(log.LevelDebug, true, 0)
+	if err != nil {
+		t.Errorf("Log() returns error:%v", err)
+	}
+}
+
+func TestToString(t *testing.T) {
+	tests := []struct {
+		in  interface{}
+		out string
+	}{
+		{math.MaxFloat64, "17976931348623157000000000000000000000000000000000000" +
+			"000000000000000000000000000000000000000000000000000000000000000000000000000" +
+			"000000000000000000000000000000000000000000000000000000000000000000000000000" +
+			"000000000000000000000000000000000000000000000000000000000000000000000000000" +
+			"0000000000000000000000000000000"},
+		{math.MaxFloat32, "340282346638528860000000000000000000000"},
+		{1<<((32<<(^uint(0)>>63))-1) - 1, "9223372036854775807"},
+		{uint(1<<(32<<(^uint(0)>>63)) - 1), "-1"},
+		{math.MaxInt8, "127"},
+		{math.MaxUint8, "255"},
+		{math.MaxInt16, "32767"},
+		{math.MaxUint16, "65535"},
+		{math.MaxInt32, "2147483647"},
+		{math.MaxUint32, "4294967295"},
+		{math.MaxInt64, "9223372036854775807"},
+		{uint64(math.MaxUint64), "18446744073709551615"},
+		{"abc", "abc"},
+		{[]byte("abc"), "abc"},
+	}
+	for _, test := range tests {
+		if toString(test.in) != test.out {
+			t.Fatalf("want: %s, got: %s", test.out, toString(test.in))
+		}
+	}
 }
diff --git a/contrib/log/logrus/logrus_test.go b/contrib/log/logrus/logrus_test.go
index 3dcd6e64..45fe9da2 100644
--- a/contrib/log/logrus/logrus_test.go
+++ b/contrib/log/logrus/logrus_test.go
@@ -5,9 +5,9 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/go-kratos/kratos/v2/log"
 	"github.com/sirupsen/logrus"
-	"github.com/stretchr/testify/assert"
+
+	"github.com/go-kratos/kratos/v2/log"
 )
 
 func TestLoggerLog(t *testing.T) {
@@ -58,7 +58,9 @@ func TestLoggerLog(t *testing.T) {
 			wrapped := NewLogger(logger)
 			_ = wrapped.Log(test.logLevel, test.kvs...)
 
-			assert.True(t, strings.HasPrefix(output.String(), test.want))
+			if !strings.HasPrefix(output.String(), test.want) {
+				t.Errorf("TestName(%s): %s has not prefix %s", name, output.String(), test.want)
+			}
 		})
 	}
 }
diff --git a/contrib/opensergo/opensergo_test.go b/contrib/opensergo/opensergo_test.go
index 9f49bbee..b63430e2 100644
--- a/contrib/opensergo/opensergo_test.go
+++ b/contrib/opensergo/opensergo_test.go
@@ -338,7 +338,7 @@ func TestOpenSergo(t *testing.T) {
 				fileContent := `{"endpoint": "127.0.0.1:9090"}`
 				err := os.WriteFile("test.json", []byte(fileContent), 0o644)
 				if err != nil {
-					t.Fatalf("ioutil.WriteFile error:%s", err)
+					t.Fatalf("os.WriteFile error:%s", err)
 				}
 				confPath, err := filepath.Abs("./test.json")
 				if err != nil {
diff --git a/contrib/registry/consul/registry_test.go b/contrib/registry/consul/registry_test.go
index 483faf1a..6a1523c4 100644
--- a/contrib/registry/consul/registry_test.go
+++ b/contrib/registry/consul/registry_test.go
@@ -8,8 +8,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	"github.com/hashicorp/consul/api"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 func tcpServer(t *testing.T, lis net.Listener) {
diff --git a/contrib/registry/etcd/registry_test.go b/contrib/registry/etcd/registry_test.go
index 844d67ff..8fcecf94 100644
--- a/contrib/registry/etcd/registry_test.go
+++ b/contrib/registry/etcd/registry_test.go
@@ -8,8 +8,9 @@ import (
 
 	"google.golang.org/grpc"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	clientv3 "go.etcd.io/etcd/client/v3"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 func TestRegistry(t *testing.T) {
diff --git a/contrib/registry/servicecomb/registry_test.go b/contrib/registry/servicecomb/registry_test.go
index d100c68a..85afe306 100644
--- a/contrib/registry/servicecomb/registry_test.go
+++ b/contrib/registry/servicecomb/registry_test.go
@@ -6,17 +6,14 @@ import (
 
 	pb "github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/sc-client"
-
 	"github.com/go-kratos/kratos/v2/registry"
 	"github.com/gofrs/uuid"
-	"github.com/stretchr/testify/assert"
 )
 
 var r *Registry
 
 func init() {
-	c := &mockClient{}
-	r = NewRegistry(c)
+	r = NewRegistry(&mockClient{})
 }
 
 type mockClient struct{}
@@ -28,7 +25,6 @@ func (receiver *mockClient) WatchMicroService(microServiceID string, callback fu
 //nolint
 func (receiver *mockClient) FindMicroServiceInstances(consumerID,
 	appID, microServiceName, versionRule string, opts ...sc.CallOption,
-
 ) ([]*pb.MicroServiceInstance, error) {
 	if microServiceName == "KratosServicecomb" {
 		return []*pb.MicroServiceInstance{{}}, nil
@@ -56,10 +52,11 @@ func (receiver *mockClient) GetMicroServiceID(appID, microServiceName, version,
 	return "", nil
 }
 
-// TestRegistry
 func TestRegistry(t *testing.T) {
 	instanceID, err := uuid.NewV4()
-	assert.NoError(t, err)
+	if err != nil {
+		t.Fatal(err)
+	}
 	svc := &registry.ServiceInstance{
 		Name:      "KratosServicecomb",
 		Version:   "0.0.1",
@@ -70,25 +67,34 @@ func TestRegistry(t *testing.T) {
 	ctx := context.TODO()
 	t.Run("Register test, expected: success.", func(t *testing.T) {
 		err = r.Register(ctx, svc)
-		assert.NoError(t, err)
+		if err != nil {
+			t.Error(err)
+		}
 	})
 	t.Run("GetService test, expected: success.", func(t *testing.T) {
 		var insts []*registry.ServiceInstance
 		insts, err = r.GetService(ctx, svc.Name)
-		assert.NoError(t, err)
-		assert.Greater(t, len(insts), 0)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(insts) <= 0 {
+			t.Errorf("inst len less than 0")
+		}
 	})
 	t.Run("Deregister test, expected: success.", func(t *testing.T) {
 		svc.ID = instanceID.String()
 		err = r.Deregister(ctx, svc)
-		assert.NoError(t, err)
+		if err != nil {
+			t.Error(err)
+		}
 	})
 }
 
 func TestWatcher(t *testing.T) {
-	ctx := context.TODO()
 	instanceID1, err := uuid.NewV4()
-	assert.NoError(t, err)
+	if err != nil {
+		t.Fatal(err)
+	}
 	svc1 := &registry.ServiceInstance{
 		Name:      "WatcherTest",
 		Version:   "0.0.1",
@@ -96,33 +102,56 @@ func TestWatcher(t *testing.T) {
 		Endpoints: []string{"tcp://127.0.0.1:9000?isSecure=false"},
 		ID:        instanceID1.String(),
 	}
+	ctx := context.TODO()
 	err = r.Register(ctx, svc1)
-	assert.NoError(t, err)
+	if err != nil {
+		t.Fatal(err)
+	}
 	w, err := r.Watch(ctx, "WatcherTest")
-	assert.NoError(t, err)
-	assert.NotEmpty(t, w)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if w == nil {
+		t.Fatal("w is nil")
+	}
 	sbWatcher := w.(*Watcher)
 	t.Run("Watch register event, expected: success", func(t *testing.T) {
 		go sbWatcher.Put(svc1)
 		var instances []*registry.ServiceInstance
 		instances, err = w.Next()
-		assert.NoError(t, err)
-		assert.NotEmpty(t, instances)
-		assert.Equal(t, instanceID1.String(), instances[0].ID)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(instances) == 0 {
+			t.Errorf("instances is empty")
+		}
+		if instanceID1.String() != instances[0].ID {
+			t.Errorf("expected %v, got %v", instanceID1.String(), instances[0].ID)
+		}
 	})
 	t.Run("Watch deregister event, expected: success", func(t *testing.T) {
 		// Deregister instance1.
 		err = r.Deregister(ctx, svc1)
-		assert.NoError(t, err)
+		if err != nil {
+			t.Fatal(err)
+		}
 		go sbWatcher.Put(svc1)
 		var instances []*registry.ServiceInstance
 		instances, err = w.Next()
-		assert.NoError(t, err)
-		assert.NotEmpty(t, instances)
-		assert.Equal(t, instanceID1.String(), instances[0].ID)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(instances) == 0 {
+			t.Errorf("instances is empty")
+		}
+		if instanceID1.String() != instances[0].ID {
+			t.Errorf("expected %v, got %v", instanceID1.String(), instances[0].ID)
+		}
 	})
 	t.Run("Stop test, expected: success", func(t *testing.T) {
 		err = w.Stop()
-		assert.NoError(t, err)
+		if err != nil {
+			t.Error(err)
+		}
 	})
 }
diff --git a/contrib/registry/zookeeper/register_test.go b/contrib/registry/zookeeper/register_test.go
index 131f3ee1..a6f4515e 100644
--- a/contrib/registry/zookeeper/register_test.go
+++ b/contrib/registry/zookeeper/register_test.go
@@ -6,8 +6,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	"github.com/go-zookeeper/zk"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 func TestRegistry_GetService(t *testing.T) {
diff --git a/encoding/encoding_test.go b/encoding/encoding_test.go
index d2886567..1d79ebbd 100644
--- a/encoding/encoding_test.go
+++ b/encoding/encoding_test.go
@@ -63,7 +63,7 @@ func TestRegisterCodec(t *testing.T) {
 	}
 }
 
-// PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics
+// PanicTestFunc defines a func that should be passed to assert.Panics and assert.NotPanics
 // methods, and represents a simple func that takes no arguments, and returns nothing.
 type PanicTestFunc func()
 
diff --git a/log/global_test.go b/log/global_test.go
index 16aa6773..8ee15705 100644
--- a/log/global_test.go
+++ b/log/global_test.go
@@ -48,7 +48,7 @@ func TestGlobalLog(t *testing.T) {
 		},
 	}
 
-	expected := []string{}
+	var expected []string
 	for _, tc := range testCases {
 		msg := fmt.Sprintf(tc.content[0].(string), tc.content[1:]...)
 		switch tc.level {
diff --git a/middleware/circuitbreaker/circuitbreaker_test.go b/middleware/circuitbreaker/circuitbreaker_test.go
index b7c2553c..611419c7 100644
--- a/middleware/circuitbreaker/circuitbreaker_test.go
+++ b/middleware/circuitbreaker/circuitbreaker_test.go
@@ -5,7 +5,7 @@ import (
 	"errors"
 	"testing"
 
-	kratos_errors "github.com/go-kratos/kratos/v2/errors"
+	kratoserrors "github.com/go-kratos/kratos/v2/errors"
 	"github.com/go-kratos/kratos/v2/internal/group"
 	"github.com/go-kratos/kratos/v2/transport"
 )
@@ -62,7 +62,7 @@ func Test_Server(t *testing.T) {
 		return "Hello valid", nil
 	}
 	nextInvalid := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return nil, kratos_errors.InternalServer("", "")
+		return nil, kratoserrors.InternalServer("", "")
 	}
 
 	ctx := transport.NewClientContext(context.Background(), &transportMock{})
diff --git a/middleware/metadata/metadata_test.go b/middleware/metadata/metadata_test.go
index d0190b67..e46a94f5 100644
--- a/middleware/metadata/metadata_test.go
+++ b/middleware/metadata/metadata_test.go
@@ -134,6 +134,6 @@ func Test_WithPropagatedPrefix(t *testing.T) {
 	WithPropagatedPrefix("something", "another")(o)
 
 	if len(o.prefix) != 2 {
-		t.Error("The prefix must be overrided.")
+		t.Error("The prefix must be overridden.")
 	}
 }
diff --git a/middleware/tracing/span_test.go b/middleware/tracing/span_test.go
index aad4614f..110dc6f5 100644
--- a/middleware/tracing/span_test.go
+++ b/middleware/tracing/span_test.go
@@ -7,13 +7,14 @@ import (
 	"reflect"
 	"testing"
 
-	"github.com/go-kratos/kratos/v2/internal/testdata/binding"
-	"github.com/go-kratos/kratos/v2/metadata"
-	"github.com/go-kratos/kratos/v2/transport"
 	"go.opentelemetry.io/otel/attribute"
 	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
 	"go.opentelemetry.io/otel/trace"
 	"google.golang.org/grpc/peer"
+
+	"github.com/go-kratos/kratos/v2/internal/testdata/binding"
+	"github.com/go-kratos/kratos/v2/metadata"
+	"github.com/go-kratos/kratos/v2/transport"
 )
 
 func Test_parseFullMethod(t *testing.T) {
diff --git a/middleware/tracing/tracer_test.go b/middleware/tracing/tracer_test.go
index fbd51c07..af63844e 100644
--- a/middleware/tracing/tracer_test.go
+++ b/middleware/tracing/tracer_test.go
@@ -5,8 +5,9 @@ import (
 	"errors"
 	"testing"
 
-	"github.com/go-kratos/kratos/v2/internal/testdata/binding"
 	"go.opentelemetry.io/otel/trace"
+
+	"github.com/go-kratos/kratos/v2/internal/testdata/binding"
 )
 
 func Test_NewTracer(t *testing.T) {
diff --git a/middleware/tracing/tracing_test.go b/middleware/tracing/tracing_test.go
index 222a6acc..b95771ab 100644
--- a/middleware/tracing/tracing_test.go
+++ b/middleware/tracing/tracing_test.go
@@ -7,11 +7,12 @@ import (
 	"reflect"
 	"testing"
 
-	"github.com/go-kratos/kratos/v2/log"
-	"github.com/go-kratos/kratos/v2/transport"
 	"go.opentelemetry.io/otel/propagation"
 	tracesdk "go.opentelemetry.io/otel/sdk/trace"
 	"go.opentelemetry.io/otel/trace"
+
+	"github.com/go-kratos/kratos/v2/log"
+	"github.com/go-kratos/kratos/v2/transport"
 )
 
 var _ transport.Transporter = (*mockTransport)(nil)
diff --git a/middleware/validate/validate_test.go b/middleware/validate/validate_test.go
index f1597820..34fc3349 100644
--- a/middleware/validate/validate_test.go
+++ b/middleware/validate/validate_test.go
@@ -2,10 +2,10 @@ package validate
 
 import (
 	"context"
-	"fmt"
+	"errors"
 	"testing"
 
-	"github.com/go-kratos/kratos/v2/errors"
+	kratoserrors "github.com/go-kratos/kratos/v2/errors"
 	"github.com/go-kratos/kratos/v2/middleware"
 )
 
@@ -18,7 +18,7 @@ type protoVali struct {
 
 func (v protoVali) Validate() error {
 	if v.name == "" || v.age < 0 {
-		return fmt.Errorf("err")
+		return errors.New("err")
 	}
 	return nil
 }
@@ -35,7 +35,7 @@ func TestTable(t *testing.T) {
 		t.Run(test.name, func(t *testing.T) {
 			v := Validator()(mock)
 			_, err := v(context.Background(), test)
-			if want, have := test.isErr, errors.IsBadRequest(err); want != have {
+			if want, have := test.isErr, kratoserrors.IsBadRequest(err); want != have {
 				t.Errorf("fail data %v, want %v, have %v", test, want, have)
 			}
 		})
diff --git a/selector/selector_test.go b/selector/selector_test.go
index bcc08264..ca30fc0a 100644
--- a/selector/selector_test.go
+++ b/selector/selector_test.go
@@ -277,7 +277,7 @@ func TestNoPick(t *testing.T) {
 	}
 }
 
-func TestGolobal(t *testing.T) {
+func TestGlobalSelector(t *testing.T) {
 	builder := DefaultBuilder{
 		Node:     &mockWeightedNodeBuilder{},
 		Balancer: &mockBalancerBuilder{},
diff --git a/transport/grpc/balancer_test.go b/transport/grpc/balancer_test.go
index 5b700264..2dbb53bb 100644
--- a/transport/grpc/balancer_test.go
+++ b/transport/grpc/balancer_test.go
@@ -5,8 +5,9 @@ import (
 	"reflect"
 	"testing"
 
-	"github.com/go-kratos/kratos/v2/selector"
 	"google.golang.org/grpc/metadata"
+
+	"github.com/go-kratos/kratos/v2/selector"
 )
 
 func TestTrailer(t *testing.T) {
diff --git a/transport/grpc/client_test.go b/transport/grpc/client_test.go
index d2540a7d..7ad55368 100644
--- a/transport/grpc/client_test.go
+++ b/transport/grpc/client_test.go
@@ -7,9 +7,10 @@ import (
 	"testing"
 	"time"
 
+	"google.golang.org/grpc"
+
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/registry"
-	"google.golang.org/grpc"
 )
 
 func TestWithEndpoint(t *testing.T) {
diff --git a/transport/grpc/codec_test.go b/transport/grpc/codec_test.go
new file mode 100644
index 00000000..534439ff
--- /dev/null
+++ b/transport/grpc/codec_test.go
@@ -0,0 +1,28 @@
+package grpc
+
+import (
+	"reflect"
+	"testing"
+
+	"google.golang.org/protobuf/types/known/structpb"
+)
+
+func TestCodec(t *testing.T) {
+	in, err := structpb.NewStruct(map[string]interface{}{"Golang": "Kratos"})
+	if err != nil {
+		t.Errorf("grpc codec create input data error:%v", err)
+	}
+	c := codec{}
+	data, err := c.Marshal(in)
+	if err != nil {
+		t.Errorf("grpc codec marshal error:%v", err)
+	}
+	out := &structpb.Struct{}
+	err = c.Unmarshal(data, out)
+	if err != nil {
+		t.Errorf("grpc codec unmarshal error:%v", err)
+	}
+	if !reflect.DeepEqual(in, out) {
+		t.Errorf("grpc codec want %v, got %v", in, out)
+	}
+}
diff --git a/transport/grpc/resolver/direct/builder_test.go b/transport/grpc/resolver/direct/builder_test.go
index 1cd6bf40..82cd8cd1 100644
--- a/transport/grpc/resolver/direct/builder_test.go
+++ b/transport/grpc/resolver/direct/builder_test.go
@@ -1,7 +1,7 @@
 package direct
 
 import (
-	"fmt"
+	"errors"
 	"reflect"
 	"testing"
 
@@ -22,7 +22,7 @@ type mockConn struct {
 
 func (m *mockConn) UpdateState(resolver.State) error {
 	if m.needUpdateStateErr {
-		return fmt.Errorf("mock test needUpdateStateErr")
+		return errors.New("mock test needUpdateStateErr")
 	}
 	return nil
 }
diff --git a/transport/grpc/resolver/discovery/builder_test.go b/transport/grpc/resolver/discovery/builder_test.go
index 11541cb7..664b5d44 100644
--- a/transport/grpc/resolver/discovery/builder_test.go
+++ b/transport/grpc/resolver/discovery/builder_test.go
@@ -2,13 +2,15 @@ package discovery
 
 import (
 	"context"
+	"net/url"
 	"reflect"
 	"testing"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	"google.golang.org/grpc/resolver"
 	"google.golang.org/grpc/serviceconfig"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 func TestWithInsecure(t *testing.T) {
@@ -74,8 +76,10 @@ func TestBuilder_Build(t *testing.T) {
 	b := NewBuilder(&mockDiscovery{}, DisableDebugLog())
 	_, err := b.Build(
 		resolver.Target{
-			Scheme:   resolver.GetDefaultScheme(),
-			Endpoint: "gprc://authority/endpoint",
+			URL: url.URL{
+				Scheme: resolver.GetDefaultScheme(),
+				Path:   "grpc://authority/endpoint",
+			},
 		},
 		&mockConn{},
 		resolver.BuildOptions{},
@@ -87,8 +91,10 @@ func TestBuilder_Build(t *testing.T) {
 	timeoutBuilder := NewBuilder(&mockDiscovery{}, WithTimeout(0))
 	_, err = timeoutBuilder.Build(
 		resolver.Target{
-			Scheme:   resolver.GetDefaultScheme(),
-			Endpoint: "gprc://authority/endpoint",
+			URL: url.URL{
+				Scheme: resolver.GetDefaultScheme(),
+				Path:   "grpc://authority/endpoint",
+			},
 		},
 		&mockConn{},
 		resolver.BuildOptions{},
diff --git a/transport/grpc/resolver/discovery/resolver_test.go b/transport/grpc/resolver/discovery/resolver_test.go
index 33d9fc27..39ae400e 100644
--- a/transport/grpc/resolver/discovery/resolver_test.go
+++ b/transport/grpc/resolver/discovery/resolver_test.go
@@ -7,8 +7,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	"google.golang.org/grpc/resolver"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 type testClientConn struct {
diff --git a/transport/grpc/server_test.go b/transport/grpc/server_test.go
index fd1ae675..4db44fe9 100644
--- a/transport/grpc/server_test.go
+++ b/transport/grpc/server_test.go
@@ -11,12 +11,13 @@ import (
 	"testing"
 	"time"
 
+	"google.golang.org/grpc"
+
 	"github.com/go-kratos/kratos/v2/errors"
 	"github.com/go-kratos/kratos/v2/internal/matcher"
 	pb "github.com/go-kratos/kratos/v2/internal/testdata/helloworld"
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/transport"
-	"google.golang.org/grpc"
 )
 
 // server is used to implement helloworld.GreeterServer.
diff --git a/transport/http/binding/encode_test.go b/transport/http/binding/encode_test.go
index fdc2bb78..7e8286c9 100644
--- a/transport/http/binding/encode_test.go
+++ b/transport/http/binding/encode_test.go
@@ -1,87 +1,139 @@
 package binding
 
 import (
-	"fmt"
 	"testing"
 
-	"github.com/go-kratos/kratos/v2/internal/testdata/binding"
 	"google.golang.org/protobuf/types/known/fieldmaskpb"
+
+	"github.com/go-kratos/kratos/v2/internal/testdata/binding"
 )
 
 func TestProtoPath(t *testing.T) {
-	url := EncodeURL("http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}", &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "2233!!!"}}, false)
-	fmt.Println(url)
-	if url != `http://helloworld.Greeter/helloworld/test/sub/2233!!!` {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-	url = EncodeURL("http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}", nil, false)
-	fmt.Println(url)
-	if url != "http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}" {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-	url = EncodeURL("http://helloworld.Greeter/helloworld/{}/sub/{sub.name}", &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "hello"}}, false)
-	fmt.Println(url)
-	if url != "http://helloworld.Greeter/helloworld/{}/sub/hello" {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-	url = EncodeURL("http://helloworld.Greeter/helloworld/{}/sub/{sub.name.cc}", &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "hello"}}, false)
-	fmt.Println(url)
-	if url != "http://helloworld.Greeter/helloworld/{}/sub/{sub.name.cc}" {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-
-	url = EncodeURL(
-		"http://helloworld.Greeter/helloworld/{}/sub/{test_repeated.1}",
-		&binding.HelloRequest{
-			Name: "test", Sub: &binding.Sub{Name: "hello"},
-			TestRepeated: []string{"123", "456"},
-		},
-		false,
-	)
-	fmt.Println(url)
-	if url != "http://helloworld.Greeter/helloworld/{}/sub/{test_repeated.1}" {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-
-	url = EncodeURL("http://helloworld.Greeter/helloworld/{name}/sub/{sub.naming}", &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "5566!!!"}}, false)
-	fmt.Println(url)
-	if url != `http://helloworld.Greeter/helloworld/test/sub/5566!!!` {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-
-	url = EncodeURL("http://helloworld.Greeter/helloworld/sub", &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "2233!!!"}}, false)
-	fmt.Println(url)
-	if url != `http://helloworld.Greeter/helloworld/sub` {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-
-	url = EncodeURL("http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}", &binding.HelloRequest{Name: "test"}, false)
-	fmt.Println(url)
-	if url != `http://helloworld.Greeter/helloworld/test/sub/` {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-
-	url = EncodeURL("http://helloworld.Greeter/helloworld/{name}/sub/{sub.name33}", &binding.HelloRequest{Name: "test"}, false)
-	fmt.Println(url)
-	if url != `http://helloworld.Greeter/helloworld/test/sub/{sub.name33}` {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-
-	url = EncodeURL("http://helloworld.Greeter/helloworld/{name}/sub", &binding.HelloRequest{
-		Name: "go",
-		Sub:  &binding.Sub{Name: "kratos"},
-	}, true)
-	fmt.Println(url)
-	if url != `http://helloworld.Greeter/helloworld/go/sub?sub.naming=kratos` {
-		t.Fatalf("proto path not expected!actual: %s ", url)
+	tests := []struct {
+		pathTemplate string
+		request      *binding.HelloRequest
+		needQuery    bool
+		want         string
+	}{
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{name}/sub/{sub.naming}",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "2233!!!!"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/test/sub/2233!!!!",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{name}/sub/{sub.naming}",
+			request:      nil,
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{name}/sub/{sub.naming}",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{}/sub/{sub.naming}",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "hello"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{}/sub/hello",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{}/sub/{sub.naming}",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "hello"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{}/sub/hello",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{}/sub/{sub.name.cc}",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "hello"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{}/sub/",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{}/sub/{test_repeated}",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "hello"}, TestRepeated: []string{"123", "456"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{}/sub/123",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{name}/sub/{sub.naming}",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "5566!!!"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/test/sub/5566!!!",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/sub",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "2233!!!"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/sub",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}",
+			request:      &binding.HelloRequest{Name: "test"},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/test/sub/",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}",
+			request:      &binding.HelloRequest{Name: "test"},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/test/sub/",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{name}/sub",
+			request:      &binding.HelloRequest{Name: "go", Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    true,
+			want:         "http://helloworld.Greeter/helloworld/go/sub?sub.naming=kratos",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/sub/{sub.naming}",
+			request:      &binding.HelloRequest{Sub: &binding.Sub{Name: "kratos"}, UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"name", "sub.naming"}}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/sub/kratos?updateMask=name,sub.naming",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/sub/[{sub.naming}]",
+			request:      &binding.HelloRequest{Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/sub/[kratos]",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/[{name}]/sub/[{sub.naming}]",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/[test]/sub/[kratos]",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/[{}]/sub/[{sub.naming}]",
+			request:      &binding.HelloRequest{Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/[{}]/sub/[kratos]",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/[{}]/sub/[{sub.naming}]/{[]}",
+			request:      &binding.HelloRequest{Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/[{}]/sub/[kratos]/{[]}",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{[sub]}/[{sub.naming}]",
+			request:      &binding.HelloRequest{Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{[sub]}/[kratos]",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{[name]}/[{sub.naming}]",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{[name]}/[kratos]",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{}/[]/[{sub.naming}]",
+			request:      &binding.HelloRequest{Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{}/[]/[kratos]",
+		},
 	}
 
-	url = EncodeURL("http://helloworld.Greeter/helloworld/sub/{sub.name}", &binding.HelloRequest{
-		Sub:        &binding.Sub{Name: "kratos"},
-		UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"name", "sub.name"}},
-	}, false)
-	fmt.Println(url)
-	if url != `http://helloworld.Greeter/helloworld/sub/kratos?updateMask=name,sub.name` {
-		t.Fatalf("proto path not expected!actual: %s ", url)
+	for _, test := range tests {
+		if EncodeURL(test.pathTemplate, test.request, test.needQuery) != test.want {
+			t.Fatalf("want: %s, got: %s", test.want, EncodeURL(test.pathTemplate, test.request, test.needQuery))
+		}
 	}
 }
diff --git a/transport/http/client_test.go b/transport/http/client_test.go
index 4ee00456..ab8031dd 100644
--- a/transport/http/client_test.go
+++ b/transport/http/client_test.go
@@ -33,7 +33,7 @@ type mockCallOption struct {
 
 func (x *mockCallOption) before(info *callInfo) error {
 	if x.needErr {
-		return fmt.Errorf("option need return err")
+		return errors.New("option need return err")
 	}
 	return nil
 }
@@ -357,7 +357,7 @@ func TestNewClient(t *testing.T) {
 		t.Error("err should be equal to callOption err")
 	}
 	client.opts.encoder = func(ctx context.Context, contentType string, in interface{}) (body []byte, err error) {
-		return nil, fmt.Errorf("mock test encoder error")
+		return nil, errors.New("mock test encoder error")
 	}
 	err = client.Invoke(context.Background(), "POST", "/go", map[string]string{"name": "kratos"}, nil, EmptyCallOption{})
 	if err == nil {
diff --git a/transport/http/context_test.go b/transport/http/context_test.go
index 3b7466bf..b440e9df 100644
--- a/transport/http/context_test.go
+++ b/transport/http/context_test.go
@@ -4,7 +4,6 @@ import (
 	"bytes"
 	"context"
 	"errors"
-	"fmt"
 	"net/http"
 	"net/http/httptest"
 	"net/url"
@@ -92,7 +91,7 @@ func TestContextResponse(t *testing.T) {
 	if err != nil {
 		t.Errorf("expected %v, got %v", nil, err)
 	}
-	needErr := fmt.Errorf("some error")
+	needErr := errors.New("some error")
 	err = w.Returns(map[string]string{}, needErr)
 	if !errors.Is(err, needErr) {
 		t.Errorf("expected %v, got %v", needErr, err)
diff --git a/transport/http/resolver_test.go b/transport/http/resolver_test.go
index 27473d12..e95d8850 100644
--- a/transport/http/resolver_test.go
+++ b/transport/http/resolver_test.go
@@ -73,7 +73,7 @@ const errServiceName = "needErr"
 
 func (d *mockDiscoveries) Watch(ctx context.Context, serviceName string) (registry.Watcher, error) {
 	if serviceName == errServiceName {
-		return nil, fmt.Errorf("mock test service name watch err")
+		return nil, errors.New("mock test service name watch err")
 	}
 	return &mockWatch{ctx: ctx, isSecure: d.isSecure, nextErr: d.nextErr, stopErr: d.stopErr}, nil
 }
@@ -116,7 +116,7 @@ func (m *mockWatch) Next() ([]*registry.ServiceInstance, error) {
 
 func (m *mockWatch) Stop() error {
 	if m.stopErr {
-		return fmt.Errorf("mock test error")
+		return errors.New("mock test error")
 	}
 	// 标记 next 需要报错
 	m.nextErr = true
diff --git a/transport/http/server_test.go b/transport/http/server_test.go
index 05bc8399..0d4be88b 100644
--- a/transport/http/server_test.go
+++ b/transport/http/server_test.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"crypto/tls"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"io"
 	"net"
@@ -13,8 +14,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/errors"
-
+	kratoserrors "github.com/go-kratos/kratos/v2/errors"
 	"github.com/go-kratos/kratos/v2/internal/host"
 )
 
@@ -49,9 +49,9 @@ func TestServeHTTP(t *testing.T) {
 	mux := NewServer(Listener(ln))
 	mux.HandleFunc("/index", h)
 	mux.Route("/errors").GET("/cause", func(ctx Context) error {
-		return errors.BadRequest("xxx", "zzz").
+		return kratoserrors.BadRequest("xxx", "zzz").
 			WithMetadata(map[string]string{"foo": "bar"}).
-			WithCause(fmt.Errorf("error cause"))
+			WithCause(errors.New("error cause"))
 	})
 	if err = mux.WalkRoute(func(r RouteInfo) error {
 		t.Logf("WalkRoute: %+v", r)
@@ -65,7 +65,7 @@ func TestServeHTTP(t *testing.T) {
 	srv := http.Server{Handler: mux}
 	go func() {
 		if err := srv.Serve(ln); err != nil {
-			if errors.Is(err, http.ErrServerClosed) {
+			if kratoserrors.Is(err, http.ErrServerClosed) {
 				return
 			}
 			panic(err)
@@ -87,9 +87,9 @@ func TestServer(t *testing.T) {
 		_ = json.NewEncoder(w).Encode(testData{Path: r.RequestURI})
 	})
 	srv.Route("/errors").GET("/cause", func(ctx Context) error {
-		return errors.BadRequest("xxx", "zzz").
+		return kratoserrors.BadRequest("xxx", "zzz").
 			WithMetadata(map[string]string{"foo": "bar"}).
-			WithCause(fmt.Errorf("error cause"))
+			WithCause(errors.New("error cause"))
 	})
 
 	if e, err := srv.Endpoint(); err != nil || e == nil || strings.HasSuffix(e.Host, ":0") {
@@ -135,7 +135,7 @@ func testAccept(t *testing.T, srv *Server) {
 		}
 		req.Header.Set("Content-Type", test.contentType)
 		resp, err := client.Do(req)
-		if errors.Code(err) != 400 {
+		if kratoserrors.Code(err) != 400 {
 			t.Errorf("expected 400 got %v", err)
 		}
 		if err == nil {
@@ -205,7 +205,7 @@ func testClient(t *testing.T, srv *Server) {
 			t.Fatal(err)
 		}
 		resp, err := client.Do(req)
-		if errors.Code(err) != test.code {
+		if kratoserrors.Code(err) != test.code {
 			t.Fatalf("want %v, but got %v", test, err)
 		}
 		if err != nil {
@@ -231,7 +231,7 @@ func testClient(t *testing.T, srv *Server) {
 	for _, test := range tests {
 		var res testData
 		err := client.Invoke(context.Background(), test.method, test.path, nil, &res)
-		if errors.Code(err) != test.code {
+		if kratoserrors.Code(err) != test.code {
 			t.Fatalf("want %v, but got %v", test, err)
 		}
 		if err != nil {
diff --git a/transport/transport_test.go b/transport/transport_test.go
index b83c8ee3..cba7f2ae 100644
--- a/transport/transport_test.go
+++ b/transport/transport_test.go
@@ -53,7 +53,7 @@ func TestServerTransport(t *testing.T) {
 		t.Errorf("expected:%v got:%v", true, ok)
 	}
 	if mtr == nil {
-		t.Errorf("expected:%v got:%v", nil, mtr)
+		t.Fatalf("expected:%v got:%v", nil, mtr)
 	}
 	if mtr.Kind().String() != KindGRPC.String() {
 		t.Errorf("expected:%v got:%v", KindGRPC.String(), mtr.Kind().String())