...
1 package cmd
2
3 import (
4 "bytes"
5 "fmt"
6 "time"
7
8 "github.com/linkerd/linkerd2/pkg/k8s"
9 "github.com/spf13/cobra"
10 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11 )
12
13
14
15 type ControllerMetricsOptions struct {
16 wait time.Duration
17 }
18
19
20
21
22
23 func newControllerMetricsOptions() *ControllerMetricsOptions {
24 return &ControllerMetricsOptions{
25 wait: 30 * time.Second,
26 }
27 }
28
29
30 func newCmdControllerMetrics() *cobra.Command {
31 options := newControllerMetricsOptions()
32
33 cmd := &cobra.Command{
34 Use: "controller-metrics",
35 Aliases: []string{"cp-metrics"},
36 Short: "Fetch metrics directly from the Linkerd control plane containers",
37 Long: `Fetch metrics directly from Linkerd control plane containers.
38
39 This command initiates port-forward to each control plane process, and
40 queries the /metrics endpoint on them.`,
41 Args: cobra.NoArgs,
42 RunE: func(cmd *cobra.Command, args []string) error {
43 k8sAPI, err := k8s.NewAPI(kubeconfigPath, kubeContext, impersonate, impersonateGroup, 0)
44 if err != nil {
45 return err
46 }
47
48 pods, err := k8sAPI.CoreV1().Pods(controlPlaneNamespace).List(cmd.Context(), metav1.ListOptions{})
49 if err != nil {
50 return err
51 }
52
53 results := getMetrics(k8sAPI, pods.Items, k8s.AdminHTTPPortName, options.wait, verbose)
54
55 var buf bytes.Buffer
56 for i, result := range results {
57 content := fmt.Sprintf("#\n# POD %s (%d of %d)\n", result.pod, i+1, len(results))
58 if result.err != nil {
59 content += fmt.Sprintf("# ERROR %s\n", result.err)
60 } else {
61 content += fmt.Sprintf("# CONTAINER %s \n#\n", result.container)
62 content += string(result.metrics)
63 }
64 buf.WriteString(content)
65 }
66 fmt.Printf("%s", buf.String())
67
68 return nil
69 },
70 }
71
72 cmd.Flags().DurationVarP(&options.wait, "wait", "w", options.wait, "Time allowed to fetch diagnostics")
73
74 return cmd
75 }
76
View as plain text