Commit a57c3587 by Spencer Gibb

prefix hystrix metric same with context id and add ability to disable.

fixes gh-135 created hystrix.stream.amqp.send-id to allow disabling of sending the context id as the metric id. Turbine AMQP then defaults to serviceId:host:port fixes gh-131
parent c992066a
...@@ -76,6 +76,16 @@ ...@@ -76,6 +76,16 @@
<scope>compile</scope> <scope>compile</scope>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>
package org.springframework.netflix.hystrix.amqp;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author Spencer Gibb
*/
@ConfigurationProperties("hystrix.stream.amqp")
@Data
public class HystrixStreamAmqpProperties {
private boolean enabled = true;
private boolean prefixMetricName = true;
private boolean sendId = true;
}
...@@ -8,6 +8,7 @@ import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; ...@@ -8,6 +8,7 @@ import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.netflix.Constants; import org.springframework.cloud.netflix.Constants;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
...@@ -28,6 +29,7 @@ import com.netflix.hystrix.HystrixCircuitBreaker; ...@@ -28,6 +29,7 @@ import com.netflix.hystrix.HystrixCircuitBreaker;
@ConditionalOnClass({ HystrixCircuitBreaker.class, RabbitTemplate.class }) @ConditionalOnClass({ HystrixCircuitBreaker.class, RabbitTemplate.class })
@ConditionalOnExpression("${hystrix.stream.amqp.enabled:true}") @ConditionalOnExpression("${hystrix.stream.amqp.enabled:true}")
@IntegrationComponentScan(basePackageClasses = HystrixStreamChannel.class) @IntegrationComponentScan(basePackageClasses = HystrixStreamChannel.class)
@EnableConfigurationProperties
@EnableScheduling @EnableScheduling
public class HystrixStreamAutoConfiguration { public class HystrixStreamAutoConfiguration {
...@@ -37,6 +39,7 @@ public class HystrixStreamAutoConfiguration { ...@@ -37,6 +39,7 @@ public class HystrixStreamAutoConfiguration {
@Autowired(required = false) @Autowired(required = false)
private ObjectMapper objectMapper; private ObjectMapper objectMapper;
@PostConstruct @PostConstruct
public void init() { public void init() {
Jackson2JsonMessageConverter converter = messageConverter(); Jackson2JsonMessageConverter converter = messageConverter();
...@@ -44,6 +47,11 @@ public class HystrixStreamAutoConfiguration { ...@@ -44,6 +47,11 @@ public class HystrixStreamAutoConfiguration {
} }
@Bean @Bean
public HystrixStreamAmqpProperties hystrixStreamAmqpProperties() {
return new HystrixStreamAmqpProperties();
}
@Bean
public HystrixStreamTask hystrixStreamTask() { public HystrixStreamTask hystrixStreamTask() {
return new HystrixStreamTask(); return new HystrixStreamTask();
} }
......
...@@ -5,10 +5,12 @@ import com.netflix.hystrix.util.HystrixRollingNumberEvent; ...@@ -5,10 +5,12 @@ import com.netflix.hystrix.util.HystrixRollingNumberEvent;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.JsonGenerator;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import java.io.IOException; import java.io.IOException;
...@@ -22,7 +24,7 @@ import java.util.concurrent.LinkedBlockingQueue; ...@@ -22,7 +24,7 @@ import java.util.concurrent.LinkedBlockingQueue;
* see com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller.MetricsPoller * see com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller.MetricsPoller
*/ */
@Slf4j @Slf4j
public class HystrixStreamTask { public class HystrixStreamTask implements ApplicationContextAware {
@Autowired @Autowired
private HystrixStreamChannel channel; private HystrixStreamChannel channel;
...@@ -30,13 +32,20 @@ public class HystrixStreamTask { ...@@ -30,13 +32,20 @@ public class HystrixStreamTask {
@Autowired @Autowired
private DiscoveryClient discoveryClient; private DiscoveryClient discoveryClient;
@Autowired
private ApplicationContext context; private ApplicationContext context;
@Autowired
private HystrixStreamAmqpProperties properties;
private final LinkedBlockingQueue<String> jsonMetrics = new LinkedBlockingQueue<>(1000); private final LinkedBlockingQueue<String> jsonMetrics = new LinkedBlockingQueue<>(1000);
private final JsonFactory jsonFactory = new JsonFactory(); private final JsonFactory jsonFactory = new JsonFactory();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
//TODO: use integration to split this up? //TODO: use integration to split this up?
@Scheduled(fixedRateString = "${hystrix.stream.amqp.sendRate:500}") @Scheduled(fixedRateString = "${hystrix.stream.amqp.sendRate:500}")
public void sendMetrics() { public void sendMetrics() {
...@@ -66,6 +75,9 @@ public class HystrixStreamTask { ...@@ -66,6 +75,9 @@ public class HystrixStreamTask {
if (!instances.isEmpty()) { if (!instances.isEmpty()) {
log.trace("gathering metrics size: " + instances.size()); log.trace("gathering metrics size: " + instances.size());
} }
ServiceInstance localService = discoveryClient.getLocalServiceInstance();
for (HystrixCommandMetrics commandMetrics : instances) { for (HystrixCommandMetrics commandMetrics : instances) {
HystrixCommandKey key = commandMetrics.getCommandKey(); HystrixCommandKey key = commandMetrics.getCommandKey();
HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(key); HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(key);
...@@ -73,12 +85,19 @@ public class HystrixStreamTask { ...@@ -73,12 +85,19 @@ public class HystrixStreamTask {
StringWriter jsonString = new StringWriter(); StringWriter jsonString = new StringWriter();
JsonGenerator json = jsonFactory.createJsonGenerator(jsonString); JsonGenerator json = jsonFactory.createJsonGenerator(jsonString);
json.writeStartObject(); json.writeStartObject();
addServiceData(json); addServiceData(json, localService);
json.writeObjectFieldStart("data"); json.writeObjectFieldStart("data");
json.writeStringField("type", "HystrixCommand"); json.writeStringField("type", "HystrixCommand");
json.writeStringField("name", key.name()); String name = key.name();
if (properties.isPrefixMetricName()) {
name = localService.getServiceId() +"."+name;
}
json.writeStringField("name", name);
json.writeStringField("group", commandMetrics.getCommandGroup().name()); json.writeStringField("group", commandMetrics.getCommandGroup().name());
json.writeNumberField("currentTime", System.currentTimeMillis()); json.writeNumberField("currentTime", System.currentTimeMillis());
...@@ -187,7 +206,7 @@ public class HystrixStreamTask { ...@@ -187,7 +206,7 @@ public class HystrixStreamTask {
JsonGenerator json = jsonFactory.createJsonGenerator(jsonString); JsonGenerator json = jsonFactory.createJsonGenerator(jsonString);
json.writeStartObject(); json.writeStartObject();
addServiceData(json); addServiceData(json, localService);
json.writeObjectFieldStart("data"); json.writeObjectFieldStart("data");
json.writeStringField("type", "HystrixThreadPool"); json.writeStringField("type", "HystrixThreadPool");
...@@ -221,13 +240,15 @@ public class HystrixStreamTask { ...@@ -221,13 +240,15 @@ public class HystrixStreamTask {
} }
} }
private void addServiceData(JsonGenerator json) throws IOException { private void addServiceData(JsonGenerator json, ServiceInstance localService) throws IOException {
ServiceInstance localService = discoveryClient.getLocalServiceInstance();
json.writeObjectFieldStart("origin"); json.writeObjectFieldStart("origin");
json.writeStringField("host", localService.getHost()); json.writeStringField("host", localService.getHost());
json.writeNumberField("port", localService.getPort()); json.writeNumberField("port", localService.getPort());
json.writeStringField("serviceId", localService.getServiceId()); json.writeStringField("serviceId", localService.getServiceId());
json.writeStringField("id", context.getId()); if (properties.isSendId()) {
json.writeStringField("id", context.getId());
}
json.writeEndObject(); json.writeEndObject();
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment