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

wusheng 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 0883266  Support sampling config in network profiling (#171)
0883266 is described below

commit 0883266bfaa36612927b69e35781b64ea181758d
Author: mrproliu <[email protected]>
AuthorDate: Thu Nov 24 08:51:39 2022 +0800

    Support sampling config in network profiling (#171)
---
 CHANGES.md                                         |  1 +
 dist/LICENSE                                       |  2 +-
 examples/network-sampling.yaml                     | 49 ++++++++++++
 go.mod                                             |  2 +-
 go.sum                                             |  4 +-
 internal/commands/profiling/ebpf/create/network.go | 93 ++++++++++++++++++++++
 6 files changed, 147 insertions(+), 4 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 76d865b..fea6fa6 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -33,6 +33,7 @@ Release Notes.
 * Add compatibility documentation by @mrproliu in 
https://github.com/apache/skywalking-cli/pull/164
 * Add the sub-command `records list` for adapt the new record query API by 
@mrproliu in https://github.com/apache/skywalking-cli/pull/167
 * Add the attached events fields into the `trace` sub-command by @mrproliu in 
https://github.com/apache/skywalking-cli/pull/169
+* Add the sampling config file into the `profiling ebpf create network` 
sub-command by @mrproliu in https://github.com/apache/skywalking-cli/pull/171
 
 0.10.0
 ------------------
diff --git a/dist/LICENSE b/dist/LICENSE
index d9b8a30..a9a7c66 100644
--- a/dist/LICENSE
+++ b/dist/LICENSE
@@ -213,7 +213,7 @@ The text of each license is also included at 
licenses/license-[project].txt.
     k8s.io/utils v0.0.0-20210802155522-efc7438f0176 Apache-2.0
     sigs.k8s.io/controller-runtime v0.10.0 Apache-2.0
     sigs.k8s.io/structured-merge-diff/v4 v4.1.2 Apache-2.0
-    skywalking.apache.org/repo/goapi v0.0.0-20221019074310-53ebda305187 
Apache-2.0
+    skywalking.apache.org/repo/goapi v0.0.0-20221123034834-51b3101f6c9f 
Apache-2.0
 
 ========================================================================
 BSD-2-Clause licenses
diff --git a/examples/network-sampling.yaml b/examples/network-sampling.yaml
new file mode 100644
index 0000000..4d86561
--- /dev/null
+++ b/examples/network-sampling.yaml
@@ -0,0 +1,49 @@
+# 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.
+
+# The command `dashboard global` supports displaying three kinds of data:
+# `global metrics`, `global response latency`, `Global heat map`.
+# If you don't want to display an item, you can just delete or comment its 
whole configuration below.
+# Generally, there is no need to modify properties unless there is a 
explanatory comment.
+
+# Sampling config
+# samplings: the sampling config list
+# - uri_pattern: <optional> string. The match pattern for HTTP request. This 
is HTTP URI-oriented. matches all requests if not set
+#   min_duration: <optional> int(ms). The minimal request duration to activate 
the network data(HTTP request/response raw data) sampling.
+#   when_4xx: <required> bool. Collecting requests when the response code is 
400-499.
+#   when_5xx: <required> bool. Collecting requests when the response code is 
500-599.
+#   setting: define how to collect sampled data
+#     require_request: <required> bool. Require to collect the complete 
request.
+#     max_request_size: <optional> int. The max size of request context. The 
unit is byte.
+#     require_response: <required> bool. Require to collect the complete 
response.
+#     max_response_size: <optional> int. The max size of response context. The 
unit is byte.
+
+samplings:
+  # define collecting full request data when the response code is 400-499 and 
500-599 .
+  - when_4xx: true
+    when_5xx: true
+    setting:
+      require_request: true
+      require_response: false
+  # define collecting first 1KB response data when the response code is 
500-599 and the duration bigger than or equals 10ms.
+  - uri_pattern: /index.html
+    when_4xx: false
+    when_5xx: true
+    min_duration: 10
+    setting:
+      require_request: false
+      require_response: true
+      max_response_size: 1024
\ No newline at end of file
diff --git a/go.mod b/go.mod
index a5beccc..a86f33f 100644
--- a/go.mod
+++ b/go.mod
@@ -20,7 +20,7 @@ require (
        gopkg.in/yaml.v2 v2.4.0
        k8s.io/apimachinery v0.22.1
        sigs.k8s.io/controller-runtime v0.10.0
-       skywalking.apache.org/repo/goapi v0.0.0-20221019074310-53ebda305187
+       skywalking.apache.org/repo/goapi v0.0.0-20221123034834-51b3101f6c9f
 )
 
 require (
diff --git a/go.sum b/go.sum
index 4bc7dae..5204896 100644
--- a/go.sum
+++ b/go.sum
@@ -857,5 +857,5 @@ sigs.k8s.io/structured-merge-diff/v4 v4.1.2 
h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3
 sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod 
h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
 sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
 sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
-skywalking.apache.org/repo/goapi v0.0.0-20221019074310-53ebda305187 
h1:6JgAg9aohcHd72VplZUGycZgCNo6iQrz735nmtOTCnE=
-skywalking.apache.org/repo/goapi v0.0.0-20221019074310-53ebda305187/go.mod 
h1:lxmYWY1uAP5SLVKNymAyDzn7KG6dhPWN+pYHmyt+0vo=
+skywalking.apache.org/repo/goapi v0.0.0-20221123034834-51b3101f6c9f 
h1:iRQHKYsca0gbSxGWFjlkQ/WIuLyKReFUk2PscgzBqAw=
+skywalking.apache.org/repo/goapi v0.0.0-20221123034834-51b3101f6c9f/go.mod 
h1:lxmYWY1uAP5SLVKNymAyDzn7KG6dhPWN+pYHmyt+0vo=
diff --git a/internal/commands/profiling/ebpf/create/network.go 
b/internal/commands/profiling/ebpf/create/network.go
index aadf2c8..b30c86b 100644
--- a/internal/commands/profiling/ebpf/create/network.go
+++ b/internal/commands/profiling/ebpf/create/network.go
@@ -18,17 +18,41 @@
 package create
 
 import (
+       "fmt"
+       "os"
+
        "github.com/apache/skywalking-cli/internal/commands/interceptor"
        "github.com/apache/skywalking-cli/internal/flags"
        "github.com/apache/skywalking-cli/pkg/display"
        "github.com/apache/skywalking-cli/pkg/display/displayable"
        "github.com/apache/skywalking-cli/pkg/graphql/profiling"
 
+       "gopkg.in/yaml.v2"
+
        "github.com/urfave/cli/v2"
 
        api "skywalking.apache.org/repo/goapi/query"
 )
 
+type SamplingConfig struct {
+       Samplings []*SamplingRule `yaml:"samplings"`
+}
+
+type SamplingRule struct {
+       URIPattern  *string          `yaml:"uri_pattern"`
+       MinDuration *int             `yaml:"min_duration"`
+       When4xx     *bool            `yaml:"when_4xx"`
+       When5xx     *bool            `yaml:"when_5xx"`
+       Setting     *SamplingSetting `yaml:"setting"`
+}
+
+type SamplingSetting struct {
+       RequireRequest  *bool `yaml:"require_request"`
+       MaxRequestSize  *int  `yaml:"max_request_size"`
+       RequireResponse *bool `yaml:"require_response"`
+       MaxResponseSize *int  `yaml:"max_response_size"`
+}
+
 var NetworkCreateCommand = &cli.Command{
        Name:    "network",
        Aliases: []string{"net"},
@@ -41,6 +65,13 @@ $ swctl profiling ebpf create network 
--service-instance-id=abc`,
        Flags: flags.Flags(
                flags.ServiceFlags,
                flags.InstanceFlags,
+               []cli.Flag{
+                       &cli.StringFlag{
+                               Name:     "sampling-config",
+                               Usage:    "the `sampling-config` file define 
how to sampling the network data, if not then then ignore data sampling",
+                               Required: false,
+                       },
+               },
        ),
        Before: interceptor.BeforeChain(
                interceptor.ParseInstance(true),
@@ -48,8 +79,29 @@ $ swctl profiling ebpf create network 
--service-instance-id=abc`,
        Action: func(ctx *cli.Context) error {
                instanceID := ctx.String("instance-id")
 
+               samplingConfigFile := ctx.String("sampling-config")
+
+               // convert the sampling rule
+               var samplings = make([]*api.EBPFNetworkSamplingRule, 0)
+               if samplingConfigFile != "" {
+                       config, err := os.ReadFile(samplingConfigFile)
+                       if err != nil {
+                               return err
+                       }
+                       r := &SamplingConfig{}
+                       if e := yaml.Unmarshal(config, r); e != nil {
+                               return e
+                       }
+
+                       samplings, err = parsingNetworkSampling(r)
+                       if err != nil {
+                               return err
+                       }
+               }
+
                request := &api.EBPFProfilingNetworkTaskRequest{
                        InstanceID: instanceID,
+                       Samplings:  samplings,
                }
 
                task, err := profiling.CreateEBPFNetworkProfilingTask(ctx, 
request)
@@ -61,3 +113,44 @@ $ swctl profiling ebpf create network 
--service-instance-id=abc`,
                return display.Display(ctx, &displayable.Displayable{Data: 
task, Condition: request})
        },
 }
+
+func parsingNetworkSampling(config *SamplingConfig) 
([]*api.EBPFNetworkSamplingRule, error) {
+       rules := make([]*api.EBPFNetworkSamplingRule, 0)
+       if config == nil || len(config.Samplings) == 0 {
+               return rules, nil
+       }
+       for _, conf := range config.Samplings {
+               rule := &api.EBPFNetworkSamplingRule{}
+               rule.URIRegex = conf.URIPattern
+               rule.MinDuration = conf.MinDuration
+               if conf.When4xx == nil {
+                       return nil, fmt.Errorf("the when_4xx is required")
+               }
+               rule.When4xx = *conf.When4xx
+               if conf.When5xx == nil {
+                       return nil, fmt.Errorf("the when_5xx is required")
+               }
+               rule.When5xx = *conf.When5xx
+
+               confSetting := conf.Setting
+               if confSetting == nil {
+                       return nil, fmt.Errorf("the sampling settings is 
required")
+               }
+               setting := &api.EBPFNetworkDataCollectingSettings{}
+               rule.Settings = setting
+               if confSetting.RequireRequest == nil {
+                       return nil, fmt.Errorf("the sampling request is 
required")
+               }
+               setting.RequireCompleteRequest = *confSetting.RequireRequest
+               setting.MaxRequestSize = confSetting.MaxRequestSize
+               if confSetting.RequireResponse == nil {
+                       return nil, fmt.Errorf("the sampling response is 
required")
+               }
+               setting.RequireCompleteResponse = *confSetting.RequireResponse
+               setting.MaxResponseSize = confSetting.MaxResponseSize
+
+               rules = append(rules, rule)
+       }
+
+       return rules, nil
+}

Reply via email to