You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by li...@apache.org on 2020/12/26 06:53:45 UTC

[skywalking-satellite] branch main updated: mmap-queue-plugin (#10)

This is an automated email from the ASF dual-hosted git repository.

liujiapeng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-satellite.git


The following commit(s) were added to refs/heads/main by this push:
     new cfc07ea  mmap-queue-plugin (#10)
cfc07ea is described below

commit cfc07ea2d28dc8e0e1927eb13e854f20ac3856d2
Author: Evan <31...@users.noreply.github.com>
AuthorDate: Sat Dec 26 14:53:38 2020 +0800

    mmap-queue-plugin (#10)
    
    * mmap-queue-plugin
    
    * add git modules
    
    * submodule
    
    * polish license & remove lock & use atomic int32
    
    * Delete make check
    
    * fix unit test
    
    * convert event to proto and add generate codes
    
    * add bigqueue lisense
    
    * add satellite in license
    
    * Update .github/workflows/build-and-test.yaml
    
    * The supplementary license
    
    * The supplementary license
    
    * try fix licenser
    
    * Fix wrong PHONY and try fix licenser
    
    * polish beanchmark doc  and polish license-checker
    
    * polish license location
    
    * polish LICENSE
    
    * push gen codes
    
    * add generate codes check
    
    * fix generate codes check
    
    * tidy go mod
    
    * go mod tidy
    
    * remove go.mod& go.sum from the check
    
    * polish mmap magic number & enhance swap method
    
    * polish code lint
    
    Co-authored-by: Evan <ev...@outlook.com>
    Co-authored-by: Zhenxu Ke <ke...@apache.org>
---
 .github/workflows/build-and-test.yaml              |   13 +-
 .gitmodules                                        |    3 +
 LICENSE                                            |   12 +-
 Makefile                                           |   25 +-
 README.md                                          |    2 +
 dist/LICENSE                                       |   12 +-
 .../licenses/{LICENSE-cli => LICENSE-bigqueue.txt} |    2 +-
 dist/licenses/{LICENSE-cli => LICENSE-cli.txt}     |    0
 dist/licenses/LICENSE-github-protobuf.txt          |   27 +
 dist/licenses/LICENSE-go-cmp.txt                   |   27 +
 dist/licenses/LICENSE-google-protobuf.txt          |   27 +
 .../{LICENSE-logrus => LICENSE-logrus.txt}         |    0
 dist/licenses/{LICENSE-cli => LICENSE-mmap.txt}    |    2 +-
 dist/licenses/{LICENSE-viper => LICENSE-viper.txt} |    0
 docs/compile/compile.md                            |   10 +
 docs/configuration/queue.md                        |   11 +
 docs/plugins/queue/mmap/README.md                  |   86 ++
 go.mod                                             |    8 +-
 go.sum                                             |   75 +-
 internal/pkg/event/event.go                        |   61 +-
 internal/pkg/log/log.go                            |    2 +-
 internal/satellite/event/event.go                  |  109 --
 .../satellite/module/gatherer/fetcher_gatherer.go  |   26 +-
 .../satellite/module/gatherer/receiver_gatherer.go |   25 +-
 internal/satellite/module/processor/processor.go   |    3 +-
 internal/satellite/module/sender/sender.go         |    7 +-
 .../LICENSE-cli => licenses/LICENSE-bigqueue.txt   |    2 +-
 plugins/fetcher/api/fetcher.go                     |    2 +-
 plugins/forwarder/api/forwarder.go                 |    3 +-
 plugins/init.go                                    |    2 +-
 plugins/parser/api/parser.go                       |    4 +-
 plugins/queue/api/queue.go                         |   18 +-
 plugins/queue/mmap/README.md                       |    1 -
 plugins/queue/mmap/branchmark_test.go              |  114 +++
 plugins/queue/mmap/meta/meta.go                    |  166 +++
 plugins/queue/mmap/meta/meta_test.go               |  208 ++++
 plugins/queue/mmap/queue.go                        |  273 +++++
 plugins/queue/mmap/queue_opreation.go              |  170 ++++
 plugins/queue/mmap/queue_test.go                   |  441 ++++++++
 plugins/queue/mmap/segment/segment.go              |   68 ++
 plugins/queue/mmap/segment/segment_test.go         |  187 ++++
 plugins/queue/mmap/segment_operation.go            |  131 +++
 plugins/queue/{api => }/queue_repository.go        |   18 +-
 plugins/receiver/api/receiver.go                   |    4 +-
 protocol/gen-codes/satellite/protocol/Event.pb.go  |  498 +++++++++
 .../skywalking/network/common/v3/Common.pb.go      |  441 ++++++++
 protocol/gen-codes/skywalking/network/go.mod       |    9 +
 protocol/gen-codes/skywalking/network/go.sum       |   85 ++
 .../network/language/agent/v3/BrowserPerf.pb.go    |  632 ++++++++++++
 .../language/agent/v3/BrowserPerf_grpc.pb.go       |  173 ++++
 .../network/language/agent/v3/CLRMetric.pb.go      |  500 +++++++++
 .../network/language/agent/v3/CLRMetric_grpc.pb.go |   99 ++
 .../network/language/agent/v3/JVMMetric.pb.go      |  815 +++++++++++++++
 .../network/language/agent/v3/JVMMetric_grpc.pb.go |   99 ++
 .../network/language/agent/v3/Meter.pb.go          |  657 ++++++++++++
 .../network/language/agent/v3/Meter_grpc.pb.go     |  134 +++
 .../network/language/agent/v3/Tracing.pb.go        | 1067 ++++++++++++++++++++
 .../network/language/agent/v3/Tracing_grpc.pb.go   |  184 ++++
 .../network/language/profile/v3/Profile.pb.go      |  484 +++++++++
 .../network/language/profile/v3/Profile_grpc.pb.go |  211 ++++
 .../skywalking/network/logging/v3/Logging.pb.go    |  687 +++++++++++++
 .../network/logging/v3/Logging_grpc.pb.go          |  138 +++
 .../network/management/v3/Management.pb.go         |  289 ++++++
 .../network/management/v3/Management_grpc.pb.go    |  142 +++
 .../network/servicemesh/v3/service-mesh.pb.go      |  435 ++++++++
 .../network/servicemesh/v3/service-mesh_grpc.pb.go |  132 +++
 protocol/satellite-protocol/event/Event.proto      |   72 ++
 protocol/skywalking-data-collect-protocol          |    1 +
 tools/protocol_gen.sh                              |   53 +
 69 files changed, 10209 insertions(+), 215 deletions(-)

diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml
index 592fd3b..0096f38 100644
--- a/.github/workflows/build-and-test.yaml
+++ b/.github/workflows/build-and-test.yaml
@@ -36,6 +36,12 @@ jobs:
         with:
           go-version: ${{ matrix.go-version }}
 
+      - name: Install Protoc
+        uses: arduino/setup-protoc@v1
+        with:
+          version: '3.x'
+          include-pre-releases: true
+
       - name: Check out code into the Go module directory
         uses: actions/checkout@v2
         with:
@@ -47,11 +53,17 @@ jobs:
       - name: Get dependencies
         run: make deps
 
+      - name: Check generate codes
+        run: make gen && make check
+
       - name: Lint
         run: make lint
 
       - name: Test
         run: make test
+
+
+
   result:
     runs-on: ubuntu-latest
     timeout-minutes: 90
@@ -59,4 +71,3 @@ jobs:
     steps:
       - name: Build Result
         run: echo "Just to make the GitHub merge button green"
-
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..3cc9e11
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "protocol/skywalking-data-collect-protocol"]
+	path = protocol/skywalking-data-collect-protocol
+	url = https://github.com/apache/skywalking-data-collect-protocol
diff --git a/LICENSE b/LICENSE
index ba12634..471fdac 100644
--- a/LICENSE
+++ b/LICENSE
@@ -201,9 +201,9 @@
    limitations under the License.
 
 =======================================================================
-Apache SkyWalking Subcomponents:
+Apache SkyWalking Satellite Subcomponents:
 
-The Apache SkyWalking project contains subcomponents with separate copyright
+The Apache SkyWalking Satellite project contains subcomponents with separate copyright
 notices and license terms. Your use of the source code for the these
 subcomponents is subject to the terms and conditions of the following
 licenses.
@@ -224,3 +224,11 @@ The following components are provided under a BSD license. See project link for
 The text of each license is also included at licenses/LICENSE-[project].txt.
 
 
+========================================================================
+MIT licenses
+========================================================================
+
+The following components are provided under the MIT License. See project link for details.
+The text of each license is also included at licenses/LICENSE-[project].txt.
+
+grandecola (bigqueue) v0.4.0: https://github.com/grandecola/bigqueue MIT
\ No newline at end of file
diff --git a/Makefile b/Makefile
index dbbc0e8..edc7a64 100644
--- a/Makefile
+++ b/Makefile
@@ -25,6 +25,7 @@ RELEASE_SRC = skywalking-satellite-$(VERSION)-src
 OS = $(shell uname)
 
 GO = go
+GIT = git
 GO_PATH = $$($(GO) env GOPATH)
 GO_BUILD = $(GO) build
 GO_GET = $(GO) get
@@ -36,7 +37,7 @@ GO_BUILD_FLAGS = -v
 GO_BUILD_LDFLAGS = -X main.version=$(VERSION)
 GQL_GEN = $(GO_PATH)/bin/gqlgen
 
-PLATFORMS := windows linux darwin
+PLATFORMS := linux darwin
 os = $(word 1, $@)
 ARCH = amd64
 
@@ -44,6 +45,7 @@ SHELL = /bin/bash
 
 all: clean license deps lint test build
 
+.PHONY: tools
 tools:
 	$(GO_PACKR) -v || $(GO_GET) -u github.com/gobuffalo/packr/v2/...
 	$(GO_LINT) version || curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GO_PATH)/bin v1.33.0
@@ -52,17 +54,21 @@ tools:
 deps: tools
 	$(GO_GET) -v -t -d ./...
 
+.PHONY: gen
+gen:
+	/bin/sh tools/protocol_gen.sh
+
 .PHONY: lint
 lint: tools
 	$(GO_LINT) run -v ./...
 
-.PHONE: test
+.PHONY: test
 test: clean lint
 	$(GO_TEST) ./... -coverprofile=coverage.txt -covermode=atomic
 
 .PHONY: license
 license: clean tools
-	$(GO_LICENSER) -d -licensor='Apache Software Foundation (ASF)' .
+	$(GO_LICENSER) -d -exclude=plugins/queue/mmap/queue_opreation.go -exclude=protocol/gen-codes -licensor='Apache Software Foundation (ASF)' ./
 
 .PHONY: verify
 verify: clean license lint test
@@ -72,8 +78,17 @@ clean: tools
 	-rm -rf coverage.txt
 
 .PHONY: build
-build: deps windows linux darwin
-
+build: deps linux darwin
+
+.PHONY: check
+check:
+	$(MAKE) clean
+	$(GO) mod tidy &> /dev/null
+	@if [ ! -z "`git status -s |grep -v 'go.mod\|go.sum'`" ]; then \
+		echo "Following files are not consistent with CI:"; \
+		git status -s |grep -v 'go.mod\|go.sum'; \
+		exit 1; \
+	fi
 
 .PHONY: $(PLATFORMS)
 $(PLATFORMS):
diff --git a/README.md b/README.md
index 8c4b88e..da4ac82 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,8 @@ Apache SkyWalking Satellite
 
 # Download
 
+# Compile
+[How to compile the Satellite.](./docs/compile/compile.md)
 # Contact Us
 * Mail list: **dev@skywalking.apache.org**. Mail to `dev-subscribe@skywalking.apache.org`, follow the reply to subscribe the mail list.
 * Join `skywalking` channel at [Apache Slack](http://s.apache.org/slack-invite). If the link is not working, find the latest one at [Apache INFRA WIKI](https://cwiki.apache.org/confluence/display/INFRA/Slack+Guest+Invites).
diff --git a/dist/LICENSE b/dist/LICENSE
index 618fe55..9cb8a3a 100644
--- a/dist/LICENSE
+++ b/dist/LICENSE
@@ -201,9 +201,9 @@
    limitations under the License.
 
 =======================================================================
-Apache SkyWalking Subcomponents:
+Apache SkyWalking Satellite Subcomponents:
 
-The Apache SkyWalking project contains subcomponents with separate copyright
+Apache SkyWalking Satellite project contains subcomponents with separate copyright
 notices and license terms. Your use of the source code for the these
 subcomponents is subject to the terms and conditions of the following
 licenses.
@@ -222,7 +222,9 @@ BSD licenses
 
 The following components are provided under a BSD license. See project link for details.
 The text of each license is also included at licenses/LICENSE-[project].txt.
-
+    google (go-cmp) v0.5.4 https://github.com/google/go-cmp BSD
+    golang(protobuf) v1.4.3   https://github.com/golang/protobuf BSD
+    google(protobuf v1.25.0 https://google.golang.org/protobuf BSD
 
 ========================================================================
 MIT licenses
@@ -234,3 +236,7 @@ The text of each license is also included at licenses/LICENSE-[project].txt.
 	sirupsen (logrus) v1.7.0: https://github.com/sirupsen/logrus MIT
 	spf13 (viper) v1.7.1: https://github.com/spf13/viper MIT
 	urfave (cli) v2.3.0: https://github.com/urfave/cli MIT
+	grandecola (mmap) v0.6.0: https://github.com/grandecola/mmap MIT
+    grandecola (bigqueue) v0.4.0: https://github.com/grandecola/bigqueue MIT
+
+
diff --git a/dist/licenses/LICENSE-cli b/dist/licenses/LICENSE-bigqueue.txt
similarity index 95%
copy from dist/licenses/LICENSE-cli
copy to dist/licenses/LICENSE-bigqueue.txt
index 42a597e..be28ae0 100644
--- a/dist/licenses/LICENSE-cli
+++ b/dist/licenses/LICENSE-bigqueue.txt
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2016 Jeremy Saenz & Contributors
+Copyright (c) 2018 Aman Mangal
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/dist/licenses/LICENSE-cli b/dist/licenses/LICENSE-cli.txt
similarity index 100%
copy from dist/licenses/LICENSE-cli
copy to dist/licenses/LICENSE-cli.txt
diff --git a/dist/licenses/LICENSE-github-protobuf.txt b/dist/licenses/LICENSE-github-protobuf.txt
new file mode 100644
index 0000000..1d8ab97
--- /dev/null
+++ b/dist/licenses/LICENSE-github-protobuf.txt
@@ -0,0 +1,27 @@
+Copyright 2010 The Go Authors.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/dist/licenses/LICENSE-go-cmp.txt b/dist/licenses/LICENSE-go-cmp.txt
new file mode 100644
index 0000000..32017f8
--- /dev/null
+++ b/dist/licenses/LICENSE-go-cmp.txt
@@ -0,0 +1,27 @@
+Copyright (c) 2017 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/dist/licenses/LICENSE-google-protobuf.txt b/dist/licenses/LICENSE-google-protobuf.txt
new file mode 100644
index 0000000..ea5ea89
--- /dev/null
+++ b/dist/licenses/LICENSE-google-protobuf.txt
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/dist/licenses/LICENSE-logrus b/dist/licenses/LICENSE-logrus.txt
similarity index 100%
rename from dist/licenses/LICENSE-logrus
rename to dist/licenses/LICENSE-logrus.txt
diff --git a/dist/licenses/LICENSE-cli b/dist/licenses/LICENSE-mmap.txt
similarity index 95%
copy from dist/licenses/LICENSE-cli
copy to dist/licenses/LICENSE-mmap.txt
index 42a597e..be28ae0 100644
--- a/dist/licenses/LICENSE-cli
+++ b/dist/licenses/LICENSE-mmap.txt
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2016 Jeremy Saenz & Contributors
+Copyright (c) 2018 Aman Mangal
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/dist/licenses/LICENSE-viper b/dist/licenses/LICENSE-viper.txt
similarity index 100%
rename from dist/licenses/LICENSE-viper
rename to dist/licenses/LICENSE-viper.txt
diff --git a/docs/compile/compile.md b/docs/compile/compile.md
new file mode 100644
index 0000000..1d0d115
--- /dev/null
+++ b/docs/compile/compile.md
@@ -0,0 +1,10 @@
+# Compile
+## command
+```
+make build
+```
+## platform
+Linux and MacOs is supported in SkyWalking Satellite. Windows is not good supported beacuse some features is not adaptive on the Windows, such as the mmap feature. 
+
+The Windows platform does not support plugins list:
+1. mmap-queue
\ No newline at end of file
diff --git a/docs/configuration/queue.md b/docs/configuration/queue.md
new file mode 100644
index 0000000..3781b3b
--- /dev/null
+++ b/docs/configuration/queue.md
@@ -0,0 +1,11 @@
+# queue configuration
+
+|  Type   | Param  | DefaultValue| Meaning| 
+|  ----  | ----  |----  | ----  |
+| mmap-queue  | segment_size | 131072 | The size of each segment(Unit:Byte). The minimum value is the system memory page size.
+| mmap-queue  | max_in_mem_segments | 10 | The max num of segments in memory. The minimum value is 4.
+| mmap-queue  | queue_capacity_segments | 4000 | The capacity of Queue = segment_size * queue_capacity_segments.
+| mmap-queue  | flush_period | 1000 | The period flush time. The unit is ms.
+| mmap-queue  | flush_ceiling_num | 10000 | The max number in one flush time.
+| mmap-queue  | queue_dir | satellite-mmap-queue |Contains all files in the queue.
+| mmap-queue  | max_event_size | 20480 |The max size of the input event(Unit:Byte).
diff --git a/docs/plugins/queue/mmap/README.md b/docs/plugins/queue/mmap/README.md
new file mode 100644
index 0000000..7d6845f
--- /dev/null
+++ b/docs/plugins/queue/mmap/README.md
@@ -0,0 +1,86 @@
+# Design
+The mmap-queue is a big, fast, and persistent queue based on the memory-mapped files. One mmap-queue has a directory to store the whole data. The queue directory is made up of many segments and 1 metafile. This is originally implemented by [bigqueue](https://github.com/grandecola/bigqueue) project, we changed it a little for fitting the Satellite project requirements.
+
+- Segment: Segment is the real data store center, that provides large-space storage and does not reduce read and write performance as much as possible by using mmap. And we will avoid deleting files by reusing them.
+- Meta: The purpose of meta is to find the data that the consumer needs.
+
+## Meta
+Metadata only needs 80B to store the Metadata for the pipe. But for memory alignment, it takes at least one memory page size, which is generally 4K.
+```
+[    8Bit   ][  8Bit ][  8Bit ][  8Bit ][  8Bit ][  8Bit ][  8Bit ][  8Bit ][  8Bit ][  8Bit  ]
+[metaVersion][  ID   ][ offset][  ID   ][ offset][  ID   ][ offset][  ID   ][ offset][capacity]
+[metaVersion][writing   offset][watermark offset][committed offset][reading   offset][capacity]
+
+```
+### Transforming
+
+![](https://skywalking.apache.org/blog/2020-11-25-skywalking-satellite-0.1.0-design/offset-convert.jpg)
+
+## Configuration
+[Configuration Params](../../../configuration/queue.md)
+
+## Segment
+Segments are a series of files of the same size. Each input data would cost `8Bit+Len(data)Bit` to store the raw bytes. The first 8Bit is equal to `Len(data)` for finding the ending position. 
+### Swapper
+For the performance and resources thinking, we define a page replacement policy.
+
+- Keep the reading and writing segments on the memory.
+- When the mmapcount is greater or equals to the max_in_mem_segments, we first scan the read scope and then scan the written scope to swap the segments to promise the reading or writing segments are always in memory.
+    - Read scope: [reading_offset - max_in_mem_segments,reading_offset - 1]
+    - Written scope: [writing_offset - max_in_mem_segments,writing_offset - 1]
+    - Each displacement operation guarantees at least `max_in_mem_segments/2-1` capacity available. Subtract operation to subtract the amount of memory that must always exist.
+
+## BenchmarkTest
+Test machine: macbook pro 2018
+
+```
+Model Name:	MacBook Pro
+Model Identifier:	MacBookPro15,1
+Processor Name:	6-Core Intel Core i7
+Processor Speed:	2.2 GHz
+Number of Processors:	1
+Total Number of Cores:	6
+L2 Cache (per Core):	256 KB
+L3 Cache:	9 MB
+Hyper-Threading Technology:	Enabled
+Memory:	16 GB
+System Firmware Version:	1554.60.15.0.0 (iBridge: 18.16.13030.0.0,0
+```
+
+### push operation
+
+```
+goos: darwin
+goarch: amd64
+pkg: github.com/apache/skywalking-satellite/plugins/queue/mmap
+BenchmarkPush
+BenchmarkPush/segmentSize:_128KB_maxInMemSegments:10_message:8KB_queueCapacity:10000
+BenchmarkPush/segmentSize:_128KB_maxInMemSegments:10_message:8KB_queueCapacity:10000-12         	   45946	     28185 ns/op	    9884 B/op	       9 allocs/op
+BenchmarkPush/segmentSize:_256KB_maxInMemSegments:10_message:8KB_queueCapacity:10000
+BenchmarkPush/segmentSize:_256KB_maxInMemSegments:10_message:8KB_queueCapacity:10000-12         	   68137	     19142 ns/op	    9838 B/op	       9 allocs/op
+BenchmarkPush/segmentSize:_128KB_maxInMemSegments:20_message:8KB_queueCapacity:10000
+BenchmarkPush/segmentSize:_128KB_maxInMemSegments:20_message:8KB_queueCapacity:10000-12         	   47361	     22318 ns/op	    9884 B/op	       9 allocs/op
+BenchmarkPush/segmentSize:_128KB_maxInMemSegments:10_message:16KB_queueCapacity:10000
+BenchmarkPush/segmentSize:_128KB_maxInMemSegments:10_message:16KB_queueCapacity:10000-12        	   24478	     45501 ns/op	   18934 B/op	      10 allocs/op
+BenchmarkPush/segmentSize:_128KB_maxInMemSegments:10_message:8KB_queueCapacity:100000
+BenchmarkPush/segmentSize:_128KB_maxInMemSegments:10_message:8KB_queueCapacity:100000-12        	   45691	     29413 ns/op	    9884 B/op	       9 allocs/op
+PASS
+```
+### push and pop operation
+```
+goos: darwin
+goarch: amd64
+pkg: github.com/apache/skywalking-satellite/plugins/queue/mmap
+BenchmarkPushAndPop
+BenchmarkPushAndPop/segmentSize:_128KB_maxInMemSegments:10_message:8KB_queueCapacity:10000
+BenchmarkPushAndPop/segmentSize:_128KB_maxInMemSegments:10_message:8KB_queueCapacity:10000-12         	   30657	     34182 ns/op	   28725 B/op	      41 allocs/op
+BenchmarkPushAndPop/segmentSize:_256KB_maxInMemSegments:10_message:8KB_queueCapacity:10000
+BenchmarkPushAndPop/segmentSize:_256KB_maxInMemSegments:10_message:8KB_queueCapacity:10000-12         	   34617	     31619 ns/op	   28677 B/op	      41 allocs/op
+BenchmarkPushAndPop/segmentSize:_128KB_maxInMemSegments:20_message:8KB_queueCapacity:10000
+BenchmarkPushAndPop/segmentSize:_128KB_maxInMemSegments:20_message:8KB_queueCapacity:10000-12         	   32440	     38439 ns/op	   28726 B/op	      41 allocs/op
+BenchmarkPushAndPop/segmentSize:_128KB_maxInMemSegments:10_message:16KB_queueCapacity:10000
+BenchmarkPushAndPop/segmentSize:_128KB_maxInMemSegments:10_message:16KB_queueCapacity:10000-12        	   18554	     56840 ns/op	   54931 B/op	      42 allocs/op
+BenchmarkPushAndPop/segmentSize:_128KB_maxInMemSegments:10_message:8KB_queueCapacity:100000
+BenchmarkPushAndPop/segmentSize:_128KB_maxInMemSegments:10_message:8KB_queueCapacity:100000-12        	   27303	     40016 ns/op	   28725 B/op	      41 allocs/op
+PASS
+```
diff --git a/go.mod b/go.mod
index 3bf717f..d1ab22e 100644
--- a/go.mod
+++ b/go.mod
@@ -2,9 +2,15 @@ module github.com/apache/skywalking-satellite
 
 go 1.14
 
+replace skywalking/network v1.0.0 => ./protocol/gen-codes/skywalking/network
+
 require (
+	github.com/golang/protobuf v1.4.3
+	github.com/google/go-cmp v0.5.4
+	github.com/grandecola/mmap v0.6.0
 	github.com/sirupsen/logrus v1.7.0
 	github.com/spf13/viper v1.7.1
 	github.com/urfave/cli/v2 v2.3.0
+	google.golang.org/protobuf v1.25.0
+	skywalking/network v1.0.0
 )
-
diff --git a/go.sum b/go.sum
index e84cc08..714aaf3 100644
--- a/go.sum
+++ b/go.sum
@@ -11,6 +11,7 @@ cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqCl
 cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
 cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
@@ -23,8 +24,10 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
 github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@@ -37,6 +40,11 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@@ -48,6 +56,7 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@@ -56,27 +65,50 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
+github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.1.2/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/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/grandecola/mmap v0.6.0 h1:dYrZWLay1rDlmlsGsSIoXGQ+JMu/t2ZnKt8vT1h+1o0=
+github.com/grandecola/mmap v0.6.0/go.mod h1:q5v9jpm393rcp5PXE6biArHKc2SWJBpXjfxSRtQMtNU=
 github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
 github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
 github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
 github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
 github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
 github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
 github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
 github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
 github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
 github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
@@ -95,22 +127,27 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
 github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
 github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
+github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
 github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
 github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
 github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
@@ -126,6 +163,7 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI
 github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -134,6 +172,7 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
 github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
 github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
@@ -150,7 +189,9 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
 github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
@@ -165,14 +206,17 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
 github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
 github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
-github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
 github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
 github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
@@ -186,11 +230,13 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
 golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
 golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw=
 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@@ -218,9 +264,11 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -258,6 +306,7 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3
 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
@@ -267,6 +316,8 @@ golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc h1:NCy3Ohtk6Iny5V/reW2Ktypo4zIpWBdRJ1uFMjBxdg8=
 golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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=
 google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
@@ -275,6 +326,7 @@ google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -285,11 +337,30 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
 google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
 google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.34.0 h1:raiipEjMOIC/TO2AvyTxP25XFdLxNIBwzDh3FM3XztI=
+google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
+google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
 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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
@@ -297,11 +368,13 @@ gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
diff --git a/internal/pkg/event/event.go b/internal/pkg/event/event.go
index a834fae..2b118b0 100644
--- a/internal/pkg/event/event.go
+++ b/internal/pkg/event/event.go
@@ -19,19 +19,8 @@ package event
 
 import (
 	"fmt"
-	"time"
-)
 
-// The event type.
-const (
-	// Mapping to the type supported by SkyWalking OAP.
-	_ Type = iota
-	MetricsEvent
-	ProfilingEvent
-	SegmentEvent
-	ManagementEvent
-	MeterEvent
-	LogEvent
+	"github.com/apache/skywalking-satellite/protocol/gen-codes/satellite/protocol"
 )
 
 type Type int32
@@ -39,56 +28,22 @@ type Type int32
 // Offset is a generic form, which allows having different definitions in different Queues.
 type Offset string
 
-// Event that implement this interface would be allowed to transmit in the Satellite.
-type Event interface {
-	// Name returns the event name.
-	Name() string
-
-	// Meta is a pair of key and value to record meta data, such as labels.
-	Meta() map[string]string
-
-	// Data returns the wrapped data.
-	Data() interface{}
-
-	// Time returns the event time.
-	Time() time.Time
-
-	// Type is to distinguish different events.
-	Type() Type
-
-	// IsRemote means is a output event when returns true.
-	IsRemote() bool
-}
-
-// SerializableEvent is used in Collector to bridge Queue.
-type SerializableEvent interface {
-	Event
-
-	// ToBytes serialize the event to a byte array.
-	ToBytes() []byte
-
-	// FromBytes deserialize the byte array to an event.
-	FromBytes(bytes []byte) SerializableEvent
-}
-
 // BatchEvents is used by Forwarder to forward.
-type BatchEvents []Event
+type BatchEvents []*protocol.Event
 
 // OutputEventContext is a container to store the output context.
 type OutputEventContext struct {
-	Context map[string]Event
+	Context map[string]*protocol.Event
 	Offset  Offset
 }
 
-// Put puts the incoming event into the context when the event is a remote event.
-func (c *OutputEventContext) Put(event Event) {
-	if event.IsRemote() {
-		c.Context[event.Name()] = event
-	}
+// Put puts the incoming event into the context.
+func (c *OutputEventContext) Put(event *protocol.Event) {
+	c.Context[event.GetName()] = event
 }
 
-// Get returns a event in the context. When the eventName does not exist, a error would be returned.
-func (c *OutputEventContext) Get(eventName string) (Event, error) {
+// Get returns an event in the context. When the eventName does not exist, an error would be returned.
+func (c *OutputEventContext) Get(eventName string) (*protocol.Event, error) {
 	e, ok := c.Context[eventName]
 	if !ok {
 		err := fmt.Errorf("cannot find the event name in OutputEventContext : %s", eventName)
diff --git a/internal/pkg/log/log.go b/internal/pkg/log/log.go
index 6040c2f..2ea41f3 100644
--- a/internal/pkg/log/log.go
+++ b/internal/pkg/log/log.go
@@ -29,7 +29,7 @@ import (
 // Default logger config.
 const (
 	defaultLogPattern  = "%time [%level][%field] - %msg"
-	defaultTimePattern = "2006-01-02 15:04:05.001"
+	defaultTimePattern = "2006-01-02 15:04:05.000"
 )
 
 // LoggerConfig initializes the global logger config.
diff --git a/internal/satellite/event/event.go b/internal/satellite/event/event.go
deleted file mode 100644
index a53720b..0000000
--- a/internal/satellite/event/event.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Licensed to Apache Software Foundation (ASF) under one or more contributor
-// license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright
-// ownership. Apache Software Foundation (ASF) licenses this file to you under
-// the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package event
-
-import (
-	"time"
-
-	"github.com/apache/skywalking-satellite/internal/pkg/event"
-)
-
-// Event defines the common fields.
-type Event struct {
-	name      string
-	timestamp time.Time
-	meta      map[string]string
-	eventType event.Type
-	remote    bool
-}
-
-// ETBFunc serialize event to bytes.
-type ETBFunc func(event event.SerializableEvent) []byte
-
-// BToFunc deserialize bytes to event.
-type BToFunc func(bytes []byte) event.SerializableEvent
-
-// StructuredEvent works when the data is a struct type.
-type StructuredEvent struct {
-	Event
-	data interface{}
-}
-
-// StructuredEvent works when the data is not a struct type.
-type UnstructuredEvent struct {
-	Event
-	data map[string]interface{}
-}
-
-// StructuredEvent works when the data is a struct type in the collector.
-type StructuredSerializableEvent struct {
-	StructuredEvent
-	etb ETBFunc
-	bte BToFunc
-}
-
-// StructuredEvent works when the data is not a struct type in the collector.
-type UnstructuredSerializableEvent struct {
-	UnstructuredEvent
-	etb ETBFunc
-	bte BToFunc
-}
-
-func (s *Event) Name() string {
-	return s.name
-}
-
-func (s *Event) Meta() map[string]string {
-	return s.meta
-}
-
-func (s *Event) Time() time.Time {
-	return s.timestamp
-}
-
-func (s *Event) Type() event.Type {
-	return s.eventType
-}
-
-func (s *Event) IsRemote() bool {
-	return s.remote
-}
-
-func (u *StructuredEvent) Data() interface{} {
-	return u.data
-}
-
-func (u *UnstructuredEvent) Data() interface{} {
-	return u.data
-}
-
-func (s *StructuredSerializableEvent) ToBytes() []byte {
-	return s.etb(s)
-}
-
-func (s *StructuredSerializableEvent) FromBytes(bytes []byte) event.SerializableEvent {
-	return s.bte(bytes)
-}
-
-func (u *UnstructuredSerializableEvent) ToBytes() []byte {
-	return u.etb(u)
-}
-
-func (u *UnstructuredSerializableEvent) FromBytes(bytes []byte) event.SerializableEvent {
-	return u.bte(bytes)
-}
diff --git a/internal/satellite/module/gatherer/fetcher_gatherer.go b/internal/satellite/module/gatherer/fetcher_gatherer.go
index 77ac6d0..f218657 100644
--- a/internal/satellite/module/gatherer/fetcher_gatherer.go
+++ b/internal/satellite/module/gatherer/fetcher_gatherer.go
@@ -47,7 +47,7 @@ func (f *FetcherGatherer) Prepare() error {
 
 func (f *FetcherGatherer) Boot(ctx context.Context) {
 	var wg sync.WaitGroup
-	wg.Add(1)
+	wg.Add(2)
 	go func() {
 		defer wg.Done()
 		timeTicker := time.NewTicker(time.Duration(f.config.FetchInterval) * time.Millisecond)
@@ -55,21 +55,37 @@ func (f *FetcherGatherer) Boot(ctx context.Context) {
 			select {
 			case <-timeTicker.C:
 				events := f.runningFetcher.Fetch()
-				for _, event := range events {
-					err := f.runningQueue.Push(event)
+				for _, e := range events {
+					err := f.runningQueue.Push(e)
 					if err != nil {
 						// todo add abandonedCount metrics
 						log.Logger.Errorf("cannot put event into queue in %s namespace, %v", f.config.NamespaceName, err)
 					}
 				}
-			case e := <-f.runningQueue.Pop():
-				f.outputChannel <- e
 			case <-ctx.Done():
 				f.Shutdown()
 				return
 			}
 		}
 	}()
+
+	go func() {
+		defer wg.Done()
+		for {
+			select {
+			case <-ctx.Done():
+				f.Shutdown()
+				return
+			default:
+				if e, err := f.runningQueue.Pop(); err == nil {
+					f.outputChannel <- e
+				} else {
+					log.Logger.Errorf("error in popping from the queue: %v", err)
+					time.Sleep(time.Second)
+				}
+			}
+		}
+	}()
 	wg.Wait()
 }
 
diff --git a/internal/satellite/module/gatherer/receiver_gatherer.go b/internal/satellite/module/gatherer/receiver_gatherer.go
index 5735474..de812a5 100644
--- a/internal/satellite/module/gatherer/receiver_gatherer.go
+++ b/internal/satellite/module/gatherer/receiver_gatherer.go
@@ -20,6 +20,7 @@ package gatherer
 import (
 	"context"
 	"sync"
+	"time"
 
 	"github.com/apache/skywalking-satellite/internal/pkg/event"
 	"github.com/apache/skywalking-satellite/internal/pkg/log"
@@ -45,7 +46,7 @@ type ReceiverGatherer struct {
 func (r *ReceiverGatherer) Prepare() error {
 	log.Logger.Infof("receiver gatherer module of %s namespace is preparing", r.config.NamespaceName)
 	r.runningReceiver.RegisterHandler(r.runningServer)
-	if err := r.runningQueue.Prepare(); err != nil {
+	if err := r.runningQueue.Initialize(); err != nil {
 		log.Logger.Infof("the %s queue of %s namespace was failed to initialize", r.runningQueue.Name(), r.config.NamespaceName)
 		return err
 	}
@@ -54,7 +55,7 @@ func (r *ReceiverGatherer) Prepare() error {
 
 func (r *ReceiverGatherer) Boot(ctx context.Context) {
 	var wg sync.WaitGroup
-	wg.Add(1)
+	wg.Add(2)
 	go func() {
 		defer wg.Done()
 		for {
@@ -65,14 +66,30 @@ func (r *ReceiverGatherer) Boot(ctx context.Context) {
 					// todo add abandonedCount metrics
 					log.Logger.Errorf("cannot put event into queue in %s namespace, error is: %v", r.config.NamespaceName, err)
 				}
-			case e := <-r.runningQueue.Pop():
-				r.outputChannel <- e
 			case <-ctx.Done():
 				r.Shutdown()
 				return
 			}
 		}
 	}()
+
+	go func() {
+		defer wg.Done()
+		for {
+			select {
+			case <-ctx.Done():
+				r.Shutdown()
+				return
+			default:
+				if e, err := r.runningQueue.Pop(); err == nil {
+					r.outputChannel <- e
+				} else {
+					log.Logger.Errorf("error in popping from the queue: %v", err)
+					time.Sleep(time.Second)
+				}
+			}
+		}
+	}()
 	wg.Wait()
 }
 
diff --git a/internal/satellite/module/processor/processor.go b/internal/satellite/module/processor/processor.go
index 640f605..990be07 100644
--- a/internal/satellite/module/processor/processor.go
+++ b/internal/satellite/module/processor/processor.go
@@ -27,6 +27,7 @@ import (
 	processor "github.com/apache/skywalking-satellite/internal/satellite/module/processor/api"
 	sender "github.com/apache/skywalking-satellite/internal/satellite/module/sender/api"
 	filter "github.com/apache/skywalking-satellite/plugins/filter/api"
+	"github.com/apache/skywalking-satellite/protocol/gen-codes/satellite/protocol"
 )
 
 // Processor is the processing module in Satellite.
@@ -60,7 +61,7 @@ func (p *Processor) Boot(ctx context.Context) {
 			case e := <-p.gatherer.OutputDataChannel():
 				c := &event.OutputEventContext{
 					Offset:  e.Offset,
-					Context: make(map[string]event.Event),
+					Context: make(map[string]*protocol.Event),
 				}
 				c.Put(e.Event)
 				// processing the event with filters, that put the necessary events to OutputEventContext.
diff --git a/internal/satellite/module/sender/sender.go b/internal/satellite/module/sender/sender.go
index 19a469b..9ff723d 100644
--- a/internal/satellite/module/sender/sender.go
+++ b/internal/satellite/module/sender/sender.go
@@ -30,6 +30,7 @@ import (
 	client "github.com/apache/skywalking-satellite/plugins/client/api"
 	fallbacker "github.com/apache/skywalking-satellite/plugins/fallbacker/api"
 	forwarder "github.com/apache/skywalking-satellite/plugins/forwarder/api"
+	"github.com/apache/skywalking-satellite/protocol/gen-codes/satellite/protocol"
 )
 
 // Sender is the forward module in Satellite.
@@ -130,12 +131,12 @@ func (s *Sender) Shutdown() {
 func (s *Sender) consume(batch *buffer.BatchBuffer) {
 	log.Logger.Infof("sender module of %s namespace is flushing a new batch buffer."+
 		" the start offset is %s, and the size is %d", s.config.NamespaceName, batch.Last(), batch.Len())
-	var events = make(map[event.Type]event.BatchEvents)
+	var events = make(map[protocol.EventType]event.BatchEvents)
 	for i := 0; i < batch.Len(); i++ {
 		eventContext := batch.Buf()[i]
 		for _, e := range eventContext.Context {
-			if e.IsRemote() {
-				events[e.Type()] = append(events[e.Type()], e)
+			if e.Remote {
+				events[e.Type] = append(events[e.Type], e)
 			}
 		}
 	}
diff --git a/dist/licenses/LICENSE-cli b/licenses/LICENSE-bigqueue.txt
similarity index 95%
rename from dist/licenses/LICENSE-cli
rename to licenses/LICENSE-bigqueue.txt
index 42a597e..be28ae0 100644
--- a/dist/licenses/LICENSE-cli
+++ b/licenses/LICENSE-bigqueue.txt
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2016 Jeremy Saenz & Contributors
+Copyright (c) 2018 Aman Mangal
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/plugins/fetcher/api/fetcher.go b/plugins/fetcher/api/fetcher.go
index 4021473..83139a9 100644
--- a/plugins/fetcher/api/fetcher.go
+++ b/plugins/fetcher/api/fetcher.go
@@ -27,5 +27,5 @@ type Fetcher interface {
 	plugin.Plugin
 
 	// Fetch would fetch some APM data.
-	Fetch() []event.SerializableEvent
+	Fetch() event.BatchEvents
 }
diff --git a/plugins/forwarder/api/forwarder.go b/plugins/forwarder/api/forwarder.go
index df22ca4..6b7b881 100644
--- a/plugins/forwarder/api/forwarder.go
+++ b/plugins/forwarder/api/forwarder.go
@@ -20,6 +20,7 @@ package api
 import (
 	"github.com/apache/skywalking-satellite/internal/pkg/event"
 	"github.com/apache/skywalking-satellite/internal/pkg/plugin"
+	"github.com/apache/skywalking-satellite/protocol/gen-codes/satellite/protocol"
 )
 
 // Forwarder is a plugin interface, that defines new forwarders.
@@ -28,7 +29,7 @@ type Forwarder interface {
 	// Forward the batch events to the external services, such as Kafka MQ and SkyWalking OAP cluster.
 	Forward(connection interface{}, batch event.BatchEvents) error
 	// ForwardType returns the supported event type.
-	ForwardType() event.Type
+	ForwardType() protocol.EventType
 }
 
 // ForwardFunc represent the Forward() in Forwarder
diff --git a/plugins/init.go b/plugins/init.go
index 2bf3bf4..97f0177 100644
--- a/plugins/init.go
+++ b/plugins/init.go
@@ -24,7 +24,7 @@ import (
 	filter "github.com/apache/skywalking-satellite/plugins/filter/api"
 	forwarder "github.com/apache/skywalking-satellite/plugins/forwarder/api"
 	parser "github.com/apache/skywalking-satellite/plugins/parser/api"
-	queue "github.com/apache/skywalking-satellite/plugins/queue/api"
+	"github.com/apache/skywalking-satellite/plugins/queue"
 	receiver "github.com/apache/skywalking-satellite/plugins/receiver/api"
 	server "github.com/apache/skywalking-satellite/plugins/server/api"
 )
diff --git a/plugins/parser/api/parser.go b/plugins/parser/api/parser.go
index 754037f..3e09e3a 100644
--- a/plugins/parser/api/parser.go
+++ b/plugins/parser/api/parser.go
@@ -27,8 +27,8 @@ type Parser interface {
 	plugin.Plugin
 
 	// ParseBytes parse the byte buffer into events.
-	ParseBytes(bytes []byte) ([]event.SerializableEvent, error)
+	ParseBytes(bytes []byte) (event.BatchEvents, error)
 
 	// ParseStr parse the string into events.
-	ParseStr(str string) ([]event.SerializableEvent, error)
+	ParseStr(str string) (event.BatchEvents, error)
 }
diff --git a/plugins/queue/api/queue.go b/plugins/queue/api/queue.go
index f25b2ff..fcf9628 100644
--- a/plugins/queue/api/queue.go
+++ b/plugins/queue/api/queue.go
@@ -18,22 +18,25 @@
 package api
 
 import (
+	"reflect"
+
 	"github.com/apache/skywalking-satellite/internal/pkg/event"
 	"github.com/apache/skywalking-satellite/internal/pkg/plugin"
+	"github.com/apache/skywalking-satellite/protocol/gen-codes/satellite/protocol"
 )
 
 // Queue is a plugin interface, that defines new queues.
 type Queue interface {
 	plugin.Plugin
 
-	// Prepare creates the queue.
-	Prepare() error
+	// Initialize creates the queue.
+	Initialize() error
 
 	// Push a inputEvent into the queue.
-	Push(event event.SerializableEvent) error
+	Push(event *protocol.Event) error
 
 	// Pop returns a SequenceEvent when Queue is not empty,
-	Pop() chan *SequenceEvent
+	Pop() (*SequenceEvent, error)
 
 	// Close would close the queue.
 	Close() error
@@ -44,6 +47,11 @@ type Queue interface {
 
 // SequenceEvent is a wrapper to pass the event and the offset.
 type SequenceEvent struct {
-	Event  event.Event
+	Event  *protocol.Event
 	Offset event.Offset
 }
+
+// GetQueue an initialized filter plugin.
+func GetQueue(config plugin.Config) Queue {
+	return plugin.Get(reflect.TypeOf((*Queue)(nil)).Elem(), config).(Queue)
+}
diff --git a/plugins/queue/mmap/README.md b/plugins/queue/mmap/README.md
deleted file mode 100644
index 3f03ea1..0000000
--- a/plugins/queue/mmap/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# Plugin description
\ No newline at end of file
diff --git a/plugins/queue/mmap/branchmark_test.go b/plugins/queue/mmap/branchmark_test.go
new file mode 100644
index 0000000..d4eb030
--- /dev/null
+++ b/plugins/queue/mmap/branchmark_test.go
@@ -0,0 +1,114 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package mmap
+
+import (
+	"fmt"
+	"os"
+	"testing"
+
+	"github.com/apache/skywalking-satellite/internal/pkg/plugin"
+	"github.com/apache/skywalking-satellite/plugins/queue/api"
+)
+
+type benchmarkParam struct {
+	segmentSize      int
+	message          int // unit KB
+	maxInMemSegments int
+	queueCapacity    int
+}
+
+var params = []benchmarkParam{
+	{segmentSize: 1024 * 128, message: 8, maxInMemSegments: 10, queueCapacity: 10000},
+	// compare the influence of the segmentSize.
+	{segmentSize: 1024 * 256, message: 8, maxInMemSegments: 10, queueCapacity: 10000},
+	// compare the influence of the maxInMemSegments.
+	{segmentSize: 1024 * 128, message: 8, maxInMemSegments: 20, queueCapacity: 10000},
+	// compare the influence of the message size.
+	{segmentSize: 1024 * 128, message: 16, maxInMemSegments: 10, queueCapacity: 10000},
+	{segmentSize: 1024 * 128, message: 8, maxInMemSegments: 10, queueCapacity: 100000},
+}
+
+func cleanBenchmarkQueue(b *testing.B, q api.Queue) {
+	if err := os.RemoveAll(q.(*Queue).QueueDir); err != nil {
+		b.Errorf("cannot remove test queue dir, %v", err)
+	}
+}
+
+func BenchmarkPush(b *testing.B) {
+	for _, param := range params {
+		name := fmt.Sprintf("segmentSize: %dKB maxInMemSegments:%d message:%dKB queueCapacity:%d",
+			param.segmentSize/1024, param.maxInMemSegments, param.message, param.queueCapacity)
+		b.Run(name, func(b *testing.B) {
+			q, err := initMmapQueue(plugin.Config{
+				"queue_dir":               "BenchmarkPush",
+				"segment_size":            param.segmentSize,
+				"max_in_mem_segments":     param.maxInMemSegments,
+				"queue_capacity_segments": param.queueCapacity,
+			})
+			if err != nil {
+				b.Fatalf("cannot get a mmap queue: %v", err)
+			}
+			event := getLargeEvent(param.message)
+			b.ReportAllocs()
+			b.ResetTimer()
+			println()
+			for i := 0; i < b.N; i++ {
+				if err := q.Push(event); err != nil {
+					b.Fatalf("error in pushing: %v", err)
+				}
+			}
+			b.StopTimer()
+			_ = q.Close()
+			cleanBenchmarkQueue(b, q)
+		})
+	}
+}
+
+func BenchmarkPushAndPop(b *testing.B) {
+	for _, param := range params {
+		name := fmt.Sprintf("segmentSize: %dKB maxInMemSegments:%d message:%dKB queueCapacity:%d",
+			param.segmentSize/1024, param.maxInMemSegments, param.message, param.queueCapacity)
+		b.Run(name, func(b *testing.B) {
+			q, err := initMmapQueue(plugin.Config{
+				"queue_dir":               "BenchmarkPushAndPop",
+				"segment_size":            param.segmentSize,
+				"max_in_mem_segments":     param.maxInMemSegments,
+				"queue_capacity_segments": param.queueCapacity,
+			})
+			if err != nil {
+				b.Fatalf("cannot get a mmap queue: %v", err)
+			}
+			event := getLargeEvent(param.message)
+			b.ReportAllocs()
+			b.ResetTimer()
+			println()
+			for i := 0; i < b.N; i++ {
+				if err := q.Push(event); err != nil {
+					b.Fatalf("error in pushing: %v", err)
+				}
+				if _, err := q.Pop(); err != nil {
+					b.Fatalf("error in pushing: %v", err)
+				}
+			}
+			b.StopTimer()
+			_ = q.Close()
+			cleanBenchmarkQueue(b, q)
+		})
+	}
+}
diff --git a/plugins/queue/mmap/meta/meta.go b/plugins/queue/mmap/meta/meta.go
new file mode 100644
index 0000000..ea36595
--- /dev/null
+++ b/plugins/queue/mmap/meta/meta.go
@@ -0,0 +1,166 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package meta
+
+import (
+	"fmt"
+	"path/filepath"
+	"syscall"
+
+	"github.com/grandecola/mmap"
+
+	"github.com/apache/skywalking-satellite/plugins/queue/mmap/segment"
+)
+
+const (
+	metaSize    = 80
+	metaName    = "meta.dat"
+	metaVersion = 1
+)
+
+// Offset position
+const (
+	versionPos = iota * 8
+	widPos
+	woffsetPos
+	wmidPos
+	wmoffsetPos
+	cidPos
+	coffsetPos
+	ridPos
+	roffsetPos
+	capacityPos
+)
+
+// Metadata only needs 80B to store the Metadata for the pipe. But for memory alignment,
+// it takes at least one memory page size, which is generally 4K.
+//
+// [    8Bit   ][  8Bit ][  8Bit ][  8Bit ][  8Bit ][  8Bit ][  8Bit ][  8Bit ][  8Bit ][  8Bit  ]
+// [metaVersion][  ID   ][ offset][  ID   ][ offset][  ID   ][ offset][  ID   ][ offset][capacity]
+// [metaVersion][writing   offset][watermark offset][committed offset][reading   offset][capacity]
+type Metadata struct {
+	metaFile *mmap.File
+	name     string
+	size     int
+	capacity int
+}
+
+// NewMetaData read or create a Metadata with supported metaVersion
+func NewMetaData(metaDir string, capacity int) (*Metadata, error) {
+	path := filepath.Join(metaDir, metaName)
+	metaFile, err := segment.NewSegment(path, metaSize)
+	if err != nil {
+		return nil, fmt.Errorf("error in crating the Metadata memory mapped file: %v", err)
+	}
+
+	m := &Metadata{
+		metaFile: metaFile,
+		name:     metaName,
+		size:     metaSize,
+		capacity: capacity,
+	}
+
+	v := m.GetVersion()
+	if v != 0 && v != metaVersion {
+		return nil, fmt.Errorf("metadata metaVersion is not matching, the Metadata metaVersion is %d", v)
+	}
+	c := m.GetCapacity()
+	if c != 0 && c != capacity {
+		return nil, fmt.Errorf("metadata catapacity is not equal to the old capacity, the old capacity is %d", c)
+	}
+	m.PutVersion(metaVersion)
+	m.PutCapacity(int64(capacity))
+	return m, nil
+}
+
+// GetVersion returns the meta version.
+func (m *Metadata) GetVersion() int {
+	return int(m.metaFile.ReadUint64At(versionPos))
+}
+
+// PutVersion put the version into the memory mapped file.
+func (m *Metadata) PutVersion(version int64) {
+	m.metaFile.WriteUint64At(uint64(version), versionPos)
+}
+
+// GetWritingOffset returns the writing offset, which contains the segment ID and the offset of the segment.
+func (m *Metadata) GetWritingOffset() (segmentID, offset int64) {
+	return int64(m.metaFile.ReadUint64At(widPos)), int64(m.metaFile.ReadUint64At(woffsetPos))
+}
+
+// PutWritingOffset put the segment ID and the offset of the segment into the writing offset.
+func (m *Metadata) PutWritingOffset(segmentID, offset int64) {
+	m.metaFile.WriteUint64At(uint64(segmentID), widPos)
+	m.metaFile.WriteUint64At(uint64(offset), woffsetPos)
+}
+
+// GetWatermarkOffset returns the watermark offset, which contains the segment ID and the offset of the segment.
+func (m *Metadata) GetWatermarkOffset() (segmentID, offset int64) {
+	return int64(m.metaFile.ReadUint64At(wmidPos)), int64(m.metaFile.ReadUint64At(wmoffsetPos))
+}
+
+// PutWatermarkOffset put the segment ID and the offset of the segment into the watermark offset.
+func (m *Metadata) PutWatermarkOffset(segmentID, offset int64) {
+	m.metaFile.WriteUint64At(uint64(segmentID), wmidPos)
+	m.metaFile.WriteUint64At(uint64(offset), wmoffsetPos)
+}
+
+// GetCommittedOffset returns the committed offset, which contains the segment ID and the offset of the segment.
+func (m *Metadata) GetCommittedOffset() (segmentID, offset int64) {
+	return int64(m.metaFile.ReadUint64At(cidPos)), int64(m.metaFile.ReadUint64At(coffsetPos))
+}
+
+// PutCommittedOffset put the segment ID and the offset of the segment into the committed offset.
+func (m *Metadata) PutCommittedOffset(segmentID, offset int64) {
+	m.metaFile.WriteUint64At(uint64(segmentID), cidPos)
+	m.metaFile.WriteUint64At(uint64(offset), coffsetPos)
+}
+
+// GetReadingOffset returns the reading offset, which contains the segment ID and the offset of the segment.
+func (m *Metadata) GetReadingOffset() (segmentID, offset int64) {
+	return int64(m.metaFile.ReadUint64At(ridPos)), int64(m.metaFile.ReadUint64At(roffsetPos))
+}
+
+// PutReadingOffset put the segment ID and the offset of the segment into the reading offset.
+func (m *Metadata) PutReadingOffset(segmentID, offset int64) {
+	m.metaFile.WriteUint64At(uint64(segmentID), ridPos)
+	m.metaFile.WriteUint64At(uint64(offset), roffsetPos)
+}
+
+// GetCapacity returns the capacity of the queue.
+func (m *Metadata) GetCapacity() int {
+	return int(m.metaFile.ReadUint64At(capacityPos))
+}
+
+// PutCapacity put the capacity into the memory mapped file.
+func (m *Metadata) PutCapacity(version int64) {
+	m.metaFile.WriteUint64At(uint64(version), capacityPos)
+}
+
+// Flush the memory mapped file to the disk.
+func (m *Metadata) Flush() error {
+	return m.metaFile.Flush(syscall.MS_SYNC)
+}
+
+// Close do Flush operation and unmap the memory mapped file.
+func (m *Metadata) Close() error {
+	if err := m.Flush(); err != nil {
+		return err
+	}
+	return m.metaFile.Unmap()
+}
diff --git a/plugins/queue/mmap/meta/meta_test.go b/plugins/queue/mmap/meta/meta_test.go
new file mode 100644
index 0000000..fcc6b57
--- /dev/null
+++ b/plugins/queue/mmap/meta/meta_test.go
@@ -0,0 +1,208 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package meta
+
+import (
+	"os"
+	"reflect"
+	"testing"
+)
+
+type args struct {
+	metaVersion int
+	capacity    int
+	// ID
+	writingSegID   int64
+	readingSegID   int64
+	committedSegID int64
+	watermarkSegID int64
+	// offset
+	writingSegOffset   int64
+	readingSegOffset   int64
+	committedSegOffset int64
+	watermarkSegOffset int64
+}
+
+type tests struct {
+	name    string
+	args    args
+	want    args
+	wantErr bool
+}
+
+func Test_newMetaData(t *testing.T) {
+	const testDir = "testMeta"
+	const preCapacity = 500
+	params := []tests{
+		buildMetaverionErrorTest(),
+		buildNormalTest(),
+		buildCapacitynErrorTest(),
+	}
+
+	for _, tt := range params {
+		t.Run(tt.name, func(t *testing.T) {
+			// clean
+			defer func() {
+				if err := os.RemoveAll(testDir); err != nil {
+					t.Errorf("remove Metadata dir error: %v", err)
+				}
+			}()
+
+			got, err := NewMetaData(testDir, preCapacity)
+			if err != nil {
+				t.Errorf("cannot create Metadata file: %v", err)
+				return
+			}
+
+			// write args
+			got.PutVersion(int64(tt.args.metaVersion))
+			got.PutWritingOffset(tt.args.writingSegID, tt.args.writingSegOffset)
+			got.PutReadingOffset(tt.args.readingSegID, tt.args.readingSegOffset)
+			got.PutCommittedOffset(tt.args.committedSegID, tt.args.committedSegOffset)
+			got.PutWatermarkOffset(tt.args.watermarkSegID, tt.args.watermarkSegOffset)
+			if got.Close() != nil {
+				t.Errorf("cannot Close the Metadata file: %v", err)
+				return
+			}
+
+			oldMeta, err := NewMetaData(testDir, tt.args.capacity)
+			if err != nil {
+				if tt.wantErr {
+					return
+				}
+				t.Errorf("cannot read old Metadata file: %v", err)
+				return
+			}
+
+			// read args
+			wmID, wmOffset := oldMeta.GetWatermarkOffset()
+			cID, cOffset := oldMeta.GetCommittedOffset()
+			rID, rOffset := oldMeta.GetReadingOffset()
+			wID, wOffset := oldMeta.GetWritingOffset()
+
+			readArgs := args{
+				metaVersion:        oldMeta.GetVersion(),
+				capacity:           oldMeta.GetCapacity(),
+				watermarkSegID:     wmID,
+				writingSegID:       wID,
+				readingSegID:       rID,
+				committedSegID:     cID,
+				watermarkSegOffset: wmOffset,
+				readingSegOffset:   rOffset,
+				committedSegOffset: cOffset,
+				writingSegOffset:   wOffset,
+			}
+			if !reflect.DeepEqual(readArgs, tt.want) {
+				t.Errorf("want meta info is [%+v]\n ,but got [%+v]", tt.want, readArgs)
+			}
+		})
+	}
+}
+
+func buildMetaverionErrorTest() tests {
+	return tests{
+		name: "wrong version",
+		args: args{
+			metaVersion:        2,
+			capacity:           500,
+			watermarkSegID:     1,
+			writingSegID:       2,
+			readingSegID:       3,
+			committedSegID:     4,
+			watermarkSegOffset: 10,
+			readingSegOffset:   20,
+			committedSegOffset: 30,
+			writingSegOffset:   40,
+		},
+		want: args{
+			metaVersion:        2,
+			capacity:           500,
+			watermarkSegID:     1,
+			writingSegID:       2,
+			readingSegID:       3,
+			committedSegID:     4,
+			watermarkSegOffset: 10,
+			readingSegOffset:   20,
+			committedSegOffset: 30,
+			writingSegOffset:   40,
+		},
+		wantErr: true,
+	}
+}
+
+func buildCapacitynErrorTest() tests {
+	return tests{
+		name: "wrong version",
+		args: args{
+			metaVersion:        1,
+			capacity:           600,
+			watermarkSegID:     1,
+			writingSegID:       2,
+			readingSegID:       3,
+			committedSegID:     4,
+			watermarkSegOffset: 10,
+			readingSegOffset:   20,
+			committedSegOffset: 30,
+			writingSegOffset:   40,
+		},
+		want: args{
+			metaVersion:        1,
+			capacity:           600,
+			watermarkSegID:     1,
+			writingSegID:       2,
+			readingSegID:       3,
+			committedSegID:     4,
+			watermarkSegOffset: 10,
+			readingSegOffset:   20,
+			committedSegOffset: 30,
+			writingSegOffset:   40,
+		},
+		wantErr: true,
+	}
+}
+
+func buildNormalTest() tests {
+	return tests{
+		name: "correct version",
+		args: args{
+			metaVersion:        1,
+			capacity:           500,
+			watermarkSegID:     2,
+			writingSegID:       3,
+			readingSegID:       4,
+			committedSegID:     5,
+			watermarkSegOffset: 6,
+			readingSegOffset:   7,
+			committedSegOffset: 8,
+			writingSegOffset:   9,
+		},
+		want: args{
+			metaVersion:        1,
+			capacity:           500,
+			watermarkSegID:     2,
+			writingSegID:       3,
+			readingSegID:       4,
+			committedSegID:     5,
+			watermarkSegOffset: 6,
+			readingSegOffset:   7,
+			committedSegOffset: 8,
+			writingSegOffset:   9,
+		},
+		wantErr: true,
+	}
+}
diff --git a/plugins/queue/mmap/queue.go b/plugins/queue/mmap/queue.go
new file mode 100644
index 0000000..68712c9
--- /dev/null
+++ b/plugins/queue/mmap/queue.go
@@ -0,0 +1,273 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package mmap
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"strconv"
+	"strings"
+	"sync"
+	"syscall"
+	"time"
+
+	"github.com/grandecola/mmap"
+
+	"google.golang.org/protobuf/proto"
+
+	"github.com/apache/skywalking-satellite/internal/pkg/event"
+	"github.com/apache/skywalking-satellite/internal/pkg/log"
+	"github.com/apache/skywalking-satellite/plugins/queue/api"
+	"github.com/apache/skywalking-satellite/plugins/queue/mmap/meta"
+	"github.com/apache/skywalking-satellite/protocol/gen-codes/satellite/protocol"
+)
+
+const (
+	data4KB         = 131072
+	minimumSegments = 4
+)
+
+// Queue is a memory mapped queue to store the input data.
+type Queue struct {
+	sync.Mutex
+	// config
+	SegmentSize           int    `mapstructure:"segment_size"`            // The size of each segment. The unit is byte.
+	MaxInMemSegments      int32  `mapstructure:"max_in_mem_segments"`     // The max num of segments in memory.
+	QueueCapacitySegments int    `mapstructure:"queue_capacity_segments"` // The capacity of Queue = segment_size * queue_capacity_segments.
+	FlushPeriod           int    `mapstructure:"flush_period"`            // The period flush time. The unit is ms.
+	FlushCeilingNum       int    `mapstructure:"flush_ceiling_num"`       // The max number in one flush time.
+	MaxEventSize          int    `mapstructure:"max_event_size"`          // The max size of the input event.
+	QueueDir              string `mapstructure:"queue_dir"`               // Contains all files in the queue.
+
+	// running components
+	meta                   *meta.Metadata // The metadata file.
+	segments               []*mmap.File   // The data files.
+	mmapCount              int32          // The number of the memory mapped files.
+	unflushedNum           int            // The unflushed number.
+	flushChannel           chan struct{}  // The flushChannel channel would receive a signal when the unflushedNum reach the flush_ceiling_num.
+	insufficientMemChannel chan struct{}  // Notify when memory is insufficient
+	sufficientMemChannel   chan struct{}  // Notify when memory is sufficient
+	markReadChannel        chan int64
+
+	// control components
+	ctx        context.Context    // Parent ctx
+	cancel     context.CancelFunc // Parent ctx cancel function
+	showDownWg sync.WaitGroup     // The shutdown wait group.
+
+}
+
+func (q *Queue) Name() string {
+	return "mmap-queue"
+}
+
+func (q *Queue) Description() string {
+	return "this is a mmap queue"
+}
+
+func (q *Queue) DefaultConfig() string {
+	return `
+# The size of each segment. Default value is 128K. The unit is Byte.
+segment_size: 131072
+# The max num of segments in memory. Default value is 10.
+max_in_mem_segments: 10
+# The capacity of Queue = segment_size * queue_capacity_segments.
+queue_capacity_segments: 4000
+# The period flush time. The unit is ms. Default value is 1 second.
+flush_period: 1000
+# The max number in one flush time.  Default value is 10000.
+flush_ceiling_num: 10000
+# Contains all files in the queue.
+queue_dir: satellite-mmap-queue
+# The max size of the input event. Default value is 20k.
+max_event_size: 20480
+`
+}
+
+func (q *Queue) Initialize() error {
+	// the size of each segment file should be a multiple of the page size.
+	pageSize := os.Getpagesize()
+	if q.SegmentSize%pageSize != 0 {
+		q.SegmentSize -= q.SegmentSize % pageSize
+	}
+	if q.SegmentSize/pageSize == 0 {
+		q.SegmentSize = data4KB
+	}
+	// the minimum MaxInMemSegments value should be 4.
+	if q.MaxInMemSegments < minimumSegments {
+		q.MaxInMemSegments = minimumSegments
+	}
+	// load metadata and override the reading or writing offset by the committed or watermark offset.
+	md, err := meta.NewMetaData(q.QueueDir, q.QueueCapacitySegments)
+	if err != nil {
+		return fmt.Errorf("error in creating the metadata: %v", err)
+	}
+	q.meta = md
+	cmID, cmOffset := md.GetCommittedOffset()
+	wmID, wmOffset := md.GetWatermarkOffset()
+	md.PutWritingOffset(wmID, wmOffset)
+	md.PutReadingOffset(cmID, cmOffset)
+	// keep the reading or writing segments in the memory.
+	q.segments = make([]*mmap.File, q.QueueCapacitySegments)
+	if _, err := q.GetSegment(cmID); err != nil {
+		return err
+	}
+	if _, err := q.GetSegment(wmID); err != nil {
+		return err
+	}
+	// init components
+	q.insufficientMemChannel = make(chan struct{})
+	q.sufficientMemChannel = make(chan struct{})
+	q.markReadChannel = make(chan int64, 1)
+	q.flushChannel = make(chan struct{})
+	q.ctx, q.cancel = context.WithCancel(context.Background())
+	// async supported processes.
+	q.showDownWg.Add(2)
+	go q.segmentSwapper()
+	go q.flush()
+	return nil
+}
+
+func (q *Queue) Push(e *protocol.Event) error {
+	data, err := proto.Marshal(e)
+	if err != nil {
+		return err
+	}
+	if len(data) > q.MaxEventSize {
+		return fmt.Errorf("cannot push the event to the queue because the size %dB is over ceiling", len(data))
+	}
+	return q.push(data)
+}
+
+func (q *Queue) Pop() (*api.SequenceEvent, error) {
+	data, id, offset, err := q.pop()
+	if err != nil {
+		return nil, err
+	}
+	e := &protocol.Event{}
+	err = proto.Unmarshal(data, e)
+	if err != nil {
+		return nil, err
+	}
+	return &api.SequenceEvent{
+		Event:  e,
+		Offset: q.encodeOffset(id, offset),
+	}, nil
+}
+
+func (q *Queue) Close() error {
+	q.cancel()
+	q.showDownWg.Wait()
+	for i, segment := range q.segments {
+		if segment != nil {
+			err := segment.Unmap()
+			if err != nil {
+				log.Logger.Errorf("cannot unmap the segments: %d, %v", i, err)
+			}
+		}
+	}
+	if err := q.meta.Close(); err != nil {
+		log.Logger.Errorf("cannot unmap the metadata: %v", err)
+	}
+	return nil
+}
+
+func (q *Queue) Ack(lastOffset event.Offset) {
+	id, offset, err := q.decodeOffset(lastOffset)
+	if err != nil {
+		log.Logger.Errorf("cannot ack queue with the offset:%s", lastOffset)
+	}
+	q.meta.PutCommittedOffset(id, offset)
+}
+
+// flush control the flush operation by timer or counter.
+func (q *Queue) flush() {
+	defer q.showDownWg.Done()
+	ctx, cancel := context.WithCancel(q.ctx)
+	defer cancel()
+	for {
+		timer := time.NewTimer(time.Duration(q.FlushPeriod) * time.Millisecond)
+		select {
+		case <-q.flushChannel:
+			q.doFlush()
+			timer.Reset(time.Duration(q.FlushPeriod) * time.Millisecond)
+		case <-timer.C:
+			q.doFlush()
+		case <-ctx.Done():
+			q.doFlush()
+			return
+		}
+	}
+}
+
+// doFlush flush the segment and meta files to the disk.
+func (q *Queue) doFlush() {
+	q.Lock()
+	defer q.Unlock()
+	for _, segment := range q.segments {
+		if segment == nil {
+			continue
+		}
+		if err := segment.Flush(syscall.MS_SYNC); err != nil {
+			log.Logger.Errorf("cannot flush segment file: %v", err)
+		}
+	}
+	wid, woffset := q.meta.GetWritingOffset()
+	q.meta.PutWatermarkOffset(wid, woffset)
+	if err := q.meta.Flush(); err != nil {
+		log.Logger.Errorf("cannot flush meta file: %v", err)
+	}
+}
+
+// isEmpty returns the capacity status
+func (q *Queue) isEmpty() bool {
+	rid, roffset := q.meta.GetReadingOffset()
+	wid, woffset := q.meta.GetWritingOffset()
+	return rid == wid && roffset == woffset
+}
+
+// isEmpty returns the capacity status
+func (q *Queue) isFull() bool {
+	rid, _ := q.meta.GetReadingOffset()
+	wid, _ := q.meta.GetWritingOffset()
+	// ensure enough spaces to promise data stability.
+	maxWid := rid + int64(q.QueueCapacitySegments) - 1 - int64(q.MaxEventSize/q.SegmentSize)
+	return wid >= maxWid
+}
+
+// encode the meta to the offset
+func (q *Queue) encodeOffset(id, offset int64) event.Offset {
+	return event.Offset(strconv.FormatInt(id, 10) + "-" + strconv.FormatInt(offset, 10))
+}
+
+// decode the offset to the meta of the mmap queue.
+func (q *Queue) decodeOffset(val event.Offset) (id, offset int64, err error) {
+	arr := strings.Split(string(val), "-")
+	if len(arr) == 2 {
+		id, err := strconv.ParseInt(arr[0], 10, 64)
+		if err != nil {
+			return 0, 0, err
+		}
+		offset, err := strconv.ParseInt(arr[1], 10, 64)
+		if err != nil {
+			return 0, 0, err
+		}
+		return id, offset, nil
+	}
+	return 0, 0, fmt.Errorf("the input offset string is illegal: %s", val)
+}
diff --git a/plugins/queue/mmap/queue_opreation.go b/plugins/queue/mmap/queue_opreation.go
new file mode 100644
index 0000000..3559ef1
--- /dev/null
+++ b/plugins/queue/mmap/queue_opreation.go
@@ -0,0 +1,170 @@
+// MIT License
+//
+// Copyright (c) 2018 Aman Mangal
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+package mmap
+
+import (
+	"fmt"
+)
+
+// Because the design of the mmap-queue in Satellite references the design of the
+// bigqueue(https://github.com/grandecola/bigqueue), the queue operation file retains
+// the original author license.
+//
+// The reason why we references the source codes of bigqueue rather than using the lib
+// is the file queue in Satellite is like following.
+// 1. Only one consumer and publisher in the Satellite queue.
+// 2. Reusing files strategy is required to reduce the creation times in the Satellite queue.
+// 3. More complex OFFSET design is needed to ensure the final stability of data.
+
+const uInt64Size = 8
+
+// push writes the data into the file system. It first writes the length of the data,
+// then the data itself. It means the whole data may not exist in the one segments.
+func (q *Queue) push(bytes []byte) error {
+	if q.isFull() {
+		return fmt.Errorf("cannot push data when the queue is full")
+	}
+	id, offset := q.meta.GetWritingOffset()
+	id, offset, err := q.writeLength(len(bytes), id, offset)
+	if err != nil {
+		return err
+	}
+	id, offset, err = q.writeBytes(bytes, id, offset)
+	if err != nil {
+		return err
+	}
+	q.meta.PutWritingOffset(id, offset)
+	q.unflushedNum++
+	if q.unflushedNum == q.FlushCeilingNum {
+		q.flushChannel <- struct{}{}
+		q.unflushedNum = 0
+	}
+	return nil
+}
+
+// pop reads the data from the file system. It first reads the length of the data,
+// then the data itself. It means the whole data may not exist in the one segments.
+func (q *Queue) pop() (data []byte, rid, roffset int64, err error) {
+	if q.isEmpty() {
+		return nil, 0, 0, fmt.Errorf("cannot read data when the queue is empty")
+	}
+	preID, preOffset := q.meta.GetReadingOffset()
+	id, offset, length, err := q.readLength(preID, preOffset)
+	if err != nil {
+		return nil, 0, 0, err
+	}
+	bytes, id, offset, err := q.readBytes(id, offset, length)
+	if err != nil {
+		return nil, 0, 0, err
+	}
+	q.meta.PutReadingOffset(id, offset)
+	if id != preID {
+		q.markReadChannel <- preID
+	}
+	return bytes, id, offset, nil
+}
+
+// readBytes reads bytes into the memory mapped file.
+func (q *Queue) readBytes(id, offset int64, length int) (data []byte, newID, newOffset int64, err error) {
+	counter := 0
+	res := make([]byte, length)
+	for {
+		segment, err := q.GetSegment(id)
+		if err != nil {
+			return nil, 0, 0, err
+		}
+		readBytes, err := segment.ReadAt(res[counter:], offset)
+		if err != nil {
+			return nil, 0, 0, err
+		}
+		counter += readBytes
+		offset += int64(readBytes)
+		if offset == int64(q.SegmentSize) {
+			id, offset = id+1, 0
+		}
+		if counter == length {
+			break
+		}
+	}
+	return res, id, offset, nil
+}
+
+// readLength reads the data length with 8 Bits spaces.
+func (q *Queue) readLength(id, offset int64) (newID, newOffset int64, length int, err error) {
+	if offset+uInt64Size > int64(q.SegmentSize) {
+		id, offset = id+1, 0
+	}
+	segment, err := q.GetSegment(id)
+	if err != nil {
+		return 0, 0, 0, err
+	}
+	num := segment.ReadUint64At(offset)
+	offset += uInt64Size
+	if offset == int64(q.SegmentSize) {
+		id, offset = id+1, 0
+	}
+	return id, offset, int(num), nil
+}
+
+// writeLength write the data length with 8 Bits spaces.
+func (q *Queue) writeLength(length int, id, offset int64) (newID, newOffset int64, err error) {
+	if offset+uInt64Size > int64(q.SegmentSize) {
+		id, offset = id+1, 0
+	}
+	segment, err := q.GetSegment(id)
+	if err != nil {
+		return 0, 0, err
+	}
+	segment.WriteUint64At(uint64(length), offset)
+	offset += uInt64Size
+	if offset == int64(q.SegmentSize) {
+		id, offset = id+1, 0
+	}
+	return id, offset, nil
+}
+
+// writeBytes writes bytes into the memory mapped file.
+func (q *Queue) writeBytes(bytes []byte, id, offset int64) (newID, newOffset int64, err error) {
+	counter := 0
+	length := len(bytes)
+
+	for {
+		segment, err := q.GetSegment(id)
+		if err != nil {
+			return 0, 0, err
+		}
+		writtenBytes, err := segment.WriteAt(bytes[counter:], offset)
+		if err != nil {
+			return 0, 0, err
+		}
+		counter += writtenBytes
+		offset += int64(writtenBytes)
+		if offset == int64(q.SegmentSize) {
+			id, offset = id+1, 0
+		}
+		if counter == length {
+			break
+		}
+	}
+	return id, offset, nil
+}
diff --git a/plugins/queue/mmap/queue_test.go b/plugins/queue/mmap/queue_test.go
new file mode 100644
index 0000000..910368d
--- /dev/null
+++ b/plugins/queue/mmap/queue_test.go
@@ -0,0 +1,441 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package mmap
+
+import (
+	"fmt"
+	"os"
+	"reflect"
+	v3 "skywalking/network/common/v3"
+	logging "skywalking/network/logging/v3"
+	"strconv"
+	"strings"
+	"testing"
+	"time"
+
+	"github.com/google/go-cmp/cmp"
+
+	"github.com/apache/skywalking-satellite/internal/pkg/log"
+	"github.com/apache/skywalking-satellite/internal/pkg/plugin"
+	"github.com/apache/skywalking-satellite/plugins/queue/api"
+	"github.com/apache/skywalking-satellite/protocol/gen-codes/satellite/protocol"
+)
+
+func initMmapQueue(cfg plugin.Config) (*Queue, error) {
+	log.Init(&log.LoggerConfig{})
+	plugin.RegisterPluginCategory(reflect.TypeOf((*api.Queue)(nil)).Elem())
+	plugin.RegisterPlugin(&Queue{})
+	var config plugin.Config = map[string]interface{}{
+		plugin.NameField: "mmap-queue",
+	}
+	for k, v := range cfg {
+		config[k] = v
+	}
+	q := api.GetQueue(config)
+	if q == nil {
+		return nil, fmt.Errorf("cannot get a default config mmap queue from the registry")
+	}
+	if err := q.Initialize(); err != nil {
+		return nil, fmt.Errorf("queue cannot initialize: %v", err)
+	}
+	return q.(*Queue), nil
+}
+
+func cleanTestQueue(t *testing.T, q api.Queue) {
+	if err := os.RemoveAll(q.(*Queue).QueueDir); err != nil {
+		t.Errorf("cannot remove test queue dir, %v", err)
+	}
+}
+
+func getBatchEvents(count int) []*protocol.Event {
+	var slice []*protocol.Event
+	for i := 0; i < count; i++ {
+		slice = append(slice, &protocol.Event{
+			Name:      "event" + strconv.Itoa(i),
+			Timestamp: time.Now().Unix(),
+			Meta: map[string]string{
+				"meta": "mval" + strconv.Itoa(i),
+			},
+			Type:   protocol.EventType_Logging,
+			Remote: true,
+			Data: &protocol.Event_Log{
+				Log: &logging.LogData{
+					Service:         "mock-service",
+					ServiceInstance: "mock-serviceInstance",
+					Timestamp:       time.Date(2020, 12, 20, 12, 12, 12, 0, time.UTC).Unix(),
+					Endpoint:        "mock-endpoint",
+					Tags:            make([]*v3.KeyStringValuePair, 0),
+					TraceContext: &logging.TraceContext{
+						TraceId:        "traceId",
+						TraceSegmentId: "trace-segmentId",
+						SpanId:         12,
+					},
+					Body: &logging.LogDataBody{
+						Type: "body-type",
+						Content: &logging.LogDataBody_Text{
+							Text: &logging.TextLog{
+								Text: getNKData(2) + strconv.Itoa(i),
+							},
+						},
+					},
+				},
+			},
+		},
+		)
+	}
+	return slice
+}
+
+func getNKData(n int) string {
+	return strings.Repeat("a", n*1024)
+}
+
+func getLargeEvent(n int) *protocol.Event {
+	return &protocol.Event{
+		Name:      "largeEvent",
+		Timestamp: time.Now().Unix(),
+		Meta: map[string]string{
+			"meta": "largeEvent",
+		},
+		Type:   protocol.EventType_Logging,
+		Remote: true,
+		Data: &protocol.Event_Log{
+			Log: &logging.LogData{
+				Service:         "mock-service",
+				ServiceInstance: "mock-serviceInstance",
+				Timestamp:       time.Date(2020, 12, 20, 12, 12, 12, 0, time.UTC).Unix(),
+				Endpoint:        "mock-endpoint",
+				Tags: []*v3.KeyStringValuePair{
+					{
+						Key:   "tags-key",
+						Value: "tags-val",
+					},
+				},
+				TraceContext: &logging.TraceContext{
+					TraceId:        "traceId",
+					TraceSegmentId: "trace-segmentId",
+					SpanId:         12,
+				},
+				Body: &logging.LogDataBody{
+					Type: "body-type",
+					Content: &logging.LogDataBody_Text{
+						Text: &logging.TextLog{
+							Text: getNKData(n),
+						},
+					},
+				},
+			},
+		},
+	}
+}
+
+func TestQueue_Normal(t *testing.T) {
+	q, err := initMmapQueue(plugin.Config{
+		"queue_dir": "TestQueue_Normal",
+	})
+	defer cleanTestQueue(t, q)
+	if err != nil {
+		t.Fatalf("error in initializing the mmap queue: %v", err)
+	}
+	events := getBatchEvents(10)
+	for _, e := range events {
+		if err = q.Push(e); err != nil {
+			t.Errorf("queue cannot push one event: %+v", err)
+		}
+	}
+	for i := 0; i < 10; i++ {
+		sequenceEvent, err := q.Pop()
+		if err != nil {
+			t.Errorf("error in fetching data from queue: %v", err)
+		} else if !cmp.Equal(events[i].String(), sequenceEvent.Event.String()) {
+			t.Errorf("history data and fetching data is not equal\n,history:%+v\n. pop data:%+v\n", events[i], sequenceEvent.Event)
+		}
+	}
+}
+
+func TestQueue_ReadHistory(t *testing.T) {
+	cfg := plugin.Config{
+		"queue_dir":    "TestQueue_ReadHistory",
+		"segment_size": 10240,
+	}
+
+	q, err := initMmapQueue(cfg)
+	defer cleanTestQueue(t, q)
+	if err != nil {
+		t.Fatalf("error in initializing the mmap queue: %v", err)
+	}
+	// close the queue to create a history empty queue.
+	if err := q.Close(); err != nil {
+		t.Fatalf("error in closing queue, %v", err)
+	}
+
+	// test cases.
+	batchSize := 10
+	batchNum := 100
+	events := getBatchEvents(batchSize * batchNum)
+
+	// Insert batchNum pieces of data in batchNum times
+	for i := 0; i < batchSize; i++ {
+		// recreate the queue
+		q, err := initMmapQueue(cfg)
+		if err != nil {
+			t.Fatalf("error in initializing the mmap queue: %v", err)
+		}
+		for j := 0; j < batchNum; j++ {
+			index := i*batchSize + j
+			if err = q.Push(events[index]); err != nil {
+				t.Errorf("queue cannot push one event: %+v", err)
+			}
+		}
+		if err := q.Close(); err != nil {
+			t.Fatalf("error in closing queue, %v", err)
+		}
+	}
+
+	// Read batchNum pieces of data in batchNum times
+	for i := 0; i < batchSize; i++ {
+		// recreate the queue
+		q, err := initMmapQueue(cfg)
+		if err != nil {
+			t.Fatalf("error in initializing the mmap queue: %v", err)
+		}
+		for j := 0; j < batchNum; j++ {
+			index := i*batchSize + j
+			sequenceEvent, err := q.Pop()
+			if err != nil {
+				t.Errorf("error in fetching data from queue: %v", err)
+			} else if cmp.Equal(events[index].String(), sequenceEvent.Event.String()) {
+				q.Ack(sequenceEvent.Offset)
+			} else {
+				t.Errorf("history data and fetching data is not equal\n,history:%+v\n. pop data:%+v\n", events[index], sequenceEvent.Event)
+			}
+		}
+		if err := q.Close(); err != nil {
+			t.Fatalf("error in closing queue, %v", err)
+		}
+	}
+}
+
+func TestQueue_PushOverCeilingMsg(t *testing.T) {
+	cfg := plugin.Config{
+		"queue_dir":      "TestQueue_PushOverCeilingMsg",
+		"segment_size":   10240,
+		"max_event_size": 1024 * 8,
+	}
+	largeEvent := getLargeEvent(20)
+	q, err := initMmapQueue(cfg)
+	if err != nil {
+		t.Fatalf("cannot get a mmap queue: %v", err)
+	}
+	defer cleanTestQueue(t, q)
+	err = q.Push(largeEvent)
+	if err == nil {
+		t.Fatalf("The insertion of the over ceiling event is not as expected")
+	} else {
+		fmt.Printf("want err: %v", err)
+	}
+}
+
+func TestQueue_FlushWhenReachNum(t *testing.T) {
+	cfg := plugin.Config{
+		"queue_dir":         "TestQueue_FlushWhenReachNum",
+		"segment_size":      10240,
+		"flush_ceiling_num": 5,
+		"flush_period":      1000 * 60,
+	}
+	q, err := initMmapQueue(cfg)
+	if err != nil {
+		t.Fatalf("cannot get a mmap queue: %v", err)
+	}
+	defer cleanTestQueue(t, q)
+	events := getBatchEvents(5)
+
+	for _, e := range events {
+		err = q.Push(e)
+		if err != nil {
+			t.Errorf("queue cannot push one event: %+v", err)
+		}
+	}
+	time.Sleep(time.Second)
+	wID, wOffset := q.meta.GetWritingOffset()
+	wmID, wmOffset := q.meta.GetWatermarkOffset()
+	if wID != wmID || wOffset != wmOffset {
+		t.Fatalf("the flush operation was not invoking when reach the flush_ceiling_num.")
+	}
+}
+
+func TestQueue_FlushPeriod(t *testing.T) {
+	cfg := plugin.Config{
+		"queue_dir":         "TestQueue_FlushPeriod",
+		"segment_size":      10240,
+		"flush_ceiling_num": 50,
+		"flush_period":      1000 * 1,
+	}
+	q, err := initMmapQueue(cfg)
+	if err != nil {
+		t.Fatalf("cannot get a mmap queue: %v", err)
+	}
+	defer cleanTestQueue(t, q)
+	events := getBatchEvents(5)
+
+	for _, e := range events {
+		err = q.Push(e)
+		if err != nil {
+			t.Errorf("queue cannot push one event: %+v", err)
+		}
+	}
+	time.Sleep(time.Second * 2)
+	wID, wOffset := q.meta.GetWritingOffset()
+	wmID, wmOffset := q.meta.GetWatermarkOffset()
+	if wID != wmID || wOffset != wmOffset {
+		t.Fatalf("the flush operation was not invoking when reach the flush_ceiling_num.")
+	}
+}
+
+func TestQueue_MemCost(t *testing.T) {
+	cfg := plugin.Config{
+		"queue_dir":           "TestQueue_MemCost",
+		"segment_size":        1024 * 4,
+		"max_in_mem_segments": 8,
+	}
+	q, err := initMmapQueue(cfg)
+	if err != nil {
+		t.Fatalf("cannot get a mmap queue: %v", err)
+	}
+	defer cleanTestQueue(t, q)
+	events := getBatchEvents(20)
+	var memcost []int32
+	for _, e := range events {
+		err = q.Push(e)
+		memcost = append(memcost, q.mmapCount)
+		if err != nil {
+			t.Errorf("queue cannot push one event: %+v", err)
+		}
+	}
+	want := []int32{
+		1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 6, 6, 7, 7, 8, 5,
+	}
+	if !cmp.Equal(want, memcost) {
+		t.Fatalf("the memory cost trends are not in line with expectations,\n want: %v,\n but got: %v", want, memcost)
+	}
+}
+
+func TestQueue_OverSegmentEvent(t *testing.T) {
+	cfg := plugin.Config{
+		"queue_dir":    "TestQueue_OverSegmentEvent",
+		"segment_size": 1024 * 4,
+	}
+	q, err := initMmapQueue(cfg)
+	if err != nil {
+		t.Fatalf("cannot get a mmap queue: %v", err)
+	}
+	defer cleanTestQueue(t, q)
+	size := 10
+	wantPos := size * 1024 / q.SegmentSize
+	largeEvent := getLargeEvent(size)
+	err = q.Push(largeEvent)
+	if err != nil {
+		t.Errorf("queue cannot push one event: %+v", err)
+	}
+	id, _ := q.meta.GetWritingOffset()
+	if int(id) != wantPos {
+		t.Fatalf("the writing offset id should at %d segment, but at %d", id, wantPos)
+	}
+}
+
+func TestQueue_ReusingFiles(t *testing.T) {
+	cfg := plugin.Config{
+		"queue_dir":               "TestQueue_ReusingFiles",
+		"segment_size":            1024 * 4,
+		"queue_capacity_segments": 5,
+		"max_event_size":          1024 * 3,
+	}
+	q, err := initMmapQueue(cfg)
+	if err != nil {
+		t.Fatalf("cannot get a mmap queue: %v", err)
+	}
+	defer cleanTestQueue(t, q)
+
+	for i := 0; i < 100; i++ {
+		err = q.Push(getLargeEvent(2))
+		if err != nil {
+			t.Errorf("queue cannot push one event: %+v", err)
+		}
+		_, err := q.Pop()
+		if err != nil {
+			t.Errorf("error in fetching data from queue: %v", err)
+		}
+	}
+	rid, roffset := q.meta.GetReadingOffset()
+	wid, woffset := q.meta.GetWritingOffset()
+	fmt.Printf("rid:%d, roffset:%d, wid:%d, woffset:%d\n", rid, roffset, wid, woffset)
+	if int(wid) <= q.QueueCapacitySegments || int(rid) <= q.QueueCapacitySegments {
+		t.Errorf("cannot valid reusing files")
+	}
+}
+
+func TestQueue_Empty(t *testing.T) {
+	cfg := plugin.Config{
+		"queue_dir":               "TestQueue_ReusingFiles",
+		"segment_size":            1024 * 4,
+		"queue_capacity_segments": 10,
+	}
+	q, err := initMmapQueue(cfg)
+	if err != nil {
+		t.Fatalf("cannot get a mmap queue: %v", err)
+	}
+	defer cleanTestQueue(t, q)
+	for _, e := range getBatchEvents(3) {
+		err = q.Push(e)
+		if err != nil {
+			t.Errorf("queue cannot push one event: %+v", err)
+		}
+	}
+	for i := 0; i < 3; i++ {
+		if _, err = q.Pop(); err != nil {
+			t.Errorf("error in fetching data from queue: %v", err)
+		}
+	}
+	_, err = q.Pop()
+	if err != nil && err.Error() != "cannot read data when the queue is empty" {
+		t.Fatalf("not except err: %v", err)
+	}
+}
+
+func TestQueue_Full(t *testing.T) {
+	cfg := plugin.Config{
+		"queue_dir":               "TestQueue_ReusingFiles",
+		"segment_size":            1024 * 4,
+		"queue_capacity_segments": 10,
+	}
+	q, err := initMmapQueue(cfg)
+	if err != nil {
+		t.Fatalf("cannot get a mmap queue: %v", err)
+	}
+	defer cleanTestQueue(t, q)
+	for _, e := range getBatchEvents(8) {
+		err = q.Push(e)
+		if err != nil {
+			t.Errorf("queue cannot push one event: %+v", err)
+		}
+	}
+	err = q.Push(getLargeEvent(2))
+	if err != nil && err.Error() != "cannot push data when the queue is full" {
+		t.Fatalf("not except err: %v", err)
+	}
+}
diff --git a/plugins/queue/mmap/segment/segment.go b/plugins/queue/mmap/segment/segment.go
new file mode 100644
index 0000000..cf738d1
--- /dev/null
+++ b/plugins/queue/mmap/segment/segment.go
@@ -0,0 +1,68 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package segment
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+	"syscall"
+
+	"github.com/grandecola/mmap"
+)
+
+const FileSuffix = "_segment.dat"
+
+// NewSegment returns a pointer to a memory mapped file according to the given file name and file size.
+// The size of each segment file should be a multiple of the page size.
+func NewSegment(name string, size int) (*mmap.File, error) {
+	name, err := filepath.Abs(name)
+	if err != nil {
+		return nil, fmt.Errorf("error in getting the absolute path of the segment file : %v", err)
+	}
+	paths, _ := filepath.Split(name)
+	_, err = os.Stat(paths)
+	if err != nil && os.IsNotExist(err) && os.MkdirAll(paths, 0744) != nil {
+		return nil, fmt.Errorf("error in creating the parent dirs of the segment file : %v", err)
+	}
+
+	file, err := os.OpenFile(name, os.O_CREATE|os.O_RDWR, 0744)
+	if err != nil {
+		return nil, fmt.Errorf("error in opening segment file : %v", err)
+	}
+
+	stat, err := file.Stat()
+	if err != nil {
+		return nil, fmt.Errorf("error in reading info of the segment file : %v", err)
+	}
+
+	if stat.Size() != int64(size) {
+		if file.Truncate(int64(size)) != nil {
+			return nil, fmt.Errorf("error in truncating file: %v", err)
+		}
+	}
+
+	segment, err := mmap.NewSharedFileMmap(file, 0, size, syscall.PROT_READ|syscall.PROT_WRITE)
+	if err != nil {
+		return nil, fmt.Errorf("error in creating the mmap segment file : %v", err)
+	}
+	if err := file.Close(); err != nil {
+		return nil, fmt.Errorf("error in closing the segment file : %v", err)
+	}
+	return segment, nil
+}
diff --git a/plugins/queue/mmap/segment/segment_test.go b/plugins/queue/mmap/segment/segment_test.go
new file mode 100644
index 0000000..98c38e6
--- /dev/null
+++ b/plugins/queue/mmap/segment/segment_test.go
@@ -0,0 +1,187 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package segment
+
+import (
+	"os"
+	"testing"
+
+	"github.com/grandecola/mmap"
+)
+
+func Test_newSegmentWithOldFile(t *testing.T) {
+	type args struct {
+		fileName     string
+		originalSize int
+		neededSize   int
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    int64
+		wantErr bool
+	}{
+		{
+			name: "less than the needed size",
+			args: args{
+				fileName:     "temp.segment",
+				originalSize: os.Getpagesize(),
+				neededSize:   os.Getpagesize() * 2,
+			},
+			want:    int64(os.Getpagesize() * 2),
+			wantErr: false,
+		},
+		{
+			name: "equal to the needed size",
+			args: args{
+				fileName:     "temp2.segment",
+				originalSize: os.Getpagesize() * 2,
+				neededSize:   os.Getpagesize() * 2,
+			},
+			want:    int64(os.Getpagesize() * 2),
+			wantErr: false,
+		},
+		{
+			name: "larger than the needed size",
+			args: args{
+				fileName:     "temp3.segment",
+				originalSize: os.Getpagesize() * 3,
+				neededSize:   os.Getpagesize() * 2,
+			},
+			want:    int64(os.Getpagesize() * 2),
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if file, err := os.Create(tt.args.fileName); err != nil {
+				t.Errorf("cannot create the original file: %v", err)
+				return
+			} else if err := file.Truncate(int64(tt.args.originalSize)); err != nil {
+				t.Errorf("cannot set the original file size: %v", err)
+			}
+
+			got, err := NewSegment(tt.args.fileName, tt.args.neededSize)
+			defer clean(got, tt.args.fileName, t)
+
+			if (err != nil) != tt.wantErr {
+				t.Errorf("NewSegment() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if file, err := os.Open(tt.args.fileName); err != nil {
+				t.Errorf("cannot open the mmap file: %v", err)
+			} else if stat, err := file.Stat(); err != nil {
+				t.Errorf("cannot read mmap file info: %v", err)
+			} else if stat.Size() != tt.want {
+				t.Errorf("want file size is %d ,but got %d", tt.want, stat.Size())
+			}
+		})
+	}
+}
+
+func Test_newSegmentSize(t *testing.T) {
+	type args struct {
+		fileName string
+		size     int
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    int64
+		wantErr bool
+	}{
+		{
+			name: "equal to page size",
+			args: args{
+				fileName: "temp2.segment",
+				size:     os.Getpagesize() * 2,
+			},
+			want:    int64(os.Getpagesize() * 2),
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := NewSegment(tt.args.fileName, tt.args.size)
+			defer clean(got, tt.args.fileName, t)
+
+			if (err != nil) != tt.wantErr {
+				t.Errorf("NewSegment() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if file, err := os.Open(tt.args.fileName); err != nil {
+				t.Errorf("cannot open the mmap file: %v", err)
+			} else if stat, err := file.Stat(); err != nil {
+				t.Errorf("cannot read mmap file info: %v", err)
+			} else if stat.Size() != tt.want {
+				t.Errorf("want file size is %d ,but got %d", tt.want, stat.Size())
+			}
+		})
+	}
+}
+
+func Test_newSegmentMultiDir(t *testing.T) {
+	const testDir = "testQueue"
+	defer func() {
+		if err := os.RemoveAll(testDir); err != nil {
+			t.Errorf("cannot clean the testqueue dir: %v", err)
+			return
+		}
+	}()
+
+	type args struct {
+		fileName string
+		size     int
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{
+			name: "test multi dir",
+			args: args{
+				fileName: testDir + "/temp.segment",
+				size:     10,
+			},
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := NewSegment(tt.args.fileName, tt.args.size)
+			defer clean(got, tt.args.fileName, t)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("NewSegment() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+		})
+	}
+}
+
+func clean(file *mmap.File, fileName string, t *testing.T) {
+	if file == nil {
+		return
+	}
+	if err := file.Unmap(); err != nil {
+		t.Errorf("unmap segment file error: %v", err)
+	}
+	if err := os.Remove(fileName); err != nil {
+		t.Errorf("delete segment file error: %v", err)
+	}
+}
diff --git a/plugins/queue/mmap/segment_operation.go b/plugins/queue/mmap/segment_operation.go
new file mode 100644
index 0000000..7d34bb2
--- /dev/null
+++ b/plugins/queue/mmap/segment_operation.go
@@ -0,0 +1,131 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package mmap
+
+import (
+	"context"
+	"fmt"
+	"path"
+	"strconv"
+	"sync/atomic"
+
+	"github.com/grandecola/mmap"
+
+	"github.com/apache/skywalking-satellite/internal/pkg/log"
+	"github.com/apache/skywalking-satellite/plugins/queue/mmap/segment"
+)
+
+// GetSegment returns a memory mapped file at the segmentID position.
+func (q *Queue) GetSegment(segmentID int64) (*mmap.File, error) {
+	index := q.GetIndex(segmentID)
+	if q.mmapCount >= q.MaxInMemSegments {
+		q.insufficientMemChannel <- struct{}{}
+		<-q.sufficientMemChannel
+	}
+	if err := q.mapSegment(segmentID); err != nil {
+		return nil, err
+	}
+	if q.segments[index] != nil {
+		return q.segments[index], nil
+	}
+	return nil, fmt.Errorf("cannot get a memory mapped file at %d segment", segmentID)
+}
+
+// mapSegment load the segment file reference to the segments.
+func (q *Queue) mapSegment(segmentID int64) error {
+	index := q.GetIndex(segmentID)
+	if q.segments[index] != nil {
+		return nil
+	}
+	filePath := path.Join(q.QueueDir, strconv.Itoa(index)+segment.FileSuffix)
+	file, err := segment.NewSegment(filePath, q.SegmentSize)
+	if err != nil {
+		return err
+	}
+	atomic.AddInt32(&q.mmapCount, 1)
+	q.segments[index] = file
+	return nil
+}
+
+// unmapSegment cancel the memory mapped status.
+func (q *Queue) unmapSegment(segmentID int64) error {
+	index := q.GetIndex(segmentID)
+	if q.segments[index] == nil {
+		return nil
+	}
+	if err := q.segments[index].Unmap(); err != nil {
+		return fmt.Errorf("error in unmap segemnt: %v", err)
+	}
+	atomic.AddInt32(&q.mmapCount, -1)
+	q.segments[index] = nil
+	return nil
+}
+
+// segmentSwapper run with a go routine to ensure the memory cost.
+func (q *Queue) segmentSwapper() {
+	defer q.showDownWg.Done()
+	ctx, cancel := context.WithCancel(q.ctx)
+	defer cancel()
+	for {
+		select {
+		case id := <-q.markReadChannel:
+			if q.unmapSegment(id) != nil {
+				log.Logger.Errorf("cannot unmap the markread segment: %d", id)
+			}
+		case <-q.insufficientMemChannel:
+			if q.mmapCount >= q.MaxInMemSegments {
+				if q.doSwap() != nil {
+					log.Logger.Errorf("cannot get enough memory to receive new data")
+				}
+			}
+			q.sufficientMemChannel <- struct{}{}
+		case <-ctx.Done():
+			return
+		}
+	}
+}
+
+// doSwap swap the memory mapped files to normal files to promise the memory resources cost.
+func (q *Queue) doSwap() error {
+	rID, _ := q.meta.GetReadingOffset()
+	wID, _ := q.meta.GetWritingOffset()
+	logicWID := wID + int64(q.QueueCapacitySegments)
+	wIndex := q.GetIndex(wID)
+	rIndex := q.GetIndex(rID)
+	for q.mmapCount >= q.MaxInMemSegments {
+		for i := logicWID - 1; i >= 0 && i >= logicWID-int64(q.MaxInMemSegments); i-- {
+			if q.GetIndex(i) == wIndex || q.GetIndex(i) == rIndex {
+				continue
+			}
+			if err := q.unmapSegment(i); err != nil {
+				return err
+			}
+			// the writing segment and the reading segment should still in memory.
+			// q.MaxInMemSegments/2-1 means keeping half available spaces to receive new data.
+			if q.MaxInMemSegments-q.mmapCount >= q.MaxInMemSegments/2-1 {
+				return nil
+			}
+		}
+	}
+	return nil
+}
+
+// GetIndex returns the index of the segments.
+func (q *Queue) GetIndex(segmentID int64) int {
+	return int(segmentID) % q.QueueCapacitySegments
+}
diff --git a/plugins/queue/api/queue_repository.go b/plugins/queue/queue_repository.go
similarity index 76%
rename from plugins/queue/api/queue_repository.go
rename to plugins/queue/queue_repository.go
index 11031d0..1c49822 100644
--- a/plugins/queue/api/queue_repository.go
+++ b/plugins/queue/queue_repository.go
@@ -15,26 +15,24 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package api
+package queue
 
 import (
 	"reflect"
 
 	"github.com/apache/skywalking-satellite/internal/pkg/plugin"
+	"github.com/apache/skywalking-satellite/plugins/queue/api"
+	"github.com/apache/skywalking-satellite/plugins/queue/mmap"
 )
 
-// GetQueue an initialized filter plugin.
-func GetQueue(config plugin.Config) Queue {
-	return plugin.Get(reflect.TypeOf((*Queue)(nil)).Elem(), config).(Queue)
-}
-
 // RegisterQueuePlugins register the used queue plugins.
 func RegisterQueuePlugins() {
-	plugin.RegisterPluginCategory(reflect.TypeOf((*Queue)(nil)).Elem())
-	queues := []Queue{
+	plugin.RegisterPluginCategory(reflect.TypeOf((*api.Queue)(nil)).Elem())
+	queues := []api.Queue{
+		&mmap.Queue{},
 		// Please register the queue plugins at here.
 	}
-	for _, queue := range queues {
-		plugin.RegisterPlugin(queue)
+	for _, q := range queues {
+		plugin.RegisterPlugin(q)
 	}
 }
diff --git a/plugins/receiver/api/receiver.go b/plugins/receiver/api/receiver.go
index 9e47692..ba7f208 100644
--- a/plugins/receiver/api/receiver.go
+++ b/plugins/receiver/api/receiver.go
@@ -18,9 +18,9 @@
 package api
 
 import (
-	"github.com/apache/skywalking-satellite/internal/pkg/event"
 	"github.com/apache/skywalking-satellite/internal/pkg/plugin"
 	"github.com/apache/skywalking-satellite/plugins/server/api"
+	"github.com/apache/skywalking-satellite/protocol/gen-codes/satellite/protocol"
 )
 
 // Receiver is a plugin interface, that defines new collectors.
@@ -31,5 +31,5 @@ type Receiver interface {
 	RegisterHandler(server api.Server)
 
 	// Channel would be put a data when the receiver receives an APM data.
-	Channel() <-chan event.SerializableEvent
+	Channel() <-chan *protocol.Event
 }
diff --git a/protocol/gen-codes/satellite/protocol/Event.pb.go b/protocol/gen-codes/satellite/protocol/Event.pb.go
new file mode 100644
index 0000000..89d4821
--- /dev/null
+++ b/protocol/gen-codes/satellite/protocol/Event.pb.go
@@ -0,0 +1,498 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.25.0
+// 	protoc        v3.14.0
+// source: event/Event.proto
+
+package protocol
+
+import (
+	proto "github.com/golang/protobuf/proto"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	v3 "skywalking/network/language/agent/v3"
+	v33 "skywalking/network/language/profile/v3"
+	v31 "skywalking/network/logging/v3"
+	v32 "skywalking/network/management/v3"
+	v34 "skywalking/network/servicemesh/v3"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+// EventType declares the supported transfer data type.
+type EventType int32
+
+const (
+	EventType_CLRMetricType   EventType = 0
+	EventType_JVMMetricType   EventType = 1
+	EventType_MeterType       EventType = 2
+	EventType_TracingType     EventType = 3
+	EventType_Logging         EventType = 4
+	EventType_ManagementType  EventType = 5
+	EventType_ProfileType     EventType = 6
+	EventType_ServiceMeshType EventType = 7
+)
+
+// Enum value maps for EventType.
+var (
+	EventType_name = map[int32]string{
+		0: "CLRMetricType",
+		1: "JVMMetricType",
+		2: "MeterType",
+		3: "TracingType",
+		4: "Logging",
+		5: "ManagementType",
+		6: "ProfileType",
+		7: "ServiceMeshType",
+	}
+	EventType_value = map[string]int32{
+		"CLRMetricType":   0,
+		"JVMMetricType":   1,
+		"MeterType":       2,
+		"TracingType":     3,
+		"Logging":         4,
+		"ManagementType":  5,
+		"ProfileType":     6,
+		"ServiceMeshType": 7,
+	}
+)
+
+func (x EventType) Enum() *EventType {
+	p := new(EventType)
+	*p = x
+	return p
+}
+
+func (x EventType) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (EventType) Descriptor() protoreflect.EnumDescriptor {
+	return file_event_Event_proto_enumTypes[0].Descriptor()
+}
+
+func (EventType) Type() protoreflect.EnumType {
+	return &file_event_Event_proto_enumTypes[0]
+}
+
+func (x EventType) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use EventType.Descriptor instead.
+func (EventType) EnumDescriptor() ([]byte, []int) {
+	return file_event_Event_proto_rawDescGZIP(), []int{0}
+}
+
+// Event is the transfer unit in Satellite.
+type Event struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The occur time.
+	Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	// unique event name.
+	Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	// The data type.
+	Type EventType `protobuf:"varint,3,opt,name=type,proto3,enum=skywalking.v3.EventType" json:"type,omitempty"`
+	// Whether to send to remote. It is used in sampling.
+	Remote bool `protobuf:"varint,4,opt,name=remote,proto3" json:"remote,omitempty"`
+	// Additional meta-information.
+	Meta map[string]string `protobuf:"bytes,5,rep,name=meta,proto3" json:"meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	// Transfer data.
+	//
+	// Types that are assignable to Data:
+	//	*Event_Clr
+	//	*Event_Jvm
+	//	*Event_Meter
+	//	*Event_Segment
+	//	*Event_Log
+	//	*Event_Instance
+	//	*Event_Profile
+	//	*Event_ServiceMesh
+	Data isEvent_Data `protobuf_oneof:"data"`
+}
+
+func (x *Event) Reset() {
+	*x = Event{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_event_Event_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Event) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Event) ProtoMessage() {}
+
+func (x *Event) ProtoReflect() protoreflect.Message {
+	mi := &file_event_Event_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Event.ProtoReflect.Descriptor instead.
+func (*Event) Descriptor() ([]byte, []int) {
+	return file_event_Event_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Event) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+func (x *Event) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *Event) GetType() EventType {
+	if x != nil {
+		return x.Type
+	}
+	return EventType_CLRMetricType
+}
+
+func (x *Event) GetRemote() bool {
+	if x != nil {
+		return x.Remote
+	}
+	return false
+}
+
+func (x *Event) GetMeta() map[string]string {
+	if x != nil {
+		return x.Meta
+	}
+	return nil
+}
+
+func (m *Event) GetData() isEvent_Data {
+	if m != nil {
+		return m.Data
+	}
+	return nil
+}
+
+func (x *Event) GetClr() *v3.CLRMetricCollection {
+	if x, ok := x.GetData().(*Event_Clr); ok {
+		return x.Clr
+	}
+	return nil
+}
+
+func (x *Event) GetJvm() *v3.JVMMetricCollection {
+	if x, ok := x.GetData().(*Event_Jvm); ok {
+		return x.Jvm
+	}
+	return nil
+}
+
+func (x *Event) GetMeter() *v3.MeterData {
+	if x, ok := x.GetData().(*Event_Meter); ok {
+		return x.Meter
+	}
+	return nil
+}
+
+func (x *Event) GetSegment() *v3.SegmentObject {
+	if x, ok := x.GetData().(*Event_Segment); ok {
+		return x.Segment
+	}
+	return nil
+}
+
+func (x *Event) GetLog() *v31.LogData {
+	if x, ok := x.GetData().(*Event_Log); ok {
+		return x.Log
+	}
+	return nil
+}
+
+func (x *Event) GetInstance() *v32.InstanceProperties {
+	if x, ok := x.GetData().(*Event_Instance); ok {
+		return x.Instance
+	}
+	return nil
+}
+
+func (x *Event) GetProfile() *v33.ThreadSnapshot {
+	if x, ok := x.GetData().(*Event_Profile); ok {
+		return x.Profile
+	}
+	return nil
+}
+
+func (x *Event) GetServiceMesh() *v34.ServiceMeshMetric {
+	if x, ok := x.GetData().(*Event_ServiceMesh); ok {
+		return x.ServiceMesh
+	}
+	return nil
+}
+
+type isEvent_Data interface {
+	isEvent_Data()
+}
+
+type Event_Clr struct {
+	Clr *v3.CLRMetricCollection `protobuf:"bytes,6,opt,name=clr,proto3,oneof"`
+}
+
+type Event_Jvm struct {
+	Jvm *v3.JVMMetricCollection `protobuf:"bytes,7,opt,name=jvm,proto3,oneof"`
+}
+
+type Event_Meter struct {
+	Meter *v3.MeterData `protobuf:"bytes,8,opt,name=meter,proto3,oneof"`
+}
+
+type Event_Segment struct {
+	Segment *v3.SegmentObject `protobuf:"bytes,9,opt,name=segment,proto3,oneof"`
+}
+
+type Event_Log struct {
+	Log *v31.LogData `protobuf:"bytes,10,opt,name=log,proto3,oneof"`
+}
+
+type Event_Instance struct {
+	Instance *v32.InstanceProperties `protobuf:"bytes,11,opt,name=instance,proto3,oneof"`
+}
+
+type Event_Profile struct {
+	Profile *v33.ThreadSnapshot `protobuf:"bytes,12,opt,name=profile,proto3,oneof"`
+}
+
+type Event_ServiceMesh struct {
+	ServiceMesh *v34.ServiceMeshMetric `protobuf:"bytes,13,opt,name=serviceMesh,proto3,oneof"`
+}
+
+func (*Event_Clr) isEvent_Data() {}
+
+func (*Event_Jvm) isEvent_Data() {}
+
+func (*Event_Meter) isEvent_Data() {}
+
+func (*Event_Segment) isEvent_Data() {}
+
+func (*Event_Log) isEvent_Data() {}
+
+func (*Event_Instance) isEvent_Data() {}
+
+func (*Event_Profile) isEvent_Data() {}
+
+func (*Event_ServiceMesh) isEvent_Data() {}
+
+var File_event_Event_proto protoreflect.FileDescriptor
+
+var file_event_Event_proto_rawDesc = []byte{
+	0x0a, 0x11, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2f, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e,
+	0x76, 0x33, 0x1a, 0x1e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x61, 0x67, 0x65,
+	0x6e, 0x74, 0x2f, 0x43, 0x4c, 0x52, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x1a, 0x1e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x61, 0x67, 0x65,
+	0x6e, 0x74, 0x2f, 0x4a, 0x56, 0x4d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x1a, 0x1a, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x61, 0x67, 0x65,
+	0x6e, 0x74, 0x2f, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c,
+	0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x54,
+	0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x6c, 0x6f,
+	0x67, 0x67, 0x69, 0x6e, 0x67, 0x2f, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f,
+	0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x1a, 0x15, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x25, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x2d, 0x6d, 0x65, 0x73, 0x68, 0x2d, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x2d, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbe,
+	0x05, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65,
+	0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d,
+	0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x74, 0x79,
+	0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61,
+	0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79,
+	0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f,
+	0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65,
+	0x12, 0x32, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e,
+	0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x45,
+	0x76, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04,
+	0x6d, 0x65, 0x74, 0x61, 0x12, 0x36, 0x0a, 0x03, 0x63, 0x6c, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x22, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76,
+	0x33, 0x2e, 0x43, 0x4c, 0x52, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x43, 0x6f, 0x6c, 0x6c, 0x65,
+	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x03, 0x63, 0x6c, 0x72, 0x12, 0x36, 0x0a, 0x03,
+	0x6a, 0x76, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x6b, 0x79, 0x77,
+	0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4a, 0x56, 0x4d, 0x4d, 0x65, 0x74,
+	0x72, 0x69, 0x63, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52,
+	0x03, 0x6a, 0x76, 0x6d, 0x12, 0x30, 0x0a, 0x05, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x08, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67,
+	0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52,
+	0x05, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x07, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e,
+	0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c,
+	0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4f,
+	0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x00, 0x52, 0x07, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74,
+	0x12, 0x2a, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e,
+	0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f,
+	0x67, 0x44, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12, 0x3f, 0x0a, 0x08,
+	0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21,
+	0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x49,
+	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65,
+	0x73, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x39, 0x0a,
+	0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d,
+	0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x54,
+	0x68, 0x72, 0x65, 0x61, 0x64, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x48, 0x00, 0x52,
+	0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x68, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e,
+	0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x68, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x48,
+	0x00, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x68, 0x1a, 0x37,
+	0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
+	0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a,
+	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61,
+	0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a,
+	0x98, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x11, 0x0a,
+	0x0d, 0x43, 0x4c, 0x52, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x10, 0x00,
+	0x12, 0x11, 0x0a, 0x0d, 0x4a, 0x56, 0x4d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70,
+	0x65, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65,
+	0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70,
+	0x65, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x10, 0x04,
+	0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79,
+	0x70, 0x65, 0x10, 0x05, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54,
+	0x79, 0x70, 0x65, 0x10, 0x06, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x4d, 0x65, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x10, 0x07, 0x42, 0x14, 0x5a, 0x12, 0x73, 0x61,
+	0x74, 0x65, 0x6c, 0x6c, 0x69, 0x74, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
+	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_event_Event_proto_rawDescOnce sync.Once
+	file_event_Event_proto_rawDescData = file_event_Event_proto_rawDesc
+)
+
+func file_event_Event_proto_rawDescGZIP() []byte {
+	file_event_Event_proto_rawDescOnce.Do(func() {
+		file_event_Event_proto_rawDescData = protoimpl.X.CompressGZIP(file_event_Event_proto_rawDescData)
+	})
+	return file_event_Event_proto_rawDescData
+}
+
+var file_event_Event_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_event_Event_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_event_Event_proto_goTypes = []interface{}{
+	(EventType)(0),                 // 0: skywalking.v3.EventType
+	(*Event)(nil),                  // 1: skywalking.v3.Event
+	nil,                            // 2: skywalking.v3.Event.MetaEntry
+	(*v3.CLRMetricCollection)(nil), // 3: skywalking.v3.CLRMetricCollection
+	(*v3.JVMMetricCollection)(nil), // 4: skywalking.v3.JVMMetricCollection
+	(*v3.MeterData)(nil),           // 5: skywalking.v3.MeterData
+	(*v3.SegmentObject)(nil),       // 6: skywalking.v3.SegmentObject
+	(*v31.LogData)(nil),            // 7: skywalking.v3.LogData
+	(*v32.InstanceProperties)(nil), // 8: skywalking.v3.InstanceProperties
+	(*v33.ThreadSnapshot)(nil),     // 9: skywalking.v3.ThreadSnapshot
+	(*v34.ServiceMeshMetric)(nil),  // 10: skywalking.v3.ServiceMeshMetric
+}
+var file_event_Event_proto_depIdxs = []int32{
+	0,  // 0: skywalking.v3.Event.type:type_name -> skywalking.v3.EventType
+	2,  // 1: skywalking.v3.Event.meta:type_name -> skywalking.v3.Event.MetaEntry
+	3,  // 2: skywalking.v3.Event.clr:type_name -> skywalking.v3.CLRMetricCollection
+	4,  // 3: skywalking.v3.Event.jvm:type_name -> skywalking.v3.JVMMetricCollection
+	5,  // 4: skywalking.v3.Event.meter:type_name -> skywalking.v3.MeterData
+	6,  // 5: skywalking.v3.Event.segment:type_name -> skywalking.v3.SegmentObject
+	7,  // 6: skywalking.v3.Event.log:type_name -> skywalking.v3.LogData
+	8,  // 7: skywalking.v3.Event.instance:type_name -> skywalking.v3.InstanceProperties
+	9,  // 8: skywalking.v3.Event.profile:type_name -> skywalking.v3.ThreadSnapshot
+	10, // 9: skywalking.v3.Event.serviceMesh:type_name -> skywalking.v3.ServiceMeshMetric
+	10, // [10:10] is the sub-list for method output_type
+	10, // [10:10] is the sub-list for method input_type
+	10, // [10:10] is the sub-list for extension type_name
+	10, // [10:10] is the sub-list for extension extendee
+	0,  // [0:10] is the sub-list for field type_name
+}
+
+func init() { file_event_Event_proto_init() }
+func file_event_Event_proto_init() {
+	if File_event_Event_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_event_Event_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Event); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	file_event_Event_proto_msgTypes[0].OneofWrappers = []interface{}{
+		(*Event_Clr)(nil),
+		(*Event_Jvm)(nil),
+		(*Event_Meter)(nil),
+		(*Event_Segment)(nil),
+		(*Event_Log)(nil),
+		(*Event_Instance)(nil),
+		(*Event_Profile)(nil),
+		(*Event_ServiceMesh)(nil),
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_event_Event_proto_rawDesc,
+			NumEnums:      1,
+			NumMessages:   2,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_event_Event_proto_goTypes,
+		DependencyIndexes: file_event_Event_proto_depIdxs,
+		EnumInfos:         file_event_Event_proto_enumTypes,
+		MessageInfos:      file_event_Event_proto_msgTypes,
+	}.Build()
+	File_event_Event_proto = out.File
+	file_event_Event_proto_rawDesc = nil
+	file_event_Event_proto_goTypes = nil
+	file_event_Event_proto_depIdxs = nil
+}
diff --git a/protocol/gen-codes/skywalking/network/common/v3/Common.pb.go b/protocol/gen-codes/skywalking/network/common/v3/Common.pb.go
new file mode 100644
index 0000000..a3c545d
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/common/v3/Common.pb.go
@@ -0,0 +1,441 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.25.0
+// 	protoc        v3.14.0
+// source: common/Common.proto
+
+package v3
+
+import (
+	proto "github.com/golang/protobuf/proto"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+// In most cases, detect point should be `server` or `client`.
+// Even in service mesh, this means `server`/`client` side sidecar
+// `proxy` is reserved only.
+type DetectPoint int32
+
+const (
+	DetectPoint_client DetectPoint = 0
+	DetectPoint_server DetectPoint = 1
+	DetectPoint_proxy  DetectPoint = 2
+)
+
+// Enum value maps for DetectPoint.
+var (
+	DetectPoint_name = map[int32]string{
+		0: "client",
+		1: "server",
+		2: "proxy",
+	}
+	DetectPoint_value = map[string]int32{
+		"client": 0,
+		"server": 1,
+		"proxy":  2,
+	}
+)
+
+func (x DetectPoint) Enum() *DetectPoint {
+	p := new(DetectPoint)
+	*p = x
+	return p
+}
+
+func (x DetectPoint) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (DetectPoint) Descriptor() protoreflect.EnumDescriptor {
+	return file_common_Common_proto_enumTypes[0].Descriptor()
+}
+
+func (DetectPoint) Type() protoreflect.EnumType {
+	return &file_common_Common_proto_enumTypes[0]
+}
+
+func (x DetectPoint) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use DetectPoint.Descriptor instead.
+func (DetectPoint) EnumDescriptor() ([]byte, []int) {
+	return file_common_Common_proto_rawDescGZIP(), []int{0}
+}
+
+type KeyStringValuePair struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Key   string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
+	Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (x *KeyStringValuePair) Reset() {
+	*x = KeyStringValuePair{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_common_Common_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *KeyStringValuePair) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*KeyStringValuePair) ProtoMessage() {}
+
+func (x *KeyStringValuePair) ProtoReflect() protoreflect.Message {
+	mi := &file_common_Common_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use KeyStringValuePair.ProtoReflect.Descriptor instead.
+func (*KeyStringValuePair) Descriptor() ([]byte, []int) {
+	return file_common_Common_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *KeyStringValuePair) GetKey() string {
+	if x != nil {
+		return x.Key
+	}
+	return ""
+}
+
+func (x *KeyStringValuePair) GetValue() string {
+	if x != nil {
+		return x.Value
+	}
+	return ""
+}
+
+type CPU struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	UsagePercent float64 `protobuf:"fixed64,2,opt,name=usagePercent,proto3" json:"usagePercent,omitempty"`
+}
+
+func (x *CPU) Reset() {
+	*x = CPU{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_common_Common_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CPU) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CPU) ProtoMessage() {}
+
+func (x *CPU) ProtoReflect() protoreflect.Message {
+	mi := &file_common_Common_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CPU.ProtoReflect.Descriptor instead.
+func (*CPU) Descriptor() ([]byte, []int) {
+	return file_common_Common_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *CPU) GetUsagePercent() float64 {
+	if x != nil {
+		return x.UsagePercent
+	}
+	return 0
+}
+
+type Commands struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Commands []*Command `protobuf:"bytes,1,rep,name=commands,proto3" json:"commands,omitempty"`
+}
+
+func (x *Commands) Reset() {
+	*x = Commands{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_common_Common_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Commands) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Commands) ProtoMessage() {}
+
+func (x *Commands) ProtoReflect() protoreflect.Message {
+	mi := &file_common_Common_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Commands.ProtoReflect.Descriptor instead.
+func (*Commands) Descriptor() ([]byte, []int) {
+	return file_common_Common_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *Commands) GetCommands() []*Command {
+	if x != nil {
+		return x.Commands
+	}
+	return nil
+}
+
+type Command struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Command string                `protobuf:"bytes,1,opt,name=command,proto3" json:"command,omitempty"`
+	Args    []*KeyStringValuePair `protobuf:"bytes,2,rep,name=args,proto3" json:"args,omitempty"`
+}
+
+func (x *Command) Reset() {
+	*x = Command{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_common_Common_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Command) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Command) ProtoMessage() {}
+
+func (x *Command) ProtoReflect() protoreflect.Message {
+	mi := &file_common_Common_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Command.ProtoReflect.Descriptor instead.
+func (*Command) Descriptor() ([]byte, []int) {
+	return file_common_Common_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *Command) GetCommand() string {
+	if x != nil {
+		return x.Command
+	}
+	return ""
+}
+
+func (x *Command) GetArgs() []*KeyStringValuePair {
+	if x != nil {
+		return x.Args
+	}
+	return nil
+}
+
+var File_common_Common_proto protoreflect.FileDescriptor
+
+var file_common_Common_proto_rawDesc = []byte{
+	0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e,
+	0x67, 0x2e, 0x76, 0x33, 0x22, 0x3c, 0x0a, 0x12, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x69, 0x6e,
+	0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x61, 0x69, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
+	0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05,
+	0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
+	0x75, 0x65, 0x22, 0x29, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x12, 0x22, 0x0a, 0x0c, 0x75, 0x73, 0x61,
+	0x67, 0x65, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52,
+	0x0c, 0x75, 0x73, 0x61, 0x67, 0x65, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x22, 0x3e, 0x0a,
+	0x08, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x32, 0x0a, 0x08, 0x63, 0x6f, 0x6d,
+	0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x6b,
+	0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6d, 0x6d,
+	0x61, 0x6e, 0x64, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x5a, 0x0a,
+	0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d,
+	0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
+	0x6e, 0x64, 0x12, 0x35, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x21, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33,
+	0x2e, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50,
+	0x61, 0x69, 0x72, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x2a, 0x30, 0x0a, 0x0b, 0x44, 0x65, 0x74,
+	0x65, 0x63, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65,
+	0x6e, 0x74, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x10, 0x01,
+	0x12, 0x09, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x10, 0x02, 0x42, 0x6d, 0x0a, 0x2b, 0x6f,
+	0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c,
+	0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x61, 0x70, 0x6d, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+	0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x33, 0x50, 0x01, 0x5a, 0x1c, 0x73, 0x6b,
+	0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+	0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x33, 0xaa, 0x02, 0x1d, 0x53, 0x6b, 0x79,
+	0x57, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x50,
+	0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x33,
+}
+
+var (
+	file_common_Common_proto_rawDescOnce sync.Once
+	file_common_Common_proto_rawDescData = file_common_Common_proto_rawDesc
+)
+
+func file_common_Common_proto_rawDescGZIP() []byte {
+	file_common_Common_proto_rawDescOnce.Do(func() {
+		file_common_Common_proto_rawDescData = protoimpl.X.CompressGZIP(file_common_Common_proto_rawDescData)
+	})
+	return file_common_Common_proto_rawDescData
+}
+
+var file_common_Common_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_common_Common_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_common_Common_proto_goTypes = []interface{}{
+	(DetectPoint)(0),           // 0: skywalking.v3.DetectPoint
+	(*KeyStringValuePair)(nil), // 1: skywalking.v3.KeyStringValuePair
+	(*CPU)(nil),                // 2: skywalking.v3.CPU
+	(*Commands)(nil),           // 3: skywalking.v3.Commands
+	(*Command)(nil),            // 4: skywalking.v3.Command
+}
+var file_common_Common_proto_depIdxs = []int32{
+	4, // 0: skywalking.v3.Commands.commands:type_name -> skywalking.v3.Command
+	1, // 1: skywalking.v3.Command.args:type_name -> skywalking.v3.KeyStringValuePair
+	2, // [2:2] is the sub-list for method output_type
+	2, // [2:2] is the sub-list for method input_type
+	2, // [2:2] is the sub-list for extension type_name
+	2, // [2:2] is the sub-list for extension extendee
+	0, // [0:2] is the sub-list for field type_name
+}
+
+func init() { file_common_Common_proto_init() }
+func file_common_Common_proto_init() {
+	if File_common_Common_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_common_Common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*KeyStringValuePair); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_common_Common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CPU); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_common_Common_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Commands); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_common_Common_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Command); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_common_Common_proto_rawDesc,
+			NumEnums:      1,
+			NumMessages:   4,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_common_Common_proto_goTypes,
+		DependencyIndexes: file_common_Common_proto_depIdxs,
+		EnumInfos:         file_common_Common_proto_enumTypes,
+		MessageInfos:      file_common_Common_proto_msgTypes,
+	}.Build()
+	File_common_Common_proto = out.File
+	file_common_Common_proto_rawDesc = nil
+	file_common_Common_proto_goTypes = nil
+	file_common_Common_proto_depIdxs = nil
+}
diff --git a/protocol/gen-codes/skywalking/network/go.mod b/protocol/gen-codes/skywalking/network/go.mod
new file mode 100644
index 0000000..a6555ad
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/go.mod
@@ -0,0 +1,9 @@
+module skywalking/network
+
+go 1.14
+
+require (
+	github.com/golang/protobuf v1.4.3
+	google.golang.org/grpc v1.34.0
+	google.golang.org/protobuf v1.25.0
+)
diff --git a/protocol/gen-codes/skywalking/network/go.sum b/protocol/gen-codes/skywalking/network/go.sum
new file mode 100644
index 0000000..2c6c370
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/go.sum
@@ -0,0 +1,85 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.34.0 h1:raiipEjMOIC/TO2AvyTxP25XFdLxNIBwzDh3FM3XztI=
+google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
+google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+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=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/protocol/gen-codes/skywalking/network/language/agent/v3/BrowserPerf.pb.go b/protocol/gen-codes/skywalking/network/language/agent/v3/BrowserPerf.pb.go
new file mode 100644
index 0000000..b460ab9
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/language/agent/v3/BrowserPerf.pb.go
@@ -0,0 +1,632 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.25.0
+// 	protoc        v3.14.0
+// source: browser/BrowserPerf.proto
+
+package v3
+
+import (
+	proto "github.com/golang/protobuf/proto"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	v3 "skywalking/network/common/v3"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+type ErrorCategory int32
+
+const (
+	ErrorCategory_ajax     ErrorCategory = 0
+	ErrorCategory_resource ErrorCategory = 1
+	ErrorCategory_vue      ErrorCategory = 2
+	ErrorCategory_promise  ErrorCategory = 3
+	ErrorCategory_js       ErrorCategory = 4
+	ErrorCategory_unknown  ErrorCategory = 5
+)
+
+// Enum value maps for ErrorCategory.
+var (
+	ErrorCategory_name = map[int32]string{
+		0: "ajax",
+		1: "resource",
+		2: "vue",
+		3: "promise",
+		4: "js",
+		5: "unknown",
+	}
+	ErrorCategory_value = map[string]int32{
+		"ajax":     0,
+		"resource": 1,
+		"vue":      2,
+		"promise":  3,
+		"js":       4,
+		"unknown":  5,
+	}
+)
+
+func (x ErrorCategory) Enum() *ErrorCategory {
+	p := new(ErrorCategory)
+	*p = x
+	return p
+}
+
+func (x ErrorCategory) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ErrorCategory) Descriptor() protoreflect.EnumDescriptor {
+	return file_browser_BrowserPerf_proto_enumTypes[0].Descriptor()
+}
+
+func (ErrorCategory) Type() protoreflect.EnumType {
+	return &file_browser_BrowserPerf_proto_enumTypes[0]
+}
+
+func (x ErrorCategory) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ErrorCategory.Descriptor instead.
+func (ErrorCategory) EnumDescriptor() ([]byte, []int) {
+	return file_browser_BrowserPerf_proto_rawDescGZIP(), []int{0}
+}
+
+type BrowserPerfData struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
+	// Service version in browser is the Instance concept in the backend.
+	ServiceVersion string `protobuf:"bytes,2,opt,name=serviceVersion,proto3" json:"serviceVersion,omitempty"`
+	// Perf data time, set by the backend side.
+	Time int64 `protobuf:"varint,3,opt,name=time,proto3" json:"time,omitempty"`
+	// Page path in browser is the endpoint concept in the backend
+	// Page path in the browser, mostly it is URI, without parameter
+	PagePath string `protobuf:"bytes,4,opt,name=pagePath,proto3" json:"pagePath,omitempty"`
+	// Unit of all time related field should be `ms`.
+	RedirectTime int32 `protobuf:"varint,5,opt,name=redirectTime,proto3" json:"redirectTime,omitempty"`
+	// DNS query time
+	DnsTime int32 `protobuf:"varint,6,opt,name=dnsTime,proto3" json:"dnsTime,omitempty"`
+	// Time to first Byte
+	TtfbTime int32 `protobuf:"varint,7,opt,name=ttfbTime,proto3" json:"ttfbTime,omitempty"`
+	//  TCP connection time
+	TcpTime int32 `protobuf:"varint,8,opt,name=tcpTime,proto3" json:"tcpTime,omitempty"`
+	// Content transfer time
+	TransTime int32 `protobuf:"varint,9,opt,name=transTime,proto3" json:"transTime,omitempty"`
+	// Dom parsing time
+	DomAnalysisTime int32 `protobuf:"varint,10,opt,name=domAnalysisTime,proto3" json:"domAnalysisTime,omitempty"`
+	// First paint time or blank screen time
+	FptTime int32 `protobuf:"varint,11,opt,name=fptTime,proto3" json:"fptTime,omitempty"`
+	// Dom ready time
+	DomReadyTime int32 `protobuf:"varint,12,opt,name=domReadyTime,proto3" json:"domReadyTime,omitempty"`
+	// Page full load time
+	LoadPageTime int32 `protobuf:"varint,13,opt,name=loadPageTime,proto3" json:"loadPageTime,omitempty"`
+	// Synchronous load resources in the page
+	ResTime int32 `protobuf:"varint,14,opt,name=resTime,proto3" json:"resTime,omitempty"`
+	// Only valid for HTTPS
+	SslTime int32 `protobuf:"varint,15,opt,name=sslTime,proto3" json:"sslTime,omitempty"`
+	// Time to interact
+	TtlTime int32 `protobuf:"varint,16,opt,name=ttlTime,proto3" json:"ttlTime,omitempty"`
+	// First pack time
+	FirstPackTime int32 `protobuf:"varint,17,opt,name=firstPackTime,proto3" json:"firstPackTime,omitempty"`
+	// First Meaningful Paint
+	FmpTime int32 `protobuf:"varint,18,opt,name=fmpTime,proto3" json:"fmpTime,omitempty"`
+}
+
+func (x *BrowserPerfData) Reset() {
+	*x = BrowserPerfData{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_browser_BrowserPerf_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *BrowserPerfData) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BrowserPerfData) ProtoMessage() {}
+
+func (x *BrowserPerfData) ProtoReflect() protoreflect.Message {
+	mi := &file_browser_BrowserPerf_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use BrowserPerfData.ProtoReflect.Descriptor instead.
+func (*BrowserPerfData) Descriptor() ([]byte, []int) {
+	return file_browser_BrowserPerf_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *BrowserPerfData) GetService() string {
+	if x != nil {
+		return x.Service
+	}
+	return ""
+}
+
+func (x *BrowserPerfData) GetServiceVersion() string {
+	if x != nil {
+		return x.ServiceVersion
+	}
+	return ""
+}
+
+func (x *BrowserPerfData) GetTime() int64 {
+	if x != nil {
+		return x.Time
+	}
+	return 0
+}
+
+func (x *BrowserPerfData) GetPagePath() string {
+	if x != nil {
+		return x.PagePath
+	}
+	return ""
+}
+
+func (x *BrowserPerfData) GetRedirectTime() int32 {
+	if x != nil {
+		return x.RedirectTime
+	}
+	return 0
+}
+
+func (x *BrowserPerfData) GetDnsTime() int32 {
+	if x != nil {
+		return x.DnsTime
+	}
+	return 0
+}
+
+func (x *BrowserPerfData) GetTtfbTime() int32 {
+	if x != nil {
+		return x.TtfbTime
+	}
+	return 0
+}
+
+func (x *BrowserPerfData) GetTcpTime() int32 {
+	if x != nil {
+		return x.TcpTime
+	}
+	return 0
+}
+
+func (x *BrowserPerfData) GetTransTime() int32 {
+	if x != nil {
+		return x.TransTime
+	}
+	return 0
+}
+
+func (x *BrowserPerfData) GetDomAnalysisTime() int32 {
+	if x != nil {
+		return x.DomAnalysisTime
+	}
+	return 0
+}
+
+func (x *BrowserPerfData) GetFptTime() int32 {
+	if x != nil {
+		return x.FptTime
+	}
+	return 0
+}
+
+func (x *BrowserPerfData) GetDomReadyTime() int32 {
+	if x != nil {
+		return x.DomReadyTime
+	}
+	return 0
+}
+
+func (x *BrowserPerfData) GetLoadPageTime() int32 {
+	if x != nil {
+		return x.LoadPageTime
+	}
+	return 0
+}
+
+func (x *BrowserPerfData) GetResTime() int32 {
+	if x != nil {
+		return x.ResTime
+	}
+	return 0
+}
+
+func (x *BrowserPerfData) GetSslTime() int32 {
+	if x != nil {
+		return x.SslTime
+	}
+	return 0
+}
+
+func (x *BrowserPerfData) GetTtlTime() int32 {
+	if x != nil {
+		return x.TtlTime
+	}
+	return 0
+}
+
+func (x *BrowserPerfData) GetFirstPackTime() int32 {
+	if x != nil {
+		return x.FirstPackTime
+	}
+	return 0
+}
+
+func (x *BrowserPerfData) GetFmpTime() int32 {
+	if x != nil {
+		return x.FmpTime
+	}
+	return 0
+}
+
+type BrowserErrorLog struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// UUID
+	UniqueId string `protobuf:"bytes,1,opt,name=uniqueId,proto3" json:"uniqueId,omitempty"`
+	Service  string `protobuf:"bytes,2,opt,name=service,proto3" json:"service,omitempty"`
+	// Service version in browser is the Instance concept in the backend.
+	ServiceVersion string `protobuf:"bytes,3,opt,name=serviceVersion,proto3" json:"serviceVersion,omitempty"`
+	// Error log time, set by the backend side.
+	Time int64 `protobuf:"varint,4,opt,name=time,proto3" json:"time,omitempty"`
+	// Page path in browser is the endpoint concept in the backend
+	// Page path in the browser, mostly it is URI, without parameter
+	PagePath string        `protobuf:"bytes,5,opt,name=pagePath,proto3" json:"pagePath,omitempty"`
+	Category ErrorCategory `protobuf:"varint,6,opt,name=category,proto3,enum=skywalking.v3.ErrorCategory" json:"category,omitempty"`
+	Grade    string        `protobuf:"bytes,7,opt,name=grade,proto3" json:"grade,omitempty"`
+	Message  string        `protobuf:"bytes,8,opt,name=message,proto3" json:"message,omitempty"`
+	Line     int32         `protobuf:"varint,9,opt,name=line,proto3" json:"line,omitempty"`
+	Col      int32         `protobuf:"varint,10,opt,name=col,proto3" json:"col,omitempty"`
+	Stack    string        `protobuf:"bytes,11,opt,name=stack,proto3" json:"stack,omitempty"`
+	ErrorUrl string        `protobuf:"bytes,12,opt,name=errorUrl,proto3" json:"errorUrl,omitempty"`
+	// Then the PV with error is only calculated when firstReportedError is true.
+	FirstReportedError bool `protobuf:"varint,13,opt,name=firstReportedError,proto3" json:"firstReportedError,omitempty"`
+}
+
+func (x *BrowserErrorLog) Reset() {
+	*x = BrowserErrorLog{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_browser_BrowserPerf_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *BrowserErrorLog) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BrowserErrorLog) ProtoMessage() {}
+
+func (x *BrowserErrorLog) ProtoReflect() protoreflect.Message {
+	mi := &file_browser_BrowserPerf_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use BrowserErrorLog.ProtoReflect.Descriptor instead.
+func (*BrowserErrorLog) Descriptor() ([]byte, []int) {
+	return file_browser_BrowserPerf_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *BrowserErrorLog) GetUniqueId() string {
+	if x != nil {
+		return x.UniqueId
+	}
+	return ""
+}
+
+func (x *BrowserErrorLog) GetService() string {
+	if x != nil {
+		return x.Service
+	}
+	return ""
+}
+
+func (x *BrowserErrorLog) GetServiceVersion() string {
+	if x != nil {
+		return x.ServiceVersion
+	}
+	return ""
+}
+
+func (x *BrowserErrorLog) GetTime() int64 {
+	if x != nil {
+		return x.Time
+	}
+	return 0
+}
+
+func (x *BrowserErrorLog) GetPagePath() string {
+	if x != nil {
+		return x.PagePath
+	}
+	return ""
+}
+
+func (x *BrowserErrorLog) GetCategory() ErrorCategory {
+	if x != nil {
+		return x.Category
+	}
+	return ErrorCategory_ajax
+}
+
+func (x *BrowserErrorLog) GetGrade() string {
+	if x != nil {
+		return x.Grade
+	}
+	return ""
+}
+
+func (x *BrowserErrorLog) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+func (x *BrowserErrorLog) GetLine() int32 {
+	if x != nil {
+		return x.Line
+	}
+	return 0
+}
+
+func (x *BrowserErrorLog) GetCol() int32 {
+	if x != nil {
+		return x.Col
+	}
+	return 0
+}
+
+func (x *BrowserErrorLog) GetStack() string {
+	if x != nil {
+		return x.Stack
+	}
+	return ""
+}
+
+func (x *BrowserErrorLog) GetErrorUrl() string {
+	if x != nil {
+		return x.ErrorUrl
+	}
+	return ""
+}
+
+func (x *BrowserErrorLog) GetFirstReportedError() bool {
+	if x != nil {
+		return x.FirstReportedError
+	}
+	return false
+}
+
+var File_browser_BrowserPerf_proto protoreflect.FileDescriptor
+
+var file_browser_BrowserPerf_proto_rawDesc = []byte{
+	0x0a, 0x19, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x2f, 0x42, 0x72, 0x6f, 0x77, 0x73, 0x65,
+	0x72, 0x50, 0x65, 0x72, 0x66, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x73, 0x6b, 0x79,
+	0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x1a, 0x13, 0x63, 0x6f, 0x6d, 0x6d,
+	0x6f, 0x6e, 0x2f, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
+	0xaf, 0x04, 0x0a, 0x0f, 0x42, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x66, 0x44,
+	0x61, 0x74, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x26, 0x0a,
+	0x0e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x56, 0x65,
+	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x67,
+	0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x67,
+	0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63,
+	0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x72, 0x65, 0x64,
+	0x69, 0x72, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x6e, 0x73,
+	0x54, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x64, 0x6e, 0x73, 0x54,
+	0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x74, 0x66, 0x62, 0x54, 0x69, 0x6d, 0x65, 0x18,
+	0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x74, 0x74, 0x66, 0x62, 0x54, 0x69, 0x6d, 0x65, 0x12,
+	0x18, 0x0a, 0x07, 0x74, 0x63, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05,
+	0x52, 0x07, 0x74, 0x63, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x72, 0x61,
+	0x6e, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x74, 0x72,
+	0x61, 0x6e, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x41, 0x6e,
+	0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05,
+	0x52, 0x0f, 0x64, 0x6f, 0x6d, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d,
+	0x65, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x70, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01,
+	0x28, 0x05, 0x52, 0x07, 0x66, 0x70, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x64,
+	0x6f, 0x6d, 0x52, 0x65, 0x61, 0x64, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28,
+	0x05, 0x52, 0x0c, 0x64, 0x6f, 0x6d, 0x52, 0x65, 0x61, 0x64, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x12,
+	0x22, 0x0a, 0x0c, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x61, 0x67, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18,
+	0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x61, 0x67, 0x65, 0x54,
+	0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x0e,
+	0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a,
+	0x07, 0x73, 0x73, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07,
+	0x73, 0x73, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x74, 0x6c, 0x54, 0x69,
+	0x6d, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x74, 0x74, 0x6c, 0x54, 0x69, 0x6d,
+	0x65, 0x12, 0x24, 0x0a, 0x0d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x50, 0x61, 0x63, 0x6b, 0x54, 0x69,
+	0x6d, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x50,
+	0x61, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x6d, 0x70, 0x54, 0x69,
+	0x6d, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x66, 0x6d, 0x70, 0x54, 0x69, 0x6d,
+	0x65, 0x22, 0x91, 0x03, 0x0a, 0x0f, 0x42, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x45, 0x72, 0x72,
+	0x6f, 0x72, 0x4c, 0x6f, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49,
+	0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x73,
+	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73,
+	0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
+	0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x67, 0x65, 0x50,
+	0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x50,
+	0x61, 0x74, 0x68, 0x12, 0x38, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18,
+	0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69,
+	0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x61, 0x74, 0x65, 0x67,
+	0x6f, 0x72, 0x79, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x14, 0x0a,
+	0x05, 0x67, 0x72, 0x61, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72,
+	0x61, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x08,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a,
+	0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6c, 0x69, 0x6e,
+	0x65, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x6f, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03,
+	0x63, 0x6f, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x0b, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x72, 0x72,
+	0x6f, 0x72, 0x55, 0x72, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x72, 0x72,
+	0x6f, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x2e, 0x0a, 0x12, 0x66, 0x69, 0x72, 0x73, 0x74, 0x52, 0x65,
+	0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28,
+	0x08, 0x52, 0x12, 0x66, 0x69, 0x72, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64,
+	0x45, 0x72, 0x72, 0x6f, 0x72, 0x2a, 0x52, 0x0a, 0x0d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x61,
+	0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x61, 0x6a, 0x61, 0x78, 0x10, 0x00,
+	0x12, 0x0c, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x10, 0x01, 0x12, 0x07,
+	0x0a, 0x03, 0x76, 0x75, 0x65, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6d, 0x69,
+	0x73, 0x65, 0x10, 0x03, 0x12, 0x06, 0x0a, 0x02, 0x6a, 0x73, 0x10, 0x04, 0x12, 0x0b, 0x0a, 0x07,
+	0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x05, 0x32, 0xb3, 0x01, 0x0a, 0x12, 0x42, 0x72,
+	0x6f, 0x77, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x66, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x12, 0x4c, 0x0a, 0x0f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x50, 0x65, 0x72, 0x66, 0x44,
+	0x61, 0x74, 0x61, 0x12, 0x1e, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67,
+	0x2e, 0x76, 0x33, 0x2e, 0x42, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x66, 0x44,
+	0x61, 0x74, 0x61, 0x1a, 0x17, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67,
+	0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x00, 0x12, 0x4f,
+	0x0a, 0x10, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4c, 0x6f,
+	0x67, 0x73, 0x12, 0x1e, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e,
+	0x76, 0x33, 0x2e, 0x42, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4c,
+	0x6f, 0x67, 0x1a, 0x17, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e,
+	0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x00, 0x28, 0x01, 0x42,
+	0x7d, 0x0a, 0x33, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x73, 0x6b,
+	0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x61, 0x70, 0x6d, 0x2e, 0x6e, 0x65, 0x74,
+	0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x61, 0x67,
+	0x65, 0x6e, 0x74, 0x2e, 0x76, 0x33, 0x50, 0x01, 0x5a, 0x24, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c,
+	0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x61, 0x6e,
+	0x67, 0x75, 0x61, 0x67, 0x65, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x76, 0x33, 0xaa, 0x02,
+	0x1d, 0x53, 0x6b, 0x79, 0x57, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x4e, 0x65, 0x74, 0x77,
+	0x6f, 0x72, 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x56, 0x33, 0x62, 0x06,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_browser_BrowserPerf_proto_rawDescOnce sync.Once
+	file_browser_BrowserPerf_proto_rawDescData = file_browser_BrowserPerf_proto_rawDesc
+)
+
+func file_browser_BrowserPerf_proto_rawDescGZIP() []byte {
+	file_browser_BrowserPerf_proto_rawDescOnce.Do(func() {
+		file_browser_BrowserPerf_proto_rawDescData = protoimpl.X.CompressGZIP(file_browser_BrowserPerf_proto_rawDescData)
+	})
+	return file_browser_BrowserPerf_proto_rawDescData
+}
+
+var file_browser_BrowserPerf_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_browser_BrowserPerf_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_browser_BrowserPerf_proto_goTypes = []interface{}{
+	(ErrorCategory)(0),      // 0: skywalking.v3.ErrorCategory
+	(*BrowserPerfData)(nil), // 1: skywalking.v3.BrowserPerfData
+	(*BrowserErrorLog)(nil), // 2: skywalking.v3.BrowserErrorLog
+	(*v3.Commands)(nil),     // 3: skywalking.v3.Commands
+}
+var file_browser_BrowserPerf_proto_depIdxs = []int32{
+	0, // 0: skywalking.v3.BrowserErrorLog.category:type_name -> skywalking.v3.ErrorCategory
+	1, // 1: skywalking.v3.BrowserPerfService.collectPerfData:input_type -> skywalking.v3.BrowserPerfData
+	2, // 2: skywalking.v3.BrowserPerfService.collectErrorLogs:input_type -> skywalking.v3.BrowserErrorLog
+	3, // 3: skywalking.v3.BrowserPerfService.collectPerfData:output_type -> skywalking.v3.Commands
+	3, // 4: skywalking.v3.BrowserPerfService.collectErrorLogs:output_type -> skywalking.v3.Commands
+	3, // [3:5] is the sub-list for method output_type
+	1, // [1:3] is the sub-list for method input_type
+	1, // [1:1] is the sub-list for extension type_name
+	1, // [1:1] is the sub-list for extension extendee
+	0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_browser_BrowserPerf_proto_init() }
+func file_browser_BrowserPerf_proto_init() {
+	if File_browser_BrowserPerf_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_browser_BrowserPerf_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*BrowserPerfData); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_browser_BrowserPerf_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*BrowserErrorLog); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_browser_BrowserPerf_proto_rawDesc,
+			NumEnums:      1,
+			NumMessages:   2,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_browser_BrowserPerf_proto_goTypes,
+		DependencyIndexes: file_browser_BrowserPerf_proto_depIdxs,
+		EnumInfos:         file_browser_BrowserPerf_proto_enumTypes,
+		MessageInfos:      file_browser_BrowserPerf_proto_msgTypes,
+	}.Build()
+	File_browser_BrowserPerf_proto = out.File
+	file_browser_BrowserPerf_proto_rawDesc = nil
+	file_browser_BrowserPerf_proto_goTypes = nil
+	file_browser_BrowserPerf_proto_depIdxs = nil
+}
diff --git a/protocol/gen-codes/skywalking/network/language/agent/v3/BrowserPerf_grpc.pb.go b/protocol/gen-codes/skywalking/network/language/agent/v3/BrowserPerf_grpc.pb.go
new file mode 100644
index 0000000..b47b11b
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/language/agent/v3/BrowserPerf_grpc.pb.go
@@ -0,0 +1,173 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package v3
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	v3 "skywalking/network/common/v3"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion7
+
+// BrowserPerfServiceClient is the client API for BrowserPerfService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type BrowserPerfServiceClient interface {
+	// report once per page
+	CollectPerfData(ctx context.Context, in *BrowserPerfData, opts ...grpc.CallOption) (*v3.Commands, error)
+	// report one or more error logs for pages, could report multiple times.
+	CollectErrorLogs(ctx context.Context, opts ...grpc.CallOption) (BrowserPerfService_CollectErrorLogsClient, error)
+}
+
+type browserPerfServiceClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewBrowserPerfServiceClient(cc grpc.ClientConnInterface) BrowserPerfServiceClient {
+	return &browserPerfServiceClient{cc}
+}
+
+func (c *browserPerfServiceClient) CollectPerfData(ctx context.Context, in *BrowserPerfData, opts ...grpc.CallOption) (*v3.Commands, error) {
+	out := new(v3.Commands)
+	err := c.cc.Invoke(ctx, "/skywalking.v3.BrowserPerfService/collectPerfData", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *browserPerfServiceClient) CollectErrorLogs(ctx context.Context, opts ...grpc.CallOption) (BrowserPerfService_CollectErrorLogsClient, error) {
+	stream, err := c.cc.NewStream(ctx, &_BrowserPerfService_serviceDesc.Streams[0], "/skywalking.v3.BrowserPerfService/collectErrorLogs", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &browserPerfServiceCollectErrorLogsClient{stream}
+	return x, nil
+}
+
+type BrowserPerfService_CollectErrorLogsClient interface {
+	Send(*BrowserErrorLog) error
+	CloseAndRecv() (*v3.Commands, error)
+	grpc.ClientStream
+}
+
+type browserPerfServiceCollectErrorLogsClient struct {
+	grpc.ClientStream
+}
+
+func (x *browserPerfServiceCollectErrorLogsClient) Send(m *BrowserErrorLog) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *browserPerfServiceCollectErrorLogsClient) CloseAndRecv() (*v3.Commands, error) {
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	m := new(v3.Commands)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+// BrowserPerfServiceServer is the server API for BrowserPerfService service.
+// All implementations must embed UnimplementedBrowserPerfServiceServer
+// for forward compatibility
+type BrowserPerfServiceServer interface {
+	// report once per page
+	CollectPerfData(context.Context, *BrowserPerfData) (*v3.Commands, error)
+	// report one or more error logs for pages, could report multiple times.
+	CollectErrorLogs(BrowserPerfService_CollectErrorLogsServer) error
+	mustEmbedUnimplementedBrowserPerfServiceServer()
+}
+
+// UnimplementedBrowserPerfServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedBrowserPerfServiceServer struct {
+}
+
+func (UnimplementedBrowserPerfServiceServer) CollectPerfData(context.Context, *BrowserPerfData) (*v3.Commands, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method CollectPerfData not implemented")
+}
+func (UnimplementedBrowserPerfServiceServer) CollectErrorLogs(BrowserPerfService_CollectErrorLogsServer) error {
+	return status.Errorf(codes.Unimplemented, "method CollectErrorLogs not implemented")
+}
+func (UnimplementedBrowserPerfServiceServer) mustEmbedUnimplementedBrowserPerfServiceServer() {}
+
+// UnsafeBrowserPerfServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to BrowserPerfServiceServer will
+// result in compilation errors.
+type UnsafeBrowserPerfServiceServer interface {
+	mustEmbedUnimplementedBrowserPerfServiceServer()
+}
+
+func RegisterBrowserPerfServiceServer(s grpc.ServiceRegistrar, srv BrowserPerfServiceServer) {
+	s.RegisterService(&_BrowserPerfService_serviceDesc, srv)
+}
+
+func _BrowserPerfService_CollectPerfData_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(BrowserPerfData)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BrowserPerfServiceServer).CollectPerfData(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/skywalking.v3.BrowserPerfService/collectPerfData",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BrowserPerfServiceServer).CollectPerfData(ctx, req.(*BrowserPerfData))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BrowserPerfService_CollectErrorLogs_Handler(srv interface{}, stream grpc.ServerStream) error {
+	return srv.(BrowserPerfServiceServer).CollectErrorLogs(&browserPerfServiceCollectErrorLogsServer{stream})
+}
+
+type BrowserPerfService_CollectErrorLogsServer interface {
+	SendAndClose(*v3.Commands) error
+	Recv() (*BrowserErrorLog, error)
+	grpc.ServerStream
+}
+
+type browserPerfServiceCollectErrorLogsServer struct {
+	grpc.ServerStream
+}
+
+func (x *browserPerfServiceCollectErrorLogsServer) SendAndClose(m *v3.Commands) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *browserPerfServiceCollectErrorLogsServer) Recv() (*BrowserErrorLog, error) {
+	m := new(BrowserErrorLog)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+var _BrowserPerfService_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "skywalking.v3.BrowserPerfService",
+	HandlerType: (*BrowserPerfServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "collectPerfData",
+			Handler:    _BrowserPerfService_CollectPerfData_Handler,
+		},
+	},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "collectErrorLogs",
+			Handler:       _BrowserPerfService_CollectErrorLogs_Handler,
+			ClientStreams: true,
+		},
+	},
+	Metadata: "browser/BrowserPerf.proto",
+}
diff --git a/protocol/gen-codes/skywalking/network/language/agent/v3/CLRMetric.pb.go b/protocol/gen-codes/skywalking/network/language/agent/v3/CLRMetric.pb.go
new file mode 100644
index 0000000..53ce96d
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/language/agent/v3/CLRMetric.pb.go
@@ -0,0 +1,500 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.25.0
+// 	protoc        v3.14.0
+// source: language-agent/CLRMetric.proto
+
+package v3
+
+import (
+	proto "github.com/golang/protobuf/proto"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	v3 "skywalking/network/common/v3"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+type CLRMetricCollection struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Metrics         []*CLRMetric `protobuf:"bytes,1,rep,name=metrics,proto3" json:"metrics,omitempty"`
+	Service         string       `protobuf:"bytes,2,opt,name=service,proto3" json:"service,omitempty"`
+	ServiceInstance string       `protobuf:"bytes,3,opt,name=serviceInstance,proto3" json:"serviceInstance,omitempty"`
+}
+
+func (x *CLRMetricCollection) Reset() {
+	*x = CLRMetricCollection{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_CLRMetric_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CLRMetricCollection) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CLRMetricCollection) ProtoMessage() {}
+
+func (x *CLRMetricCollection) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_CLRMetric_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CLRMetricCollection.ProtoReflect.Descriptor instead.
+func (*CLRMetricCollection) Descriptor() ([]byte, []int) {
+	return file_language_agent_CLRMetric_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *CLRMetricCollection) GetMetrics() []*CLRMetric {
+	if x != nil {
+		return x.Metrics
+	}
+	return nil
+}
+
+func (x *CLRMetricCollection) GetService() string {
+	if x != nil {
+		return x.Service
+	}
+	return ""
+}
+
+func (x *CLRMetricCollection) GetServiceInstance() string {
+	if x != nil {
+		return x.ServiceInstance
+	}
+	return ""
+}
+
+type CLRMetric struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Time   int64      `protobuf:"varint,1,opt,name=time,proto3" json:"time,omitempty"`
+	Cpu    *v3.CPU    `protobuf:"bytes,2,opt,name=cpu,proto3" json:"cpu,omitempty"`
+	Gc     *ClrGC     `protobuf:"bytes,3,opt,name=gc,proto3" json:"gc,omitempty"`
+	Thread *ClrThread `protobuf:"bytes,4,opt,name=thread,proto3" json:"thread,omitempty"`
+}
+
+func (x *CLRMetric) Reset() {
+	*x = CLRMetric{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_CLRMetric_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CLRMetric) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CLRMetric) ProtoMessage() {}
+
+func (x *CLRMetric) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_CLRMetric_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CLRMetric.ProtoReflect.Descriptor instead.
+func (*CLRMetric) Descriptor() ([]byte, []int) {
+	return file_language_agent_CLRMetric_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *CLRMetric) GetTime() int64 {
+	if x != nil {
+		return x.Time
+	}
+	return 0
+}
+
+func (x *CLRMetric) GetCpu() *v3.CPU {
+	if x != nil {
+		return x.Cpu
+	}
+	return nil
+}
+
+func (x *CLRMetric) GetGc() *ClrGC {
+	if x != nil {
+		return x.Gc
+	}
+	return nil
+}
+
+func (x *CLRMetric) GetThread() *ClrThread {
+	if x != nil {
+		return x.Thread
+	}
+	return nil
+}
+
+type ClrGC struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Gen0CollectCount int64 `protobuf:"varint,1,opt,name=Gen0CollectCount,proto3" json:"Gen0CollectCount,omitempty"`
+	Gen1CollectCount int64 `protobuf:"varint,2,opt,name=Gen1CollectCount,proto3" json:"Gen1CollectCount,omitempty"`
+	Gen2CollectCount int64 `protobuf:"varint,3,opt,name=Gen2CollectCount,proto3" json:"Gen2CollectCount,omitempty"`
+	HeapMemory       int64 `protobuf:"varint,4,opt,name=HeapMemory,proto3" json:"HeapMemory,omitempty"`
+}
+
+func (x *ClrGC) Reset() {
+	*x = ClrGC{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_CLRMetric_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ClrGC) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ClrGC) ProtoMessage() {}
+
+func (x *ClrGC) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_CLRMetric_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ClrGC.ProtoReflect.Descriptor instead.
+func (*ClrGC) Descriptor() ([]byte, []int) {
+	return file_language_agent_CLRMetric_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *ClrGC) GetGen0CollectCount() int64 {
+	if x != nil {
+		return x.Gen0CollectCount
+	}
+	return 0
+}
+
+func (x *ClrGC) GetGen1CollectCount() int64 {
+	if x != nil {
+		return x.Gen1CollectCount
+	}
+	return 0
+}
+
+func (x *ClrGC) GetGen2CollectCount() int64 {
+	if x != nil {
+		return x.Gen2CollectCount
+	}
+	return 0
+}
+
+func (x *ClrGC) GetHeapMemory() int64 {
+	if x != nil {
+		return x.HeapMemory
+	}
+	return 0
+}
+
+type ClrThread struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	AvailableCompletionPortThreads int32 `protobuf:"varint,1,opt,name=AvailableCompletionPortThreads,proto3" json:"AvailableCompletionPortThreads,omitempty"`
+	AvailableWorkerThreads         int32 `protobuf:"varint,2,opt,name=AvailableWorkerThreads,proto3" json:"AvailableWorkerThreads,omitempty"`
+	MaxCompletionPortThreads       int32 `protobuf:"varint,3,opt,name=MaxCompletionPortThreads,proto3" json:"MaxCompletionPortThreads,omitempty"`
+	MaxWorkerThreads               int32 `protobuf:"varint,4,opt,name=MaxWorkerThreads,proto3" json:"MaxWorkerThreads,omitempty"`
+}
+
+func (x *ClrThread) Reset() {
+	*x = ClrThread{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_CLRMetric_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ClrThread) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ClrThread) ProtoMessage() {}
+
+func (x *ClrThread) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_CLRMetric_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ClrThread.ProtoReflect.Descriptor instead.
+func (*ClrThread) Descriptor() ([]byte, []int) {
+	return file_language_agent_CLRMetric_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *ClrThread) GetAvailableCompletionPortThreads() int32 {
+	if x != nil {
+		return x.AvailableCompletionPortThreads
+	}
+	return 0
+}
+
+func (x *ClrThread) GetAvailableWorkerThreads() int32 {
+	if x != nil {
+		return x.AvailableWorkerThreads
+	}
+	return 0
+}
+
+func (x *ClrThread) GetMaxCompletionPortThreads() int32 {
+	if x != nil {
+		return x.MaxCompletionPortThreads
+	}
+	return 0
+}
+
+func (x *ClrThread) GetMaxWorkerThreads() int32 {
+	if x != nil {
+		return x.MaxWorkerThreads
+	}
+	return 0
+}
+
+var File_language_agent_CLRMetric_proto protoreflect.FileDescriptor
+
+var file_language_agent_CLRMetric_proto_rawDesc = []byte{
+	0x0a, 0x1e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74,
+	0x2f, 0x43, 0x4c, 0x52, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x12, 0x0d, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x1a,
+	0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8d, 0x01, 0x0a, 0x13, 0x43, 0x4c, 0x52, 0x4d, 0x65, 0x74, 0x72,
+	0x69, 0x63, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x07,
+	0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e,
+	0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x4c,
+	0x52, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+	0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74,
+	0x61, 0x6e, 0x63, 0x65, 0x22, 0x9d, 0x01, 0x0a, 0x09, 0x43, 0x4c, 0x52, 0x4d, 0x65, 0x74, 0x72,
+	0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
+	0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67,
+	0x2e, 0x76, 0x33, 0x2e, 0x43, 0x50, 0x55, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x24, 0x0a, 0x02,
+	0x67, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61,
+	0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6c, 0x72, 0x47, 0x43, 0x52, 0x02,
+	0x67, 0x63, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e,
+	0x76, 0x33, 0x2e, 0x43, 0x6c, 0x72, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x52, 0x06, 0x74, 0x68,
+	0x72, 0x65, 0x61, 0x64, 0x22, 0xab, 0x01, 0x0a, 0x05, 0x43, 0x6c, 0x72, 0x47, 0x43, 0x12, 0x2a,
+	0x0a, 0x10, 0x47, 0x65, 0x6e, 0x30, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x75,
+	0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x47, 0x65, 0x6e, 0x30, 0x43, 0x6f,
+	0x6c, 0x6c, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x47, 0x65,
+	0x6e, 0x31, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x47, 0x65, 0x6e, 0x31, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
+	0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x32, 0x43, 0x6f,
+	0x6c, 0x6c, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03,
+	0x52, 0x10, 0x47, 0x65, 0x6e, 0x32, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x75,
+	0x6e, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x48, 0x65, 0x61, 0x70, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x48, 0x65, 0x61, 0x70, 0x4d, 0x65, 0x6d, 0x6f,
+	0x72, 0x79, 0x22, 0xf3, 0x01, 0x0a, 0x09, 0x43, 0x6c, 0x72, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64,
+	0x12, 0x46, 0x0a, 0x1e, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6d,
+	0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x54, 0x68, 0x72, 0x65, 0x61,
+	0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x1e, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61,
+	0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x72,
+	0x74, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x12, 0x36, 0x0a, 0x16, 0x41, 0x76, 0x61, 0x69,
+	0x6c, 0x61, 0x62, 0x6c, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x54, 0x68, 0x72, 0x65, 0x61,
+	0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x16, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61,
+	0x62, 0x6c, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73,
+	0x12, 0x3a, 0x0a, 0x18, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f,
+	0x6e, 0x50, 0x6f, 0x72, 0x74, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x05, 0x52, 0x18, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f,
+	0x6e, 0x50, 0x6f, 0x72, 0x74, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x10,
+	0x4d, 0x61, 0x78, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x4d, 0x61, 0x78, 0x57, 0x6f, 0x72, 0x6b, 0x65,
+	0x72, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x32, 0x62, 0x0a, 0x16, 0x43, 0x4c, 0x52, 0x4d,
+	0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x12, 0x48, 0x0a, 0x07, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x22, 0x2e,
+	0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x4c,
+	0x52, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f,
+	0x6e, 0x1a, 0x17, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76,
+	0x33, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x00, 0x42, 0x7d, 0x0a, 0x33,
+	0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61,
+	0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x61, 0x70, 0x6d, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+	0x6b, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74,
+	0x2e, 0x76, 0x33, 0x50, 0x01, 0x5a, 0x24, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e,
+	0x67, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61,
+	0x67, 0x65, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x76, 0x33, 0xaa, 0x02, 0x1d, 0x53, 0x6b,
+	0x79, 0x57, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+	0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x33,
+}
+
+var (
+	file_language_agent_CLRMetric_proto_rawDescOnce sync.Once
+	file_language_agent_CLRMetric_proto_rawDescData = file_language_agent_CLRMetric_proto_rawDesc
+)
+
+func file_language_agent_CLRMetric_proto_rawDescGZIP() []byte {
+	file_language_agent_CLRMetric_proto_rawDescOnce.Do(func() {
+		file_language_agent_CLRMetric_proto_rawDescData = protoimpl.X.CompressGZIP(file_language_agent_CLRMetric_proto_rawDescData)
+	})
+	return file_language_agent_CLRMetric_proto_rawDescData
+}
+
+var file_language_agent_CLRMetric_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_language_agent_CLRMetric_proto_goTypes = []interface{}{
+	(*CLRMetricCollection)(nil), // 0: skywalking.v3.CLRMetricCollection
+	(*CLRMetric)(nil),           // 1: skywalking.v3.CLRMetric
+	(*ClrGC)(nil),               // 2: skywalking.v3.ClrGC
+	(*ClrThread)(nil),           // 3: skywalking.v3.ClrThread
+	(*v3.CPU)(nil),              // 4: skywalking.v3.CPU
+	(*v3.Commands)(nil),         // 5: skywalking.v3.Commands
+}
+var file_language_agent_CLRMetric_proto_depIdxs = []int32{
+	1, // 0: skywalking.v3.CLRMetricCollection.metrics:type_name -> skywalking.v3.CLRMetric
+	4, // 1: skywalking.v3.CLRMetric.cpu:type_name -> skywalking.v3.CPU
+	2, // 2: skywalking.v3.CLRMetric.gc:type_name -> skywalking.v3.ClrGC
+	3, // 3: skywalking.v3.CLRMetric.thread:type_name -> skywalking.v3.ClrThread
+	0, // 4: skywalking.v3.CLRMetricReportService.collect:input_type -> skywalking.v3.CLRMetricCollection
+	5, // 5: skywalking.v3.CLRMetricReportService.collect:output_type -> skywalking.v3.Commands
+	5, // [5:6] is the sub-list for method output_type
+	4, // [4:5] is the sub-list for method input_type
+	4, // [4:4] is the sub-list for extension type_name
+	4, // [4:4] is the sub-list for extension extendee
+	0, // [0:4] is the sub-list for field type_name
+}
+
+func init() { file_language_agent_CLRMetric_proto_init() }
+func file_language_agent_CLRMetric_proto_init() {
+	if File_language_agent_CLRMetric_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_language_agent_CLRMetric_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CLRMetricCollection); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_CLRMetric_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CLRMetric); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_CLRMetric_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ClrGC); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_CLRMetric_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ClrThread); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_language_agent_CLRMetric_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   4,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_language_agent_CLRMetric_proto_goTypes,
+		DependencyIndexes: file_language_agent_CLRMetric_proto_depIdxs,
+		MessageInfos:      file_language_agent_CLRMetric_proto_msgTypes,
+	}.Build()
+	File_language_agent_CLRMetric_proto = out.File
+	file_language_agent_CLRMetric_proto_rawDesc = nil
+	file_language_agent_CLRMetric_proto_goTypes = nil
+	file_language_agent_CLRMetric_proto_depIdxs = nil
+}
diff --git a/protocol/gen-codes/skywalking/network/language/agent/v3/CLRMetric_grpc.pb.go b/protocol/gen-codes/skywalking/network/language/agent/v3/CLRMetric_grpc.pb.go
new file mode 100644
index 0000000..eced7ef
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/language/agent/v3/CLRMetric_grpc.pb.go
@@ -0,0 +1,99 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package v3
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	v3 "skywalking/network/common/v3"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion7
+
+// CLRMetricReportServiceClient is the client API for CLRMetricReportService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type CLRMetricReportServiceClient interface {
+	Collect(ctx context.Context, in *CLRMetricCollection, opts ...grpc.CallOption) (*v3.Commands, error)
+}
+
+type cLRMetricReportServiceClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewCLRMetricReportServiceClient(cc grpc.ClientConnInterface) CLRMetricReportServiceClient {
+	return &cLRMetricReportServiceClient{cc}
+}
+
+func (c *cLRMetricReportServiceClient) Collect(ctx context.Context, in *CLRMetricCollection, opts ...grpc.CallOption) (*v3.Commands, error) {
+	out := new(v3.Commands)
+	err := c.cc.Invoke(ctx, "/skywalking.v3.CLRMetricReportService/collect", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// CLRMetricReportServiceServer is the server API for CLRMetricReportService service.
+// All implementations must embed UnimplementedCLRMetricReportServiceServer
+// for forward compatibility
+type CLRMetricReportServiceServer interface {
+	Collect(context.Context, *CLRMetricCollection) (*v3.Commands, error)
+	mustEmbedUnimplementedCLRMetricReportServiceServer()
+}
+
+// UnimplementedCLRMetricReportServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedCLRMetricReportServiceServer struct {
+}
+
+func (UnimplementedCLRMetricReportServiceServer) Collect(context.Context, *CLRMetricCollection) (*v3.Commands, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method Collect not implemented")
+}
+func (UnimplementedCLRMetricReportServiceServer) mustEmbedUnimplementedCLRMetricReportServiceServer() {
+}
+
+// UnsafeCLRMetricReportServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to CLRMetricReportServiceServer will
+// result in compilation errors.
+type UnsafeCLRMetricReportServiceServer interface {
+	mustEmbedUnimplementedCLRMetricReportServiceServer()
+}
+
+func RegisterCLRMetricReportServiceServer(s grpc.ServiceRegistrar, srv CLRMetricReportServiceServer) {
+	s.RegisterService(&_CLRMetricReportService_serviceDesc, srv)
+}
+
+func _CLRMetricReportService_Collect_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(CLRMetricCollection)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CLRMetricReportServiceServer).Collect(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/skywalking.v3.CLRMetricReportService/collect",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CLRMetricReportServiceServer).Collect(ctx, req.(*CLRMetricCollection))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _CLRMetricReportService_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "skywalking.v3.CLRMetricReportService",
+	HandlerType: (*CLRMetricReportServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "collect",
+			Handler:    _CLRMetricReportService_Collect_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "language-agent/CLRMetric.proto",
+}
diff --git a/protocol/gen-codes/skywalking/network/language/agent/v3/JVMMetric.pb.go b/protocol/gen-codes/skywalking/network/language/agent/v3/JVMMetric.pb.go
new file mode 100644
index 0000000..e322cf4
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/language/agent/v3/JVMMetric.pb.go
@@ -0,0 +1,815 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.25.0
+// 	protoc        v3.14.0
+// source: language-agent/JVMMetric.proto
+
+package v3
+
+import (
+	proto "github.com/golang/protobuf/proto"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	v3 "skywalking/network/common/v3"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+type PoolType int32
+
+const (
+	PoolType_CODE_CACHE_USAGE PoolType = 0
+	PoolType_NEWGEN_USAGE     PoolType = 1
+	PoolType_OLDGEN_USAGE     PoolType = 2
+	PoolType_SURVIVOR_USAGE   PoolType = 3
+	PoolType_PERMGEN_USAGE    PoolType = 4
+	PoolType_METASPACE_USAGE  PoolType = 5
+)
+
+// Enum value maps for PoolType.
+var (
+	PoolType_name = map[int32]string{
+		0: "CODE_CACHE_USAGE",
+		1: "NEWGEN_USAGE",
+		2: "OLDGEN_USAGE",
+		3: "SURVIVOR_USAGE",
+		4: "PERMGEN_USAGE",
+		5: "METASPACE_USAGE",
+	}
+	PoolType_value = map[string]int32{
+		"CODE_CACHE_USAGE": 0,
+		"NEWGEN_USAGE":     1,
+		"OLDGEN_USAGE":     2,
+		"SURVIVOR_USAGE":   3,
+		"PERMGEN_USAGE":    4,
+		"METASPACE_USAGE":  5,
+	}
+)
+
+func (x PoolType) Enum() *PoolType {
+	p := new(PoolType)
+	*p = x
+	return p
+}
+
+func (x PoolType) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (PoolType) Descriptor() protoreflect.EnumDescriptor {
+	return file_language_agent_JVMMetric_proto_enumTypes[0].Descriptor()
+}
+
+func (PoolType) Type() protoreflect.EnumType {
+	return &file_language_agent_JVMMetric_proto_enumTypes[0]
+}
+
+func (x PoolType) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use PoolType.Descriptor instead.
+func (PoolType) EnumDescriptor() ([]byte, []int) {
+	return file_language_agent_JVMMetric_proto_rawDescGZIP(), []int{0}
+}
+
+type GCPhrase int32
+
+const (
+	GCPhrase_NEW GCPhrase = 0
+	GCPhrase_OLD GCPhrase = 1
+)
+
+// Enum value maps for GCPhrase.
+var (
+	GCPhrase_name = map[int32]string{
+		0: "NEW",
+		1: "OLD",
+	}
+	GCPhrase_value = map[string]int32{
+		"NEW": 0,
+		"OLD": 1,
+	}
+)
+
+func (x GCPhrase) Enum() *GCPhrase {
+	p := new(GCPhrase)
+	*p = x
+	return p
+}
+
+func (x GCPhrase) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (GCPhrase) Descriptor() protoreflect.EnumDescriptor {
+	return file_language_agent_JVMMetric_proto_enumTypes[1].Descriptor()
+}
+
+func (GCPhrase) Type() protoreflect.EnumType {
+	return &file_language_agent_JVMMetric_proto_enumTypes[1]
+}
+
+func (x GCPhrase) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use GCPhrase.Descriptor instead.
+func (GCPhrase) EnumDescriptor() ([]byte, []int) {
+	return file_language_agent_JVMMetric_proto_rawDescGZIP(), []int{1}
+}
+
+type JVMMetricCollection struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Metrics         []*JVMMetric `protobuf:"bytes,1,rep,name=metrics,proto3" json:"metrics,omitempty"`
+	Service         string       `protobuf:"bytes,2,opt,name=service,proto3" json:"service,omitempty"`
+	ServiceInstance string       `protobuf:"bytes,3,opt,name=serviceInstance,proto3" json:"serviceInstance,omitempty"`
+}
+
+func (x *JVMMetricCollection) Reset() {
+	*x = JVMMetricCollection{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_JVMMetric_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *JVMMetricCollection) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*JVMMetricCollection) ProtoMessage() {}
+
+func (x *JVMMetricCollection) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_JVMMetric_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use JVMMetricCollection.ProtoReflect.Descriptor instead.
+func (*JVMMetricCollection) Descriptor() ([]byte, []int) {
+	return file_language_agent_JVMMetric_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *JVMMetricCollection) GetMetrics() []*JVMMetric {
+	if x != nil {
+		return x.Metrics
+	}
+	return nil
+}
+
+func (x *JVMMetricCollection) GetService() string {
+	if x != nil {
+		return x.Service
+	}
+	return ""
+}
+
+func (x *JVMMetricCollection) GetServiceInstance() string {
+	if x != nil {
+		return x.ServiceInstance
+	}
+	return ""
+}
+
+type JVMMetric struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Time       int64         `protobuf:"varint,1,opt,name=time,proto3" json:"time,omitempty"`
+	Cpu        *v3.CPU       `protobuf:"bytes,2,opt,name=cpu,proto3" json:"cpu,omitempty"`
+	Memory     []*Memory     `protobuf:"bytes,3,rep,name=memory,proto3" json:"memory,omitempty"`
+	MemoryPool []*MemoryPool `protobuf:"bytes,4,rep,name=memoryPool,proto3" json:"memoryPool,omitempty"`
+	Gc         []*GC         `protobuf:"bytes,5,rep,name=gc,proto3" json:"gc,omitempty"`
+	Thread     *Thread       `protobuf:"bytes,6,opt,name=thread,proto3" json:"thread,omitempty"`
+}
+
+func (x *JVMMetric) Reset() {
+	*x = JVMMetric{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_JVMMetric_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *JVMMetric) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*JVMMetric) ProtoMessage() {}
+
+func (x *JVMMetric) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_JVMMetric_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use JVMMetric.ProtoReflect.Descriptor instead.
+func (*JVMMetric) Descriptor() ([]byte, []int) {
+	return file_language_agent_JVMMetric_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *JVMMetric) GetTime() int64 {
+	if x != nil {
+		return x.Time
+	}
+	return 0
+}
+
+func (x *JVMMetric) GetCpu() *v3.CPU {
+	if x != nil {
+		return x.Cpu
+	}
+	return nil
+}
+
+func (x *JVMMetric) GetMemory() []*Memory {
+	if x != nil {
+		return x.Memory
+	}
+	return nil
+}
+
+func (x *JVMMetric) GetMemoryPool() []*MemoryPool {
+	if x != nil {
+		return x.MemoryPool
+	}
+	return nil
+}
+
+func (x *JVMMetric) GetGc() []*GC {
+	if x != nil {
+		return x.Gc
+	}
+	return nil
+}
+
+func (x *JVMMetric) GetThread() *Thread {
+	if x != nil {
+		return x.Thread
+	}
+	return nil
+}
+
+type Memory struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	IsHeap    bool  `protobuf:"varint,1,opt,name=isHeap,proto3" json:"isHeap,omitempty"`
+	Init      int64 `protobuf:"varint,2,opt,name=init,proto3" json:"init,omitempty"`
+	Max       int64 `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty"`
+	Used      int64 `protobuf:"varint,4,opt,name=used,proto3" json:"used,omitempty"`
+	Committed int64 `protobuf:"varint,5,opt,name=committed,proto3" json:"committed,omitempty"`
+}
+
+func (x *Memory) Reset() {
+	*x = Memory{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_JVMMetric_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Memory) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Memory) ProtoMessage() {}
+
+func (x *Memory) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_JVMMetric_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Memory.ProtoReflect.Descriptor instead.
+func (*Memory) Descriptor() ([]byte, []int) {
+	return file_language_agent_JVMMetric_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *Memory) GetIsHeap() bool {
+	if x != nil {
+		return x.IsHeap
+	}
+	return false
+}
+
+func (x *Memory) GetInit() int64 {
+	if x != nil {
+		return x.Init
+	}
+	return 0
+}
+
+func (x *Memory) GetMax() int64 {
+	if x != nil {
+		return x.Max
+	}
+	return 0
+}
+
+func (x *Memory) GetUsed() int64 {
+	if x != nil {
+		return x.Used
+	}
+	return 0
+}
+
+func (x *Memory) GetCommitted() int64 {
+	if x != nil {
+		return x.Committed
+	}
+	return 0
+}
+
+type MemoryPool struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Type      PoolType `protobuf:"varint,1,opt,name=type,proto3,enum=skywalking.v3.PoolType" json:"type,omitempty"`
+	Init      int64    `protobuf:"varint,2,opt,name=init,proto3" json:"init,omitempty"`
+	Max       int64    `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty"`
+	Used      int64    `protobuf:"varint,4,opt,name=used,proto3" json:"used,omitempty"`
+	Committed int64    `protobuf:"varint,5,opt,name=committed,proto3" json:"committed,omitempty"`
+}
+
+func (x *MemoryPool) Reset() {
+	*x = MemoryPool{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_JVMMetric_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *MemoryPool) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MemoryPool) ProtoMessage() {}
+
+func (x *MemoryPool) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_JVMMetric_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use MemoryPool.ProtoReflect.Descriptor instead.
+func (*MemoryPool) Descriptor() ([]byte, []int) {
+	return file_language_agent_JVMMetric_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *MemoryPool) GetType() PoolType {
+	if x != nil {
+		return x.Type
+	}
+	return PoolType_CODE_CACHE_USAGE
+}
+
+func (x *MemoryPool) GetInit() int64 {
+	if x != nil {
+		return x.Init
+	}
+	return 0
+}
+
+func (x *MemoryPool) GetMax() int64 {
+	if x != nil {
+		return x.Max
+	}
+	return 0
+}
+
+func (x *MemoryPool) GetUsed() int64 {
+	if x != nil {
+		return x.Used
+	}
+	return 0
+}
+
+func (x *MemoryPool) GetCommitted() int64 {
+	if x != nil {
+		return x.Committed
+	}
+	return 0
+}
+
+type GC struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Phrase GCPhrase `protobuf:"varint,1,opt,name=phrase,proto3,enum=skywalking.v3.GCPhrase" json:"phrase,omitempty"`
+	Count  int64    `protobuf:"varint,2,opt,name=count,proto3" json:"count,omitempty"`
+	Time   int64    `protobuf:"varint,3,opt,name=time,proto3" json:"time,omitempty"`
+}
+
+func (x *GC) Reset() {
+	*x = GC{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_JVMMetric_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GC) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GC) ProtoMessage() {}
+
+func (x *GC) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_JVMMetric_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GC.ProtoReflect.Descriptor instead.
+func (*GC) Descriptor() ([]byte, []int) {
+	return file_language_agent_JVMMetric_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *GC) GetPhrase() GCPhrase {
+	if x != nil {
+		return x.Phrase
+	}
+	return GCPhrase_NEW
+}
+
+func (x *GC) GetCount() int64 {
+	if x != nil {
+		return x.Count
+	}
+	return 0
+}
+
+func (x *GC) GetTime() int64 {
+	if x != nil {
+		return x.Time
+	}
+	return 0
+}
+
+type Thread struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	LiveCount   int64 `protobuf:"varint,1,opt,name=liveCount,proto3" json:"liveCount,omitempty"`
+	DaemonCount int64 `protobuf:"varint,2,opt,name=daemonCount,proto3" json:"daemonCount,omitempty"`
+	PeakCount   int64 `protobuf:"varint,3,opt,name=peakCount,proto3" json:"peakCount,omitempty"`
+}
+
+func (x *Thread) Reset() {
+	*x = Thread{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_JVMMetric_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Thread) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Thread) ProtoMessage() {}
+
+func (x *Thread) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_JVMMetric_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Thread.ProtoReflect.Descriptor instead.
+func (*Thread) Descriptor() ([]byte, []int) {
+	return file_language_agent_JVMMetric_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *Thread) GetLiveCount() int64 {
+	if x != nil {
+		return x.LiveCount
+	}
+	return 0
+}
+
+func (x *Thread) GetDaemonCount() int64 {
+	if x != nil {
+		return x.DaemonCount
+	}
+	return 0
+}
+
+func (x *Thread) GetPeakCount() int64 {
+	if x != nil {
+		return x.PeakCount
+	}
+	return 0
+}
+
+var File_language_agent_JVMMetric_proto protoreflect.FileDescriptor
+
+var file_language_agent_JVMMetric_proto_rawDesc = []byte{
+	0x0a, 0x1e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74,
+	0x2f, 0x4a, 0x56, 0x4d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x12, 0x0d, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x1a,
+	0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8d, 0x01, 0x0a, 0x13, 0x4a, 0x56, 0x4d, 0x4d, 0x65, 0x74, 0x72,
+	0x69, 0x63, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x07,
+	0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e,
+	0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4a, 0x56,
+	0x4d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+	0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74,
+	0x61, 0x6e, 0x63, 0x65, 0x22, 0x81, 0x02, 0x0a, 0x09, 0x4a, 0x56, 0x4d, 0x4d, 0x65, 0x74, 0x72,
+	0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
+	0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67,
+	0x2e, 0x76, 0x33, 0x2e, 0x43, 0x50, 0x55, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x2d, 0x0a, 0x06,
+	0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73,
+	0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x65, 0x6d,
+	0x6f, 0x72, 0x79, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x6d,
+	0x65, 0x6d, 0x6f, 0x72, 0x79, 0x50, 0x6f, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x19, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e,
+	0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x6f,
+	0x72, 0x79, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x21, 0x0a, 0x02, 0x67, 0x63, 0x18, 0x05, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e,
+	0x76, 0x33, 0x2e, 0x47, 0x43, 0x52, 0x02, 0x67, 0x63, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x68, 0x72,
+	0x65, 0x61, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x6b, 0x79, 0x77,
+	0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64,
+	0x52, 0x06, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x22, 0x78, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x6f,
+	0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x48, 0x65, 0x61, 0x70, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x48, 0x65, 0x61, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e,
+	0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x12, 0x10,
+	0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6d, 0x61, 0x78,
+	0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04,
+	0x75, 0x73, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65,
+	0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74,
+	0x65, 0x64, 0x22, 0x91, 0x01, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x50, 0x6f, 0x6f,
+	0x6c, 0x12, 0x2b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
+	0x17, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e,
+	0x50, 0x6f, 0x6f, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12,
+	0x0a, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x69, 0x6e,
+	0x69, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
+	0x03, 0x6d, 0x61, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x03, 0x52, 0x04, 0x75, 0x73, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d,
+	0x69, 0x74, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6f, 0x6d,
+	0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x22, 0x5f, 0x0a, 0x02, 0x47, 0x43, 0x12, 0x2f, 0x0a, 0x06,
+	0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x73,
+	0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x43, 0x50,
+	0x68, 0x72, 0x61, 0x73, 0x65, 0x52, 0x06, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, 0x14, 0x0a,
+	0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f,
+	0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x66, 0x0a, 0x06, 0x54, 0x68, 0x72, 0x65, 0x61,
+	0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6c, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12,
+	0x20, 0x0a, 0x0b, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e,
+	0x74, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x65, 0x61, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x70, 0x65, 0x61, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x2a,
+	0x80, 0x01, 0x0a, 0x08, 0x50, 0x6f, 0x6f, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10,
+	0x43, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x5f, 0x55, 0x53, 0x41, 0x47, 0x45,
+	0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x4e, 0x45, 0x57, 0x47, 0x45, 0x4e, 0x5f, 0x55, 0x53, 0x41,
+	0x47, 0x45, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x4c, 0x44, 0x47, 0x45, 0x4e, 0x5f, 0x55,
+	0x53, 0x41, 0x47, 0x45, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x55, 0x52, 0x56, 0x49, 0x56,
+	0x4f, 0x52, 0x5f, 0x55, 0x53, 0x41, 0x47, 0x45, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x45,
+	0x52, 0x4d, 0x47, 0x45, 0x4e, 0x5f, 0x55, 0x53, 0x41, 0x47, 0x45, 0x10, 0x04, 0x12, 0x13, 0x0a,
+	0x0f, 0x4d, 0x45, 0x54, 0x41, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x55, 0x53, 0x41, 0x47, 0x45,
+	0x10, 0x05, 0x2a, 0x1c, 0x0a, 0x08, 0x47, 0x43, 0x50, 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, 0x07,
+	0x0a, 0x03, 0x4e, 0x45, 0x57, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x4c, 0x44, 0x10, 0x01,
+	0x32, 0x62, 0x0a, 0x16, 0x4a, 0x56, 0x4d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x65, 0x70,
+	0x6f, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x07, 0x63, 0x6f,
+	0x6c, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x22, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69,
+	0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4a, 0x56, 0x4d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x43,
+	0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x17, 0x2e, 0x73, 0x6b, 0x79, 0x77,
+	0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+	0x64, 0x73, 0x22, 0x00, 0x42, 0x7d, 0x0a, 0x33, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63,
+	0x68, 0x65, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x61, 0x70,
+	0x6d, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61,
+	0x67, 0x65, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x33, 0x50, 0x01, 0x5a, 0x24, 0x73,
+	0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+	0x6b, 0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74,
+	0x2f, 0x76, 0x33, 0xaa, 0x02, 0x1d, 0x53, 0x6b, 0x79, 0x57, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67,
+	0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
+	0x2e, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_language_agent_JVMMetric_proto_rawDescOnce sync.Once
+	file_language_agent_JVMMetric_proto_rawDescData = file_language_agent_JVMMetric_proto_rawDesc
+)
+
+func file_language_agent_JVMMetric_proto_rawDescGZIP() []byte {
+	file_language_agent_JVMMetric_proto_rawDescOnce.Do(func() {
+		file_language_agent_JVMMetric_proto_rawDescData = protoimpl.X.CompressGZIP(file_language_agent_JVMMetric_proto_rawDescData)
+	})
+	return file_language_agent_JVMMetric_proto_rawDescData
+}
+
+var file_language_agent_JVMMetric_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
+var file_language_agent_JVMMetric_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
+var file_language_agent_JVMMetric_proto_goTypes = []interface{}{
+	(PoolType)(0),               // 0: skywalking.v3.PoolType
+	(GCPhrase)(0),               // 1: skywalking.v3.GCPhrase
+	(*JVMMetricCollection)(nil), // 2: skywalking.v3.JVMMetricCollection
+	(*JVMMetric)(nil),           // 3: skywalking.v3.JVMMetric
+	(*Memory)(nil),              // 4: skywalking.v3.Memory
+	(*MemoryPool)(nil),          // 5: skywalking.v3.MemoryPool
+	(*GC)(nil),                  // 6: skywalking.v3.GC
+	(*Thread)(nil),              // 7: skywalking.v3.Thread
+	(*v3.CPU)(nil),              // 8: skywalking.v3.CPU
+	(*v3.Commands)(nil),         // 9: skywalking.v3.Commands
+}
+var file_language_agent_JVMMetric_proto_depIdxs = []int32{
+	3, // 0: skywalking.v3.JVMMetricCollection.metrics:type_name -> skywalking.v3.JVMMetric
+	8, // 1: skywalking.v3.JVMMetric.cpu:type_name -> skywalking.v3.CPU
+	4, // 2: skywalking.v3.JVMMetric.memory:type_name -> skywalking.v3.Memory
+	5, // 3: skywalking.v3.JVMMetric.memoryPool:type_name -> skywalking.v3.MemoryPool
+	6, // 4: skywalking.v3.JVMMetric.gc:type_name -> skywalking.v3.GC
+	7, // 5: skywalking.v3.JVMMetric.thread:type_name -> skywalking.v3.Thread
+	0, // 6: skywalking.v3.MemoryPool.type:type_name -> skywalking.v3.PoolType
+	1, // 7: skywalking.v3.GC.phrase:type_name -> skywalking.v3.GCPhrase
+	2, // 8: skywalking.v3.JVMMetricReportService.collect:input_type -> skywalking.v3.JVMMetricCollection
+	9, // 9: skywalking.v3.JVMMetricReportService.collect:output_type -> skywalking.v3.Commands
+	9, // [9:10] is the sub-list for method output_type
+	8, // [8:9] is the sub-list for method input_type
+	8, // [8:8] is the sub-list for extension type_name
+	8, // [8:8] is the sub-list for extension extendee
+	0, // [0:8] is the sub-list for field type_name
+}
+
+func init() { file_language_agent_JVMMetric_proto_init() }
+func file_language_agent_JVMMetric_proto_init() {
+	if File_language_agent_JVMMetric_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_language_agent_JVMMetric_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*JVMMetricCollection); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_JVMMetric_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*JVMMetric); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_JVMMetric_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Memory); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_JVMMetric_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MemoryPool); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_JVMMetric_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GC); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_JVMMetric_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Thread); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_language_agent_JVMMetric_proto_rawDesc,
+			NumEnums:      2,
+			NumMessages:   6,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_language_agent_JVMMetric_proto_goTypes,
+		DependencyIndexes: file_language_agent_JVMMetric_proto_depIdxs,
+		EnumInfos:         file_language_agent_JVMMetric_proto_enumTypes,
+		MessageInfos:      file_language_agent_JVMMetric_proto_msgTypes,
+	}.Build()
+	File_language_agent_JVMMetric_proto = out.File
+	file_language_agent_JVMMetric_proto_rawDesc = nil
+	file_language_agent_JVMMetric_proto_goTypes = nil
+	file_language_agent_JVMMetric_proto_depIdxs = nil
+}
diff --git a/protocol/gen-codes/skywalking/network/language/agent/v3/JVMMetric_grpc.pb.go b/protocol/gen-codes/skywalking/network/language/agent/v3/JVMMetric_grpc.pb.go
new file mode 100644
index 0000000..3b6b0d4
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/language/agent/v3/JVMMetric_grpc.pb.go
@@ -0,0 +1,99 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package v3
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	v3 "skywalking/network/common/v3"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion7
+
+// JVMMetricReportServiceClient is the client API for JVMMetricReportService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type JVMMetricReportServiceClient interface {
+	Collect(ctx context.Context, in *JVMMetricCollection, opts ...grpc.CallOption) (*v3.Commands, error)
+}
+
+type jVMMetricReportServiceClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewJVMMetricReportServiceClient(cc grpc.ClientConnInterface) JVMMetricReportServiceClient {
+	return &jVMMetricReportServiceClient{cc}
+}
+
+func (c *jVMMetricReportServiceClient) Collect(ctx context.Context, in *JVMMetricCollection, opts ...grpc.CallOption) (*v3.Commands, error) {
+	out := new(v3.Commands)
+	err := c.cc.Invoke(ctx, "/skywalking.v3.JVMMetricReportService/collect", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// JVMMetricReportServiceServer is the server API for JVMMetricReportService service.
+// All implementations must embed UnimplementedJVMMetricReportServiceServer
+// for forward compatibility
+type JVMMetricReportServiceServer interface {
+	Collect(context.Context, *JVMMetricCollection) (*v3.Commands, error)
+	mustEmbedUnimplementedJVMMetricReportServiceServer()
+}
+
+// UnimplementedJVMMetricReportServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedJVMMetricReportServiceServer struct {
+}
+
+func (UnimplementedJVMMetricReportServiceServer) Collect(context.Context, *JVMMetricCollection) (*v3.Commands, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method Collect not implemented")
+}
+func (UnimplementedJVMMetricReportServiceServer) mustEmbedUnimplementedJVMMetricReportServiceServer() {
+}
+
+// UnsafeJVMMetricReportServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to JVMMetricReportServiceServer will
+// result in compilation errors.
+type UnsafeJVMMetricReportServiceServer interface {
+	mustEmbedUnimplementedJVMMetricReportServiceServer()
+}
+
+func RegisterJVMMetricReportServiceServer(s grpc.ServiceRegistrar, srv JVMMetricReportServiceServer) {
+	s.RegisterService(&_JVMMetricReportService_serviceDesc, srv)
+}
+
+func _JVMMetricReportService_Collect_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(JVMMetricCollection)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(JVMMetricReportServiceServer).Collect(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/skywalking.v3.JVMMetricReportService/collect",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(JVMMetricReportServiceServer).Collect(ctx, req.(*JVMMetricCollection))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _JVMMetricReportService_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "skywalking.v3.JVMMetricReportService",
+	HandlerType: (*JVMMetricReportServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "collect",
+			Handler:    _JVMMetricReportService_Collect_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "language-agent/JVMMetric.proto",
+}
diff --git a/protocol/gen-codes/skywalking/network/language/agent/v3/Meter.pb.go b/protocol/gen-codes/skywalking/network/language/agent/v3/Meter.pb.go
new file mode 100644
index 0000000..fa944d4
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/language/agent/v3/Meter.pb.go
@@ -0,0 +1,657 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.25.0
+// 	protoc        v3.14.0
+// source: language-agent/Meter.proto
+
+package v3
+
+import (
+	proto "github.com/golang/protobuf/proto"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	v3 "skywalking/network/common/v3"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+// Label of the meter
+type Label struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name  string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (x *Label) Reset() {
+	*x = Label{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_Meter_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Label) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Label) ProtoMessage() {}
+
+func (x *Label) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_Meter_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Label.ProtoReflect.Descriptor instead.
+func (*Label) Descriptor() ([]byte, []int) {
+	return file_language_agent_Meter_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Label) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *Label) GetValue() string {
+	if x != nil {
+		return x.Value
+	}
+	return ""
+}
+
+// The histogram element definition. It includes the bucket lower boundary and the count in the bucket.
+type MeterBucketValue struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The value represents the min value of the bucket,
+	// the  upper boundary is determined by next MeterBucketValue$bucket,
+	// if it doesn't exist, the upper boundary is positive infinity.
+	// Also, could use Int32.MIN_VALUE to represent negative infinity.
+	Bucket float64 `protobuf:"fixed64,1,opt,name=bucket,proto3" json:"bucket,omitempty"`
+	Count  int64   `protobuf:"varint,2,opt,name=count,proto3" json:"count,omitempty"`
+}
+
+func (x *MeterBucketValue) Reset() {
+	*x = MeterBucketValue{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_Meter_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *MeterBucketValue) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MeterBucketValue) ProtoMessage() {}
+
+func (x *MeterBucketValue) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_Meter_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use MeterBucketValue.ProtoReflect.Descriptor instead.
+func (*MeterBucketValue) Descriptor() ([]byte, []int) {
+	return file_language_agent_Meter_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *MeterBucketValue) GetBucket() float64 {
+	if x != nil {
+		return x.Bucket
+	}
+	return 0
+}
+
+func (x *MeterBucketValue) GetCount() int64 {
+	if x != nil {
+		return x.Count
+	}
+	return 0
+}
+
+// Meter single value
+type MeterSingleValue struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Meter name
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	// Labels
+	Labels []*Label `protobuf:"bytes,2,rep,name=labels,proto3" json:"labels,omitempty"`
+	// Single value
+	Value float64 `protobuf:"fixed64,3,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (x *MeterSingleValue) Reset() {
+	*x = MeterSingleValue{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_Meter_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *MeterSingleValue) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MeterSingleValue) ProtoMessage() {}
+
+func (x *MeterSingleValue) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_Meter_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use MeterSingleValue.ProtoReflect.Descriptor instead.
+func (*MeterSingleValue) Descriptor() ([]byte, []int) {
+	return file_language_agent_Meter_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *MeterSingleValue) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *MeterSingleValue) GetLabels() []*Label {
+	if x != nil {
+		return x.Labels
+	}
+	return nil
+}
+
+func (x *MeterSingleValue) GetValue() float64 {
+	if x != nil {
+		return x.Value
+	}
+	return 0
+}
+
+// Histogram
+type MeterHistogram struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Meter name
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	// Labels
+	Labels []*Label `protobuf:"bytes,2,rep,name=labels,proto3" json:"labels,omitempty"`
+	// Customize the buckets
+	Values []*MeterBucketValue `protobuf:"bytes,3,rep,name=values,proto3" json:"values,omitempty"`
+}
+
+func (x *MeterHistogram) Reset() {
+	*x = MeterHistogram{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_Meter_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *MeterHistogram) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MeterHistogram) ProtoMessage() {}
+
+func (x *MeterHistogram) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_Meter_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use MeterHistogram.ProtoReflect.Descriptor instead.
+func (*MeterHistogram) Descriptor() ([]byte, []int) {
+	return file_language_agent_Meter_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *MeterHistogram) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *MeterHistogram) GetLabels() []*Label {
+	if x != nil {
+		return x.Labels
+	}
+	return nil
+}
+
+func (x *MeterHistogram) GetValues() []*MeterBucketValue {
+	if x != nil {
+		return x.Values
+	}
+	return nil
+}
+
+// Single meter data, if the same metrics have a different label, they will separate.
+type MeterData struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Meter data could be a single value or histogram.
+	//
+	// Types that are assignable to Metric:
+	//	*MeterData_SingleValue
+	//	*MeterData_Histogram
+	Metric isMeterData_Metric `protobuf_oneof:"metric"`
+	// Service name, be set value in the first element in the stream-call.
+	Service string `protobuf:"bytes,3,opt,name=service,proto3" json:"service,omitempty"`
+	// Service instance name, be set value in the first element in the stream-call.
+	ServiceInstance string `protobuf:"bytes,4,opt,name=serviceInstance,proto3" json:"serviceInstance,omitempty"`
+	// Meter data report time, be set value in the first element in the stream-call.
+	Timestamp int64 `protobuf:"varint,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+}
+
+func (x *MeterData) Reset() {
+	*x = MeterData{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_Meter_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *MeterData) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MeterData) ProtoMessage() {}
+
+func (x *MeterData) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_Meter_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use MeterData.ProtoReflect.Descriptor instead.
+func (*MeterData) Descriptor() ([]byte, []int) {
+	return file_language_agent_Meter_proto_rawDescGZIP(), []int{4}
+}
+
+func (m *MeterData) GetMetric() isMeterData_Metric {
+	if m != nil {
+		return m.Metric
+	}
+	return nil
+}
+
+func (x *MeterData) GetSingleValue() *MeterSingleValue {
+	if x, ok := x.GetMetric().(*MeterData_SingleValue); ok {
+		return x.SingleValue
+	}
+	return nil
+}
+
+func (x *MeterData) GetHistogram() *MeterHistogram {
+	if x, ok := x.GetMetric().(*MeterData_Histogram); ok {
+		return x.Histogram
+	}
+	return nil
+}
+
+func (x *MeterData) GetService() string {
+	if x != nil {
+		return x.Service
+	}
+	return ""
+}
+
+func (x *MeterData) GetServiceInstance() string {
+	if x != nil {
+		return x.ServiceInstance
+	}
+	return ""
+}
+
+func (x *MeterData) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+type isMeterData_Metric interface {
+	isMeterData_Metric()
+}
+
+type MeterData_SingleValue struct {
+	SingleValue *MeterSingleValue `protobuf:"bytes,1,opt,name=singleValue,proto3,oneof"`
+}
+
+type MeterData_Histogram struct {
+	Histogram *MeterHistogram `protobuf:"bytes,2,opt,name=histogram,proto3,oneof"`
+}
+
+func (*MeterData_SingleValue) isMeterData_Metric() {}
+
+func (*MeterData_Histogram) isMeterData_Metric() {}
+
+type MeterDataCollection struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	MeterData []*MeterData `protobuf:"bytes,1,rep,name=meterData,proto3" json:"meterData,omitempty"`
+}
+
+func (x *MeterDataCollection) Reset() {
+	*x = MeterDataCollection{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_Meter_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *MeterDataCollection) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MeterDataCollection) ProtoMessage() {}
+
+func (x *MeterDataCollection) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_Meter_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use MeterDataCollection.ProtoReflect.Descriptor instead.
+func (*MeterDataCollection) Descriptor() ([]byte, []int) {
+	return file_language_agent_Meter_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *MeterDataCollection) GetMeterData() []*MeterData {
+	if x != nil {
+		return x.MeterData
+	}
+	return nil
+}
+
+var File_language_agent_Meter_proto protoreflect.FileDescriptor
+
+var file_language_agent_Meter_proto_rawDesc = []byte{
+	0x0a, 0x1a, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74,
+	0x2f, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x73, 0x6b,
+	0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x1a, 0x13, 0x63, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x2f, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x22, 0x31, 0x0a, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a,
+	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61,
+	0x6c, 0x75, 0x65, 0x22, 0x40, 0x0a, 0x10, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x42, 0x75, 0x63, 0x6b,
+	0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65,
+	0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12,
+	0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05,
+	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x6a, 0x0a, 0x10, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x69,
+	0x6e, 0x67, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a,
+	0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e,
+	0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x61,
+	0x62, 0x65, 0x6c, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76,
+	0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
+	0x65, 0x22, 0x8b, 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x48, 0x69, 0x73, 0x74, 0x6f,
+	0x67, 0x72, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65,
+	0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61,
+	0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x06,
+	0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73,
+	0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b,
+	0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x42, 0x75, 0x63, 0x6b,
+	0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22,
+	0xfb, 0x01, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x43, 0x0a,
+	0x0b, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e,
+	0x76, 0x33, 0x2e, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x56, 0x61,
+	0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x56, 0x61, 0x6c,
+	0x75, 0x65, 0x12, 0x3d, 0x0a, 0x09, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69,
+	0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x48, 0x69, 0x73, 0x74, 0x6f,
+	0x67, 0x72, 0x61, 0x6d, 0x48, 0x00, 0x52, 0x09, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61,
+	0x6d, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x73,
+	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x73,
+	0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
+	0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
+	0x61, 0x6d, 0x70, 0x42, 0x08, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x22, 0x4d, 0x0a,
+	0x13, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
+	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x09, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74,
+	0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c,
+	0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74,
+	0x61, 0x52, 0x09, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x32, 0x56, 0x0a, 0x12,
+	0x4d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x12, 0x40, 0x0a, 0x07, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x18, 0x2e,
+	0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x65,
+	0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x17, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c,
+	0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73,
+	0x22, 0x00, 0x28, 0x01, 0x42, 0x5d, 0x0a, 0x33, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63,
+	0x68, 0x65, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x61, 0x70,
+	0x6d, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61,
+	0x67, 0x65, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x33, 0x50, 0x01, 0x5a, 0x24, 0x73,
+	0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+	0x6b, 0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74,
+	0x2f, 0x76, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_language_agent_Meter_proto_rawDescOnce sync.Once
+	file_language_agent_Meter_proto_rawDescData = file_language_agent_Meter_proto_rawDesc
+)
+
+func file_language_agent_Meter_proto_rawDescGZIP() []byte {
+	file_language_agent_Meter_proto_rawDescOnce.Do(func() {
+		file_language_agent_Meter_proto_rawDescData = protoimpl.X.CompressGZIP(file_language_agent_Meter_proto_rawDescData)
+	})
+	return file_language_agent_Meter_proto_rawDescData
+}
+
+var file_language_agent_Meter_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
+var file_language_agent_Meter_proto_goTypes = []interface{}{
+	(*Label)(nil),               // 0: skywalking.v3.Label
+	(*MeterBucketValue)(nil),    // 1: skywalking.v3.MeterBucketValue
+	(*MeterSingleValue)(nil),    // 2: skywalking.v3.MeterSingleValue
+	(*MeterHistogram)(nil),      // 3: skywalking.v3.MeterHistogram
+	(*MeterData)(nil),           // 4: skywalking.v3.MeterData
+	(*MeterDataCollection)(nil), // 5: skywalking.v3.MeterDataCollection
+	(*v3.Commands)(nil),         // 6: skywalking.v3.Commands
+}
+var file_language_agent_Meter_proto_depIdxs = []int32{
+	0, // 0: skywalking.v3.MeterSingleValue.labels:type_name -> skywalking.v3.Label
+	0, // 1: skywalking.v3.MeterHistogram.labels:type_name -> skywalking.v3.Label
+	1, // 2: skywalking.v3.MeterHistogram.values:type_name -> skywalking.v3.MeterBucketValue
+	2, // 3: skywalking.v3.MeterData.singleValue:type_name -> skywalking.v3.MeterSingleValue
+	3, // 4: skywalking.v3.MeterData.histogram:type_name -> skywalking.v3.MeterHistogram
+	4, // 5: skywalking.v3.MeterDataCollection.meterData:type_name -> skywalking.v3.MeterData
+	4, // 6: skywalking.v3.MeterReportService.collect:input_type -> skywalking.v3.MeterData
+	6, // 7: skywalking.v3.MeterReportService.collect:output_type -> skywalking.v3.Commands
+	7, // [7:8] is the sub-list for method output_type
+	6, // [6:7] is the sub-list for method input_type
+	6, // [6:6] is the sub-list for extension type_name
+	6, // [6:6] is the sub-list for extension extendee
+	0, // [0:6] is the sub-list for field type_name
+}
+
+func init() { file_language_agent_Meter_proto_init() }
+func file_language_agent_Meter_proto_init() {
+	if File_language_agent_Meter_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_language_agent_Meter_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Label); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_Meter_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MeterBucketValue); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_Meter_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MeterSingleValue); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_Meter_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MeterHistogram); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_Meter_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MeterData); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_Meter_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MeterDataCollection); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	file_language_agent_Meter_proto_msgTypes[4].OneofWrappers = []interface{}{
+		(*MeterData_SingleValue)(nil),
+		(*MeterData_Histogram)(nil),
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_language_agent_Meter_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   6,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_language_agent_Meter_proto_goTypes,
+		DependencyIndexes: file_language_agent_Meter_proto_depIdxs,
+		MessageInfos:      file_language_agent_Meter_proto_msgTypes,
+	}.Build()
+	File_language_agent_Meter_proto = out.File
+	file_language_agent_Meter_proto_rawDesc = nil
+	file_language_agent_Meter_proto_goTypes = nil
+	file_language_agent_Meter_proto_depIdxs = nil
+}
diff --git a/protocol/gen-codes/skywalking/network/language/agent/v3/Meter_grpc.pb.go b/protocol/gen-codes/skywalking/network/language/agent/v3/Meter_grpc.pb.go
new file mode 100644
index 0000000..3770721
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/language/agent/v3/Meter_grpc.pb.go
@@ -0,0 +1,134 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package v3
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	v3 "skywalking/network/common/v3"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion7
+
+// MeterReportServiceClient is the client API for MeterReportService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type MeterReportServiceClient interface {
+	// Meter data is reported in a certain period. The agent/SDK should report all collected metrics in this period through one stream.
+	Collect(ctx context.Context, opts ...grpc.CallOption) (MeterReportService_CollectClient, error)
+}
+
+type meterReportServiceClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewMeterReportServiceClient(cc grpc.ClientConnInterface) MeterReportServiceClient {
+	return &meterReportServiceClient{cc}
+}
+
+func (c *meterReportServiceClient) Collect(ctx context.Context, opts ...grpc.CallOption) (MeterReportService_CollectClient, error) {
+	stream, err := c.cc.NewStream(ctx, &_MeterReportService_serviceDesc.Streams[0], "/skywalking.v3.MeterReportService/collect", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &meterReportServiceCollectClient{stream}
+	return x, nil
+}
+
+type MeterReportService_CollectClient interface {
+	Send(*MeterData) error
+	CloseAndRecv() (*v3.Commands, error)
+	grpc.ClientStream
+}
+
+type meterReportServiceCollectClient struct {
+	grpc.ClientStream
+}
+
+func (x *meterReportServiceCollectClient) Send(m *MeterData) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *meterReportServiceCollectClient) CloseAndRecv() (*v3.Commands, error) {
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	m := new(v3.Commands)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+// MeterReportServiceServer is the server API for MeterReportService service.
+// All implementations must embed UnimplementedMeterReportServiceServer
+// for forward compatibility
+type MeterReportServiceServer interface {
+	// Meter data is reported in a certain period. The agent/SDK should report all collected metrics in this period through one stream.
+	Collect(MeterReportService_CollectServer) error
+	mustEmbedUnimplementedMeterReportServiceServer()
+}
+
+// UnimplementedMeterReportServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedMeterReportServiceServer struct {
+}
+
+func (UnimplementedMeterReportServiceServer) Collect(MeterReportService_CollectServer) error {
+	return status.Errorf(codes.Unimplemented, "method Collect not implemented")
+}
+func (UnimplementedMeterReportServiceServer) mustEmbedUnimplementedMeterReportServiceServer() {}
+
+// UnsafeMeterReportServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to MeterReportServiceServer will
+// result in compilation errors.
+type UnsafeMeterReportServiceServer interface {
+	mustEmbedUnimplementedMeterReportServiceServer()
+}
+
+func RegisterMeterReportServiceServer(s grpc.ServiceRegistrar, srv MeterReportServiceServer) {
+	s.RegisterService(&_MeterReportService_serviceDesc, srv)
+}
+
+func _MeterReportService_Collect_Handler(srv interface{}, stream grpc.ServerStream) error {
+	return srv.(MeterReportServiceServer).Collect(&meterReportServiceCollectServer{stream})
+}
+
+type MeterReportService_CollectServer interface {
+	SendAndClose(*v3.Commands) error
+	Recv() (*MeterData, error)
+	grpc.ServerStream
+}
+
+type meterReportServiceCollectServer struct {
+	grpc.ServerStream
+}
+
+func (x *meterReportServiceCollectServer) SendAndClose(m *v3.Commands) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *meterReportServiceCollectServer) Recv() (*MeterData, error) {
+	m := new(MeterData)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+var _MeterReportService_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "skywalking.v3.MeterReportService",
+	HandlerType: (*MeterReportServiceServer)(nil),
+	Methods:     []grpc.MethodDesc{},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "collect",
+			Handler:       _MeterReportService_Collect_Handler,
+			ClientStreams: true,
+		},
+	},
+	Metadata: "language-agent/Meter.proto",
+}
diff --git a/protocol/gen-codes/skywalking/network/language/agent/v3/Tracing.pb.go b/protocol/gen-codes/skywalking/network/language/agent/v3/Tracing.pb.go
new file mode 100644
index 0000000..e502b84
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/language/agent/v3/Tracing.pb.go
@@ -0,0 +1,1067 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.25.0
+// 	protoc        v3.14.0
+// source: language-agent/Tracing.proto
+
+package v3
+
+import (
+	proto "github.com/golang/protobuf/proto"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	v3 "skywalking/network/common/v3"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+// Map to the type of span
+type SpanType int32
+
+const (
+	// Server side of RPC. Consumer side of MQ.
+	SpanType_Entry SpanType = 0
+	// Client side of RPC. Producer side of MQ.
+	SpanType_Exit SpanType = 1
+	// A common local code execution.
+	SpanType_Local SpanType = 2
+)
+
+// Enum value maps for SpanType.
+var (
+	SpanType_name = map[int32]string{
+		0: "Entry",
+		1: "Exit",
+		2: "Local",
+	}
+	SpanType_value = map[string]int32{
+		"Entry": 0,
+		"Exit":  1,
+		"Local": 2,
+	}
+)
+
+func (x SpanType) Enum() *SpanType {
+	p := new(SpanType)
+	*p = x
+	return p
+}
+
+func (x SpanType) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (SpanType) Descriptor() protoreflect.EnumDescriptor {
+	return file_language_agent_Tracing_proto_enumTypes[0].Descriptor()
+}
+
+func (SpanType) Type() protoreflect.EnumType {
+	return &file_language_agent_Tracing_proto_enumTypes[0]
+}
+
+func (x SpanType) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use SpanType.Descriptor instead.
+func (SpanType) EnumDescriptor() ([]byte, []int) {
+	return file_language_agent_Tracing_proto_rawDescGZIP(), []int{0}
+}
+
+// Type of the reference
+type RefType int32
+
+const (
+	// Map to the reference targeting the segment in another OS process.
+	RefType_CrossProcess RefType = 0
+	// Map to the reference targeting the segment in the same process of the current one, just across thread.
+	// This is only used when the coding language has the thread concept.
+	RefType_CrossThread RefType = 1
+)
+
+// Enum value maps for RefType.
+var (
+	RefType_name = map[int32]string{
+		0: "CrossProcess",
+		1: "CrossThread",
+	}
+	RefType_value = map[string]int32{
+		"CrossProcess": 0,
+		"CrossThread":  1,
+	}
+)
+
+func (x RefType) Enum() *RefType {
+	p := new(RefType)
+	*p = x
+	return p
+}
+
+func (x RefType) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (RefType) Descriptor() protoreflect.EnumDescriptor {
+	return file_language_agent_Tracing_proto_enumTypes[1].Descriptor()
+}
+
+func (RefType) Type() protoreflect.EnumType {
+	return &file_language_agent_Tracing_proto_enumTypes[1]
+}
+
+func (x RefType) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use RefType.Descriptor instead.
+func (RefType) EnumDescriptor() ([]byte, []int) {
+	return file_language_agent_Tracing_proto_rawDescGZIP(), []int{1}
+}
+
+// Map to the layer of span
+type SpanLayer int32
+
+const (
+	// Unknown layer. Could be anything.
+	SpanLayer_Unknown SpanLayer = 0
+	// A database layer, used in tracing the database client component.
+	SpanLayer_Database SpanLayer = 1
+	// A RPC layer, used in both client and server sides of RPC component.
+	SpanLayer_RPCFramework SpanLayer = 2
+	// HTTP is a more specific RPCFramework.
+	SpanLayer_Http SpanLayer = 3
+	// A MQ layer, used in both producer and consuer sides of the MQ component.
+	SpanLayer_MQ SpanLayer = 4
+	// A cache layer, used in tracing the cache client component.
+	SpanLayer_Cache SpanLayer = 5
+)
+
+// Enum value maps for SpanLayer.
+var (
+	SpanLayer_name = map[int32]string{
+		0: "Unknown",
+		1: "Database",
+		2: "RPCFramework",
+		3: "Http",
+		4: "MQ",
+		5: "Cache",
+	}
+	SpanLayer_value = map[string]int32{
+		"Unknown":      0,
+		"Database":     1,
+		"RPCFramework": 2,
+		"Http":         3,
+		"MQ":           4,
+		"Cache":        5,
+	}
+)
+
+func (x SpanLayer) Enum() *SpanLayer {
+	p := new(SpanLayer)
+	*p = x
+	return p
+}
+
+func (x SpanLayer) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (SpanLayer) Descriptor() protoreflect.EnumDescriptor {
+	return file_language_agent_Tracing_proto_enumTypes[2].Descriptor()
+}
+
+func (SpanLayer) Type() protoreflect.EnumType {
+	return &file_language_agent_Tracing_proto_enumTypes[2]
+}
+
+func (x SpanLayer) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use SpanLayer.Descriptor instead.
+func (SpanLayer) EnumDescriptor() ([]byte, []int) {
+	return file_language_agent_Tracing_proto_rawDescGZIP(), []int{2}
+}
+
+// The segment is a collection of spans. It includes all collected spans in a simple one request context, such as a HTTP request process.
+//
+// We recommend the agent/SDK report all tracked data of one request once for all, such as,
+// typically, such as in Java, one segment represent all tracked operations(spans) of one request context in the same thread.
+// At the same time, in some language there is not a clear concept like golang, it could represent all tracked operations of one request context.
+type SegmentObject struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// A string id represents the whole trace.
+	TraceId string `protobuf:"bytes,1,opt,name=traceId,proto3" json:"traceId,omitempty"`
+	// A unique id represents this segment. Other segments could use this id to reference as a child segment.
+	TraceSegmentId string `protobuf:"bytes,2,opt,name=traceSegmentId,proto3" json:"traceSegmentId,omitempty"`
+	// Span collections included in this segment.
+	Spans []*SpanObject `protobuf:"bytes,3,rep,name=spans,proto3" json:"spans,omitempty"`
+	// **Service**. Represents a set/group of workloads which provide the same behaviours for incoming requests.
+	//
+	// The logic name represents the service. This would show as a separate node in the topology.
+	// The metrics analyzed from the spans, would be aggregated for this entity as the service level.
+	Service string `protobuf:"bytes,4,opt,name=service,proto3" json:"service,omitempty"`
+	// **Service Instance**. Each individual workload in the Service group is known as an instance. Like `pods` in Kubernetes, it
+	// doesn't need to be a single OS process, however, if you are using instrument agents, an instance is actually a real OS process.
+	//
+	// The logic name represents the service instance. This would show as a separate node in the instance relationship.
+	// The metrics analyzed from the spans, would be aggregated for this entity as the service instance level.
+	ServiceInstance string `protobuf:"bytes,5,opt,name=serviceInstance,proto3" json:"serviceInstance,omitempty"`
+	// Whether the segment includes all tracked spans.
+	// In the production environment tracked, some tasks could include too many spans for one request context, such as a batch update for a cache, or an async job.
+	// The agent/SDK could optimize or ignore some tracked spans for better performance.
+	// In this case, the value should be flagged as TRUE.
+	IsSizeLimited bool `protobuf:"varint,6,opt,name=isSizeLimited,proto3" json:"isSizeLimited,omitempty"`
+}
+
+func (x *SegmentObject) Reset() {
+	*x = SegmentObject{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_Tracing_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SegmentObject) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SegmentObject) ProtoMessage() {}
+
+func (x *SegmentObject) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_Tracing_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SegmentObject.ProtoReflect.Descriptor instead.
+func (*SegmentObject) Descriptor() ([]byte, []int) {
+	return file_language_agent_Tracing_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *SegmentObject) GetTraceId() string {
+	if x != nil {
+		return x.TraceId
+	}
+	return ""
+}
+
+func (x *SegmentObject) GetTraceSegmentId() string {
+	if x != nil {
+		return x.TraceSegmentId
+	}
+	return ""
+}
+
+func (x *SegmentObject) GetSpans() []*SpanObject {
+	if x != nil {
+		return x.Spans
+	}
+	return nil
+}
+
+func (x *SegmentObject) GetService() string {
+	if x != nil {
+		return x.Service
+	}
+	return ""
+}
+
+func (x *SegmentObject) GetServiceInstance() string {
+	if x != nil {
+		return x.ServiceInstance
+	}
+	return ""
+}
+
+func (x *SegmentObject) GetIsSizeLimited() bool {
+	if x != nil {
+		return x.IsSizeLimited
+	}
+	return false
+}
+
+// Segment reference represents the link between two existing segment.
+type SegmentReference struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Represent the reference type. It could be across thread or across process.
+	// Across process means there is a downstream RPC call for this.
+	// Typically, refType == CrossProcess means SpanObject#spanType = entry.
+	RefType RefType `protobuf:"varint,1,opt,name=refType,proto3,enum=skywalking.v3.RefType" json:"refType,omitempty"`
+	// A string id represents the whole trace.
+	TraceId string `protobuf:"bytes,2,opt,name=traceId,proto3" json:"traceId,omitempty"`
+	// Another segment id as the parent.
+	ParentTraceSegmentId string `protobuf:"bytes,3,opt,name=parentTraceSegmentId,proto3" json:"parentTraceSegmentId,omitempty"`
+	// The span id in the parent trace segment.
+	ParentSpanId int32 `protobuf:"varint,4,opt,name=parentSpanId,proto3" json:"parentSpanId,omitempty"`
+	// The service logic name of the parent segment.
+	// If refType == CrossThread, this name is as same as the trace segment.
+	ParentService string `protobuf:"bytes,5,opt,name=parentService,proto3" json:"parentService,omitempty"`
+	// The service logic name instance of the parent segment.
+	// If refType == CrossThread, this name is as same as the trace segment.
+	ParentServiceInstance string `protobuf:"bytes,6,opt,name=parentServiceInstance,proto3" json:"parentServiceInstance,omitempty"`
+	// The endpoint name of the parent segment.
+	// **Endpoint**. A path in a service for incoming requests, such as an HTTP URI path or a gRPC service class + method signature.
+	// In a trace segment, the endpoint name is the name of first entry span.
+	ParentEndpoint string `protobuf:"bytes,7,opt,name=parentEndpoint,proto3" json:"parentEndpoint,omitempty"`
+	// The network address, including ip/hostname and port, which is used in the client side.
+	// Such as Client --> use 127.0.11.8:913 -> Server
+	// then, in the reference of entry span reported by Server, the value of this field is 127.0.11.8:913.
+	// This plays the important role in the SkyWalking STAM(Streaming Topology Analysis Method)
+	// For more details, read https://wu-sheng.github.io/STAM/
+	NetworkAddressUsedAtPeer string `protobuf:"bytes,8,opt,name=networkAddressUsedAtPeer,proto3" json:"networkAddressUsedAtPeer,omitempty"`
+}
+
+func (x *SegmentReference) Reset() {
+	*x = SegmentReference{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_Tracing_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SegmentReference) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SegmentReference) ProtoMessage() {}
+
+func (x *SegmentReference) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_Tracing_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SegmentReference.ProtoReflect.Descriptor instead.
+func (*SegmentReference) Descriptor() ([]byte, []int) {
+	return file_language_agent_Tracing_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *SegmentReference) GetRefType() RefType {
+	if x != nil {
+		return x.RefType
+	}
+	return RefType_CrossProcess
+}
+
+func (x *SegmentReference) GetTraceId() string {
+	if x != nil {
+		return x.TraceId
+	}
+	return ""
+}
+
+func (x *SegmentReference) GetParentTraceSegmentId() string {
+	if x != nil {
+		return x.ParentTraceSegmentId
+	}
+	return ""
+}
+
+func (x *SegmentReference) GetParentSpanId() int32 {
+	if x != nil {
+		return x.ParentSpanId
+	}
+	return 0
+}
+
+func (x *SegmentReference) GetParentService() string {
+	if x != nil {
+		return x.ParentService
+	}
+	return ""
+}
+
+func (x *SegmentReference) GetParentServiceInstance() string {
+	if x != nil {
+		return x.ParentServiceInstance
+	}
+	return ""
+}
+
+func (x *SegmentReference) GetParentEndpoint() string {
+	if x != nil {
+		return x.ParentEndpoint
+	}
+	return ""
+}
+
+func (x *SegmentReference) GetNetworkAddressUsedAtPeer() string {
+	if x != nil {
+		return x.NetworkAddressUsedAtPeer
+	}
+	return ""
+}
+
+// Span represents a execution unit in the system, with duration and many other attributes.
+// Span could be a method, a RPC, MQ message produce or consume.
+// In the practice, the span should be added when it is really necessary, to avoid payload overhead.
+// We recommend to creating spans in across process(client/server of RPC/MQ) and across thread cases only.
+type SpanObject struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The number id of the span. Should be unique in the whole segment.
+	// Starting at 0.
+	SpanId int32 `protobuf:"varint,1,opt,name=spanId,proto3" json:"spanId,omitempty"`
+	// The number id of the parent span in the whole segment.
+	// -1 represents no parent span.
+	// Also, be known as the root/first span of the segment.
+	ParentSpanId int32 `protobuf:"varint,2,opt,name=parentSpanId,proto3" json:"parentSpanId,omitempty"`
+	// Start timestamp in milliseconds of this span,
+	// measured between the current time and midnight, January 1, 1970 UTC.
+	StartTime int64 `protobuf:"varint,3,opt,name=startTime,proto3" json:"startTime,omitempty"`
+	// End timestamp in milliseconds of this span,
+	// measured between the current time and midnight, January 1, 1970 UTC.
+	EndTime int64 `protobuf:"varint,4,opt,name=endTime,proto3" json:"endTime,omitempty"`
+	// <Optional>
+	// In the across thread and across process, these references targeting the parent segments.
+	// The references usually have only one element, but in batch consumer case, such as in MQ or async batch process, it could be multiple.
+	Refs []*SegmentReference `protobuf:"bytes,5,rep,name=refs,proto3" json:"refs,omitempty"`
+	// A logic name represents this span.
+	//
+	// We don't recommend to include the parameter, such as HTTP request parameters, as a part of the operation, especially this is the name of the entry span.
+	// All statistic for the endpoints are aggregated base on this name. Those parameters should be added in the tags if necessary.
+	// If in some cases, it have to be a part of the operation name,
+	// users should use the Group Parameterized Endpoints capability at the backend to get the meaningful metrics.
+	// Read https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/endpoint-grouping-rules.md
+	OperationName string `protobuf:"bytes,6,opt,name=operationName,proto3" json:"operationName,omitempty"`
+	// Remote address of the peer in RPC/MQ case.
+	// This is required when spanType = Exit, as it is a part of the SkyWalking STAM(Streaming Topology Analysis Method).
+	// For more details, read https://wu-sheng.github.io/STAM/
+	Peer string `protobuf:"bytes,7,opt,name=peer,proto3" json:"peer,omitempty"`
+	// Span type represents the role in the RPC context.
+	SpanType SpanType `protobuf:"varint,8,opt,name=spanType,proto3,enum=skywalking.v3.SpanType" json:"spanType,omitempty"`
+	// Span layer represent the component tech stack, related to the network tech.
+	SpanLayer SpanLayer `protobuf:"varint,9,opt,name=spanLayer,proto3,enum=skywalking.v3.SpanLayer" json:"spanLayer,omitempty"`
+	// Component id is a predefinited number id in the SkyWalking.
+	// It represents the framework, tech stack used by this tracked span, such as Spring.
+	// All IDs are defined in the https://github.com/apache/skywalking/blob/master/oap-server/server-bootstrap/src/main/resources/component-libraries.yml
+	// Send a pull request if you want to add languages, components or mapping defintions,
+	// all public components could be accepted.
+	// Follow this doc for more details, https://github.com/apache/skywalking/blob/master/docs/en/guides/Component-library-settings.md
+	ComponentId int32 `protobuf:"varint,10,opt,name=componentId,proto3" json:"componentId,omitempty"`
+	// The status of the span. False means the tracked execution ends in the unexpected status.
+	// This affects the successful rate statistic in the backend.
+	// Exception or error code happened in the tracked process doesn't mean isError == true, the implementations of agent plugin and tracing SDK make the final decision.
+	IsError bool `protobuf:"varint,11,opt,name=isError,proto3" json:"isError,omitempty"`
+	// String key, String value pair.
+	// Tags provides more informance, includes parameters.
+	//
+	// In the OAP backend analysis, some special tag or tag combination could provide other advanced features.
+	// https://github.com/apache/skywalking/blob/master/docs/en/guides/Java-Plugin-Development-Guide.md#special-span-tags
+	Tags []*v3.KeyStringValuePair `protobuf:"bytes,12,rep,name=tags,proto3" json:"tags,omitempty"`
+	// String key, String value pair with an accurate timestamp.
+	// Logging some events happening in the context of the span duration.
+	Logs []*Log `protobuf:"bytes,13,rep,name=logs,proto3" json:"logs,omitempty"`
+	// Force the backend don't do analysis, if the value is TRUE.
+	// The backend has its own configurations to follow or override this.
+	//
+	// Use this mostly because the agent/SDK could know more context of the service role.
+	SkipAnalysis bool `protobuf:"varint,14,opt,name=skipAnalysis,proto3" json:"skipAnalysis,omitempty"`
+}
+
+func (x *SpanObject) Reset() {
+	*x = SpanObject{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_Tracing_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SpanObject) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SpanObject) ProtoMessage() {}
+
+func (x *SpanObject) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_Tracing_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SpanObject.ProtoReflect.Descriptor instead.
+func (*SpanObject) Descriptor() ([]byte, []int) {
+	return file_language_agent_Tracing_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *SpanObject) GetSpanId() int32 {
+	if x != nil {
+		return x.SpanId
+	}
+	return 0
+}
+
+func (x *SpanObject) GetParentSpanId() int32 {
+	if x != nil {
+		return x.ParentSpanId
+	}
+	return 0
+}
+
+func (x *SpanObject) GetStartTime() int64 {
+	if x != nil {
+		return x.StartTime
+	}
+	return 0
+}
+
+func (x *SpanObject) GetEndTime() int64 {
+	if x != nil {
+		return x.EndTime
+	}
+	return 0
+}
+
+func (x *SpanObject) GetRefs() []*SegmentReference {
+	if x != nil {
+		return x.Refs
+	}
+	return nil
+}
+
+func (x *SpanObject) GetOperationName() string {
+	if x != nil {
+		return x.OperationName
+	}
+	return ""
+}
+
+func (x *SpanObject) GetPeer() string {
+	if x != nil {
+		return x.Peer
+	}
+	return ""
+}
+
+func (x *SpanObject) GetSpanType() SpanType {
+	if x != nil {
+		return x.SpanType
+	}
+	return SpanType_Entry
+}
+
+func (x *SpanObject) GetSpanLayer() SpanLayer {
+	if x != nil {
+		return x.SpanLayer
+	}
+	return SpanLayer_Unknown
+}
+
+func (x *SpanObject) GetComponentId() int32 {
+	if x != nil {
+		return x.ComponentId
+	}
+	return 0
+}
+
+func (x *SpanObject) GetIsError() bool {
+	if x != nil {
+		return x.IsError
+	}
+	return false
+}
+
+func (x *SpanObject) GetTags() []*v3.KeyStringValuePair {
+	if x != nil {
+		return x.Tags
+	}
+	return nil
+}
+
+func (x *SpanObject) GetLogs() []*Log {
+	if x != nil {
+		return x.Logs
+	}
+	return nil
+}
+
+func (x *SpanObject) GetSkipAnalysis() bool {
+	if x != nil {
+		return x.SkipAnalysis
+	}
+	return false
+}
+
+type Log struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The timestamp in milliseconds of this event.,
+	// measured between the current time and midnight, January 1, 1970 UTC.
+	Time int64 `protobuf:"varint,1,opt,name=time,proto3" json:"time,omitempty"`
+	// String key, String value pair.
+	Data []*v3.KeyStringValuePair `protobuf:"bytes,2,rep,name=data,proto3" json:"data,omitempty"`
+}
+
+func (x *Log) Reset() {
+	*x = Log{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_Tracing_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Log) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Log) ProtoMessage() {}
+
+func (x *Log) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_Tracing_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Log.ProtoReflect.Descriptor instead.
+func (*Log) Descriptor() ([]byte, []int) {
+	return file_language_agent_Tracing_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *Log) GetTime() int64 {
+	if x != nil {
+		return x.Time
+	}
+	return 0
+}
+
+func (x *Log) GetData() []*v3.KeyStringValuePair {
+	if x != nil {
+		return x.Data
+	}
+	return nil
+}
+
+// A ID could be represented by multiple string sections.
+type ID struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Id []string `protobuf:"bytes,1,rep,name=id,proto3" json:"id,omitempty"`
+}
+
+func (x *ID) Reset() {
+	*x = ID{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_Tracing_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ID) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ID) ProtoMessage() {}
+
+func (x *ID) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_Tracing_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ID.ProtoReflect.Descriptor instead.
+func (*ID) Descriptor() ([]byte, []int) {
+	return file_language_agent_Tracing_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *ID) GetId() []string {
+	if x != nil {
+		return x.Id
+	}
+	return nil
+}
+
+// The segment collections for trace report in batch and sync mode.
+type SegmentCollection struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Segments []*SegmentObject `protobuf:"bytes,1,rep,name=segments,proto3" json:"segments,omitempty"`
+}
+
+func (x *SegmentCollection) Reset() {
+	*x = SegmentCollection{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_language_agent_Tracing_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SegmentCollection) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SegmentCollection) ProtoMessage() {}
+
+func (x *SegmentCollection) ProtoReflect() protoreflect.Message {
+	mi := &file_language_agent_Tracing_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SegmentCollection.ProtoReflect.Descriptor instead.
+func (*SegmentCollection) Descriptor() ([]byte, []int) {
+	return file_language_agent_Tracing_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *SegmentCollection) GetSegments() []*SegmentObject {
+	if x != nil {
+		return x.Segments
+	}
+	return nil
+}
+
+var File_language_agent_Tracing_proto protoreflect.FileDescriptor
+
+var file_language_agent_Tracing_proto_rawDesc = []byte{
+	0x0a, 0x1c, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74,
+	0x2f, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d,
+	0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x1a, 0x13, 0x63,
+	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x22, 0xec, 0x01, 0x0a, 0x0d, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x62,
+	0x6a, 0x65, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x26,
+	0x0a, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x67,
+	0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x05, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x18,
+	0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69,
+	0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
+	0x52, 0x05, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74,
+	0x61, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x69,
+	0x73, 0x53, 0x69, 0x7a, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01,
+	0x28, 0x08, 0x52, 0x0d, 0x69, 0x73, 0x53, 0x69, 0x7a, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65,
+	0x64, 0x22, 0xf6, 0x02, 0x0a, 0x10, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66,
+	0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x30, 0x0a, 0x07, 0x72, 0x65, 0x66, 0x54, 0x79, 0x70,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c,
+	0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x66, 0x54, 0x79, 0x70, 0x65, 0x52,
+	0x07, 0x72, 0x65, 0x66, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x61, 0x63,
+	0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65,
+	0x49, 0x64, 0x12, 0x32, 0x0a, 0x14, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x72, 0x61, 0x63,
+	0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x14, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x67,
+	0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74,
+	0x53, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x61,
+	0x72, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x70, 0x61,
+	0x72, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x0d, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x12, 0x34, 0x0a, 0x15, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x15, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e,
+	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74,
+	0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e,
+	0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x3a,
+	0x0a, 0x18, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
+	0x55, 0x73, 0x65, 0x64, 0x41, 0x74, 0x50, 0x65, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x18, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
+	0x55, 0x73, 0x65, 0x64, 0x41, 0x74, 0x50, 0x65, 0x65, 0x72, 0x22, 0x9b, 0x04, 0x0a, 0x0a, 0x53,
+	0x70, 0x61, 0x6e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x70, 0x61,
+	0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49,
+	0x64, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x61, 0x6e, 0x49,
+	0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53,
+	0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69,
+	0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54,
+	0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x33, 0x0a,
+	0x04, 0x72, 0x65, 0x66, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x6b,
+	0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x67, 0x6d,
+	0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x04, 0x72, 0x65,
+	0x66, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e,
+	0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x70, 0x65, 0x72, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72,
+	0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, 0x33, 0x0a, 0x08,
+	0x73, 0x70, 0x61, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17,
+	0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53,
+	0x70, 0x61, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x73, 0x70, 0x61, 0x6e, 0x54, 0x79, 0x70,
+	0x65, 0x12, 0x36, 0x0a, 0x09, 0x73, 0x70, 0x61, 0x6e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x09,
+	0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e,
+	0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x09,
+	0x73, 0x70, 0x61, 0x6e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6d,
+	0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b,
+	0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x69,
+	0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73,
+	0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x0c, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67,
+	0x2e, 0x76, 0x33, 0x2e, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c,
+	0x75, 0x65, 0x50, 0x61, 0x69, 0x72, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x26, 0x0a, 0x04,
+	0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x6b, 0x79,
+	0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04,
+	0x6c, 0x6f, 0x67, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x41, 0x6e, 0x61, 0x6c,
+	0x79, 0x73, 0x69, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x73, 0x6b, 0x69, 0x70,
+	0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x22, 0x50, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12,
+	0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74,
+	0x69, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x21, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76,
+	0x33, 0x2e, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65,
+	0x50, 0x61, 0x69, 0x72, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x14, 0x0a, 0x02, 0x49, 0x44,
+	0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64,
+	0x22, 0x4d, 0x0a, 0x11, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65,
+	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74,
+	0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c,
+	0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4f,
+	0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x08, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2a,
+	0x2a, 0x0a, 0x08, 0x53, 0x70, 0x61, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x45,
+	0x6e, 0x74, 0x72, 0x79, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x78, 0x69, 0x74, 0x10, 0x01,
+	0x12, 0x09, 0x0a, 0x05, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x10, 0x02, 0x2a, 0x2c, 0x0a, 0x07, 0x52,
+	0x65, 0x66, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x50,
+	0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x72, 0x6f, 0x73,
+	0x73, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x10, 0x01, 0x2a, 0x55, 0x0a, 0x09, 0x53, 0x70, 0x61,
+	0x6e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
+	0x6e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x10,
+	0x01, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x50, 0x43, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x77, 0x6f, 0x72,
+	0x6b, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x74, 0x74, 0x70, 0x10, 0x03, 0x12, 0x06, 0x0a,
+	0x02, 0x4d, 0x51, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x61, 0x63, 0x68, 0x65, 0x10, 0x05,
+	0x32, 0xaf, 0x01, 0x0a, 0x19, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e,
+	0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x44,
+	0x0a, 0x07, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x2e, 0x73, 0x6b, 0x79, 0x77,
+	0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e,
+	0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x1a, 0x17, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c,
+	0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73,
+	0x22, 0x00, 0x28, 0x01, 0x12, 0x4c, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x49,
+	0x6e, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x20, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69,
+	0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6c,
+	0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x17, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c,
+	0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73,
+	0x22, 0x00, 0x42, 0x7d, 0x0a, 0x33, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65,
+	0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x61, 0x70, 0x6d, 0x2e,
+	0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65,
+	0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x33, 0x50, 0x01, 0x5a, 0x24, 0x73, 0x6b, 0x79,
+	0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f,
+	0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x76,
+	0x33, 0xaa, 0x02, 0x1d, 0x53, 0x6b, 0x79, 0x57, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x4e,
+	0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x56,
+	0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_language_agent_Tracing_proto_rawDescOnce sync.Once
+	file_language_agent_Tracing_proto_rawDescData = file_language_agent_Tracing_proto_rawDesc
+)
+
+func file_language_agent_Tracing_proto_rawDescGZIP() []byte {
+	file_language_agent_Tracing_proto_rawDescOnce.Do(func() {
+		file_language_agent_Tracing_proto_rawDescData = protoimpl.X.CompressGZIP(file_language_agent_Tracing_proto_rawDescData)
+	})
+	return file_language_agent_Tracing_proto_rawDescData
+}
+
+var file_language_agent_Tracing_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
+var file_language_agent_Tracing_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
+var file_language_agent_Tracing_proto_goTypes = []interface{}{
+	(SpanType)(0),                 // 0: skywalking.v3.SpanType
+	(RefType)(0),                  // 1: skywalking.v3.RefType
+	(SpanLayer)(0),                // 2: skywalking.v3.SpanLayer
+	(*SegmentObject)(nil),         // 3: skywalking.v3.SegmentObject
+	(*SegmentReference)(nil),      // 4: skywalking.v3.SegmentReference
+	(*SpanObject)(nil),            // 5: skywalking.v3.SpanObject
+	(*Log)(nil),                   // 6: skywalking.v3.Log
+	(*ID)(nil),                    // 7: skywalking.v3.ID
+	(*SegmentCollection)(nil),     // 8: skywalking.v3.SegmentCollection
+	(*v3.KeyStringValuePair)(nil), // 9: skywalking.v3.KeyStringValuePair
+	(*v3.Commands)(nil),           // 10: skywalking.v3.Commands
+}
+var file_language_agent_Tracing_proto_depIdxs = []int32{
+	5,  // 0: skywalking.v3.SegmentObject.spans:type_name -> skywalking.v3.SpanObject
+	1,  // 1: skywalking.v3.SegmentReference.refType:type_name -> skywalking.v3.RefType
+	4,  // 2: skywalking.v3.SpanObject.refs:type_name -> skywalking.v3.SegmentReference
+	0,  // 3: skywalking.v3.SpanObject.spanType:type_name -> skywalking.v3.SpanType
+	2,  // 4: skywalking.v3.SpanObject.spanLayer:type_name -> skywalking.v3.SpanLayer
+	9,  // 5: skywalking.v3.SpanObject.tags:type_name -> skywalking.v3.KeyStringValuePair
+	6,  // 6: skywalking.v3.SpanObject.logs:type_name -> skywalking.v3.Log
+	9,  // 7: skywalking.v3.Log.data:type_name -> skywalking.v3.KeyStringValuePair
+	3,  // 8: skywalking.v3.SegmentCollection.segments:type_name -> skywalking.v3.SegmentObject
+	3,  // 9: skywalking.v3.TraceSegmentReportService.collect:input_type -> skywalking.v3.SegmentObject
+	8,  // 10: skywalking.v3.TraceSegmentReportService.collectInSync:input_type -> skywalking.v3.SegmentCollection
+	10, // 11: skywalking.v3.TraceSegmentReportService.collect:output_type -> skywalking.v3.Commands
+	10, // 12: skywalking.v3.TraceSegmentReportService.collectInSync:output_type -> skywalking.v3.Commands
+	11, // [11:13] is the sub-list for method output_type
+	9,  // [9:11] is the sub-list for method input_type
+	9,  // [9:9] is the sub-list for extension type_name
+	9,  // [9:9] is the sub-list for extension extendee
+	0,  // [0:9] is the sub-list for field type_name
+}
+
+func init() { file_language_agent_Tracing_proto_init() }
+func file_language_agent_Tracing_proto_init() {
+	if File_language_agent_Tracing_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_language_agent_Tracing_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SegmentObject); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_Tracing_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SegmentReference); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_Tracing_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SpanObject); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_Tracing_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Log); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_Tracing_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ID); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_language_agent_Tracing_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SegmentCollection); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_language_agent_Tracing_proto_rawDesc,
+			NumEnums:      3,
+			NumMessages:   6,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_language_agent_Tracing_proto_goTypes,
+		DependencyIndexes: file_language_agent_Tracing_proto_depIdxs,
+		EnumInfos:         file_language_agent_Tracing_proto_enumTypes,
+		MessageInfos:      file_language_agent_Tracing_proto_msgTypes,
+	}.Build()
+	File_language_agent_Tracing_proto = out.File
+	file_language_agent_Tracing_proto_rawDesc = nil
+	file_language_agent_Tracing_proto_goTypes = nil
+	file_language_agent_Tracing_proto_depIdxs = nil
+}
diff --git a/protocol/gen-codes/skywalking/network/language/agent/v3/Tracing_grpc.pb.go b/protocol/gen-codes/skywalking/network/language/agent/v3/Tracing_grpc.pb.go
new file mode 100644
index 0000000..fdaba9d
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/language/agent/v3/Tracing_grpc.pb.go
@@ -0,0 +1,184 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package v3
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	v3 "skywalking/network/common/v3"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion7
+
+// TraceSegmentReportServiceClient is the client API for TraceSegmentReportService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type TraceSegmentReportServiceClient interface {
+	// Recommended trace segment report channel.
+	// gRPC streaming provides better performance.
+	// All language agents should choose this.
+	Collect(ctx context.Context, opts ...grpc.CallOption) (TraceSegmentReportService_CollectClient, error)
+	// An alternative for trace report by using gRPC unary
+	// This is provided for some 3rd-party integration, if and only if they prefer the unary mode somehow.
+	// The performance of SkyWalking OAP server would be very similar with streaming report,
+	// the performance of the network and client side are affected
+	CollectInSync(ctx context.Context, in *SegmentCollection, opts ...grpc.CallOption) (*v3.Commands, error)
+}
+
+type traceSegmentReportServiceClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewTraceSegmentReportServiceClient(cc grpc.ClientConnInterface) TraceSegmentReportServiceClient {
+	return &traceSegmentReportServiceClient{cc}
+}
+
+func (c *traceSegmentReportServiceClient) Collect(ctx context.Context, opts ...grpc.CallOption) (TraceSegmentReportService_CollectClient, error) {
+	stream, err := c.cc.NewStream(ctx, &_TraceSegmentReportService_serviceDesc.Streams[0], "/skywalking.v3.TraceSegmentReportService/collect", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &traceSegmentReportServiceCollectClient{stream}
+	return x, nil
+}
+
+type TraceSegmentReportService_CollectClient interface {
+	Send(*SegmentObject) error
+	CloseAndRecv() (*v3.Commands, error)
+	grpc.ClientStream
+}
+
+type traceSegmentReportServiceCollectClient struct {
+	grpc.ClientStream
+}
+
+func (x *traceSegmentReportServiceCollectClient) Send(m *SegmentObject) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *traceSegmentReportServiceCollectClient) CloseAndRecv() (*v3.Commands, error) {
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	m := new(v3.Commands)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func (c *traceSegmentReportServiceClient) CollectInSync(ctx context.Context, in *SegmentCollection, opts ...grpc.CallOption) (*v3.Commands, error) {
+	out := new(v3.Commands)
+	err := c.cc.Invoke(ctx, "/skywalking.v3.TraceSegmentReportService/collectInSync", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// TraceSegmentReportServiceServer is the server API for TraceSegmentReportService service.
+// All implementations must embed UnimplementedTraceSegmentReportServiceServer
+// for forward compatibility
+type TraceSegmentReportServiceServer interface {
+	// Recommended trace segment report channel.
+	// gRPC streaming provides better performance.
+	// All language agents should choose this.
+	Collect(TraceSegmentReportService_CollectServer) error
+	// An alternative for trace report by using gRPC unary
+	// This is provided for some 3rd-party integration, if and only if they prefer the unary mode somehow.
+	// The performance of SkyWalking OAP server would be very similar with streaming report,
+	// the performance of the network and client side are affected
+	CollectInSync(context.Context, *SegmentCollection) (*v3.Commands, error)
+	mustEmbedUnimplementedTraceSegmentReportServiceServer()
+}
+
+// UnimplementedTraceSegmentReportServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedTraceSegmentReportServiceServer struct {
+}
+
+func (UnimplementedTraceSegmentReportServiceServer) Collect(TraceSegmentReportService_CollectServer) error {
+	return status.Errorf(codes.Unimplemented, "method Collect not implemented")
+}
+func (UnimplementedTraceSegmentReportServiceServer) CollectInSync(context.Context, *SegmentCollection) (*v3.Commands, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method CollectInSync not implemented")
+}
+func (UnimplementedTraceSegmentReportServiceServer) mustEmbedUnimplementedTraceSegmentReportServiceServer() {
+}
+
+// UnsafeTraceSegmentReportServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to TraceSegmentReportServiceServer will
+// result in compilation errors.
+type UnsafeTraceSegmentReportServiceServer interface {
+	mustEmbedUnimplementedTraceSegmentReportServiceServer()
+}
+
+func RegisterTraceSegmentReportServiceServer(s grpc.ServiceRegistrar, srv TraceSegmentReportServiceServer) {
+	s.RegisterService(&_TraceSegmentReportService_serviceDesc, srv)
+}
+
+func _TraceSegmentReportService_Collect_Handler(srv interface{}, stream grpc.ServerStream) error {
+	return srv.(TraceSegmentReportServiceServer).Collect(&traceSegmentReportServiceCollectServer{stream})
+}
+
+type TraceSegmentReportService_CollectServer interface {
+	SendAndClose(*v3.Commands) error
+	Recv() (*SegmentObject, error)
+	grpc.ServerStream
+}
+
+type traceSegmentReportServiceCollectServer struct {
+	grpc.ServerStream
+}
+
+func (x *traceSegmentReportServiceCollectServer) SendAndClose(m *v3.Commands) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *traceSegmentReportServiceCollectServer) Recv() (*SegmentObject, error) {
+	m := new(SegmentObject)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func _TraceSegmentReportService_CollectInSync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(SegmentCollection)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(TraceSegmentReportServiceServer).CollectInSync(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/skywalking.v3.TraceSegmentReportService/collectInSync",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(TraceSegmentReportServiceServer).CollectInSync(ctx, req.(*SegmentCollection))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _TraceSegmentReportService_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "skywalking.v3.TraceSegmentReportService",
+	HandlerType: (*TraceSegmentReportServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "collectInSync",
+			Handler:    _TraceSegmentReportService_CollectInSync_Handler,
+		},
+	},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "collect",
+			Handler:       _TraceSegmentReportService_Collect_Handler,
+			ClientStreams: true,
+		},
+	},
+	Metadata: "language-agent/Tracing.proto",
+}
diff --git a/protocol/gen-codes/skywalking/network/language/profile/v3/Profile.pb.go b/protocol/gen-codes/skywalking/network/language/profile/v3/Profile.pb.go
new file mode 100644
index 0000000..9f84f14
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/language/profile/v3/Profile.pb.go
@@ -0,0 +1,484 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.25.0
+// 	protoc        v3.14.0
+// source: profile/Profile.proto
+
+package v3
+
+import (
+	proto "github.com/golang/protobuf/proto"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	v3 "skywalking/network/common/v3"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+type ProfileTaskCommandQuery struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// current sniffer information
+	Service         string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
+	ServiceInstance string `protobuf:"bytes,2,opt,name=serviceInstance,proto3" json:"serviceInstance,omitempty"`
+	// last command timestamp
+	LastCommandTime int64 `protobuf:"varint,3,opt,name=lastCommandTime,proto3" json:"lastCommandTime,omitempty"`
+}
+
+func (x *ProfileTaskCommandQuery) Reset() {
+	*x = ProfileTaskCommandQuery{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_profile_Profile_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ProfileTaskCommandQuery) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ProfileTaskCommandQuery) ProtoMessage() {}
+
+func (x *ProfileTaskCommandQuery) ProtoReflect() protoreflect.Message {
+	mi := &file_profile_Profile_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ProfileTaskCommandQuery.ProtoReflect.Descriptor instead.
+func (*ProfileTaskCommandQuery) Descriptor() ([]byte, []int) {
+	return file_profile_Profile_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *ProfileTaskCommandQuery) GetService() string {
+	if x != nil {
+		return x.Service
+	}
+	return ""
+}
+
+func (x *ProfileTaskCommandQuery) GetServiceInstance() string {
+	if x != nil {
+		return x.ServiceInstance
+	}
+	return ""
+}
+
+func (x *ProfileTaskCommandQuery) GetLastCommandTime() int64 {
+	if x != nil {
+		return x.LastCommandTime
+	}
+	return 0
+}
+
+// dumped thread snapshot
+type ThreadSnapshot struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// profile task id
+	TaskId string `protobuf:"bytes,1,opt,name=taskId,proto3" json:"taskId,omitempty"`
+	// dumped segment id
+	TraceSegmentId string `protobuf:"bytes,2,opt,name=traceSegmentId,proto3" json:"traceSegmentId,omitempty"`
+	// dump timestamp
+	Time int64 `protobuf:"varint,3,opt,name=time,proto3" json:"time,omitempty"`
+	// snapshot dump sequence, start with zero
+	Sequence int32 `protobuf:"varint,4,opt,name=sequence,proto3" json:"sequence,omitempty"`
+	// snapshot stack
+	Stack *ThreadStack `protobuf:"bytes,5,opt,name=stack,proto3" json:"stack,omitempty"`
+}
+
+func (x *ThreadSnapshot) Reset() {
+	*x = ThreadSnapshot{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_profile_Profile_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ThreadSnapshot) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ThreadSnapshot) ProtoMessage() {}
+
+func (x *ThreadSnapshot) ProtoReflect() protoreflect.Message {
+	mi := &file_profile_Profile_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ThreadSnapshot.ProtoReflect.Descriptor instead.
+func (*ThreadSnapshot) Descriptor() ([]byte, []int) {
+	return file_profile_Profile_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *ThreadSnapshot) GetTaskId() string {
+	if x != nil {
+		return x.TaskId
+	}
+	return ""
+}
+
+func (x *ThreadSnapshot) GetTraceSegmentId() string {
+	if x != nil {
+		return x.TraceSegmentId
+	}
+	return ""
+}
+
+func (x *ThreadSnapshot) GetTime() int64 {
+	if x != nil {
+		return x.Time
+	}
+	return 0
+}
+
+func (x *ThreadSnapshot) GetSequence() int32 {
+	if x != nil {
+		return x.Sequence
+	}
+	return 0
+}
+
+func (x *ThreadSnapshot) GetStack() *ThreadStack {
+	if x != nil {
+		return x.Stack
+	}
+	return nil
+}
+
+type ThreadStack struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// stack code signature list
+	CodeSignatures []string `protobuf:"bytes,1,rep,name=codeSignatures,proto3" json:"codeSignatures,omitempty"`
+}
+
+func (x *ThreadStack) Reset() {
+	*x = ThreadStack{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_profile_Profile_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ThreadStack) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ThreadStack) ProtoMessage() {}
+
+func (x *ThreadStack) ProtoReflect() protoreflect.Message {
+	mi := &file_profile_Profile_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ThreadStack.ProtoReflect.Descriptor instead.
+func (*ThreadStack) Descriptor() ([]byte, []int) {
+	return file_profile_Profile_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *ThreadStack) GetCodeSignatures() []string {
+	if x != nil {
+		return x.CodeSignatures
+	}
+	return nil
+}
+
+// profile task finished report
+type ProfileTaskFinishReport struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// current sniffer information
+	Service         string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
+	ServiceInstance string `protobuf:"bytes,2,opt,name=serviceInstance,proto3" json:"serviceInstance,omitempty"`
+	// profile task
+	TaskId string `protobuf:"bytes,3,opt,name=taskId,proto3" json:"taskId,omitempty"`
+}
+
+func (x *ProfileTaskFinishReport) Reset() {
+	*x = ProfileTaskFinishReport{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_profile_Profile_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ProfileTaskFinishReport) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ProfileTaskFinishReport) ProtoMessage() {}
+
+func (x *ProfileTaskFinishReport) ProtoReflect() protoreflect.Message {
+	mi := &file_profile_Profile_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ProfileTaskFinishReport.ProtoReflect.Descriptor instead.
+func (*ProfileTaskFinishReport) Descriptor() ([]byte, []int) {
+	return file_profile_Profile_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *ProfileTaskFinishReport) GetService() string {
+	if x != nil {
+		return x.Service
+	}
+	return ""
+}
+
+func (x *ProfileTaskFinishReport) GetServiceInstance() string {
+	if x != nil {
+		return x.ServiceInstance
+	}
+	return ""
+}
+
+func (x *ProfileTaskFinishReport) GetTaskId() string {
+	if x != nil {
+		return x.TaskId
+	}
+	return ""
+}
+
+var File_profile_Profile_proto protoreflect.FileDescriptor
+
+var file_profile_Profile_proto_rawDesc = []byte{
+	0x0a, 0x15, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b,
+	0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x1a, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x43,
+	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x87, 0x01, 0x0a, 0x17,
+	0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x6d, 0x6d, 0x61,
+	0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74,
+	0x61, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x6c,
+	0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+	0x64, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xb2, 0x01, 0x0a, 0x0e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64,
+	0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b,
+	0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64,
+	0x12, 0x26, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74,
+	0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x53,
+	0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08,
+	0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08,
+	0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x63,
+	0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c,
+	0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x53, 0x74,
+	0x61, 0x63, 0x6b, 0x52, 0x05, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x22, 0x35, 0x0a, 0x0b, 0x54, 0x68,
+	0x72, 0x65, 0x61, 0x64, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x64,
+	0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
+	0x09, 0x52, 0x0e, 0x63, 0x6f, 0x64, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
+	0x73, 0x22, 0x75, 0x0a, 0x17, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x61, 0x73, 0x6b,
+	0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07,
+	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73,
+	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
+	0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x32, 0x90, 0x02, 0x0a, 0x0b, 0x50, 0x72, 0x6f,
+	0x66, 0x69, 0x6c, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x5b, 0x0a, 0x16, 0x67, 0x65, 0x74, 0x50,
+	0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+	0x64, 0x73, 0x12, 0x26, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e,
+	0x76, 0x33, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x43, 0x6f,
+	0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x17, 0x2e, 0x73, 0x6b, 0x79,
+	0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61,
+	0x6e, 0x64, 0x73, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x0f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
+	0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x1d, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61,
+	0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x53,
+	0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x1a, 0x17, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c,
+	0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73,
+	0x22, 0x00, 0x28, 0x01, 0x12, 0x55, 0x0a, 0x10, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x61,
+	0x73, 0x6b, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x12, 0x26, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61,
+	0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65,
+	0x54, 0x61, 0x73, 0x6b, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74,
+	0x1a, 0x17, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33,
+	0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x00, 0x42, 0x81, 0x01, 0x0a, 0x35,
+	0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61,
+	0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x61, 0x70, 0x6d, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+	0x6b, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x66, 0x69,
+	0x6c, 0x65, 0x2e, 0x76, 0x33, 0x50, 0x01, 0x5a, 0x26, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b,
+	0x69, 0x6e, 0x67, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x61, 0x6e, 0x67,
+	0x75, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2f, 0x76, 0x33, 0xaa,
+	0x02, 0x1d, 0x53, 0x6b, 0x79, 0x57, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x4e, 0x65, 0x74,
+	0x77, 0x6f, 0x72, 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x56, 0x33, 0x62,
+	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_profile_Profile_proto_rawDescOnce sync.Once
+	file_profile_Profile_proto_rawDescData = file_profile_Profile_proto_rawDesc
+)
+
+func file_profile_Profile_proto_rawDescGZIP() []byte {
+	file_profile_Profile_proto_rawDescOnce.Do(func() {
+		file_profile_Profile_proto_rawDescData = protoimpl.X.CompressGZIP(file_profile_Profile_proto_rawDescData)
+	})
+	return file_profile_Profile_proto_rawDescData
+}
+
+var file_profile_Profile_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_profile_Profile_proto_goTypes = []interface{}{
+	(*ProfileTaskCommandQuery)(nil), // 0: skywalking.v3.ProfileTaskCommandQuery
+	(*ThreadSnapshot)(nil),          // 1: skywalking.v3.ThreadSnapshot
+	(*ThreadStack)(nil),             // 2: skywalking.v3.ThreadStack
+	(*ProfileTaskFinishReport)(nil), // 3: skywalking.v3.ProfileTaskFinishReport
+	(*v3.Commands)(nil),             // 4: skywalking.v3.Commands
+}
+var file_profile_Profile_proto_depIdxs = []int32{
+	2, // 0: skywalking.v3.ThreadSnapshot.stack:type_name -> skywalking.v3.ThreadStack
+	0, // 1: skywalking.v3.ProfileTask.getProfileTaskCommands:input_type -> skywalking.v3.ProfileTaskCommandQuery
+	1, // 2: skywalking.v3.ProfileTask.collectSnapshot:input_type -> skywalking.v3.ThreadSnapshot
+	3, // 3: skywalking.v3.ProfileTask.reportTaskFinish:input_type -> skywalking.v3.ProfileTaskFinishReport
+	4, // 4: skywalking.v3.ProfileTask.getProfileTaskCommands:output_type -> skywalking.v3.Commands
+	4, // 5: skywalking.v3.ProfileTask.collectSnapshot:output_type -> skywalking.v3.Commands
+	4, // 6: skywalking.v3.ProfileTask.reportTaskFinish:output_type -> skywalking.v3.Commands
+	4, // [4:7] is the sub-list for method output_type
+	1, // [1:4] is the sub-list for method input_type
+	1, // [1:1] is the sub-list for extension type_name
+	1, // [1:1] is the sub-list for extension extendee
+	0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_profile_Profile_proto_init() }
+func file_profile_Profile_proto_init() {
+	if File_profile_Profile_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_profile_Profile_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ProfileTaskCommandQuery); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_profile_Profile_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ThreadSnapshot); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_profile_Profile_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ThreadStack); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_profile_Profile_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ProfileTaskFinishReport); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_profile_Profile_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   4,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_profile_Profile_proto_goTypes,
+		DependencyIndexes: file_profile_Profile_proto_depIdxs,
+		MessageInfos:      file_profile_Profile_proto_msgTypes,
+	}.Build()
+	File_profile_Profile_proto = out.File
+	file_profile_Profile_proto_rawDesc = nil
+	file_profile_Profile_proto_goTypes = nil
+	file_profile_Profile_proto_depIdxs = nil
+}
diff --git a/protocol/gen-codes/skywalking/network/language/profile/v3/Profile_grpc.pb.go b/protocol/gen-codes/skywalking/network/language/profile/v3/Profile_grpc.pb.go
new file mode 100644
index 0000000..dcddb35
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/language/profile/v3/Profile_grpc.pb.go
@@ -0,0 +1,211 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package v3
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	v3 "skywalking/network/common/v3"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion7
+
+// ProfileTaskClient is the client API for ProfileTask service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type ProfileTaskClient interface {
+	// query all sniffer need to execute profile task commands
+	GetProfileTaskCommands(ctx context.Context, in *ProfileTaskCommandQuery, opts ...grpc.CallOption) (*v3.Commands, error)
+	// collect dumped thread snapshot
+	CollectSnapshot(ctx context.Context, opts ...grpc.CallOption) (ProfileTask_CollectSnapshotClient, error)
+	// report profiling task finished
+	ReportTaskFinish(ctx context.Context, in *ProfileTaskFinishReport, opts ...grpc.CallOption) (*v3.Commands, error)
+}
+
+type profileTaskClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewProfileTaskClient(cc grpc.ClientConnInterface) ProfileTaskClient {
+	return &profileTaskClient{cc}
+}
+
+func (c *profileTaskClient) GetProfileTaskCommands(ctx context.Context, in *ProfileTaskCommandQuery, opts ...grpc.CallOption) (*v3.Commands, error) {
+	out := new(v3.Commands)
+	err := c.cc.Invoke(ctx, "/skywalking.v3.ProfileTask/getProfileTaskCommands", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *profileTaskClient) CollectSnapshot(ctx context.Context, opts ...grpc.CallOption) (ProfileTask_CollectSnapshotClient, error) {
+	stream, err := c.cc.NewStream(ctx, &_ProfileTask_serviceDesc.Streams[0], "/skywalking.v3.ProfileTask/collectSnapshot", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &profileTaskCollectSnapshotClient{stream}
+	return x, nil
+}
+
+type ProfileTask_CollectSnapshotClient interface {
+	Send(*ThreadSnapshot) error
+	CloseAndRecv() (*v3.Commands, error)
+	grpc.ClientStream
+}
+
+type profileTaskCollectSnapshotClient struct {
+	grpc.ClientStream
+}
+
+func (x *profileTaskCollectSnapshotClient) Send(m *ThreadSnapshot) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *profileTaskCollectSnapshotClient) CloseAndRecv() (*v3.Commands, error) {
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	m := new(v3.Commands)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func (c *profileTaskClient) ReportTaskFinish(ctx context.Context, in *ProfileTaskFinishReport, opts ...grpc.CallOption) (*v3.Commands, error) {
+	out := new(v3.Commands)
+	err := c.cc.Invoke(ctx, "/skywalking.v3.ProfileTask/reportTaskFinish", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// ProfileTaskServer is the server API for ProfileTask service.
+// All implementations must embed UnimplementedProfileTaskServer
+// for forward compatibility
+type ProfileTaskServer interface {
+	// query all sniffer need to execute profile task commands
+	GetProfileTaskCommands(context.Context, *ProfileTaskCommandQuery) (*v3.Commands, error)
+	// collect dumped thread snapshot
+	CollectSnapshot(ProfileTask_CollectSnapshotServer) error
+	// report profiling task finished
+	ReportTaskFinish(context.Context, *ProfileTaskFinishReport) (*v3.Commands, error)
+	mustEmbedUnimplementedProfileTaskServer()
+}
+
+// UnimplementedProfileTaskServer must be embedded to have forward compatible implementations.
+type UnimplementedProfileTaskServer struct {
+}
+
+func (UnimplementedProfileTaskServer) GetProfileTaskCommands(context.Context, *ProfileTaskCommandQuery) (*v3.Commands, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetProfileTaskCommands not implemented")
+}
+func (UnimplementedProfileTaskServer) CollectSnapshot(ProfileTask_CollectSnapshotServer) error {
+	return status.Errorf(codes.Unimplemented, "method CollectSnapshot not implemented")
+}
+func (UnimplementedProfileTaskServer) ReportTaskFinish(context.Context, *ProfileTaskFinishReport) (*v3.Commands, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ReportTaskFinish not implemented")
+}
+func (UnimplementedProfileTaskServer) mustEmbedUnimplementedProfileTaskServer() {}
+
+// UnsafeProfileTaskServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to ProfileTaskServer will
+// result in compilation errors.
+type UnsafeProfileTaskServer interface {
+	mustEmbedUnimplementedProfileTaskServer()
+}
+
+func RegisterProfileTaskServer(s grpc.ServiceRegistrar, srv ProfileTaskServer) {
+	s.RegisterService(&_ProfileTask_serviceDesc, srv)
+}
+
+func _ProfileTask_GetProfileTaskCommands_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ProfileTaskCommandQuery)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(ProfileTaskServer).GetProfileTaskCommands(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/skywalking.v3.ProfileTask/getProfileTaskCommands",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(ProfileTaskServer).GetProfileTaskCommands(ctx, req.(*ProfileTaskCommandQuery))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _ProfileTask_CollectSnapshot_Handler(srv interface{}, stream grpc.ServerStream) error {
+	return srv.(ProfileTaskServer).CollectSnapshot(&profileTaskCollectSnapshotServer{stream})
+}
+
+type ProfileTask_CollectSnapshotServer interface {
+	SendAndClose(*v3.Commands) error
+	Recv() (*ThreadSnapshot, error)
+	grpc.ServerStream
+}
+
+type profileTaskCollectSnapshotServer struct {
+	grpc.ServerStream
+}
+
+func (x *profileTaskCollectSnapshotServer) SendAndClose(m *v3.Commands) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *profileTaskCollectSnapshotServer) Recv() (*ThreadSnapshot, error) {
+	m := new(ThreadSnapshot)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func _ProfileTask_ReportTaskFinish_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ProfileTaskFinishReport)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(ProfileTaskServer).ReportTaskFinish(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/skywalking.v3.ProfileTask/reportTaskFinish",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(ProfileTaskServer).ReportTaskFinish(ctx, req.(*ProfileTaskFinishReport))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _ProfileTask_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "skywalking.v3.ProfileTask",
+	HandlerType: (*ProfileTaskServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "getProfileTaskCommands",
+			Handler:    _ProfileTask_GetProfileTaskCommands_Handler,
+		},
+		{
+			MethodName: "reportTaskFinish",
+			Handler:    _ProfileTask_ReportTaskFinish_Handler,
+		},
+	},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "collectSnapshot",
+			Handler:       _ProfileTask_CollectSnapshot_Handler,
+			ClientStreams: true,
+		},
+	},
+	Metadata: "profile/Profile.proto",
+}
diff --git a/protocol/gen-codes/skywalking/network/logging/v3/Logging.pb.go b/protocol/gen-codes/skywalking/network/logging/v3/Logging.pb.go
new file mode 100644
index 0000000..f07c6f6
--- /dev/null
+++ b/protocol/gen-codes/skywalking/network/logging/v3/Logging.pb.go
@@ -0,0 +1,687 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.25.0
+// 	protoc        v3.14.0
+// source: logging/Logging.proto
+
+package v3
+
+import (
+	proto "github.com/golang/protobuf/proto"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	v3 "skywalking/network/common/v3"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+// Log data is collected through file scratcher of agent.
+// Natively, Satellite provides various ways to collect logs.
+type LogData struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// [Optional] The timestamp of the log, in millisecond.
+	// If not set, OAP server would use the received timestamp as log's timestamp, or relies on the OAP server analyzer.
+	Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	// [Required] **Service**. Represents a set/group of workloads which provide the same behaviours for incoming requests.
+	//
+	// The logic name represents the service. This would show as a separate node in the topology.
+	// The metrics analyzed from the spans, would be aggregated for this entity as the service level.
+	//
+	// If this is not the first element of the streaming, use the previous not-null name as the service name.
+	Service string `protobuf:"bytes,2,opt,name=service,proto3" json:"service,omitempty"`
+	// [Optional] **Service Instance**. Each individual workload in the Service group is known as an instance. Like `pods` in Kubernetes, it
+	// doesn't need to be a single OS process, however, if you are using instrument agents, an instance is actually a real OS process.
+	//
+	// The logic name represents the service instance. This would show as a separate node in the instance relationship.
+	// The metrics analyzed from the spans, would be aggregated for this entity as the service instance level.
+	ServiceInstance string `protobuf:"bytes,3,opt,name=serviceInstance,proto3" json:"serviceInstance,omitempty"`
+	// [Optional] **Endpoint**. A path in a service for incoming requests, such as an HTTP URI path or a gRPC service class + method signature.
+	//
+	// The logic name represents the endpoint, which logs belong.
+	Endpoint string `protobuf:"bytes,4,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
+	// [Required] The content of the log.
+	Body *LogDataBody `protobuf:"bytes,5,opt,name=body,proto3" json:"body,omitempty"`
+	// [Optional] Logs with trace context
+	TraceContext *TraceContext `protobuf:"bytes,6,opt,name=traceContext,proto3" json:"traceContext,omitempty"`
+	// [Optional] The available tags. OAP server could provide search/analysis capabilities base on these.
+	Tags []*v3.KeyStringValuePair `protobuf:"bytes,7,rep,name=tags,proto3" json:"tags,omitempty"`
+}
+
+func (x *LogData) Reset() {
+	*x = LogData{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_logging_Logging_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *LogData) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LogData) ProtoMessage() {}
+
+func (x *LogData) ProtoReflect() protoreflect.Message {
+	mi := &file_logging_Logging_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use LogData.ProtoReflect.Descriptor instead.
+func (*LogData) Descriptor() ([]byte, []int) {
+	return file_logging_Logging_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *LogData) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+func (x *LogData) GetService() string {
+	if x != nil {
+		return x.Service
+	}
+	return ""
+}
+
+func (x *LogData) GetServiceInstance() string {
+	if x != nil {
+		return x.ServiceInstance
+	}
+	return ""
+}
+
+func (x *LogData) GetEndpoint() string {
+	if x != nil {
+		return x.Endpoint
+	}
+	return ""
+}
+
+func (x *LogData) GetBody() *LogDataBody {
+	if x != nil {
+		return x.Body
+	}
+	return nil
+}
+
+func (x *LogData) GetTraceContext() *TraceContext {
+	if x != nil {
+		return x.TraceContext
+	}
+	return nil
+}
+
+func (x *LogData) GetTags() []*v3.KeyStringValuePair {
+	if x != nil {
+		return x.Tags
+	}
+	return nil
+}
+
+// The content of the log data
+type LogDataBody struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// A type to match analyzer(s) at the OAP server.
+	// The data could be analysis at the client side, but could be partial
+	Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
+	// Content with extendable format.
+	//
+	// Types that are assignable to Content:
+	//	*LogDataBody_Text
+	//	*LogDataBody_Json
+	//	*LogDataBody_Yaml
+	Content isLogDataBody_Content `protobuf_oneof:"content"`
+}
+
+func (x *LogDataBody) Reset() {
+	*x = LogDataBody{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_logging_Logging_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *LogDataBody) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LogDataBody) ProtoMessage() {}
+
+func (x *LogDataBody) ProtoReflect() protoreflect.Message {
+	mi := &file_logging_Logging_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use LogDataBody.ProtoReflect.Descriptor instead.
+func (*LogDataBody) Descriptor() ([]byte, []int) {
+	return file_logging_Logging_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *LogDataBody) GetType() string {
+	if x != nil {
+		return x.Type
+	}
+	return ""
+}
+
+func (m *LogDataBody) GetContent() isLogDataBody_Content {
+	if m != nil {
+		return m.Content
+	}
+	return nil
+}
+
+func (x *LogDataBody) GetText() *TextLog {
+	if x, ok := x.GetContent().(*LogDataBody_Text); ok {
+		return x.Text
+	}
+	return nil
+}
+
+func (x *LogDataBody) GetJson() *JSONLog {
+	if x, ok := x.GetContent().(*LogDataBody_Json); ok {
+		return x.Json
+	}
+	return nil
+}
+
+func (x *LogDataBody) GetYaml() *YAMLLog {
+	if x, ok := x.GetContent().(*LogDataBody_Yaml); ok {
+		return x.Yaml
+	}
+	return nil
+}
+
+type isLogDataBody_Content interface {
+	isLogDataBody_Content()
+}
+
+type LogDataBody_Text struct {
+	Text *TextLog `protobuf:"bytes,2,opt,name=text,proto3,oneof"`
+}
+
+type LogDataBody_Json struct {
+	Json *JSONLog `protobuf:"bytes,3,opt,name=json,proto3,oneof"`
+}
+
+type LogDataBody_Yaml struct {
+	Yaml *YAMLLog `protobuf:"bytes,4,opt,name=yaml,proto3,oneof"`
+}
+
+func (*LogDataBody_Text) isLogDataBody_Content() {}
+
+func (*LogDataBody_Json) isLogDataBody_Content() {}
+
+func (*LogDataBody_Yaml) isLogDataBody_Content() {}
+
+// Literal text log, typically requires regex or split mechanism to filter meaningful info.
+type TextLog struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"`
+}
+
+func (x *TextLog) Reset() {
+	*x = TextLog{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_logging_Logging_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *TextLog) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TextLog) ProtoMessage() {}
+
+func (x *TextLog) ProtoReflect() protoreflect.Message {
+	mi := &file_logging_Logging_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use TextLog.ProtoReflect.Descriptor instead.
+func (*TextLog) Descriptor() ([]byte, []int) {
+	return file_logging_Logging_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *TextLog) GetText() string {
+	if x != nil {
+		return x.Text
+	}
+	return ""
+}
+
+// JSON formatted log. The json field represents the string could be formatted as a JSON object.
+type JSONLog struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Json string `protobuf:"bytes,1,opt,name=json,proto3" json:"json,omitempty"`
+}
+
+func (x *JSONLog) Reset() {
+	*x = JSONLog{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_logging_Logging_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *JSONLog) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*JSONLog) ProtoMessage() {}
+
+func (x *JSONLog) ProtoReflect() protoreflect.Message {
+	mi := &file_logging_Logging_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use JSONLog.ProtoReflect.Descriptor instead.
+func (*JSONLog) Descriptor() ([]byte, []int) {
+	return file_logging_Logging_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *JSONLog) GetJson() string {
+	if x != nil {
+		return x.Json
+	}
+	return ""
+}
+
+// YAML formatted log. The yaml field represents the string could be formatted as a YAML map.
+type YAMLLog struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Yaml string `protobuf:"bytes,1,opt,name=yaml,proto3" json:"yaml,omitempty"`
+}
+
+func (x *YAMLLog) Reset() {
+	*x = YAMLLog{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_logging_Logging_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *YAMLLog) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*YAMLLog) ProtoMessage() {}
+
+func (x *YAMLLog) ProtoReflect() protoreflect.Message {
+	mi := &file_logging_Logging_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use YAMLLog.ProtoReflect.Descriptor instead.
+func (*YAMLLog) Descriptor() ([]byte, []int) {
+	return file_logging_Logging_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *YAMLLog) GetYaml() string {
+	if x != nil {
+		return x.Yaml
+	}
+	return ""
+}
+
+// Logs with trace context, represent agent system has injects context(IDs) into log text.
+type TraceContext struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// [Optional] A string id represents the whole trace.
+	TraceId string `protobuf:"bytes,1,opt,name=traceId,proto3" json:"traceId,omitempty"`
+	// [Optional] A unique id represents this segment. Other segments could use this id to reference as a child segment.
+	TraceSegmentId string `protobuf:"bytes,2,opt,name=traceSegmentId,proto3" json:"traceSegmentId,omitempty"`
+	// [Optional] The number id of the span. Should be unique in the whole segment.
+	// Starting at 0.
+	SpanId int32 `protobuf:"varint,3,opt,name=spanId,proto3" json:"spanId,omitempty"`
+}
+
+func (x *TraceContext) Reset() {
+	*x = TraceContext{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_logging_Logging_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *TraceContext) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TraceContext) ProtoMessage() {}
+
+func (x *TraceContext) ProtoReflect() protoreflect.Message {
+	mi := &file_logging_Logging_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use TraceContext.ProtoReflect.Descriptor instead.
+func (*TraceContext) Descriptor() ([]byte, []int) {
+	return file_logging_Logging_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *TraceContext) GetTraceId() string {
+	if x != nil {
+		return x.TraceId
+	}
+	return ""
+}
+
+func (x *TraceContext) GetTraceSegmentId() string {
+	if x != nil {
+		return x.TraceSegmentId
+	}
+	return ""
+}
+
+func (x *TraceContext) GetSpanId() int32 {
+	if x != nil {
+		return x.SpanId
+	}
+	return 0
+}
+
+var File_logging_Logging_proto protoreflect.FileDescriptor
+
+var file_logging_Logging_proto_rawDesc = []byte{
+	0x0a, 0x15, 0x6c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x2f, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e,
+	0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b,
+	0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x1a, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x43,
+	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xaf, 0x02, 0x0a, 0x07,
+	0x4c, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
+	0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65,
+	0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
+	0x28, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+	0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64,
+	0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64,
+	0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67,
+	0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x42, 0x6f, 0x64, 0x79, 0x52,
+	0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x3f, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f,
+	0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x6b,
+	0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x72, 0x61, 0x63,
+	0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x63, 0x65, 0x43,
+	0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x07,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e,
+	0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61,
+	0x6c, 0x75, 0x65, 0x50, 0x61, 0x69, 0x72, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x22, 0xb6, 0x01,
+	0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x12, 0x0a,
+	0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70,
+	0x65, 0x12, 0x2c, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x16, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e,
+	0x54, 0x65, 0x78, 0x74, 0x4c, 0x6f, 0x67, 0x48, 0x00, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12,
+	0x2c, 0x0a, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e,
+	0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4a, 0x53,
+	0x4f, 0x4e, 0x4c, 0x6f, 0x67, 0x48, 0x00, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x12, 0x2c, 0x0a,
+	0x04, 0x79, 0x61, 0x6d, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x6b,
+	0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x59, 0x41, 0x4d, 0x4c,
+	0x4c, 0x6f, 0x67, 0x48, 0x00, 0x52, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x42, 0x09, 0x0a, 0x07, 0x63,
+	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x1d, 0x0a, 0x07, 0x54, 0x65, 0x78, 0x74, 0x4c, 0x6f,
+	0x67, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x04, 0x74, 0x65, 0x78, 0x74, 0x22, 0x1d, 0x0a, 0x07, 0x4a, 0x53, 0x4f, 0x4e, 0x4c, 0x6f, 0x67,
+	0x12, 0x12, 0x0a, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+	0x6a, 0x73, 0x6f, 0x6e, 0x22, 0x1d, 0x0a, 0x07, 0x59, 0x41, 0x4d, 0x4c, 0x4c, 0x6f, 0x67, 0x12,
+	0x12, 0x0a, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x79,
+	0x61, 0x6d, 0x6c, 0x22, 0x68, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74,
+	0x65, 0x78, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x26, 0x0a,
+	0x0e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x67, 0x6d,
+	0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x32, 0x52, 0x0a,
+	0x10, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x12, 0x3e, 0x0a, 0x07, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x73,
+	0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f, 0x67,
+	0x44, 0x61, 0x74, 0x61, 0x1a, 0x17, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e,
... 1464 lines suppressed ...