Code Monkey home page Code Monkey logo

metrics-scala's People

Contributors

cb372 avatar ccare avatar chids avatar codahale avatar collinvandyck avatar dinomite avatar erikvanoosten avatar filipochnik avatar gseitz avatar gshakhn avatar jaimeagudo avatar jasonberanek avatar javasoze avatar jebl01 avatar jklukas avatar jmhodges avatar kevinclark avatar konnik avatar maciej avatar neilprosser avatar nicktelford avatar oconnor0 avatar ryantenney avatar scala-steward avatar scullxbones avatar slakah avatar stevenschlansker avatar takezoe avatar waywardmonkeys avatar xuwei-k avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

metrics-scala's Issues

`fromBooleanCheck` has dangerous signature with by-name Parameter in implicit

I believe that this signature:

implicit def fromBooleanCheck[A <% Boolean](checker: => A) = new HealthCheckMagnet {
    ...
        if (checker) Result.healthy() else Result.unhealthy(unhealthyMessage)
    ...
  }

is dangerous, as the by-name parameter probably won't always match your intention when used as part of an implicit. I think this is best illustrated with an example:

var counter = 0;
healthCheck("broken") { counter += 1; counter % 2 == 0 }

The idea here is that the block which is passed as the last argument to healthCheck will be converted to a HealtCheckMagnet using the implicit above. Because the parameter checker is by-name, you would expect the given expression to be evaluated every time it is used, i.e. every time the if (checker) is evaluated.

Assuming that the block { counter += 1; counter % 2 == 0 } is the expression passed to checker, you would thus expect counter % 2 == 0 to return false every other time and hence the Health Check to fail every other time.

This would work if healthCheck's signature would be something like def healthCheck(message: String...)(checker: => Boolean) ....

However, with (checker: HealthCheckMagnet) and the implicit doing the conversion from => Boolean to HealthCheckMagnet, the health check fails every time.

Why this is happening is made clearer when inserting some directly visible side effect as part of the block, for instance by turning it into { println("checking!"); counter += 1; counter % 2 == 0 }. This reveals that the block is only evaluated once, and only at the time the health check is defined. The reason for this lies in an idiosyncrasy of Scala: When the compiler encounters the block given to healthCheck, it will not "pass" the whole block to the implicit fromBooleanCheck. Instead it will evaluate the block up until to its last expression (counter % 2 == 0) and, since this is a Boolean, happily pass it to fromBooleanCheck, fixing whatever its result was at that time (in this case false).

A workaround would be to write the example code as follows:

healthCheck("workaround")(()=>{ counter += 1; counter % 2 == 0 }())

or

def actualCheck = { counter += 1; counter % 2 == 0 }
healthCheck("workaround")(actualCheck)

Both being somewhat non-obvious.

I believe that this is dangerous because it makes bogus health checks very easy to write by just passing a non-trivial block to healthCheck. Furthermore, because health checks are likely to pass the first time they are performed, the error will not emerge until failure of the checked system actually occurs and the health check fails to indicate this, potentially making a detectable failure much worse down the line.

I suggest changing the signature of fromBooleanCheck to something akin to

implicit def fromBooleanCheck[A <% Boolean](checker: () => A) =

or maybe using a new implicit and deprecating the old one to prevent existing code from breaking (though note that code written using that old implicit may already be unwittingly broken).

That way, checker is a function and it is obvious that it will be called for each health check, at the meager cost of having to preface each inline block with () =>.

json support

Hi,

how can I export the different collected metrics in json format ?
I saw that the java project has json module, but it was not clear to me how to use it.
would be great if you can share some example.

Thanks,

3.1.1_a2.3 uses akka-actor_2.11.0-RC4-2.3.0

3.1.1_a2.3 causes this SBT error when used with a project that uses Scala 2.11.0 and akka-actor 2.3.2:

[error] Modules were resolved with conflicting cross-version suffixes in {file:/Users/ngocdt/src/xitrum/}xitrum:
[error]    com.typesafe.akka:akka-actor _2.11, _2.11.0-RC4

I now have to use 3.1.1.1_a2.3.

Add synchronized metric trait(s)

When measuring a multithreaded class, I am getting some inconsistent results between two counters (one must be greater than the other, but that's the opposite that happens). From what I see in the code, there is no synchronization in the Metric implementation.

We should have a trait to mix in either directly, or using convenience methods such as MetricBuilder.counterSync.

Question about gauges and class instantiation ("metric already exists")

Hi there,

I had a some counters in my app, declared like so:

class Foo extends Instrumented {
val counter = metrics.counter("my-counter")
...
counter.inc(1)

and in my unit tests for Foo, I create a new instance of Foo before every tests, something like this:

class Fixture {
      val foo = new Foo()
    }

    var f: Fixture = _

    before { f = new Fixture }

    def `test Foo 1 ` { ... }
   def `testFoo 2` { ... }

Now using counters, all the tests would run fine. I switched some of these counters to gauges, and my tests fail when the class throws the exception ("metric named my-counter already exists").

It appears that there's a method

private <T extends Metric> T getOrAdd(String name, MetricBuilder<T> builder)

that calling metrics.gauge skips, while metrics.counters does call it (and seems to grab the existing counter?

I'm confused why I'm seeing these differences between gauges and counters (and does that mean I can't multiple instances of the same class for gauges, because they'll throw?). I wanted to check with the metrics-scala library first before I ask the dropwizard folks in case anyone has any pointers. It seems like catching exception for the gauge and then reading the gauge with that name from the registry would be an anti pattern - seems like I'm misunderstanding something.

Thanks!

akka-testkit has already been release for scala 2.11

I'm getting this error in my build:

[error] Modules were resolved with conflicting cross-version suffixes in main:
[error] com.typesafe.akka:akka-actor _2.11, _2.11.0-RC4
[error] com.typesafe.akka:akka-testkit _2.11.0-RC4, _2.11

akka-testkit has been released, could you make a new release?

Could we provide a DefaultInstrumented trait?

As of Dropwizard 1.0.0, Dropwizard apps register their metric registry as "default" in SharedMetricRegistries. Since there's now a mechanism to discover the app's registry via SharedMetricRegistries, this project could define a DefaultInstrumented trait that points at the registry marked as "default", avoiding the need for users to define their own Instrumented trait unless they want to point at a non-default registry.

Would you be open to such an enhancement?

Usage of Actor Instrumentation

Probably less of a bug issue than a usage thing, but I wanted to double check.

Assume I have the Instrumented trait defined and want to create a ReceiveCounterActor measure.

I assumed it should work like this (also as documented in the source):

class SomeMonitoredActor extends Actor with ReceiveCounterActor with Instrumented {
  def receive = {case "ping" => sender ! "pong" }
}

However, this results in a compiler error:

missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: PartialFunction[Any,Unit]
    def receive = {
                  ^

Trying to fix this with override yields further errors I haven't quite had the time to follow up on and understand.

The usage pattern described in the Unit tests on the other hand works:

class SomeActor extends Actor {
  def receive = {case "ping" => sender ! "pong" }
}

class SomeMonitoredActor extends ReceiveCounterActor with Instrumented

And then SomeMonitoredActor is used as the instantiated actor.

Is this the intended (or limited by the SLS) usage?

I was thinking about creating our own stackable actor implementation anyway to add multiple protocol wrappers for different functionality, so this is not a problem, more interest.

Q: defining metrics in an object

This is a question, not an issue, perhaps we can have them marked separately.

Our devs thought that metrics better be static, and defined them like

object Widget extends Instrumented {
  private val UpdateTimer = metrics.timer("update")
  ...
}

class Widget {
  import Widget._

  private def update(): Unit = synchronized {
    UpdateTimer.time { ... }
  }
}

Is it worth doing, or would it strain the metrics system if we simply define each timer in the class?

Akka dependency should be set as provided

Hi,

I'm using metrics-scala 3.0.3 and in the ivy xml file the akka-actor dependency is defined like this:

<dependency org="com.typesafe.akka" name="akka-actor_2.10" rev="[2.2,)" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>

Although I'm using Akka 2.2 in my project since today 2.3-M1 was released, and the Akka dependency is not set as provided, metrics-scala automatically pulls the latest version available.

Inherits conflicting members in the version 3.1.0_a2.3

Hi,

I believe there is a little bug in the version 3.1.0_a2.3 of your API.
Manual says you can mix in InstrumentedBuilder and CheckedBuilder traits:

trait Instrumented extends InstrumentedBuilder with CheckedBuilder {
 val metricRegistry = YourApplication.metricRegistry
 val healthCheckRegistry = YourApplication.healthCheckRegistry
}

However, both traits actually have a value called metricBaseName and so, the compiler returns an "inherits conflicting members" error.

I've solved this problem with an override of this val:

override lazy val metricBaseName = MetricName(getClass)

Thanks and congratulations for your API

Metric already exists with Actors

We use Akka in our project and we create gauges inside our actor. This causes a problem when the actor dies and restarts. When it restarts we get an exception that the gauge already exists. I have the following test that shows the behaviour.

import akka.actor.SupervisorStrategy.Restart
import akka.actor._
import akka.testkit.{DefaultTimeout, ImplicitSender, TestKit}
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike}

import scala.concurrent.duration._
/**
  * a Test to show some TestKit examples
  */
class ActorGuageSpec
  extends TestKit(ActorSystem("ActorGuageSpec"))
  with DefaultTimeout with ImplicitSender with WordSpecLike with Matchers with BeforeAndAfterAll {

  override def afterAll {
    shutdown()
  }

  val supervisor = system.actorOf(Props[SupervisingActor])
  supervisor ! Props[TestActor]
  val actor = expectMsgType[ActorRef]

  "The Actor" should {
    "Be able to replace the guage when it restarts" in {
      within(5.seconds) {
        actor ! 'increase
        expectMsg(1)
        actor ! Kill
        actor ! 'increase
        expectMsg(1)
      }
    }
  }
}

class SupervisingActor extends Actor {
  override val supervisorStrategy =
    OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1.second) {
      case _ => Restart
    }

  def receive = {
    case p: Props => sender ! context.actorOf(p)
  }
}


class TestActor extends Actor with Instrumented {

  override val supervisorStrategy =
    OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1.second) {
      case _ => Restart
    }

  var counter = 0
  metrics.gauge("test-counter") {
    counter
  }
  override def receive: Receive = {
    case 'increase =>
      counter += 1
      println(counter)
      sender ! counter
  }
}

That produces the following log when I run it:

Testing started at 5:25 PM ...
1
[ERROR] [12/09/2015 17:25:38.993] [ActorGuageSpec-akka.actor.default-dispatcher-2] [akka://ActorGuageSpec/user/$a/$a] Kill (akka.actor.ActorKilledException)
[ERROR] [12/09/2015 17:25:38.997] [ActorGuageSpec-akka.actor.default-dispatcher-3] [akka://ActorGuageSpec/user/$a/$a] A metric named TestActor.test-counter already exists
akka.actor.PostRestartException: exception post restart (class akka.actor.ActorKilledException)
    at akka.actor.dungeon.FaultHandling$$anonfun$6.apply(FaultHandling.scala:249)
    at akka.actor.dungeon.FaultHandling$$anonfun$6.apply(FaultHandling.scala:247)
    at akka.actor.dungeon.FaultHandling$$anonfun$handleNonFatalOrInterruptedException$1.applyOrElse(FaultHandling.scala:302)
    at akka.actor.dungeon.FaultHandling$$anonfun$handleNonFatalOrInterruptedException$1.applyOrElse(FaultHandling.scala:297)
    at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36)
    at akka.actor.dungeon.FaultHandling$class.finishRecreate(FaultHandling.scala:247)
    at akka.actor.dungeon.FaultHandling$class.faultRecreate(FaultHandling.scala:76)
    at akka.actor.ActorCell.faultRecreate(ActorCell.scala:374)
    at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:464)
    at akka.actor.ActorCell.systemInvoke(ActorCell.scala:483)
    at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:282)
    at akka.dispatch.Mailbox.run(Mailbox.scala:223)
    at akka.dispatch.Mailbox.exec(Mailbox.scala:234)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: java.lang.IllegalArgumentException: A metric named TestActor.test-counter already exists
    at com.codahale.metrics.MetricRegistry.register(MetricRegistry.java:91)
    at nl.grons.metrics.scala.MetricBuilder.gauge(MetricBuilder.scala:35)
    at TestActor.<init>(ActorGuageSpec.scala:57)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at java.lang.Class.newInstance(Class.java:442)
    at akka.util.Reflect$.instantiate(Reflect.scala:44)
    at akka.actor.NoArgsReflectConstructor.produce(IndirectActorProducer.scala:105)
    at akka.actor.Props.newActor(Props.scala:214)
    at akka.actor.ActorCell.newActor(ActorCell.scala:562)
    at akka.actor.dungeon.FaultHandling$class.finishRecreate(FaultHandling.scala:234)
    ... 11 more

I've tried removing guages but that says it's not supported. What kind of options do we have here?

Reporting to Graphite

Hi,

Trying to understand how should one go about reporting to Graphite using metrics-scala & metrics-graphite module in Scala ?

Thanks.

Move FutureMetrics to main source tree

Let me start by saying thank you for bringing your effort into this enriched Scala version of Metrics library.

Just one minor thing I've stumbled upon was missing FutureMetrics trait in pure 3.1.1 version of the library, so I have to use 3.1.1_a2.2 version. I did not expect a dependency on Akka, because Scala Future does not depend on Akka.

Guys, what do you think? Does it make sense to move FutureMetrics to the main source tree?

Thanks in advance!

$ in metrics names

I'm trying to send metrics to graphite, and they are not passing through. I see them in the admin servlet, and they have a $ in their names, e.g.:

"com.versal.restapi.SomeClassName$.payload"

-- is this expected and swallowable by graphite?

A+

Class name for an actor metric occurs twice in the metric name

I see something like:

name=com.foo.bar.MyActor.com.foo.bar.MyActor.receiveCounter

I suppose this is because the actor traits use the class name in the metric name, which then is appended onto the base name, which also is the class name:

trait ReceiveCounterActor extends Actor { self: InstrumentedBuilder =>

  def receiveCounterName: String = MetricName(getClass).append("receiveCounter").name
  lazy val counter: Counter = metrics.counter(receiveCounterName)

counter calls metricNameFor which is implemented as: baseName.append(name, scope).name, and the base name comes from:

trait BaseBuilder {
  /** The base name for all metrics created from this builder. */
  lazy val metricBaseName = MetricName(getClass)
}

PartialFunction resolves ahead of by-value parameter

I had to explicitly add MyTimer.time[List[Result]](myFunc(someString)) generic parameter instantiation, otherwise I was getting a PartialFunction[Int,Result] instead of List[Result] error, where the wrapped function has a signature def myFunc(x: String): List[Result]. Note the weird Int getting in from the cold. Apparently PartialFunction support needs more type inference checking/testing!

not found: value metrics

I'm having a not found: value metrics for the metrics builder object. I cannot find it in the source code, how I can import this one?

Metrics Reset

Hi,
I think it would be interesting to be able to reset metrics as I need this for my project.
My current solution involves creating new instances of MetricRegistry which is not a very clean solution...

Bad link in manual

Starting with Scala 2.10 you can also instrument Actors and Futures. This is described at Instrumenting Actors and Futures. - link gives 404

Convert to multi-project sbt setup

Currently we do magic to create specific releases for each scala version with or without Akka support. It would be better to split out Akka support to its own sub-project that depends on the metrics-core sub-project.

Ideally the names of the releases do not change.

Anyone who feels like taking this up is welcome to do so!

Hdrhistogram manual page little bit vague

Hdrhistogram.md states:

in addition, you should probably override the dependency to HdrHistogram. E.g.:

libraryDependencies += "org.hdrhistogram" % "HdrHistogram" % "2.1.6"

See the README to see which version(s) you can use.

In both README and AvailableVersions.md there is a table with column Hdr version but numbers put in this column seems to be versions of hdrhistogram-metrics-reservoir not HdrHistogram itself.

It may be confusing and actually it is for me :) I've overriden HdrHistogram to 2.1.7 (which is the most recent version) but not completely sure if it's non-breaking and the sentence See the README to see which version(s) you can use suggest that README can help me in being sure about it but it's not. I suggest either changing this sentence or extending README to contain information about "suggested" HdrHistogram version.

Also, how can I find out that HdrHistogram 2.1.7 will work with hdrhistogram-metrics-reservoir 1.1.0 - HdrHistogram does not seem to have changelog.

Actually I am not sure if this can be considered an "issue". I would rather ask first on user group forum, but AFAIK there's no user group for metrics-scala so I am asking here :)

Support for changing Reservoir

Is it possible to change Reservoir for histograms?
I want to use SlidingTimeWindowReservoir but didn't find API to do this.

Make it easy to change the reservoir of histograms and timers

I have a long running job that I want to know the lifetime distribution on processing work rather than the last 5 minutes or so. Changing the reservoir on my timer was painful. Please expose modifying the reservoir.

Best I got was

private[this] val splitTimer = {
    // metricNameFor() is protected
    val name = metrics.baseName.append("split.times").name
    new scala.Timer(metrics.registry.register( name, new Timer(new UniformReservoir())) )
}

".package" in metrics name

There is a ".package" substring in metrics name if we use scala package objects.
It would be nice to cut it too.

Calling timeFuture inside a Spray Web Service

This is more of a question than an issue. If we call the instrumentation API inside of a web service (written in spray).

The timeFuture is written as

def timeFuture[A](future: => Future[A])(implicit context: ExecutionContext): Future[A] = { val ctx = metric.time() val f = future f.onComplete(_ => ctx.stop()) f }

I wonder what is the impact of calling "onComplete" on the threadpool utilization of Spray.

Missing 2.11 build in Maven

I am unable to build with 2.11. This is what I got:

[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: nl.grons#metrics-scala_2.11;3.0.6_a2.3: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::

Is there a specific repository I have to add?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.