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

kezhenxu94 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-cli.git


The following commit(s) were added to refs/heads/master by this push:
     new ae085de  Add event report command (#88)
ae085de is described below

commit ae085deb32434a0859e49c45819fed7a5c4010b5
Author: Hoshea Jiang <[email protected]>
AuthorDate: Tue Jan 26 16:40:24 2021 +0800

    Add event report command (#88)
---
 .gitmodules                                        |   5 +-
 Makefile                                           |  18 +-
 README.md                                          |  25 ++
 cmd/swctl/main.go                                  |  26 +-
 data-collect-protocol                              |   1 +
 examples/.skywalking.yaml                          |   1 +
 .../skywalking/network/common/v3/Common.pb.go      | 441 +++++++++++++++++++++
 gen-codes/skywalking/network/event/v3/Event.pb.go  | 411 +++++++++++++++++++
 .../skywalking/network/event/v3/Event_grpc.pb.go   | 155 ++++++++
 gen-codes/skywalking/network/go.mod                |   9 +
 gen-codes/skywalking/network/go.sum                |  85 ++++
 go.mod                                             |   6 +-
 go.sum                                             |  10 +
 internal/commands/event/event.go                   |  30 ++
 internal/commands/event/report.go                  | 119 ++++++
 internal/commands/healthcheck/healthcheck.go       |   8 +-
 internal/commands/interceptor/event.go             |  44 ++
 internal/commands/interceptor/event_test.go        |  78 ++++
 internal/model/type.go                             |  52 +++
 pkg/grpc/grpc.go                                   |  51 +++
 scripts/install_protoc.sh                          |  32 ++
 21 files changed, 1585 insertions(+), 22 deletions(-)

diff --git a/.gitmodules b/.gitmodules
index 3405629..d7de06d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
 [submodule "query-protocol"]
        path = query-protocol
-       url = http://github.com/apache/skywalking-query-protocol/
\ No newline at end of file
+       url = http://github.com/apache/skywalking-query-protocol/
+[submodule "data-collect-protocol"]
+       path = data-collect-protocol
+       url = https://github.com/apache/skywalking-data-collect-protocol.git
diff --git a/Makefile b/Makefile
index 24dc586..cd5b01a 100644
--- a/Makefile
+++ b/Makefile
@@ -28,6 +28,7 @@ GO = go
 GO_PATH = $$($(GO) env GOPATH)
 GO_BUILD = $(GO) build
 GO_GET = $(GO) get
+GO_INSTALL = $(GO) install
 GO_TEST = $(GO) test
 GO_LINT = $(GO_PATH)/bin/golangci-lint
 GO_LICENSER = $(GO_PATH)/bin/go-licenser
@@ -38,6 +39,10 @@ GO_BINDATA = $(GO_PATH)/bin/go-bindata
 GO_BUILD_FLAGS = -v
 GO_BUILD_LDFLAGS = -X main.version=$(VERSION)
 GQL_GEN = $(GO_PATH)/bin/gqlgen
+PROTOC = protoc
+
+GEN_CODE_PATH = gen-codes
+COLLECT_PROTOCOL_MODULE = skywalking/network
 
 PLATFORMS := windows linux darwin
 os = $(word 1, $@)
@@ -54,6 +59,9 @@ tools:
        $(GO_LINT) version || curl -sfL 
https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh 
-s -- -b $(GO_PATH)/bin
        $(GO_LICENSER) -version || GO111MODULE=off $(GO_GET) -u 
github.com/elastic/go-licenser
        $(GQL_GEN) version || GO111MODULE=off $(GO_GET) -u 
github.com/99designs/gqlgen
+       $(PROTOC) --version || sh scripts/install_protoc.sh
+       $(GO_INSTALL) google.golang.org/protobuf/cmd/protoc-gen-go
+       $(GO_INSTALL) google.golang.org/grpc/cmd/protoc-gen-go-grpc
 
 deps: tools
        $(GO_GET) -v -t -d ./...
@@ -66,6 +74,14 @@ assets: tools
                && ../scripts/build-header.sh assets.gen.go \
                && cd ..
 
+.PHONY: proto-gen
+proto-gen: tools
+       $(PROTOC) -I=data-collect-protocol --go_out=$(GEN_CODE_PATH) 
--go-grpc_out=$(GEN_CODE_PATH) data-collect-protocol/common/*.proto 
data-collect-protocol/event/*.proto
+       cd $(GEN_CODE_PATH)/$(COLLECT_PROTOCOL_MODULE) \
+               && $(GO) mod init $(COLLECT_PROTOCOL_MODULE) \
+               && $(GO) mod tidy
+       -scripts/build-header.sh 
$(GEN_CODE_PATH)/$(COLLECT_PROTOCOL_MODULE)/event/v3/Event_grpc.pb.go
+
 gqlgen: tools
        echo 'scalar Long' > query-protocol/schema.graphqls
        $(GQL_GEN) generate
@@ -94,7 +110,7 @@ build: deps windows linux darwin
 
 .PHONY: license
 license: clean tools
-       $(GO_LICENSER) -d -licensor='Apache Software Foundation (ASF)' .
+       $(GO_LICENSER) -d -exclude=$(GEN_CODE_PATH) -licensor='Apache Software 
Foundation (ASF)' .
 
 .PHONY: verify
 verify: clean license lint test
diff --git a/README.md b/README.md
index 2d43437..8f101cd 100644
--- a/README.md
+++ b/README.md
@@ -85,6 +85,7 @@ This section covers all the available commands in SkyWalking 
CLI and their usage
 | `--config` | from where the default options values will be loaded | 
`~/.skywalking.yml`, example can be found [here](examples/.skywalking.yaml) |
 | `--debug` | enable debug mode, will print more detailed information at 
runtime | `false` |
 | `--base-url` | base url of GraphQL backend | 
`http://127.0.0.1:12800/graphql` |
+| `--grpcAddr` | The address of gRPC endpoint | `127.0.0.1:11800` |
 | `--username` | username of `Basic` authorization | `` |
 | `--password` | password of `Basic` authorization | `` |
 | `--authorization` | authorization header, can be something like `Basic 
base64<username:password>` or `Bearer jwt-token`, if `authorization` is set, 
`username` and `password` are ignored | `` |
@@ -377,6 +378,30 @@ You can imitate the content of [the default template 
file](examples/global.yml)
 
 </details>
 
+### `event`
+
+#### `report`
+
+<details>
+
+<summary>event report --uuid=uuid --service=service --name=name 
--message=message --startTime=startTime [--endTime=endTime] 
[--instance=instance] [--endpoint=endpoint] [--type=type] 
[parameters...]</summary>
+
+`event report` reports an event to OAP server via gRPC.
+
+| argument | description | default |
+| :--- | :--- | :--- |
+| `uuid` | The unique ID of the event. |  |
+| `service` | The service of the event occurred on. |  |
+| `instance` | The service instance of the event occurred on. |  |
+| `endpoint` | The endpoint of the event occurred on. |  |
+| `name` | The name of the event. For example, 'Reboot' and 'Upgrade' etc. |  |
+| `type` | The type of the event, could be `Normal` or `Error`. | `Normal` |
+| `message` | The detail of the event. This should be a one-line message that 
briefly describes why the event is reported. |  |
+| `startTime` | The start time (in milliseconds) of the event, measured 
between the current time and midnight, January 1, 1970 UTC. |  |
+| `endTime` | The end time (in milliseconds) of the event, measured between 
the current time and midnight, January 1, 1970 UTC. |  |
+
+</details>
+
 # Use Cases
 
 <details>
diff --git a/cmd/swctl/main.go b/cmd/swctl/main.go
index 712fbcb..679e62a 100644
--- a/cmd/swctl/main.go
+++ b/cmd/swctl/main.go
@@ -21,25 +21,22 @@ import (
        "io/ioutil"
        "os"
 
-       "github.com/apache/skywalking-cli/internal/commands/healthcheck"
-       "github.com/apache/skywalking-cli/internal/commands/trace"
-
        "github.com/apache/skywalking-cli/internal/commands/dashboard"
-
-       "github.com/apache/skywalking-cli/internal/commands/metrics"
-
        "github.com/apache/skywalking-cli/internal/commands/endpoint"
+       "github.com/apache/skywalking-cli/internal/commands/event"
+       "github.com/apache/skywalking-cli/internal/commands/healthcheck"
        "github.com/apache/skywalking-cli/internal/commands/install"
        "github.com/apache/skywalking-cli/internal/commands/instance"
-
-       "github.com/sirupsen/logrus"
-       "github.com/urfave/cli"
-       "github.com/urfave/cli/altsrc"
-
        "github.com/apache/skywalking-cli/internal/commands/interceptor"
+       "github.com/apache/skywalking-cli/internal/commands/metrics"
        "github.com/apache/skywalking-cli/internal/commands/service"
+       "github.com/apache/skywalking-cli/internal/commands/trace"
        "github.com/apache/skywalking-cli/internal/logger"
        "github.com/apache/skywalking-cli/pkg/util"
+
+       "github.com/sirupsen/logrus"
+       "github.com/urfave/cli"
+       "github.com/urfave/cli/altsrc"
 )
 
 var log *logrus.Logger
@@ -67,6 +64,12 @@ func main() {
                        Value:    "http://127.0.0.1:12800/graphql";,
                }),
                altsrc.NewStringFlag(cli.StringFlag{
+                       Name:     "grpcAddr",
+                       Usage:    "`host:port` to connect",
+                       Value:    "127.0.0.1:11800",
+                       Required: false,
+               }),
+               altsrc.NewStringFlag(cli.StringFlag{
                        Name:     "username",
                        Required: false,
                        Usage:    "username of basic authorization",
@@ -112,6 +115,7 @@ func main() {
                healthcheck.Command,
                dashboard.Command,
                install.Command,
+               event.Command,
        }
 
        app.Before = interceptor.BeforeChain([]cli.BeforeFunc{
diff --git a/data-collect-protocol b/data-collect-protocol
new file mode 160000
index 0000000..03963bf
--- /dev/null
+++ b/data-collect-protocol
@@ -0,0 +1 @@
+Subproject commit 03963bfecba88e9bd477535e8f8698675a6ebdfa
diff --git a/examples/.skywalking.yaml b/examples/.skywalking.yaml
index 04355cd..6e3319b 100644
--- a/examples/.skywalking.yaml
+++ b/examples/.skywalking.yaml
@@ -16,5 +16,6 @@
 # under the License.
 
 base-url: http://demo.skywalking.apache.org/graphql
+grpcAddr: 127.0.0.1:11800
 username: basic-auth-username
 password: basic-auth-password
diff --git a/gen-codes/skywalking/network/common/v3/Common.pb.go 
b/gen-codes/skywalking/network/common/v3/Common.pb.go
new file mode 100644
index 0000000..a3c545d
--- /dev/null
+++ b/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/gen-codes/skywalking/network/event/v3/Event.pb.go 
b/gen-codes/skywalking/network/event/v3/Event.pb.go
new file mode 100644
index 0000000..4812e3d
--- /dev/null
+++ b/gen-codes/skywalking/network/event/v3/Event.pb.go
@@ -0,0 +1,411 @@
+//
+// 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 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 Type int32
+
+const (
+       Type_Normal Type = 0
+       Type_Error  Type = 1
+)
+
+// Enum value maps for Type.
+var (
+       Type_name = map[int32]string{
+               0: "Normal",
+               1: "Error",
+       }
+       Type_value = map[string]int32{
+               "Normal": 0,
+               "Error":  1,
+       }
+)
+
+func (x Type) Enum() *Type {
+       p := new(Type)
+       *p = x
+       return p
+}
+
+func (x Type) String() string {
+       return protoimpl.X.EnumStringOf(x.Descriptor(), 
protoreflect.EnumNumber(x))
+}
+
+func (Type) Descriptor() protoreflect.EnumDescriptor {
+       return file_event_Event_proto_enumTypes[0].Descriptor()
+}
+
+func (Type) Type() protoreflect.EnumType {
+       return &file_event_Event_proto_enumTypes[0]
+}
+
+func (x Type) Number() protoreflect.EnumNumber {
+       return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Type.Descriptor instead.
+func (Type) EnumDescriptor() ([]byte, []int) {
+       return file_event_Event_proto_rawDescGZIP(), []int{0}
+}
+
+type Event struct {
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       // Unique ID of the event. Because an event may span a long period of 
time, the UUID is necessary to associate the
+       // start time with the end time of the same event.
+       Uuid string `protobuf:"bytes,1,opt,name=uuid,proto3" 
json:"uuid,omitempty"`
+       // The source object that the event occurs on.
+       Source *Source `protobuf:"bytes,2,opt,name=source,proto3" 
json:"source,omitempty"`
+       // The name of the event. For example, `Reboot`, `Upgrade` etc.
+       Name string `protobuf:"bytes,3,opt,name=name,proto3" 
json:"name,omitempty"`
+       // The type of the event. This field is friendly for UI visualization, 
where events of type `Normal` are considered as normal operations,
+       // while `Error` is considered as unexpected operations, such as 
`Crash` events, therefore we can mark them with different colors to be easier 
identified.
+       Type Type 
`protobuf:"varint,4,opt,name=type,proto3,enum=skywalking.v3.Type" 
json:"type,omitempty"`
+       // The detail of the event that describes why this event happened. This 
should be a one-line message that briefly describes why the event is reported.
+       // Examples of an `Upgrade` event may be something like `Upgrade from 
${from_version} to ${to_version}`.
+       // It's NOT encouraged to include the detailed logs of this event, such 
as the exception stack trace.
+       Message string `protobuf:"bytes,5,opt,name=message,proto3" 
json:"message,omitempty"`
+       // The parameters in the `message` field.
+       Parameters map[string]string 
`protobuf:"bytes,6,rep,name=parameters,proto3" json:"parameters,omitempty" 
protobuf_key:"bytes,1,opt,name=key,proto3" 
protobuf_val:"bytes,2,opt,name=value,proto3"`
+       // The start time (in milliseconds) of the event, measured between the 
current time and midnight, January 1, 1970 UTC.
+       // This field is mandatory when an event occurs.
+       StartTime int64 `protobuf:"varint,7,opt,name=startTime,proto3" 
json:"startTime,omitempty"`
+       // The end time (in milliseconds) of the event. , measured between the 
current time and midnight, January 1, 1970 UTC.
+       // This field may be empty if the event has not stopped yet, otherwise 
it should be a valid timestamp after `startTime`.
+       EndTime int64 `protobuf:"varint,8,opt,name=endTime,proto3" 
json:"endTime,omitempty"`
+}
+
+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) GetUuid() string {
+       if x != nil {
+               return x.Uuid
+       }
+       return ""
+}
+
+func (x *Event) GetSource() *Source {
+       if x != nil {
+               return x.Source
+       }
+       return nil
+}
+
+func (x *Event) GetName() string {
+       if x != nil {
+               return x.Name
+       }
+       return ""
+}
+
+func (x *Event) GetType() Type {
+       if x != nil {
+               return x.Type
+       }
+       return Type_Normal
+}
+
+func (x *Event) GetMessage() string {
+       if x != nil {
+               return x.Message
+       }
+       return ""
+}
+
+func (x *Event) GetParameters() map[string]string {
+       if x != nil {
+               return x.Parameters
+       }
+       return nil
+}
+
+func (x *Event) GetStartTime() int64 {
+       if x != nil {
+               return x.StartTime
+       }
+       return 0
+}
+
+func (x *Event) GetEndTime() int64 {
+       if x != nil {
+               return x.EndTime
+       }
+       return 0
+}
+
+// If the event occurs on a service ONLY, the `service` field is mandatory, 
the serviceInstance field and endpoint field are optional;
+// If the event occurs on a service instance, the `service` and 
`serviceInstance` are mandatory and endpoint is optional;
+// If the event occurs on an endpoint, `service` and `endpoint` are mandatory, 
`serviceInstance` is optional;
+type Source struct {
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       Service         string `protobuf:"bytes,1,opt,name=service,proto3" 
json:"service,omitempty"`
+       ServiceInstance string 
`protobuf:"bytes,2,opt,name=serviceInstance,proto3" 
json:"serviceInstance,omitempty"`
+       Endpoint        string `protobuf:"bytes,3,opt,name=endpoint,proto3" 
json:"endpoint,omitempty"`
+}
+
+func (x *Source) Reset() {
+       *x = Source{}
+       if protoimpl.UnsafeEnabled {
+               mi := &file_event_Event_proto_msgTypes[1]
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               ms.StoreMessageInfo(mi)
+       }
+}
+
+func (x *Source) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Source) ProtoMessage() {}
+
+func (x *Source) ProtoReflect() protoreflect.Message {
+       mi := &file_event_Event_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 Source.ProtoReflect.Descriptor instead.
+func (*Source) Descriptor() ([]byte, []int) {
+       return file_event_Event_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *Source) GetService() string {
+       if x != nil {
+               return x.Service
+       }
+       return ""
+}
+
+func (x *Source) GetServiceInstance() string {
+       if x != nil {
+               return x.ServiceInstance
+       }
+       return ""
+}
+
+func (x *Source) GetEndpoint() string {
+       if x != nil {
+               return x.Endpoint
+       }
+       return ""
+}
+
+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, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x43, 
0x6f, 0x6d, 0x6d, 0x6f,
+       0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xde, 0x02, 0x0a, 0x05, 
0x45, 0x76, 0x65, 0x6e,
+       0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 
0x01, 0x28, 0x09, 0x52,
+       0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x06, 0x73, 0x6f, 0x75, 
0x72, 0x63, 0x65, 0x18,
+       0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x6b, 0x79, 0x77, 
0x61, 0x6c, 0x6b, 0x69,
+       0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 
0x52, 0x06, 0x73, 0x6f,
+       0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 
0x18, 0x03, 0x20, 0x01,
+       0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x04, 
0x74, 0x79, 0x70, 0x65,
+       0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x73, 0x6b, 0x79, 
0x77, 0x61, 0x6c, 0x6b,
+       0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 
0x04, 0x74, 0x79, 0x70,
+       0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 
0x18, 0x05, 0x20, 0x01,
+       0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 
0x44, 0x0a, 0x0a, 0x70,
+       0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 
0x03, 0x28, 0x0b, 0x32,
+       0x24, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 
0x2e, 0x76, 0x33, 0x2e,
+       0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 
0x74, 0x65, 0x72, 0x73,
+       0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 
0x65, 0x74, 0x65, 0x72,
+       0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 
0x6d, 0x65, 0x18, 0x07,
+       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, 0x08, 
0x20, 0x01, 0x28, 0x03,
+       0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x1a, 0x3d, 0x0a, 
0x0f, 0x50, 0x61, 0x72,
+       0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 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, 0x22, 0x68, 0x0a, 0x06, 
0x53, 0x6f, 0x75, 0x72,
+       0x63, 0x65, 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, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 
0x64, 0x70, 0x6f, 0x69,
+       0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 
0x64, 0x70, 0x6f, 0x69,
+       0x6e, 0x74, 0x2a, 0x1d, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 
0x0a, 0x06, 0x4e, 0x6f,
+       0x72, 0x6d, 0x61, 0x6c, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x72, 
0x72, 0x6f, 0x72, 0x10,
+       0x01, 0x32, 0x4c, 0x0a, 0x0c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x65, 
0x72, 0x76, 0x69, 0x63,
+       0x65, 0x12, 0x3c, 0x0a, 0x07, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 
0x12, 0x14, 0x2e, 0x73,
+       0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 
0x2e, 0x45, 0x76, 0x65,
+       0x6e, 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, 0x42,
+       0x6b, 0x0a, 0x2a, 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, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x76, 
0x33, 0x50, 0x01, 0x5a,
+       0x1b, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 
0x6e, 0x65, 0x74, 0x77,
+       0x6f, 0x72, 0x6b, 0x2f, 0x65, 0x76, 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_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, 3)
+var file_event_Event_proto_goTypes = []interface{}{
+       (Type)(0),           // 0: skywalking.v3.Type
+       (*Event)(nil),       // 1: skywalking.v3.Event
+       (*Source)(nil),      // 2: skywalking.v3.Source
+       nil,                 // 3: skywalking.v3.Event.ParametersEntry
+       (*v3.Commands)(nil), // 4: skywalking.v3.Commands
+}
+var file_event_Event_proto_depIdxs = []int32{
+       2, // 0: skywalking.v3.Event.source:type_name -> skywalking.v3.Source
+       0, // 1: skywalking.v3.Event.type:type_name -> skywalking.v3.Type
+       3, // 2: skywalking.v3.Event.parameters:type_name -> 
skywalking.v3.Event.ParametersEntry
+       1, // 3: skywalking.v3.EventService.collect:input_type -> 
skywalking.v3.Event
+       4, // 4: skywalking.v3.EventService.collect:output_type -> 
skywalking.v3.Commands
+       4, // [4:5] is the sub-list for method output_type
+       3, // [3:4] is the sub-list for method input_type
+       3, // [3:3] is the sub-list for extension type_name
+       3, // [3:3] is the sub-list for extension extendee
+       0, // [0:3] 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[1].Exporter = func(v 
interface{}, i int) interface{} {
+                       switch v := v.(*Source); 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_event_Event_proto_rawDesc,
+                       NumEnums:      1,
+                       NumMessages:   3,
+                       NumExtensions: 0,
+                       NumServices:   1,
+               },
+               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/gen-codes/skywalking/network/event/v3/Event_grpc.pb.go 
b/gen-codes/skywalking/network/event/v3/Event_grpc.pb.go
new file mode 100644
index 0000000..45865b0
--- /dev/null
+++ b/gen-codes/skywalking/network/event/v3/Event_grpc.pb.go
@@ -0,0 +1,155 @@
+// 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.
+
+// 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
+
+// EventServiceClient is the client API for EventService 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 EventServiceClient interface {
+       // When reporting an event, you typically call the collect function 
twice, one for starting of the event and the other one for ending of the event, 
with the same UUID.
+       // There are also cases where you have both start time and end time 
already, for example, when exporting events from a 3rd-party system,
+       // the start time and end time are already known so that you can call 
the collect function only once.
+       Collect(ctx context.Context, opts ...grpc.CallOption) 
(EventService_CollectClient, error)
+}
+
+type eventServiceClient struct {
+       cc grpc.ClientConnInterface
+}
+
+func NewEventServiceClient(cc grpc.ClientConnInterface) EventServiceClient {
+       return &eventServiceClient{cc}
+}
+
+func (c *eventServiceClient) Collect(ctx context.Context, opts 
...grpc.CallOption) (EventService_CollectClient, error) {
+       stream, err := c.cc.NewStream(ctx, 
&_EventService_serviceDesc.Streams[0], "/skywalking.v3.EventService/collect", 
opts...)
+       if err != nil {
+               return nil, err
+       }
+       x := &eventServiceCollectClient{stream}
+       return x, nil
+}
+
+type EventService_CollectClient interface {
+       Send(*Event) error
+       CloseAndRecv() (*v3.Commands, error)
+       grpc.ClientStream
+}
+
+type eventServiceCollectClient struct {
+       grpc.ClientStream
+}
+
+func (x *eventServiceCollectClient) Send(m *Event) error {
+       return x.ClientStream.SendMsg(m)
+}
+
+func (x *eventServiceCollectClient) 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
+}
+
+// EventServiceServer is the server API for EventService service.
+// All implementations must embed UnimplementedEventServiceServer
+// for forward compatibility
+type EventServiceServer interface {
+       // When reporting an event, you typically call the collect function 
twice, one for starting of the event and the other one for ending of the event, 
with the same UUID.
+       // There are also cases where you have both start time and end time 
already, for example, when exporting events from a 3rd-party system,
+       // the start time and end time are already known so that you can call 
the collect function only once.
+       Collect(EventService_CollectServer) error
+       mustEmbedUnimplementedEventServiceServer()
+}
+
+// UnimplementedEventServiceServer must be embedded to have forward compatible 
implementations.
+type UnimplementedEventServiceServer struct {
+}
+
+func (UnimplementedEventServiceServer) Collect(EventService_CollectServer) 
error {
+       return status.Errorf(codes.Unimplemented, "method Collect not 
implemented")
+}
+func (UnimplementedEventServiceServer) 
mustEmbedUnimplementedEventServiceServer() {}
+
+// UnsafeEventServiceServer may be embedded to opt out of forward 
compatibility for this service.
+// Use of this interface is not recommended, as added methods to 
EventServiceServer will
+// result in compilation errors.
+type UnsafeEventServiceServer interface {
+       mustEmbedUnimplementedEventServiceServer()
+}
+
+func RegisterEventServiceServer(s grpc.ServiceRegistrar, srv 
EventServiceServer) {
+       s.RegisterService(&_EventService_serviceDesc, srv)
+}
+
+func _EventService_Collect_Handler(srv interface{}, stream grpc.ServerStream) 
error {
+       return 
srv.(EventServiceServer).Collect(&eventServiceCollectServer{stream})
+}
+
+type EventService_CollectServer interface {
+       SendAndClose(*v3.Commands) error
+       Recv() (*Event, error)
+       grpc.ServerStream
+}
+
+type eventServiceCollectServer struct {
+       grpc.ServerStream
+}
+
+func (x *eventServiceCollectServer) SendAndClose(m *v3.Commands) error {
+       return x.ServerStream.SendMsg(m)
+}
+
+func (x *eventServiceCollectServer) Recv() (*Event, error) {
+       m := new(Event)
+       if err := x.ServerStream.RecvMsg(m); err != nil {
+               return nil, err
+       }
+       return m, nil
+}
+
+var _EventService_serviceDesc = grpc.ServiceDesc{
+       ServiceName: "skywalking.v3.EventService",
+       HandlerType: (*EventServiceServer)(nil),
+       Methods:     []grpc.MethodDesc{},
+       Streams: []grpc.StreamDesc{
+               {
+                       StreamName:    "collect",
+                       Handler:       _EventService_Collect_Handler,
+                       ClientStreams: true,
+               },
+       },
+       Metadata: "event/Event.proto",
+}
diff --git a/gen-codes/skywalking/network/go.mod 
b/gen-codes/skywalking/network/go.mod
new file mode 100644
index 0000000..3ec3f7e
--- /dev/null
+++ b/gen-codes/skywalking/network/go.mod
@@ -0,0 +1,9 @@
+module skywalking/network
+
+go 1.13
+
+require (
+       github.com/golang/protobuf v1.4.3
+       google.golang.org/grpc v1.35.0
+       google.golang.org/protobuf v1.25.0
+)
diff --git a/gen-codes/skywalking/network/go.sum 
b/gen-codes/skywalking/network/go.sum
new file mode 100644
index 0000000..8f0da6e
--- /dev/null
+++ b/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-20201120205902-5459f2c99403/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.9-0.20201210154907-fd9021fe5dad/go.mod 
h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+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.35.0 h1:TwIQcH3es+MojMVojxxfQ3l3OF2KzlRxML2xZq0kRo8=
+google.golang.org/grpc v1.35.0/go.mod 
h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+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/go.mod b/go.mod
index c343c33..9d2e276 100644
--- a/go.mod
+++ b/go.mod
@@ -2,6 +2,8 @@ module github.com/apache/skywalking-cli
 
 go 1.13
 
+replace skywalking/network v1.0.0 => ./gen-codes/skywalking/network
+
 require (
        github.com/apache/skywalking-swck v0.0.0-20210107023854-d15ef19f8317
        github.com/ghodss/yaml v1.0.0
@@ -14,9 +16,9 @@ require (
        github.com/sirupsen/logrus v1.7.0
        github.com/spf13/viper v1.7.0
        github.com/urfave/cli v1.22.1
-       google.golang.org/grpc v1.27.0
-       google.golang.org/protobuf v1.25.0 // indirect
+       google.golang.org/grpc v1.35.0
        gopkg.in/yaml.v2 v2.4.0
        k8s.io/apimachinery v0.19.3
        sigs.k8s.io/controller-runtime v0.7.0-alpha.6
+       skywalking/network v1.0.0
 )
diff --git a/go.sum b/go.sum
index fd471f3..53a8333 100644
--- a/go.sum
+++ b/go.sum
@@ -72,6 +72,7 @@ github.com/chzyer/logex v1.1.10/go.mod 
h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod 
h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod 
h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
 github.com/client9/misspell v0.3.4/go.mod 
h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod 
h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod 
h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
 github.com/coreos/bbolt v1.3.2/go.mod 
h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 github.com/coreos/etcd v3.3.10+incompatible/go.mod 
h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@@ -103,7 +104,9 @@ github.com/emicklei/go-restful 
v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb
 github.com/emicklei/go-restful v2.9.5+incompatible/go.mod 
h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
 github.com/emicklei/go-restful v2.14.3+incompatible/go.mod 
h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
 github.com/emicklei/go-restful-swagger12 
v0.0.0-20201014110547-68ccff494617/go.mod 
h1:qr0VowGBT4CS4Q8vFF8BSeKz34PuqKGxs/L0IAQA9DQ=
+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.9-0.20201210154907-fd9021fe5dad/go.mod 
h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod 
h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.5.0+incompatible/go.mod 
h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/evanphx/json-patch v4.9.0+incompatible 
h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
@@ -206,6 +209,8 @@ github.com/golang/protobuf v1.4.1 
h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0
 github.com/golang/protobuf v1.4.1/go.mod 
h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
 github.com/golang/protobuf v1.4.2 
h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
 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=
@@ -227,6 +232,8 @@ github.com/google/renameio v0.1.0/go.mod 
h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
 github.com/google/uuid v1.0.0/go.mod 
h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
 github.com/google/uuid v1.1.1/go.mod 
h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
+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/googleapis/gnostic v0.4.1/go.mod 
h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
@@ -708,9 +715,12 @@ google.golang.org/grpc v1.21.0/go.mod 
h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij
 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.24.0/go.mod 
h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
+google.golang.org/grpc v1.25.1/go.mod 
h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
 google.golang.org/grpc v1.26.0/go.mod 
h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 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.35.0 h1:TwIQcH3es+MojMVojxxfQ3l3OF2KzlRxML2xZq0kRo8=
+google.golang.org/grpc v1.35.0/go.mod 
h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod 
h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod 
h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod 
h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
diff --git a/internal/commands/event/event.go b/internal/commands/event/event.go
new file mode 100644
index 0000000..3c11d1e
--- /dev/null
+++ b/internal/commands/event/event.go
@@ -0,0 +1,30 @@
+// 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 (
+       "github.com/urfave/cli"
+)
+
+var Command = cli.Command{
+       Name:  "event",
+       Usage: "Event related sub-command",
+       Subcommands: []cli.Command{
+               reportCommand,
+       },
+}
diff --git a/internal/commands/event/report.go 
b/internal/commands/event/report.go
new file mode 100644
index 0000000..8038361
--- /dev/null
+++ b/internal/commands/event/report.go
@@ -0,0 +1,119 @@
+// 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 (
+       "github.com/apache/skywalking-cli/internal/commands/interceptor"
+       "github.com/apache/skywalking-cli/internal/logger"
+       "github.com/apache/skywalking-cli/internal/model"
+       "github.com/apache/skywalking-cli/pkg/display"
+       "github.com/apache/skywalking-cli/pkg/display/displayable"
+       "github.com/apache/skywalking-cli/pkg/grpc"
+
+       "github.com/urfave/cli"
+
+       event "skywalking/network/event/v3"
+)
+
+var reportCommand = cli.Command{
+       Name:      "report",
+       Aliases:   []string{"r"},
+       Usage:     "Report an event to OAP server via gRPC",
+       ArgsUsage: "[parameters...]",
+       Flags: []cli.Flag{
+               cli.StringFlag{
+                       Name:     "uuid",
+                       Usage:    "Unique `ID` of the event.",
+                       Required: true,
+               },
+               cli.StringFlag{
+                       Name:     "service",
+                       Usage:    "The service of the event occurred on.",
+                       Required: true,
+               },
+               cli.StringFlag{
+                       Name:     "instance",
+                       Usage:    "The service instance of the event occurred 
on.",
+                       Required: false,
+               },
+               cli.StringFlag{
+                       Name:     "endpoint",
+                       Usage:    "The endpoint of the event occurred on",
+                       Required: false,
+               },
+               cli.StringFlag{
+                       Name:     "name",
+                       Usage:    "The name of the event. For example, 'Reboot' 
and 'Upgrade' etc.",
+                       Required: true,
+               },
+               cli.GenericFlag{
+                       Name:  "type",
+                       Usage: "The type of the event.",
+                       Value: &model.EventTypeEnumValue{
+                               Enum:     []event.Type{event.Type_Normal, 
event.Type_Error},
+                               Default:  event.Type_Normal,
+                               Selected: event.Type_Normal,
+                       },
+               },
+               cli.StringFlag{
+                       Name:     "message",
+                       Usage:    "The detail of the event. This should be a 
one-line message that briefly describes why the event is reported.",
+                       Required: true,
+               },
+               cli.Int64Flag{
+                       Name:     "startTime",
+                       Usage:    "The start time (in milliseconds) of the 
event, measured between the current time and midnight, January 1, 1970 UTC.",
+                       Required: true,
+               },
+               cli.Int64Flag{
+                       Name:     "endTime",
+                       Usage:    "The end time (in milliseconds) of the event, 
measured between the current time and midnight, January 1, 1970 UTC.",
+                       Required: false,
+               },
+       },
+       Action: func(ctx *cli.Context) error {
+               parameters, err := interceptor.ParseParameters(ctx.Args())
+               if err != nil {
+                       return err
+               }
+
+               event := event.Event{
+                       Uuid: ctx.String("uuid"),
+                       Source: &event.Source{
+                               Service:         ctx.String("service"),
+                               ServiceInstance: ctx.String("instance"),
+                               Endpoint:        ctx.String("endpoint"),
+                       },
+                       Name:       ctx.String("name"),
+                       Type:       
ctx.Generic("type").(*model.EventTypeEnumValue).Selected,
+                       Message:    ctx.String("message"),
+                       Parameters: parameters,
+                       StartTime:  ctx.Int64("startTime"),
+                       EndTime:    ctx.Int64("endTime"),
+               }
+
+               reply, err := grpc.ReportEvent(ctx.GlobalString("grpcAddr"), 
&event)
+               if err != nil {
+                       logger.Log.Fatalln(err)
+                       return err
+               }
+
+               logger.Log.Println("Report the event successfully, whose uuid 
is ", ctx.String("uuid"))
+               return display.Display(ctx, &displayable.Displayable{Data: 
reply})
+       },
+}
diff --git a/internal/commands/healthcheck/healthcheck.go 
b/internal/commands/healthcheck/healthcheck.go
index 12ab088..27a20a6 100644
--- a/internal/commands/healthcheck/healthcheck.go
+++ b/internal/commands/healthcheck/healthcheck.go
@@ -36,12 +36,6 @@ var Command = cli.Command{
                        Usage:    "Check gRPC by HealthCheck service",
                        Required: false,
                },
-               cli.StringFlag{
-                       Name:     "grpcAddr",
-                       Usage:    "`host:port` to connect",
-                       Value:    "127.0.0.1:11800",
-                       Required: false,
-               },
                cli.BoolFlag{
                        Name:     "grpcTLS",
                        Usage:    "use TLS for gRPC",
@@ -62,7 +56,7 @@ var Command = cli.Command{
                if !ctx.BoolT("grpc") {
                        return nil
                }
-               retCode := healthcheck.HealthCheck(ctx.String("grpcAddr"), 
ctx.Bool("grpcTLS"))
+               retCode := 
healthcheck.HealthCheck(ctx.GlobalString("grpcAddr"), ctx.Bool("grpcTLS"))
                if retCode != 0 {
                        return cli.NewExitError("gRPC: failed to check health", 
retCode)
                }
diff --git a/internal/commands/interceptor/event.go 
b/internal/commands/interceptor/event.go
new file mode 100644
index 0000000..2e30cf0
--- /dev/null
+++ b/internal/commands/interceptor/event.go
@@ -0,0 +1,44 @@
+// 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 interceptor
+
+import (
+       "fmt"
+       "strings"
+
+       "github.com/urfave/cli"
+)
+
+// ParseParameters parses parameters of the event message from args.
+func ParseParameters(paras cli.Args) (map[string]string, error) {
+       ret := make(map[string]string, len(paras))
+
+       for _, para := range paras {
+               sepIndex := strings.Index(para, "=")
+               // To make sure that len(k) > 0 && len(v) > 0
+               if len(para) >= 3 && sepIndex >= 1 && sepIndex < len(para)-1 {
+                       k := para[:sepIndex]
+                       v := para[sepIndex+1:]
+                       ret[k] = v
+               } else {
+                       return nil, fmt.Errorf("%s is not a vaild parameter, 
should like `key=value`", para)
+               }
+       }
+
+       return ret, nil
+}
diff --git a/internal/commands/interceptor/event_test.go 
b/internal/commands/interceptor/event_test.go
new file mode 100644
index 0000000..6d86437
--- /dev/null
+++ b/internal/commands/interceptor/event_test.go
@@ -0,0 +1,78 @@
+// 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 interceptor
+
+import (
+       "reflect"
+       "testing"
+
+       "github.com/urfave/cli"
+)
+
+func TestParseParameters(t *testing.T) {
+       tests := []struct {
+               name    string
+               args    cli.Args
+               want    map[string]string
+               wantErr bool
+       }{
+               {
+                       name:    "no parameters",
+                       args:    cli.Args([]string{}),
+                       want:    map[string]string{},
+                       wantErr: false,
+               },
+               {
+                       name: "all parameters are invalid",
+                       args: cli.Args([]string{
+                               "key",
+                               "key=",
+                               "=value",
+                               "=",
+                       }),
+                       want:    nil,
+                       wantErr: true,
+               },
+               {
+                       name: "all parameters are valid",
+                       args: cli.Args([]string{
+                               "key=value",
+                               "k=v===",
+                               "kk=====",
+                       }),
+                       want: map[string]string{
+                               "key": "value",
+                               "k":   "v===",
+                               "kk":  "====",
+                       },
+                       wantErr: false,
+               },
+       }
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       got, err := ParseParameters(tt.args)
+                       if (err != nil) != tt.wantErr {
+                               t.Errorf("ParseParameters() error = %v, wantErr 
%v", err, tt.wantErr)
+                               return
+                       }
+                       if !reflect.DeepEqual(got, tt.want) {
+                               t.Errorf("ParseParameters() got = %v, want %v", 
got, tt.want)
+                       }
+               })
+       }
+}
diff --git a/internal/model/type.go b/internal/model/type.go
new file mode 100644
index 0000000..74523d0
--- /dev/null
+++ b/internal/model/type.go
@@ -0,0 +1,52 @@
+// 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 model
+
+import (
+       "fmt"
+       "strings"
+
+       event "skywalking/network/event/v3"
+)
+
+// EventTypeEnumValue defines the values domain of --type option.
+type EventTypeEnumValue struct {
+       Enum     []event.Type
+       Default  event.Type
+       Selected event.Type
+}
+
+// Set the --type value, from raw string to EventTypeEnumValue.
+func (s *EventTypeEnumValue) Set(value string) error {
+       for _, enum := range s.Enum {
+               if strings.EqualFold(enum.String(), value) {
+                       s.Selected = enum
+                       return nil
+               }
+       }
+       types := make([]string, len(event.Type_name))
+       for index := range event.Type_name {
+               types[index] = event.Type_name[index]
+       }
+       return fmt.Errorf("allowed types are %s", strings.Join(types, ", "))
+}
+
+// String representation of the event type.
+func (s EventTypeEnumValue) String() string {
+       return s.Selected.String()
+}
diff --git a/pkg/grpc/grpc.go b/pkg/grpc/grpc.go
new file mode 100644
index 0000000..a0188a8
--- /dev/null
+++ b/pkg/grpc/grpc.go
@@ -0,0 +1,51 @@
+// 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 grpc
+
+import (
+       "context"
+       "time"
+
+       common "skywalking/network/common/v3"
+       event "skywalking/network/event/v3"
+
+       "google.golang.org/grpc"
+)
+
+// ReportEvent creates a grpc client and report an event.
+func ReportEvent(addr string, e *event.Event) (*common.Commands, error) {
+       conn, err := grpc.Dial(addr, grpc.WithInsecure())
+       if err != nil {
+               return nil, err
+       }
+       defer conn.Close()
+
+       rpcCtx, rpcCancel := context.WithTimeout(context.Background(), 
time.Second)
+       defer rpcCancel()
+
+       client := event.NewEventServiceClient(conn)
+       stream, err := client.Collect(rpcCtx)
+       if err != nil {
+               return nil, err
+       }
+
+       if err := stream.Send(e); err != nil {
+               return nil, err
+       }
+       return stream.CloseAndRecv()
+}
diff --git a/scripts/install_protoc.sh b/scripts/install_protoc.sh
new file mode 100644
index 0000000..b49cd99
--- /dev/null
+++ b/scripts/install_protoc.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+
+#
+# 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.
+#
+
+
+if [[ "$(uname)" == "Darwin" || "$(expr substr $(uname -s) 1 10)" == 
"MINGW32_NT" ]];then
+  echo "sorry, please install protoc by yourself."
+  exit 1
+fi
+
+PROTOC_ZIP=protoc-3.14.0-linux-x86_64.zip
+curl -OL 
https://github.com/protocolbuffers/protobuf/releases/download/v3.14.0/$PROTOC_ZIP
+sudo unzip -o $PROTOC_ZIP -d /usr/local bin/protoc
+sudo chmod 755  /usr/local/bin/protoc
+rm -f $PROTOC_ZIP
+
+echo `protoc --version`
\ No newline at end of file

Reply via email to