Skip to content

Commit

Permalink
Update example to work with old and new Stackdriver resource model
Browse files Browse the repository at this point in the history
  • Loading branch information
kawych committed Mar 15, 2018
1 parent 75b6ba3 commit c9df2f5
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 17 deletions.
3 changes: 2 additions & 1 deletion custom-metrics-stackdriver-adapter/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
build
testing/sd_dummy_exporter
examples/direct-to-sd/sd_dummy_exporter
examples/prometheus-to-sd/prometheus_dummy_exporter
*.swp
*~
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
TAG = v0.1.0
TAG = v0.2.0
PREFIX = gcr.io/google-containers

build: sd_dummy_exporter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,31 +33,59 @@ import (

// SD Dummy Exporter is a testing utility that exports a metric of constant value to Stackdriver
// in a loop. Metric name and value can be specified with flags 'metric-name' and 'metric-value'.
// SD Dummy Exporter assumes that it runs as a pod in GCE or GKE cluster, and the pod id is passed
// to it with 'pod-id' flag (which can be passed to a pod via Downward API).
// SD Dummy Exporter assumes that it runs as a pod in GCE or GKE cluster, and the pod id, pod name
// and namespace are passed to it with 'pod-id', 'pod-name' and 'namespace' flags.
// Pod ID and pod name can be passed to a pod via Downward API.
func main() {
// Gather pod information
podId := flag.String("pod-id", "", "pod id")
namespace := flag.String("namespace", "", "namespace")
podName := flag.String("pod-name", "", "pod name")
metricName := flag.String("metric-name", "foo", "custom metric name")
metricValue := flag.Int64("metric-value", 0, "custom metric value")
// Whether to use old Stackdriver resource model - use monitored resource "gke_container"
// For old resource model, podId flag has to be set.
useOldResourceModel := flag.Bool("use-old-resource-model", true, "use old stackdriver resource model")
// Whether to use new Stackdriver resource model - use monitored resource "k8s_pod"
// For new resource model, podName and namespace flags have to be set.
useNewResourceModel := flag.Bool("use-new-resource-model", false, "use new stackdriver resource model")
flag.Parse()

if *podId == "" {
if *podId == "" && *useOldResourceModel {
log.Fatalf("No pod id specified.")
}

if *podName == "" && *useNewResourceModel {
log.Fatalf("No pod name specified.")
}

if *namespace == "" && *useNewResourceModel {
log.Fatalf("No pod namespace specified.")
}

stackdriverService, err := getStackDriverService()
if err != nil {
log.Fatalf("Error getting Stackdriver service: %v", err)
}

labels := getResourceLabels(*podId)
oldModelLabels := getResourceLabelsForOldModel(*podId)
newModelLabels := getResourceLabelsForNewModel(*namespace, *podName)
for {
err := exportMetric(stackdriverService, *metricName, *metricValue, labels)
if err != nil {
log.Printf("Failed to write time series data: %v\n", err)
} else {
log.Printf("Finished writing time series with value: %v\n", metricValue)
if *useOldResourceModel {
err := exportMetric(stackdriverService, *metricName, *metricValue, "gke_container", oldModelLabels)
if err != nil {
log.Printf("Failed to write time series data for old resource model: %v\n", err)
} else {
log.Printf("Finished writing time series for new resource model with value: %v\n", metricValue)
}
}
if *useNewResourceModel {
err := exportMetric(stackdriverService, *metricName, *metricValue, "k8s_pod", newModelLabels)
if err != nil {
log.Printf("Failed to write time series data for new resource model: %v\n", err)
} else {
log.Printf("Finished writing time series for new resource model with value: %v\n", metricValue)
}
}
time.Sleep(5000 * time.Millisecond)
}
Expand All @@ -68,10 +96,10 @@ func getStackDriverService() (*monitoring.Service, error) {
return monitoring.New(oauthClient)
}

// getResourceLabels returns resource labels needed to correctly label metric data
// exported to StackDriver. Labels contain details on the cluster (name, zone, project id)
// and pod for which the metric is exported (id)
func getResourceLabels(podId string) map[string]string {
// getResourceLabelsForOldModel returns resource labels needed to correctly label metric data
// exported to StackDriver. Labels contain details on the cluster (project id, name)
// and pod for which the metric is exported (zone, id).
func getResourceLabelsForOldModel(podId string) map[string]string {
projectId, _ := gce.ProjectID()
zone, _ := gce.Zone()
clusterName, _ := gce.InstanceAttributeValue("cluster-name")
Expand All @@ -90,8 +118,26 @@ func getResourceLabels(podId string) map[string]string {
}
}

// getResourceLabelsForNewModel returns resource labels needed to correctly label metric data
// exported to StackDriver. Labels contain details on the cluster (project id, location, name)
// and pod for which the metric is exported (namespace, name).
func getResourceLabelsForNewModel(namespace, name string) map[string]string {
projectId, _ := gce.ProjectID()
location, _ := gce.InstanceAttributeValue("cluster-location")
location = strings.TrimSpace(location)
clusterName, _ := gce.InstanceAttributeValue("cluster-name")
clusterName = strings.TrimSpace(clusterName)
return map[string]string{
"project_id": projectId,
"location": location,
"cluster_name": clusterName,
"namespace_name": namespace,
"pod_name": name,
}
}

func exportMetric(stackdriverService *monitoring.Service, metricName string,
metricValue int64, resourceLabels map[string]string) error {
metricValue int64, monitoredResource string, resourceLabels map[string]string) error {
dataPoint := &monitoring.Point{
Interval: &monitoring.TimeInterval{
EndTime: time.Now().Format(time.RFC3339),
Expand All @@ -108,7 +154,7 @@ func exportMetric(stackdriverService *monitoring.Service, metricName string,
Type: "custom.googleapis.com/" + metricName,
},
Resource: &monitoring.MonitoredResource{
Type: "gke_container",
Type: monitoredResource,
Labels: resourceLabels,
},
Points: []*monitoring.Point{
Expand Down
9 changes: 9 additions & 0 deletions hack/verify-flags/exceptions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,27 @@ custom-metrics-stackdriver-adapter/README.md: podIdFlag := flag.String("po
custom-metrics-stackdriver-adapter/README.md: - `pod_id` - set this to pod UID obtained via downward API. Example configuration that passes POD_ID to your application as a flag:
custom-metrics-stackdriver-adapter/examples/direct-to-sd/sd_dummy_exporter.go: "namespace_id": "default",
custom-metrics-stackdriver-adapter/examples/direct-to-sd/sd_dummy_exporter.go: "pod_id": podId,
custom-metrics-stackdriver-adapter/examples/direct-to-sd/sd_dummy_exporter.go: "pod_name": name,
custom-metrics-stackdriver-adapter/examples/direct-to-sd/sd_dummy_exporter.go: // namespace_id and instance_id don't matter
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator.go: return timeSeries.Resource.Labels["namespace_name"] + ":" + timeSeries.Resource.Labels["pod_name"], nil
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator.go: return fmt.Sprintf("resource.label.namespace_name = %q AND resource.label.pod_name = %s", namespace, podNames[0])
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator.go: return fmt.Sprintf("resource.label.pod_id = %s", podIDs[0])
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator.go: return timeSeries.Resource.Labels["pod_id"], nil
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator.go: return "resource.label.pod_id != \"\" AND resource.label.pod_id != \"machine\""
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator.go: return fmt.Sprintf("resource.label.namespace_name = %q AND resource.label.pod_name = one_of(%s)", namespace, strings.Join(podNames, ","))
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator.go: return fmt.Sprintf("resource.label.pod_id = one_of(%s)", strings.Join(podIDs, ","))
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator_test.go: "resource.label.pod_id": "my-pod-id",
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator_test.go: "AND resource.label : pod_name " +
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator_test.go: "AND resource.label.container_name = \"\" AND resource.label.pod_id != \"\" " +
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator_test.go: "AND resource.label.pod_id != \"machine\"")
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator_test.go: "AND resource.label.pod_id = one_of(\"my-pod-id-1\",\"my-pod-id-2\")").
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator_test.go: "AND resource.label.pod_name = \"my-pod-name\" " +
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator_test.go: "AND resource.label.pod_name = one_of(\"my-pod-name-1\",\"my-pod-name-2\") " +
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator_test.go: Resource: &sd.MonitoredResource{Type: "gke_container", Labels: map[string]string{"pod_id": "my-pod-id"}},
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator_test.go: Resource: &sd.MonitoredResource{Type: "gke_container", Labels: map[string]string{"pod_id": "my-pod-id"}},
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator_test.go: Resource: &sd.MonitoredResource{Type: "gke_container", Labels: map[string]string{"pod_id": "my-pod-id"}},
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator_test.go: req2, _ := labels.NewRequirement("resource.label.pod_name", selection.Exists, []string{})
custom-metrics-stackdriver-adapter/pkg/adapter/provider/translator_test.go: req3, _ := labels.NewRequirement("resource.label.pod_name", selection.Exists, []string{})
kubelet-to-gcm/monitor/controller/translator.go: "namespace_id": "",
kubelet-to-gcm/monitor/controller/translator.go: "pod_id": "machine",
kubelet-to-gcm/monitor/kubelet/translate.go: "namespace_id": namespace,
Expand Down
2 changes: 2 additions & 0 deletions hack/verify-flags/known-flags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ one-time
on-start
path-label-config
pod-id
pod-name
pod-scheduled-timeout
poll-period
presubmit-jobs
Expand Down Expand Up @@ -174,6 +175,7 @@ use-cluster-credentials
use-ip
use-kubernetes-cluster-service
use-new-resource-model
use-old-resource-model
use-real-cloud
use-reviewers
user-whitelist
Expand Down

0 comments on commit c9df2f5

Please sign in to comment.