You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2022/07/14 14:26:58 UTC
[skywalking-cli] branch master updated: Add commands for support network profiling (#158)
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 a73f653 Add commands for support network profiling (#158)
a73f653 is described below
commit a73f65367b335e08412c0471e85ad8f15e92d411
Author: mrproliu <74...@qq.com>
AuthorDate: Thu Jul 14 22:26:55 2022 +0800
Add commands for support network profiling (#158)
---
CHANGES.md | 3 +
assets/graphqls/dependency/ProcessTopology.graphql | 36 +++++++++
.../ebpf/CreateEBPFNetworkProfilingTask.graphql | 24 ++++++
.../ebpf/KeepNetworkProfilingTask.graphql | 23 ++++++
go.mod | 2 +-
go.sum | 4 +-
internal/commands/dependency/dependency.go | 1 +
.../thermodynamic.go => dependency/process.go} | 49 ++++--------
internal/commands/interceptor/entity.go | 12 +++
internal/commands/interceptor/process.go | 91 ++++++++++++++++++++++
internal/commands/metrics/linear/linear-metrics.go | 2 +
.../metrics/linear/multiple-linear-metrics.go | 2 +
internal/commands/metrics/single/single-metrics.go | 2 +
.../metrics/thermodynamic/thermodynamic.go | 2 +
internal/commands/profiling/ebpf/create/create.go | 1 +
.../ebpf/create/network.go} | 61 +++++----------
internal/commands/profiling/ebpf/ebpf.go | 2 +
.../ebpf/{create/create.go => keep/keep.go} | 11 ++-
internal/commands/profiling/ebpf/keep/network.go | 57 ++++++++++++++
.../ebpf/create/create.go => flags/process.go} | 31 ++++++--
pkg/graphql/dependency/dependency.go | 12 +++
pkg/graphql/profiling/ebpf.go | 22 ++++++
pkg/graphql/utils/parser.go | 4 +-
pkg/graphql/utils/parser_test.go | 31 +++++++-
24 files changed, 391 insertions(+), 94 deletions(-)
diff --git a/CHANGES.md b/CHANGES.md
index ca7a107..31b9d69 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -17,6 +17,9 @@ Release Notes.
- [Breaking Change] Remove `total` field in `trace list` and `logs list` commands.(#152)
- [Breaking Change] Remove `total` field in `event list`, `browser logs list`, `alarm list` commands.(#153)
- Add `aggregate` flag in `profiling ebpf analysis` commands.(#154)
+- Add the sub-command `profiling ebpf create network` and `profiling ebpf keep network` to create and keep the network eBPF profiling task.(#158)
+- Add the sub-command `dependency process` to query the process relation.(#158)
+- Support query the metrics of process relation.(#158)
0.10.0
------------------
diff --git a/assets/graphqls/dependency/ProcessTopology.graphql b/assets/graphqls/dependency/ProcessTopology.graphql
new file mode 100644
index 0000000..ec2dd0d
--- /dev/null
+++ b/assets/graphqls/dependency/ProcessTopology.graphql
@@ -0,0 +1,36 @@
+# 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.
+
+query ($serviceInstanceId: ID!, $duration: Duration!){
+ result: getProcessTopology(serviceInstanceId: $serviceInstanceId, duration: $duration) {
+ nodes {
+ id
+ serviceId
+ serviceName
+ serviceInstanceId
+ serviceInstanceName
+ name
+ isReal
+ }
+ calls {
+ source
+ target
+ id
+ detectPoints
+ }
+ }
+}
\ No newline at end of file
diff --git a/assets/graphqls/profiling/ebpf/CreateEBPFNetworkProfilingTask.graphql b/assets/graphqls/profiling/ebpf/CreateEBPFNetworkProfilingTask.graphql
new file mode 100644
index 0000000..e3b45a6
--- /dev/null
+++ b/assets/graphqls/profiling/ebpf/CreateEBPFNetworkProfilingTask.graphql
@@ -0,0 +1,24 @@
+# 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.
+
+mutation ($request: EBPFProfilingNetworkTaskRequest!){
+ result: createEBPFNetworkProfiling(request: $request) {
+ status
+ id
+ errorReason
+ }
+}
\ No newline at end of file
diff --git a/assets/graphqls/profiling/ebpf/KeepNetworkProfilingTask.graphql b/assets/graphqls/profiling/ebpf/KeepNetworkProfilingTask.graphql
new file mode 100644
index 0000000..83525bc
--- /dev/null
+++ b/assets/graphqls/profiling/ebpf/KeepNetworkProfilingTask.graphql
@@ -0,0 +1,23 @@
+# 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.
+
+mutation ($taskId: ID!){
+ result: keepEBPFNetworkProfiling(taskId: $taskId) {
+ status
+ errorReason
+ }
+}
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 8efc146..89b1960 100644
--- a/go.mod
+++ b/go.mod
@@ -24,5 +24,5 @@ require (
gopkg.in/yaml.v2 v2.4.0
k8s.io/apimachinery v0.21.1
sigs.k8s.io/controller-runtime v0.7.0
- skywalking.apache.org/repo/goapi v0.0.0-20220519102801-965f76fbe437
+ skywalking.apache.org/repo/goapi v0.0.0-20220714130828-0d56d1f4c592
)
diff --git a/go.sum b/go.sum
index d554069..009af6f 100644
--- a/go.sum
+++ b/go.sum
@@ -950,5 +950,5 @@ sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
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-20220519102801-965f76fbe437 h1:tWUESKwKU50ZEzQJsOQv50qPvPHj72MjIxFwgeoM7Hg=
-skywalking.apache.org/repo/goapi v0.0.0-20220519102801-965f76fbe437/go.mod h1:uWwwvhcwe2MD/nJCg0c1EE/eL6KzaBosLHDfMFoEJ30=
+skywalking.apache.org/repo/goapi v0.0.0-20220714130828-0d56d1f4c592 h1:3UbXoMUpGBoYLvuUCaKPzlHCM9Q+enaaOcQ19QbTDr8=
+skywalking.apache.org/repo/goapi v0.0.0-20220714130828-0d56d1f4c592/go.mod h1:uWwwvhcwe2MD/nJCg0c1EE/eL6KzaBosLHDfMFoEJ30=
diff --git a/internal/commands/dependency/dependency.go b/internal/commands/dependency/dependency.go
index 65e343c..4b373e1 100644
--- a/internal/commands/dependency/dependency.go
+++ b/internal/commands/dependency/dependency.go
@@ -29,5 +29,6 @@ var Command = &cli.Command{
EndpointCommand,
ServiceCommand,
InstanceCommand,
+ ProcessCommand,
},
}
diff --git a/internal/commands/metrics/thermodynamic/thermodynamic.go b/internal/commands/dependency/process.go
similarity index 62%
copy from internal/commands/metrics/thermodynamic/thermodynamic.go
copy to internal/commands/dependency/process.go
index a34199b..8a89679 100644
--- a/internal/commands/metrics/thermodynamic/thermodynamic.go
+++ b/internal/commands/dependency/process.go
@@ -15,72 +15,53 @@
// specific language governing permissions and limitations
// under the License.
-package thermodynamic
+package dependency
import (
- "github.com/urfave/cli/v2"
-
"github.com/apache/skywalking-cli/internal/commands/interceptor"
"github.com/apache/skywalking-cli/internal/flags"
"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/graphql/metrics"
+ "github.com/apache/skywalking-cli/pkg/graphql/dependency"
+
+ "github.com/urfave/cli/v2"
api "skywalking.apache.org/repo/goapi/query"
)
-var Command = &cli.Command{
- Name: "thermodynamic",
- Aliases: []string{"td", "heatmap", "hp", "hm"},
- Usage: "query thermodynamic-type metrics defined in backend OAL",
- UsageText: `Query the thermodynamic-type metrics defined in backend OAL.
-
-Examples:
-1. Query the global heatmap:
-$ swctl metrics thermodynamic --scope all --name all_heatmap
-`,
+var ProcessCommand = &cli.Command{
+ Name: "process",
+ Aliases: []string{"pros"},
+ Usage: "Query the process topology, based on the given service instance",
Flags: flags.Flags(
flags.DurationFlags,
- flags.MetricsFlags,
+ flags.ServiceRelationFlags,
flags.InstanceRelationFlags,
- flags.EndpointRelationFlags,
),
Before: interceptor.BeforeChain(
interceptor.DurationInterceptor,
- interceptor.ParseEndpointRelation(false),
- interceptor.ParseInstanceRelation(false),
+ interceptor.ParseInstance(true),
),
+
Action: func(ctx *cli.Context) error {
+ instanceID := ctx.String("instance-id")
+
end := ctx.String("end")
start := ctx.String("start")
step := ctx.Generic("step")
- metricsName := ctx.String("name")
- entity, err := interceptor.ParseEntity(ctx)
- if err != nil {
- return err
- }
-
duration := api.Duration{
Start: start,
End: end,
Step: step.(*model.StepEnumValue).Selected,
}
- metricsValues, err := metrics.Thermodynamic(ctx, api.MetricsCondition{
- Name: metricsName,
- Entity: entity,
- }, duration)
-
+ dependency, err := dependency.ProcessTopology(ctx, instanceID, duration)
if err != nil {
return err
}
- return display.Display(ctx, &displayable.Displayable{
- Data: metricsValues,
- Duration: duration,
- Title: metricsName,
- })
+ return display.Display(ctx, &displayable.Displayable{Data: dependency})
},
}
diff --git a/internal/commands/interceptor/entity.go b/internal/commands/interceptor/entity.go
index 8b110a6..d03f3e2 100644
--- a/internal/commands/interceptor/entity.go
+++ b/internal/commands/interceptor/entity.go
@@ -36,10 +36,12 @@ func ParseEntity(ctx *cli.Context) (*api.Entity, error) {
serviceID := ctx.String("service-id")
instance := ctx.String("instance-name")
endpoint := ctx.String("endpoint-name")
+ process := ctx.String("process-name")
destServiceID := ctx.String("dest-service-id")
destInstance := ctx.String("dest-instance-name")
destEndpoint := ctx.String("dest-endpoint-name")
+ destProcess := ctx.String("dest-process-name")
serviceName, isNormal, err := ParseServiceID(serviceID)
if err != nil {
@@ -56,13 +58,23 @@ func ParseEntity(ctx *cli.Context) (*api.Entity, error) {
Normal: &isNormal,
ServiceInstanceName: &instance,
EndpointName: &endpoint,
+ ProcessName: &process,
DestServiceName: &destServiceName,
DestNormal: &destIsNormal,
DestServiceInstanceName: &destInstance,
DestEndpointName: &destEndpoint,
+ DestProcessName: &destProcess,
}
entity.Scope = utils.ParseScope(entity)
+ // adapt for the old version of backend
+ if *entity.ProcessName == "" {
+ entity.ProcessName = nil
+ }
+ if *entity.DestProcessName == "" {
+ entity.DestProcessName = nil
+ }
+
if logger.Log.GetLevel() <= logrus.DebugLevel {
s, _ := json.Marshal(&entity)
logger.Log.Debugf("entity: %+v", string(s))
diff --git a/internal/commands/interceptor/process.go b/internal/commands/interceptor/process.go
new file mode 100644
index 0000000..eaa5968
--- /dev/null
+++ b/internal/commands/interceptor/process.go
@@ -0,0 +1,91 @@
+// 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 (
+ "crypto/sha256"
+ "fmt"
+
+ "github.com/urfave/cli/v2"
+)
+
+const (
+ processIDFlagName = "process-id"
+ processNameFlagName = "process-name"
+ destProcessNameFlagName = "dest-process-name"
+)
+
+// ParseProcess parses the process id or process name,
+// and converts the present one to the missing one.
+// See flags.InstanceFlags.
+func ParseProcess(required bool) func(*cli.Context) error {
+ return func(ctx *cli.Context) error {
+ if err := ParseService(required)(ctx); err != nil {
+ return err
+ }
+ if err := ParseInstance(required)(ctx); err != nil {
+ return err
+ }
+ return parseProcess(required, processIDFlagName, processNameFlagName, instanceIDFlagName)(ctx)
+ }
+}
+
+// ParseProcessRelation parses the source and destination service instance id or service instance name,
+// and converts the present one to the missing one respectively.
+// See flags.InstanceRelationFlags.
+func ParseProcessRelation(required bool) func(*cli.Context) error {
+ return func(ctx *cli.Context) error {
+ if err := ParseService(required)(ctx); err != nil {
+ return err
+ }
+ if err := ParseInstance(required)(ctx); err != nil {
+ return err
+ }
+ if err := ParseProcess(required)(ctx); err != nil {
+ return err
+ }
+ if ctx.String(destProcessNameFlagName) == "" && required {
+ return fmt.Errorf(`flag "--%s" must given`, destProcessNameFlagName)
+ }
+ return nil
+ }
+}
+
+func parseProcess(required bool, idFlagName, nameFlagName, instanceIDFlagName string) func(*cli.Context) error {
+ return func(ctx *cli.Context) error {
+ id := ctx.String(idFlagName)
+ name := ctx.String(nameFlagName)
+ instanceID := ctx.String(instanceIDFlagName)
+
+ if id == "" && name == "" {
+ if required {
+ return fmt.Errorf(`either flags "--%s" or "--%s" must be given`, idFlagName, nameFlagName)
+ }
+ return nil
+ }
+
+ if name != "" {
+ if instanceID == "" {
+ return fmt.Errorf(`"--%s" is specified but its related service name or id is not given`, nameFlagName)
+ }
+ id = fmt.Sprintf("%x", sha256.New().Sum([]byte(fmt.Sprintf("%s_%s", instanceID, name))))
+ }
+
+ return ctx.Set(idFlagName, id)
+ }
+}
diff --git a/internal/commands/metrics/linear/linear-metrics.go b/internal/commands/metrics/linear/linear-metrics.go
index 25930c4..d6c4d9a 100644
--- a/internal/commands/metrics/linear/linear-metrics.go
+++ b/internal/commands/metrics/linear/linear-metrics.go
@@ -52,11 +52,13 @@ $ swctl metrics linear --name=service_relation_client_cpm --service-name consume
flags.MetricsFlags,
flags.InstanceRelationFlags,
flags.EndpointRelationFlags,
+ flags.ProcessRelationFlags,
),
Before: interceptor.BeforeChain(
interceptor.DurationInterceptor,
interceptor.ParseEndpointRelation(false),
interceptor.ParseInstanceRelation(false),
+ interceptor.ParseProcessRelation(false),
),
Action: func(ctx *cli.Context) error {
end := ctx.String("end")
diff --git a/internal/commands/metrics/linear/multiple-linear-metrics.go b/internal/commands/metrics/linear/multiple-linear-metrics.go
index 5e987e0..3ffd1eb 100644
--- a/internal/commands/metrics/linear/multiple-linear-metrics.go
+++ b/internal/commands/metrics/linear/multiple-linear-metrics.go
@@ -51,6 +51,7 @@ $ swctl metrics multiple-linear --name all_percentile --labels=0,1,2,3,4 --relab
flags.MetricsFlags,
flags.InstanceRelationFlags,
flags.EndpointRelationFlags,
+ flags.ProcessRelationFlags,
[]cli.Flag{
&cli.StringFlag{
Name: "labels",
@@ -71,6 +72,7 @@ $ swctl metrics multiple-linear --name all_percentile --labels=0,1,2,3,4 --relab
interceptor.DurationInterceptor,
interceptor.ParseEndpointRelation(false),
interceptor.ParseInstanceRelation(false),
+ interceptor.ParseProcessRelation(false),
),
Action: func(ctx *cli.Context) error {
end := ctx.String("end")
diff --git a/internal/commands/metrics/single/single-metrics.go b/internal/commands/metrics/single/single-metrics.go
index 9876485..f10dac5 100644
--- a/internal/commands/metrics/single/single-metrics.go
+++ b/internal/commands/metrics/single/single-metrics.go
@@ -46,11 +46,13 @@ $ swctl metrics single --name endpoint_cpm --service-name business-zone::project
flags.MetricsFlags,
flags.InstanceRelationFlags,
flags.EndpointRelationFlags,
+ flags.ProcessRelationFlags,
),
Before: interceptor.BeforeChain(
interceptor.DurationInterceptor,
interceptor.ParseEndpointRelation(false),
interceptor.ParseInstanceRelation(false),
+ interceptor.ParseProcessRelation(false),
),
Action: func(ctx *cli.Context) error {
end := ctx.String("end")
diff --git a/internal/commands/metrics/thermodynamic/thermodynamic.go b/internal/commands/metrics/thermodynamic/thermodynamic.go
index a34199b..dbc8303 100644
--- a/internal/commands/metrics/thermodynamic/thermodynamic.go
+++ b/internal/commands/metrics/thermodynamic/thermodynamic.go
@@ -45,11 +45,13 @@ $ swctl metrics thermodynamic --scope all --name all_heatmap
flags.MetricsFlags,
flags.InstanceRelationFlags,
flags.EndpointRelationFlags,
+ flags.ProcessRelationFlags,
),
Before: interceptor.BeforeChain(
interceptor.DurationInterceptor,
interceptor.ParseEndpointRelation(false),
interceptor.ParseInstanceRelation(false),
+ interceptor.ParseProcessRelation(false),
),
Action: func(ctx *cli.Context) error {
end := ctx.String("end")
diff --git a/internal/commands/profiling/ebpf/create/create.go b/internal/commands/profiling/ebpf/create/create.go
index bf233b1..e3829d4 100644
--- a/internal/commands/profiling/ebpf/create/create.go
+++ b/internal/commands/profiling/ebpf/create/create.go
@@ -25,5 +25,6 @@ var CreateCommand = &cli.Command{
Subcommands: []*cli.Command{
PrepareCreateCommand,
FixedTimeCreateCommand,
+ NetworkCreateCommand,
},
}
diff --git a/internal/commands/metrics/thermodynamic/thermodynamic.go b/internal/commands/profiling/ebpf/create/network.go
similarity index 50%
copy from internal/commands/metrics/thermodynamic/thermodynamic.go
copy to internal/commands/profiling/ebpf/create/network.go
index a34199b..aadf2c8 100644
--- a/internal/commands/metrics/thermodynamic/thermodynamic.go
+++ b/internal/commands/profiling/ebpf/create/network.go
@@ -15,72 +15,49 @@
// specific language governing permissions and limitations
// under the License.
-package thermodynamic
+package create
import (
- "github.com/urfave/cli/v2"
-
"github.com/apache/skywalking-cli/internal/commands/interceptor"
"github.com/apache/skywalking-cli/internal/flags"
- "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/graphql/metrics"
+ "github.com/apache/skywalking-cli/pkg/graphql/profiling"
+
+ "github.com/urfave/cli/v2"
api "skywalking.apache.org/repo/goapi/query"
)
-var Command = &cli.Command{
- Name: "thermodynamic",
- Aliases: []string{"td", "heatmap", "hp", "hm"},
- Usage: "query thermodynamic-type metrics defined in backend OAL",
- UsageText: `Query the thermodynamic-type metrics defined in backend OAL.
+var NetworkCreateCommand = &cli.Command{
+ Name: "network",
+ Aliases: []string{"net"},
+ Usage: "Create a new ebpf network profiling task",
+ UsageText: `Create a new ebpf network profiling task
Examples:
-1. Query the global heatmap:
-$ swctl metrics thermodynamic --scope all --name all_heatmap
-`,
+1. Create ebpf network profiling task
+$ swctl profiling ebpf create network --service-instance-id=abc`,
Flags: flags.Flags(
- flags.DurationFlags,
- flags.MetricsFlags,
- flags.InstanceRelationFlags,
- flags.EndpointRelationFlags,
+ flags.ServiceFlags,
+ flags.InstanceFlags,
),
Before: interceptor.BeforeChain(
- interceptor.DurationInterceptor,
- interceptor.ParseEndpointRelation(false),
- interceptor.ParseInstanceRelation(false),
+ interceptor.ParseInstance(true),
),
Action: func(ctx *cli.Context) error {
- end := ctx.String("end")
- start := ctx.String("start")
- step := ctx.Generic("step")
-
- metricsName := ctx.String("name")
- entity, err := interceptor.ParseEntity(ctx)
- if err != nil {
- return err
- }
+ instanceID := ctx.String("instance-id")
- duration := api.Duration{
- Start: start,
- End: end,
- Step: step.(*model.StepEnumValue).Selected,
+ request := &api.EBPFProfilingNetworkTaskRequest{
+ InstanceID: instanceID,
}
- metricsValues, err := metrics.Thermodynamic(ctx, api.MetricsCondition{
- Name: metricsName,
- Entity: entity,
- }, duration)
+ task, err := profiling.CreateEBPFNetworkProfilingTask(ctx, request)
if err != nil {
return err
}
- return display.Display(ctx, &displayable.Displayable{
- Data: metricsValues,
- Duration: duration,
- Title: metricsName,
- })
+ return display.Display(ctx, &displayable.Displayable{Data: task, Condition: request})
},
}
diff --git a/internal/commands/profiling/ebpf/ebpf.go b/internal/commands/profiling/ebpf/ebpf.go
index e9c9926..02c4262 100644
--- a/internal/commands/profiling/ebpf/ebpf.go
+++ b/internal/commands/profiling/ebpf/ebpf.go
@@ -19,6 +19,7 @@ package ebpf
import (
"github.com/apache/skywalking-cli/internal/commands/profiling/ebpf/create"
+ "github.com/apache/skywalking-cli/internal/commands/profiling/ebpf/keep"
"github.com/urfave/cli/v2"
)
@@ -28,6 +29,7 @@ var Command = &cli.Command{
Usage: "eBPF Profiling related sub-command",
Subcommands: []*cli.Command{
create.CreateCommand,
+ keep.KeepCommand,
ListTaskCommand,
ListScheduleCommand,
AnalyzationCommand,
diff --git a/internal/commands/profiling/ebpf/create/create.go b/internal/commands/profiling/ebpf/keep/keep.go
similarity index 83%
copy from internal/commands/profiling/ebpf/create/create.go
copy to internal/commands/profiling/ebpf/keep/keep.go
index bf233b1..22af29e 100644
--- a/internal/commands/profiling/ebpf/create/create.go
+++ b/internal/commands/profiling/ebpf/keep/keep.go
@@ -15,15 +15,14 @@
// specific language governing permissions and limitations
// under the License.
-package create
+package keep
import "github.com/urfave/cli/v2"
-var CreateCommand = &cli.Command{
- Name: "create",
- Usage: "eBPF Profiling task create related sub-command",
+var KeepCommand = &cli.Command{
+ Name: "keep",
+ Usage: "eBPF Profiling task keep-alive related sub-command",
Subcommands: []*cli.Command{
- PrepareCreateCommand,
- FixedTimeCreateCommand,
+ NetworkKeepCommand,
},
}
diff --git a/internal/commands/profiling/ebpf/keep/network.go b/internal/commands/profiling/ebpf/keep/network.go
new file mode 100644
index 0000000..8d86f6d
--- /dev/null
+++ b/internal/commands/profiling/ebpf/keep/network.go
@@ -0,0 +1,57 @@
+// 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 keep
+
+import (
+ "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"
+
+ "github.com/urfave/cli/v2"
+)
+
+var NetworkKeepCommand = &cli.Command{
+ Name: "network",
+ Aliases: []string{"net"},
+ Usage: "Keep alive the exist ebpf network profiling task",
+ UsageText: `Keep alive the exist ebpf network profiling task
+
+Examples:
+1. Keep alive the ebpf network profiling task
+$ swctl profiling ebpf keep network --task-id=abc`,
+ Flags: flags.Flags(
+ []cli.Flag{
+ &cli.StringFlag{
+ Name: "task-id",
+ Usage: "the `task-id` of the network profiling task",
+ Required: true,
+ },
+ },
+ ),
+ Action: func(ctx *cli.Context) error {
+ taskID := ctx.String("task-id")
+
+ keepResult, err := profiling.KeepNetworkProfilingTask(ctx, taskID)
+ if err != nil {
+ return err
+ }
+
+ return display.Display(ctx, &displayable.Displayable{Data: keepResult})
+ },
+}
diff --git a/internal/commands/profiling/ebpf/create/create.go b/internal/flags/process.go
similarity index 57%
copy from internal/commands/profiling/ebpf/create/create.go
copy to internal/flags/process.go
index bf233b1..8606059 100644
--- a/internal/commands/profiling/ebpf/create/create.go
+++ b/internal/flags/process.go
@@ -15,15 +15,32 @@
// specific language governing permissions and limitations
// under the License.
-package create
+package flags
import "github.com/urfave/cli/v2"
-var CreateCommand = &cli.Command{
- Name: "create",
- Usage: "eBPF Profiling task create related sub-command",
- Subcommands: []*cli.Command{
- PrepareCreateCommand,
- FixedTimeCreateCommand,
+// ProcessFlags take either process id or process name as input,
+// and transform to the other one.
+var ProcessFlags = []cli.Flag{
+ &cli.StringFlag{
+ Name: "process-id",
+ Usage: "`process id`, if you don't have process id, use `--process-name` instead",
+ Required: false,
+ },
+ &cli.StringFlag{
+ Name: "process-name",
+ Usage: "`process name`",
+ Required: false,
},
}
+
+// ProcessRelationFlags take either destination process name as input,
+var ProcessRelationFlags = append(
+ ProcessFlags,
+
+ &cli.StringFlag{
+ Name: "dest-process-name",
+ Usage: "`destination` process name",
+ Required: false,
+ },
+)
diff --git a/pkg/graphql/dependency/dependency.go b/pkg/graphql/dependency/dependency.go
index dd189ca..ea5fe1a 100644
--- a/pkg/graphql/dependency/dependency.go
+++ b/pkg/graphql/dependency/dependency.go
@@ -63,3 +63,15 @@ func InstanceTopology(ctx *cli.Context, clientServiceID, serverServiceID string,
return response["result"], err
}
+
+func ProcessTopology(ctx *cli.Context, instanceID string, duration api.Duration) (api.ProcessTopology, error) {
+ var response map[string]api.ProcessTopology
+
+ request := graphql.NewRequest(assets.Read("graphqls/dependency/ProcessTopology.graphql"))
+ request.Var("serviceInstanceId", instanceID)
+ request.Var("duration", duration)
+
+ err := client.ExecuteQuery(ctx, request, &response)
+
+ return response["result"], err
+}
diff --git a/pkg/graphql/profiling/ebpf.go b/pkg/graphql/profiling/ebpf.go
index 2d9c10c..c75e392 100644
--- a/pkg/graphql/profiling/ebpf.go
+++ b/pkg/graphql/profiling/ebpf.go
@@ -40,6 +40,17 @@ func CreateEBPFProfilingFixedTimeTask(ctx *cli.Context,
return response["result"], err
}
+func CreateEBPFNetworkProfilingTask(ctx *cli.Context, condition *api.EBPFProfilingNetworkTaskRequest) (api.EBPFProfilingTaskCreationResult, error) {
+ var response map[string]api.EBPFProfilingTaskCreationResult
+
+ request := graphql.NewRequest(assets.Read("graphqls/profiling/ebpf/CreateEBPFNetworkProfilingTask.graphql"))
+ request.Var("request", condition)
+
+ err := client.ExecuteQuery(ctx, request, &response)
+
+ return response["result"], err
+}
+
func QueryPrepareCreateEBPFProfilingTaskData(ctx *cli.Context, serviceID string) (*api.EBPFProfilingTaskPrepare, error) {
var response map[string]*api.EBPFProfilingTaskPrepare
@@ -86,3 +97,14 @@ func AnalysisEBPFProfilingResult(ctx *cli.Context, scheduleIDList []string,
return response["result"], err
}
+
+func KeepNetworkProfilingTask(ctx *cli.Context, taskID string) (*api.EBPFNetworkKeepProfilingResult, error) {
+ var response map[string]*api.EBPFNetworkKeepProfilingResult
+
+ request := graphql.NewRequest(assets.Read("graphqls/profiling/ebpf/KeepNetworkProfilingTask.graphql"))
+ request.Var("taskId", taskID)
+
+ err := client.ExecuteQuery(ctx, request, &response)
+
+ return response["result"], err
+}
diff --git a/pkg/graphql/utils/parser.go b/pkg/graphql/utils/parser.go
index 037cedd..15925c5 100644
--- a/pkg/graphql/utils/parser.go
+++ b/pkg/graphql/utils/parser.go
@@ -27,7 +27,9 @@ import (
func ParseScope(entity *api.Entity) api.Scope {
scope := api.ScopeAll
- if *entity.DestEndpointName != "" {
+ if *entity.DestProcessName != "" {
+ scope = api.ScopeProcessRelation
+ } else if *entity.DestEndpointName != "" {
scope = api.ScopeEndpointRelation
} else if *entity.DestServiceInstanceName != "" {
scope = api.ScopeServiceInstanceRelation
diff --git a/pkg/graphql/utils/parser_test.go b/pkg/graphql/utils/parser_test.go
index 9128979..9adb020 100644
--- a/pkg/graphql/utils/parser_test.go
+++ b/pkg/graphql/utils/parser_test.go
@@ -23,6 +23,7 @@ import (
api "skywalking.apache.org/repo/goapi/query"
)
+//nolint:funlen // disable function length check for the test case count
func TestParseScope(t *testing.T) {
empty := ""
nonEmpty := "test"
@@ -37,9 +38,11 @@ func TestParseScope(t *testing.T) {
ServiceName: &empty,
ServiceInstanceName: &empty,
EndpointName: &empty,
+ ProcessName: &empty,
DestServiceName: &empty,
DestServiceInstanceName: &empty,
DestEndpointName: &empty,
+ DestProcessName: &empty,
},
want: api.ScopeAll,
},
@@ -49,11 +52,13 @@ func TestParseScope(t *testing.T) {
ServiceName: &nonEmpty,
ServiceInstanceName: &nonEmpty,
EndpointName: &nonEmpty,
+ ProcessName: &nonEmpty,
DestServiceName: &nonEmpty,
DestServiceInstanceName: &nonEmpty,
DestEndpointName: &nonEmpty,
+ DestProcessName: &nonEmpty,
},
- want: api.ScopeEndpointRelation,
+ want: api.ScopeProcessRelation,
},
{
name: "only serviceName is not empty",
@@ -61,9 +66,11 @@ func TestParseScope(t *testing.T) {
ServiceName: &nonEmpty,
ServiceInstanceName: &empty,
EndpointName: &empty,
+ ProcessName: &empty,
DestServiceName: &empty,
DestServiceInstanceName: &empty,
DestEndpointName: &empty,
+ DestProcessName: &empty,
},
want: api.ScopeService,
},
@@ -73,9 +80,11 @@ func TestParseScope(t *testing.T) {
ServiceName: &nonEmpty,
ServiceInstanceName: &nonEmpty,
EndpointName: &empty,
+ ProcessName: &empty,
DestServiceName: &empty,
DestServiceInstanceName: &empty,
DestEndpointName: &empty,
+ DestProcessName: &empty,
},
want: api.ScopeServiceInstance,
},
@@ -85,9 +94,11 @@ func TestParseScope(t *testing.T) {
ServiceName: &nonEmpty,
ServiceInstanceName: &empty,
EndpointName: &nonEmpty,
+ ProcessName: &empty,
DestServiceName: &empty,
DestServiceInstanceName: &empty,
DestEndpointName: &empty,
+ DestProcessName: &empty,
},
want: api.ScopeEndpoint,
},
@@ -97,9 +108,11 @@ func TestParseScope(t *testing.T) {
ServiceName: &nonEmpty,
ServiceInstanceName: &empty,
EndpointName: &empty,
+ ProcessName: &empty,
DestServiceName: &nonEmpty,
DestServiceInstanceName: &empty,
DestEndpointName: &empty,
+ DestProcessName: &empty,
},
want: api.ScopeServiceRelation,
},
@@ -109,12 +122,28 @@ func TestParseScope(t *testing.T) {
ServiceName: &nonEmpty,
ServiceInstanceName: &nonEmpty,
EndpointName: &empty,
+ ProcessName: &empty,
DestServiceName: &nonEmpty,
DestServiceInstanceName: &nonEmpty,
DestEndpointName: &empty,
+ DestProcessName: &empty,
},
want: api.ScopeServiceInstanceRelation,
},
+ {
+ name: "destProcess is not empty",
+ args: &api.Entity{
+ ServiceName: &nonEmpty,
+ ServiceInstanceName: &nonEmpty,
+ EndpointName: &empty,
+ ProcessName: &nonEmpty,
+ DestServiceName: &nonEmpty,
+ DestServiceInstanceName: &nonEmpty,
+ DestEndpointName: &empty,
+ DestProcessName: &nonEmpty,
+ },
+ want: api.ScopeProcessRelation,
+ },
}
for _, tt := range tests {