Add commands for support network profiling (#158)
diff --git a/CHANGES.md b/CHANGES.md
index ca7a107..31b9d69 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -17,6 +17,9 @@
- [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 @@
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/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 @@
EndpointCommand,
ServiceCommand,
InstanceCommand,
+ ProcessCommand,
},
}
diff --git a/internal/commands/dependency/process.go b/internal/commands/dependency/process.go
new file mode 100644
index 0000000..8a89679
--- /dev/null
+++ b/internal/commands/dependency/process.go
@@ -0,0 +1,67 @@
+// 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 dependency
+
+import (
+ "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/dependency"
+
+ "github.com/urfave/cli/v2"
+
+ api "skywalking.apache.org/repo/goapi/query"
+)
+
+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.ServiceRelationFlags,
+ flags.InstanceRelationFlags,
+ ),
+ Before: interceptor.BeforeChain(
+ interceptor.DurationInterceptor,
+ 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")
+
+ duration := api.Duration{
+ Start: start,
+ End: end,
+ Step: step.(*model.StepEnumValue).Selected,
+ }
+
+ dependency, err := dependency.ProcessTopology(ctx, instanceID, duration)
+ if err != nil {
+ return err
+ }
+
+ 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 @@
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 @@
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 @@
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 @@
flags.MetricsFlags,
flags.InstanceRelationFlags,
flags.EndpointRelationFlags,
+ flags.ProcessRelationFlags,
[]cli.Flag{
&cli.StringFlag{
Name: "labels",
@@ -71,6 +72,7 @@
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 @@
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 @@
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 @@
Subcommands: []*cli.Command{
PrepareCreateCommand,
FixedTimeCreateCommand,
+ NetworkCreateCommand,
},
}
diff --git a/internal/commands/profiling/ebpf/create/network.go b/internal/commands/profiling/ebpf/create/network.go
new file mode 100644
index 0000000..aadf2c8
--- /dev/null
+++ b/internal/commands/profiling/ebpf/create/network.go
@@ -0,0 +1,63 @@
+// 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 create
+
+import (
+ "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"
+
+ "github.com/urfave/cli/v2"
+
+ api "skywalking.apache.org/repo/goapi/query"
+)
+
+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. Create ebpf network profiling task
+$ swctl profiling ebpf create network --service-instance-id=abc`,
+ Flags: flags.Flags(
+ flags.ServiceFlags,
+ flags.InstanceFlags,
+ ),
+ Before: interceptor.BeforeChain(
+ interceptor.ParseInstance(true),
+ ),
+ Action: func(ctx *cli.Context) error {
+ instanceID := ctx.String("instance-id")
+
+ request := &api.EBPFProfilingNetworkTaskRequest{
+ InstanceID: instanceID,
+ }
+
+ task, err := profiling.CreateEBPFNetworkProfilingTask(ctx, request)
+
+ if err != nil {
+ return err
+ }
+
+ 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 @@
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 @@
Usage: "eBPF Profiling related sub-command",
Subcommands: []*cli.Command{
create.CreateCommand,
+ keep.KeepCommand,
ListTaskCommand,
ListScheduleCommand,
AnalyzationCommand,
diff --git a/internal/commands/profiling/ebpf/keep/keep.go b/internal/commands/profiling/ebpf/keep/keep.go
new file mode 100644
index 0000000..22af29e
--- /dev/null
+++ b/internal/commands/profiling/ebpf/keep/keep.go
@@ -0,0 +1,28 @@
+// 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/urfave/cli/v2"
+
+var KeepCommand = &cli.Command{
+ Name: "keep",
+ Usage: "eBPF Profiling task keep-alive related sub-command",
+ Subcommands: []*cli.Command{
+ 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/flags/process.go b/internal/flags/process.go
new file mode 100644
index 0000000..8606059
--- /dev/null
+++ b/internal/flags/process.go
@@ -0,0 +1,46 @@
+// 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 flags
+
+import "github.com/urfave/cli/v2"
+
+// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
ServiceName: &empty,
ServiceInstanceName: &empty,
EndpointName: &empty,
+ ProcessName: &empty,
DestServiceName: &empty,
DestServiceInstanceName: &empty,
DestEndpointName: &empty,
+ DestProcessName: &empty,
},
want: api.ScopeAll,
},
@@ -49,11 +52,13 @@
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 @@
ServiceName: &nonEmpty,
ServiceInstanceName: &empty,
EndpointName: &empty,
+ ProcessName: &empty,
DestServiceName: &empty,
DestServiceInstanceName: &empty,
DestEndpointName: &empty,
+ DestProcessName: &empty,
},
want: api.ScopeService,
},
@@ -73,9 +80,11 @@
ServiceName: &nonEmpty,
ServiceInstanceName: &nonEmpty,
EndpointName: &empty,
+ ProcessName: &empty,
DestServiceName: &empty,
DestServiceInstanceName: &empty,
DestEndpointName: &empty,
+ DestProcessName: &empty,
},
want: api.ScopeServiceInstance,
},
@@ -85,9 +94,11 @@
ServiceName: &nonEmpty,
ServiceInstanceName: &empty,
EndpointName: &nonEmpty,
+ ProcessName: &empty,
DestServiceName: &empty,
DestServiceInstanceName: &empty,
DestEndpointName: &empty,
+ DestProcessName: &empty,
},
want: api.ScopeEndpoint,
},
@@ -97,9 +108,11 @@
ServiceName: &nonEmpty,
ServiceInstanceName: &empty,
EndpointName: &empty,
+ ProcessName: &empty,
DestServiceName: &nonEmpty,
DestServiceInstanceName: &empty,
DestEndpointName: &empty,
+ DestProcessName: &empty,
},
want: api.ScopeServiceRelation,
},
@@ -109,12 +122,28 @@
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 {