2016-08-05 39 views
2

So habe ich eine Spring Boot-Anwendung mit Spring-Boot-Aktor. Durch die Definition der Eigenschaft spring.metrics.export.statsd.host wird automatisch eine StatsdMetricWriter instanziiert, und für Zähler und Messgeräte funktioniert alles einwandfrei.Was ist der optimale Weg Spring-Boot mit StatsD zu verbinden, besonders für Timer?

Für timers sind die Dinge jedoch ein bisschen peinlich. Für Java8 erstellt Spring Boot automatisch eine BufferGaugeService -Instanz - was dazu führt, dass Timer-Werte im Grunde wie ein Messgerät berichtet werden: der letzte Wert alle 5s (oder was auch immer es ist, könnte man es auch konfigurieren). Dies macht Timer-Metriken grundsätzlich unbrauchbar, da all die wunderbaren Dinge, die StatsD damit macht, verzerrt sind.

Jetzt könnte man wieder auf die Verwendung des Pre-Java8-Standards DefaultGaugeService zurückgreifen, aber dann wieder, für Zähler ist die BufferCounterService einfach in Ordnung. Blick auf MetricRepositoryAutoConfiguration, dies manuell einrichten scheint nicht trivial und spröde in Bezug auf zukünftige Updates.

Haben Sie Ratschläge, wie Sie vorgehen sollen? Oder gibt es einen Blaupause, der etwas Inspiration bietet?

Aktuelle Situation beiseite: Gibt es Pläne, mit einer BufferTimerService oder einer TimerService in erster Linie zu kommen?

Antwort

1

Für was es wert ist, fand ich eine eher unaufdringliche Lösung. Nicht sicher, ob es der optimale Weg ist, aber es funktioniert einwandfrei:

@Autowired 
@Bean 
public static BeanPostProcessor wrapGaugeService(ApplicationContext applicationContext) { 
    return new BeanPostProcessor() { 
     @Override 
     public Object postProcessBeforeInitialization(Object bean, String beanName) { 
      return bean; 
     } 
     @Override 
     public Object postProcessAfterInitialization(Object bean, String beanName) { 
      if (!GaugeService.class.isInstance(bean)) { 
       return bean; 
      } 
      final GaugeService gaugeService = GaugeService.class.cast(bean); 
      final MetricWriter metricWriter = applicationContext.getBean(MetricWriter.class); 
      return (GaugeService) (metricName, value) -> { 
       if (metricName.startsWith("timer.")) { 
        metricWriter.set(new Metric<>(metricName, value)); 
       } else { 
        gaugeService.submit(metricName, value); 
       } 
      }; 
     } 
    }; 
} 

Für Timer-Werte, wir Frühling Boots pre-Java8 Verhalten sind nachahmt. Dies umschließt die von Spring Boot zur Verfügung gestellte GaugeService: für "timer. *" Werte, ruft es die MetricWriter (das sollte die StatsdMetricWriter sein, sonst macht diese ganze Einrichtung keinen Sinn), sonst geht es entlang des Messwerts an die GaugeService.

0

Vielen Dank für Ihre Lösung!
Ich habe Dropwizard-Implementierung und folgende Überschreibung geholfen, Abfrage Zeit Metriken im Timer statt Messgeräte zu fangen.

@Bean 
DropwizardMetricServices dropwizardMetricServices(MetricRegistry metricRegistry, 
                ObjectProvider<ReservoirFactory> resFactoryProvider) { 
    return new DropwizardMetricServices(metricRegistry, resFactoryProvider.getIfAvailable()) { 
     @Override 
     public void submit(String name, double value) { 
      if (name.startsWith("response.")) { 
       super.submit("timer." + name, value); 
      } else { 
       super.submit(name, value); 
      } 
     } 
    }; 
} 

In Bezug auf TimerService kann diese spring boot issue relevant sein.

Wie ich sehe, gibt es Pläne für wesentliche Verbesserungen im Frühjahr Boot-Metriken für 2.0 unter beschrieben: Metrics theme und Improvements to Actuator Metrics

+0

Sie verwenden DropWizard mit StatsD? – skirsch

+0

Sorry, ich verstehe nicht, wie das mit StatsD zusammenhängt ... – skirsch