Skip to content

Commit 51d7722

Browse files
author
Eric Wiseblatt
authored
Merge pull request #50 from ewiseblatt/1_config
Adds Stackdriver config
2 parents a9e5fd6 + 8aae6fa commit 51d7722

File tree

4 files changed

+183
-6
lines changed

4 files changed

+183
-6
lines changed

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@ allprojects {
5757
}
5858

5959
jacoco {
60-
toolVersion = '0.7.0.201403182114'
60+
toolVersion = '0.7.7.201606060606'
6161
}
6262
}

kork-stackdriver/kork-stackdriver.gradle

+8-3
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,16 @@
1515
*/
1616

1717
dependencies {
18+
compile spinnaker.dependency('bootActuator')
19+
compile spinnaker.dependency('bootDataRest')
20+
compile spinnaker.dependency('rxJava')
21+
1822
compile spinnaker.dependency('spectatorApi')
23+
// TODO(ewiseblatt): need to update spinnaker-dependencies first
24+
// compile spinnaker.dependency('spectatorWebSpring')
25+
compile "com.netflix.spectator:spectator-web-spring:${spinnaker.version('spectator')}"
1926

20-
// googleMonitoring is not yet in spinnaker-dependencies
21-
// compile spinnaker.dependency('googleMonitoring')
22-
compile compile('com.google.apis:google-api-services-monitoring:v3-rev9-1.22.0')
27+
compile spinnaker.dependency('googleMonitoring')
2328

2429
testCompile 'org.mockito:mockito-core:2.+'
2530
testCompile 'junit:junit:4.+'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/*
2+
* Copyright 2016 Google, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License")
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.netflix.spinnaker.config;
18+
19+
import com.netflix.spectator.controllers.filter.PrototypeMeasurementFilter;
20+
import com.netflix.spectator.controllers.MetricsController;
21+
import com.netflix.spectator.stackdriver.ConfigParams;
22+
import com.netflix.spectator.stackdriver.MetricDescriptorCache;
23+
import com.netflix.spectator.stackdriver.StackdriverWriter;
24+
25+
import com.netflix.spectator.api.DefaultRegistry;
26+
import com.netflix.spectator.api.Measurement;
27+
import com.netflix.spectator.api.Registry;
28+
import com.netflix.spectator.api.Spectator;
29+
30+
import org.slf4j.Logger;
31+
import org.slf4j.LoggerFactory;
32+
import org.springframework.beans.factory.annotation.Value;
33+
import org.springframework.beans.factory.annotation.Autowired;
34+
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
35+
import org.springframework.boot.context.properties.ConfigurationProperties;
36+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
37+
import org.springframework.context.annotation.Bean;
38+
import org.springframework.context.annotation.Configuration;
39+
import org.springframework.context.annotation.Import;
40+
41+
42+
import java.io.IOException;
43+
import java.util.Arrays;
44+
import java.util.ArrayList;
45+
import java.util.Date;
46+
import java.util.List;
47+
import java.util.Map;
48+
import java.util.concurrent.Executors;
49+
import java.util.concurrent.TimeUnit;
50+
import java.util.function.Predicate;
51+
52+
import rx.Observable;
53+
import rx.Scheduler;
54+
import rx.schedulers.Schedulers;
55+
56+
57+
@Configuration
58+
@EnableConfigurationProperties
59+
@Import({MetricsController.class})
60+
@ConditionalOnExpression("${spectator.stackdriver.enabled:false}")
61+
class StackdriverConfig {
62+
63+
@Value("${spectator.applicationName:${spring.application.name}}")
64+
private String applicationName;
65+
66+
@Value("${spectator.stackdriver.credentialsPath:}")
67+
private String credentialsPath;
68+
69+
@Value("${spectator.stackdriver.projectName:}")
70+
private String projectName;
71+
72+
@Value("${spectator.stackdriver.uniqueMetricsPerApplication:true}")
73+
private boolean uniqueMetricsPerApplication;
74+
75+
// If provided, takes precedence over the *Regex filters above.
76+
@Value("${spectator.webEndpoint.prototypeFilter.path:}")
77+
private String prototypeFilterPath;
78+
79+
@Value("${spectator.stackdriver.period:60}")
80+
private int pushPeriodSecs;
81+
82+
private StackdriverWriter stackdriver;
83+
84+
@Configuration
85+
@ConfigurationProperties(prefix="stackdriver")
86+
static public class StackdriverConfigurationHints {
87+
/**
88+
* This class lets spring load from our YAML file into a Hint instance.
89+
*/
90+
static public class MutableHint extends MetricDescriptorCache.CustomDescriptorHint {
91+
public void setLabels(List<String> labels) {
92+
this.labels = labels;
93+
}
94+
public void setRedacted(List<String> labels) {
95+
this.redacted = labels;
96+
}
97+
public void setName(String name) {
98+
this.name = name;
99+
}
100+
};
101+
102+
public List<MutableHint> hints;
103+
public void setHints(List<MutableHint> hints) { this.hints = hints; }
104+
public List<MutableHint> getHints() { return hints; }
105+
};
106+
107+
@Autowired
108+
StackdriverConfigurationHints stackdriverHints;
109+
110+
@Autowired
111+
Registry registry;
112+
113+
/**
114+
* Schedule a thread to flush our registry into stackdriver periodically.
115+
*
116+
* This configures our StackdriverWriter as well.
117+
*/
118+
@Bean
119+
public StackdriverWriter defaultStackdriverWriter() throws IOException {
120+
Logger log = LoggerFactory.getLogger("StackdriverConfig");
121+
log.info("Creating StackdriverWriter.");
122+
Predicate<Measurement> filterNotSpring = new Predicate<Measurement>() {
123+
public boolean test(Measurement measurement) {
124+
// Dont store measurements that dont have tags.
125+
// These are from spring; those of interest were replicated in spectator.
126+
if (measurement.id().tags().iterator().hasNext()) {
127+
return true;
128+
}
129+
130+
return false;
131+
}
132+
};
133+
Predicate<Measurement> measurementFilter;
134+
135+
if (!prototypeFilterPath.isEmpty()) {
136+
log.error("Ignoring prototypeFilterPath because it is not yet supported.");
137+
measurementFilter = null;
138+
log.info("Configuring stackdriver filter from {}", prototypeFilterPath);
139+
measurementFilter = PrototypeMeasurementFilter.loadFromPath(
140+
prototypeFilterPath).and(filterNotSpring);
141+
} else {
142+
measurementFilter = filterNotSpring;
143+
}
144+
145+
ConfigParams params = new ConfigParams.Builder()
146+
.setCounterStartTime(new Date().getTime())
147+
.setUniqueMetricsPerApplication(uniqueMetricsPerApplication)
148+
.setCustomTypeNamespace("spinnaker")
149+
.setProjectName(projectName)
150+
.setApplicationName(applicationName)
151+
.setCredentialsPath(credentialsPath)
152+
.setMeasurementFilter(measurementFilter)
153+
.build();
154+
155+
stackdriver = new StackdriverWriter(params);
156+
157+
if (stackdriverHints != null && stackdriverHints.hints != null) {
158+
log.info("Adding {} custom descriptor hints",
159+
stackdriverHints.hints.size());
160+
stackdriver.getDescriptorCache()
161+
.addCustomDescriptorHints(stackdriverHints.hints);
162+
} else {
163+
log.info("No custom descriptor hints");
164+
}
165+
Scheduler scheduler = Schedulers.from(Executors.newFixedThreadPool(1));
166+
167+
Observable.timer(pushPeriodSecs, TimeUnit.SECONDS)
168+
.repeat()
169+
.subscribe(interval -> { stackdriver.writeRegistry(registry); });
170+
171+
return stackdriver;
172+
}
173+
};

settings.gradle

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
include 'kork-core', 'kork-cassandra', 'kork-jedis-test', 'kork-swagger', 'kork-security', 'kork-web', 'kork-hystrix'
18-
//TODO(ewiseblatt) - fix for spectator 0.41.0: , 'kork-stackdriver'
17+
include 'kork-core', 'kork-cassandra', 'kork-jedis-test', 'kork-swagger', 'kork-security', 'kork-web', 'kork-hystrix', 'kork-stackdriver'
1918

2019
rootProject.name='kork'
2120

0 commit comments

Comments
 (0)