samstarling / finagle-prometheus

Provides a bridge between Finagle and Prometheus metrics
https://samstarling.co.uk/projects/finagle-prometheus/
MIT License
30 stars 18 forks source link

StatsReceiver not created from resources/META-INF/services #18

Closed cnstoll closed 6 years ago

cnstoll commented 6 years ago

Hi,

We love your library! While setting it up in a finagle project we noticed that we weren't getting any of the default finagle events despite creating a reference file in the expected path to create a PrometheusStatsReceiver by default. We found a solution - subclass and provide a default empty initializer:

import com.samstarling.prometheusfinagle.PrometheusStatsReceiver

class OurPrometheusStatsReceiver extends PrometheusStatsReceiver(namespace = "") {
}

That seems to make things work beautifully. We just wanted you to be aware.

Thanks!

samstarling commented 6 years ago

Hey @cnstoll – glad you love it! I'd love to hear more about who's using it. That's a good spot: I'd already got a test for a zero-argument constructor, to make sure that works, because Finagle needs it... Odd.

I'll try and work out what's happening over the weekend if I get a chance, but if you have any additional information (stack traces, errors, code examples) then let me know.

anthonydipietro commented 6 years ago

Hey @samstarling. I am a co-worker of @cnstoll and definitely echo everything good he said about the library! Regarding the issue above, here is the stack trace that we are encountering when attempting to add the com.samstarling.prometheusfinagle.PrometheusStatsReceiver class as the default StatsReceiver in our META-INF/services/com.twitter.finagle.stats.StatsReceiver file:

java.lang.InstantiationException: com.samstarling.prometheusfinagle.PrometheusStatsReceiver
    at java.lang.Class.newInstance(Class.java:427) [na:1.8.0_144]
    at com.twitter.app.LoadService$$anonfun$5.apply(LoadService.scala:73) [util-app_2.11-18.2.0.jar:18.2.0]
    at com.twitter.app.LoadService$$anonfun$5.apply(LoadService.scala:62) [util-app_2.11-18.2.0.jar:18.2.0]
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:241) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.AbstractTraversable.flatMap(Traversable.scala:104) [scala-library-2.11.8.jar:1.0.0]
    at com.twitter.app.LoadService$.apply(LoadService.scala:62) [util-app_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.util.LoadService$.apply(LoadService.scala:14) [finagle-core_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.stats.LoadedStatsReceiver$.<init>(LoadedStatsReceiver.scala:18) [finagle-core_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.stats.LoadedStatsReceiver$.<clinit>(LoadedStatsReceiver.scala) [finagle-core_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.stats.FinagleStatsReceiver$.<init>(LoadedStatsReceiver.scala:44) [finagle-core_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.stats.FinagleStatsReceiver$.<clinit>(LoadedStatsReceiver.scala) [finagle-core_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.netty4.HashedWheelTimer$.<init>(Netty4HashedWheelTimer.scala:80) [finagle-netty4_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.netty4.HashedWheelTimer$.<clinit>(Netty4HashedWheelTimer.scala) [finagle-netty4_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.netty4.Netty4HashedWheelTimer.<init>(Netty4HashedWheelTimer.scala:108) [finagle-netty4_2.11-18.2.0.jar:18.2.0]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [na:1.8.0_144]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) [na:1.8.0_144]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) [na:1.8.0_144]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) [na:1.8.0_144]
    at java.lang.Class.newInstance(Class.java:442) [na:1.8.0_144]
    at com.twitter.app.LoadService$$anonfun$5.apply(LoadService.scala:73) [util-app_2.11-18.2.0.jar:18.2.0]
    at com.twitter.app.LoadService$$anonfun$5.apply(LoadService.scala:62) [util-app_2.11-18.2.0.jar:18.2.0]
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:241) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.AbstractTraversable.flatMap(Traversable.scala:104) [scala-library-2.11.8.jar:1.0.0]
    at com.twitter.app.LoadService$.apply(LoadService.scala:62) [util-app_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.util.LoadService$.apply(LoadService.scala:14) [finagle-core_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.util.DefaultTimer$.<init>(DefaultTimer.scala:68) [finagle-core_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.util.DefaultTimer$.<clinit>(DefaultTimer.scala) [finagle-core_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.stats.JsonExporter.<init>(JsonExporter.scala:140) [finagle-stats_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.stats.MetricsExporter.<init>(MetricsStatsReceiver.scala:138) [finagle-stats_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.stats.MetricsExporter.<init>(MetricsStatsReceiver.scala:141) [finagle-stats_2.11-18.2.0.jar:18.2.0]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [na:1.8.0_144]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) [na:1.8.0_144]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) [na:1.8.0_144]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) [na:1.8.0_144]
    at java.lang.Class.newInstance(Class.java:442) [na:1.8.0_144]
    at com.twitter.app.LoadService$$anonfun$5.apply(LoadService.scala:73) [util-app_2.11-18.2.0.jar:18.2.0]
    at com.twitter.app.LoadService$$anonfun$5.apply(LoadService.scala:62) [util-app_2.11-18.2.0.jar:18.2.0]
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:241) [scala-library-2.11.8.jar:1.0.0]
    at scala.collection.AbstractTraversable.flatMap(Traversable.scala:104) [scala-library-2.11.8.jar:1.0.0]
    at com.twitter.app.LoadService$.apply(LoadService.scala:62) [util-app_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.util.LoadService$.apply(LoadService.scala:14) [finagle-core_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.http.HttpMuxer$.<init>(HttpMuxer.scala:120) [finagle-http_2.11-18.2.0.jar:18.2.0]
    at com.twitter.finagle.http.HttpMuxer$.<clinit>(HttpMuxer.scala) [finagle-http_2.11-18.2.0.jar:18.2.0]
    at com.twitter.server.Lifecycle$class.$init$(Lifecycle.scala:14) [twitter-server_2.11-18.2.0.jar:18.2.0]
    at io.uacf.mobile.log.LogStoreServer$.<init>(LogStoreServer.scala:16) [classes/:na]
    at io.uacf.mobile.log.LogStoreServer$.<clinit>(LogStoreServer.scala) [classes/:na]
    at io.uacf.mobile.log.LogStoreServer.main(LogStoreServer.scala) [classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_144]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144]
    at sbt.Run.invokeMain(Run.scala:67) [run-0.13.16.jar:0.13.16]
    at sbt.Run.run0(Run.scala:61) [run-0.13.16.jar:0.13.16]
    at sbt.Run.sbt$Run$$execute$1(Run.scala:51) [run-0.13.16.jar:0.13.16]
    at sbt.Run$$anonfun$run$1.apply$mcV$sp(Run.scala:55) [run-0.13.16.jar:0.13.16]
    at sbt.Run$$anonfun$run$1.apply(Run.scala:55) [run-0.13.16.jar:0.13.16]
    at sbt.Run$$anonfun$run$1.apply(Run.scala:55) [run-0.13.16.jar:0.13.16]
    at sbt.Logger$$anon$4.apply(Logger.scala:84) [logging-0.13.16.jar:0.13.16]
    at sbt.TrapExit$App.run(TrapExit.scala:248) [run-0.13.16.jar:0.13.16]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]
Caused by: java.lang.NoSuchMethodException: com.samstarling.prometheusfinagle.PrometheusStatsReceiver.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082) [na:1.8.0_144]
    at java.lang.Class.newInstance(Class.java:412) [na:1.8.0_144]

It appears that an explicit default, no-arg constructor is being searched for by the class loader and not found.

Thanks again!

samstarling commented 6 years ago

@anthonydipietro Thanks for the stacktrace: that's really useful. Looks like I was mistaken about how LoadService works, particularly with default values in constructors. I'm taking a look, and hopefully I can push a fix soon.

samstarling commented 6 years ago

Tagging @turbolent, who was also experiencing this issue.

samstarling commented 6 years ago

Hey @anthonydipietro @cnstoll and @turbolent: I've just committed a fix for this problem, and there are a couple of tests to back it up. I just released v0.0.6, which includes the fix, and it's in the process of syncing to Maven Central.

Please let me know if it doesn't fix the problems you were having.

turbolent commented 6 years ago

Perfect, that fixed it for me :+1: