blob: 59ca41d5c9a68de00dccd7f9a0fa9ef356ebc6c0 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"strings"
cloudmonitoring "google.golang.org/api/monitoring/v3"
"v.io/v23/context"
"v.io/x/lib/cmdline"
"v.io/x/lib/gcm"
"v.io/x/ref/lib/v23cmd"
)
// cmdMetricDescriptor represents the "md" command of the vmon tool.
var cmdMetricDescriptor = &cmdline.Command{
Name: "md",
Short: "Manage metric descriptors in the given GCM instance",
Long: `
Metric descriptor defines the metadata for a custom metric. It includes the
metric's name, description, a set of labels, and its type. Before adding custom
metric data points to GCM, we need to create its metric descriptor (once).
`,
Children: []*cmdline.Command{
cmdMetricDescriptorCreate,
cmdMetricDescriptorDelete,
cmdMetricDescriptorList,
cmdMetricDescriptorQuery,
},
}
// cmdMetricDescriptorCreate represents the "vmon md create" command.
var cmdMetricDescriptorCreate = &cmdline.Command{
Runner: v23cmd.RunnerFunc(runMetricDescriptorCreate),
Name: "create",
Short: "Create the given metric descriptor in GCM",
Long: "Create the given metric descriptor in GCM.",
ArgsName: "<names>",
ArgsLong: "<names> is a list of metric descriptor names to create. Available: " + strings.Join(gcm.GetSortedMetricNames(), ", "),
}
func runMetricDescriptorCreate(_ *context.T, env *cmdline.Env, args []string) error {
if err := checkArgs(env, args); err != nil {
return err
}
s, err := gcm.Authenticate(keyFileFlag)
if err != nil {
return err
}
for _, arg := range args {
md, err := gcm.GetMetric(arg, projectFlag)
if err != nil {
return err
}
_, err = s.Projects.MetricDescriptors.Create(fmt.Sprintf("projects/%s", projectFlag), md).Do()
if err != nil {
return fmt.Errorf("Create failed: %v", err)
}
}
fmt.Fprintf(env.Stdout, "OK\n")
return nil
}
// cmdMetricDescriptorDelete represents the "vmon md delete" command.
var cmdMetricDescriptorDelete = &cmdline.Command{
Runner: v23cmd.RunnerFunc(runMetricDescriptorDelete),
Name: "delete",
Short: "Delete the given metric descriptor from GCM",
Long: "Delete the given metric descriptor from GCM.",
ArgsName: "<names>",
ArgsLong: "<names> is a list of metric descriptor names to delete. Available: " + strings.Join(gcm.GetSortedMetricNames(), ", "),
}
func runMetricDescriptorDelete(_ *context.T, env *cmdline.Env, args []string) error {
if err := checkArgs(env, args); err != nil {
return err
}
s, err := gcm.Authenticate(keyFileFlag)
if err != nil {
return err
}
for _, arg := range args {
md, err := gcm.GetMetric(arg, projectFlag)
if err != nil {
return err
}
_, err = s.Projects.MetricDescriptors.Delete(md.Name).Do()
if err != nil {
return fmt.Errorf("Delete failed: %v", err)
}
}
fmt.Fprintf(env.Stdout, "OK\n")
return nil
}
// cmdMetricDescriptorList represents the "vmon md list" command.
var cmdMetricDescriptorList = &cmdline.Command{
Runner: v23cmd.RunnerFunc(runMetricDescriptorList),
Name: "list",
Short: "List known custom metric descriptors",
Long: "List known custom metric descriptors.",
}
func runMetricDescriptorList(_ *context.T, env *cmdline.Env, _ []string) error {
for _, n := range gcm.GetSortedMetricNames() {
fmt.Fprintf(env.Stdout, "%s\n", n)
}
return nil
}
// cmdMetricDescriptorQuery represents the "vmon md query" command.
var cmdMetricDescriptorQuery = &cmdline.Command{
Runner: v23cmd.RunnerFunc(runMetricDescriptorQuery),
Name: "query",
Short: "Query metric descriptors from GCM using the given filter",
Long: "Query metric descriptors from GCM using the given filter.",
}
func runMetricDescriptorQuery(_ *context.T, env *cmdline.Env, _ []string) error {
s, err := gcm.Authenticate(keyFileFlag)
if err != nil {
return err
}
// Query.
nextPageToken := ""
descriptors := []*cloudmonitoring.MetricDescriptor{}
for {
resp, err := s.Projects.MetricDescriptors.List(fmt.Sprintf("projects/%s", projectFlag)).
Filter(queryFilterFlag).
PageToken(nextPageToken).Do()
if err != nil {
return fmt.Errorf("Query failed: %v", err)
}
descriptors = append(descriptors, resp.MetricDescriptors...)
nextPageToken = resp.NextPageToken
if nextPageToken == "" {
break
}
}
// Output results.
for _, metric := range descriptors {
fmt.Fprintf(env.Stdout, "%s\n", metric.Type)
fmt.Fprintf(env.Stdout, "- Name: %s\n", metric.Name)
fmt.Fprintf(env.Stdout, "- Description: %s\n", metric.Description)
fmt.Fprintf(env.Stdout, "- Metric Type: %s\n", metric.MetricKind)
fmt.Fprintf(env.Stdout, "- Value Type: %s\n", metric.ValueType)
if len(metric.Labels) > 0 {
fmt.Fprintf(env.Stdout, "- Labels:\n")
for _, label := range metric.Labels {
fmt.Fprintf(env.Stdout, " - Name: %s\n", label.Key)
fmt.Fprintf(env.Stdout, " - Description: %s\n", label.Description)
}
}
fmt.Fprintln(env.Stdout)
}
return nil
}
func checkArgs(env *cmdline.Env, args []string) error {
for _, arg := range args {
if _, err := gcm.GetMetric(arg, projectFlag); err != nil {
return err
}
}
if len(args) == 0 {
return env.UsageErrorf("no metric descriptor provided")
}
return nil
}