Skip to content
This repository was archived by the owner on Dec 3, 2024. It is now read-only.

Commit ced9b46

Browse files
committed
feat(custom-monitored-resource): impl, tests
1 parent 132b04a commit ced9b46

File tree

3 files changed

+117
-10
lines changed

3 files changed

+117
-10
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.iml

stackdriver.go

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ type Sink struct {
5555
prefix string
5656
taskInfo *taskInfo
5757

58+
monitoredResource *monitoredrespb.MonitoredResource
59+
5860
mu sync.Mutex
5961
debugLogs bool
6062
}
@@ -104,6 +106,15 @@ type Config struct {
104106
// will log additional information that is helpful when debugging errors.
105107
// Optional. Defaults to false.
106108
DebugLogs bool
109+
110+
//MonitoredResource identifies the machine/service/resource
111+
//that is monitored.
112+
//Different possible settings are defined here:
113+
//https://cloud.google.com/monitoring/api/resources
114+
//
115+
//setting a nil MonitoredResource will run
116+
//a defaultMonitoredResource function.
117+
MonitoredResource *monitoredrespb.MonitoredResource
107118
}
108119

109120
type taskInfo struct {
@@ -123,6 +134,20 @@ type BucketFn func([]string) []float64
123134
// writing to stackdriver.
124135
type ExtractLabelsFn func([]string, string) ([]string, []metrics.Label, error)
125136

137+
// defaultMonitoredResource returns default monitored resource
138+
func defaultMonitoredResource(taskInfo *taskInfo) *monitoredrespb.MonitoredResource {
139+
return &monitoredrespb.MonitoredResource{
140+
Type: "generic_task",
141+
Labels: map[string]string{
142+
"project_id": taskInfo.ProjectID,
143+
"location": taskInfo.Location,
144+
"namespace": taskInfo.Namespace,
145+
"job": taskInfo.Job,
146+
"task_id": taskInfo.TaskID,
147+
},
148+
}
149+
}
150+
126151
// DefaultBucketer is the default BucketFn used to determing bucketing values
127152
// for metrics.
128153
func DefaultBucketer(key []string) []float64 {
@@ -211,6 +236,12 @@ func NewSink(client *monitoring.MetricClient, config *Config) *Sink {
211236
s.taskInfo.TaskID = "go-" + strconv.Itoa(os.Getpid()) + "@" + hostname
212237
}
213238

239+
if config.MonitoredResource != nil {
240+
s.monitoredResource = config.MonitoredResource
241+
} else {
242+
s.monitoredResource = defaultMonitoredResource(s.taskInfo)
243+
}
244+
214245
s.reset()
215246

216247
// run cancelable goroutine that reports on interval
@@ -291,16 +322,7 @@ func (s *Sink) report(ctx context.Context) {
291322
end, rGauges, rCounters, rHistograms := s.deep()
292323

293324
// https://cloud.google.com/monitoring/api/resources
294-
resource := &monitoredrespb.MonitoredResource{
295-
Type: "generic_task",
296-
Labels: map[string]string{
297-
"project_id": s.taskInfo.ProjectID,
298-
"location": s.taskInfo.Location,
299-
"namespace": s.taskInfo.Namespace,
300-
"job": s.taskInfo.Job,
301-
"task_id": s.taskInfo.TaskID,
302-
},
303-
}
325+
resource := s.monitoredResource
304326

305327
ts := []*monitoringpb.TimeSeries{}
306328

stackdriver_test.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@
1414
package stackdriver
1515

1616
import (
17+
"bytes"
1718
"context"
19+
"encoding/json"
1820
"errors"
1921
"fmt"
22+
monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres"
2023
"net"
2124
"sync"
2225
"testing"
@@ -1091,3 +1094,84 @@ func diffCreateMsg(want, got *monitoringpb.CreateTimeSeriesRequest) string {
10911094
}
10921095
return out
10931096
}
1097+
1098+
func TestCustomMonitorResource(t *testing.T) {
1099+
checkLabels := func(sink *Sink, labels map[string]string) error {
1100+
expectedLabels := sink.monitoredResource.GetLabels()
1101+
1102+
expectedLabelsBytes, _ := json.Marshal(expectedLabels)
1103+
labelsBytes, _ := json.Marshal(labels)
1104+
1105+
if expectedLabelsBytes == nil || !bytes.Equal(expectedLabelsBytes, labelsBytes) {
1106+
return errors.New("invalid labels")
1107+
}
1108+
1109+
return nil
1110+
}
1111+
1112+
{
1113+
labels := map[string]string{
1114+
"project_id": "project",
1115+
"location": "zone",
1116+
"cluster_name": "cluster",
1117+
"container_name": "container_name",
1118+
"namespace_name": "namespace_name",
1119+
"pod_name": "pod_name",
1120+
}
1121+
1122+
sink := NewSink(nil, &Config{
1123+
ProjectID: "example_project",
1124+
Prefix: sPtr(""),
1125+
MonitoredResource: &monitoredrespb.MonitoredResource{
1126+
Labels: labels,
1127+
Type: "k8s_container",
1128+
},
1129+
})
1130+
1131+
if err := checkLabels(sink, labels); err != nil {
1132+
t.Error(err)
1133+
}
1134+
}
1135+
1136+
{
1137+
sink := NewSink(nil, &Config{
1138+
ProjectID: "example_project",
1139+
Prefix: sPtr(""),
1140+
})
1141+
1142+
labels := defaultMonitoredResource(sink.taskInfo).GetLabels()
1143+
1144+
if err := checkLabels(sink, labels); err != nil {
1145+
t.Error(err)
1146+
}
1147+
}
1148+
1149+
{
1150+
labels := map[string]string{
1151+
"project_id": "project",
1152+
"location": "zone",
1153+
"cluster_name": "cluster",
1154+
"container_name": "container_name",
1155+
"namespace_name": "namespace_name",
1156+
"pod_name": "pod_name",
1157+
}
1158+
1159+
invalidLabels := map[string]string{
1160+
"project_id": "project",
1161+
}
1162+
1163+
sink := NewSink(nil, &Config{
1164+
ProjectID: "example_project",
1165+
Prefix: sPtr(""),
1166+
MonitoredResource: &monitoredrespb.MonitoredResource{
1167+
Labels: labels,
1168+
Type: "k8s_container",
1169+
},
1170+
})
1171+
1172+
if err := checkLabels(sink, invalidLabels); err == nil {
1173+
t.Error("labels should be the same")
1174+
}
1175+
}
1176+
1177+
}

0 commit comments

Comments
 (0)