Domanda

I'm looking for a performance metrics library in python.

I'm familiar with metrics by Coda Hale, which is written for the JVM and so I wonder if there's a python equivalent for that (and which does not utilize the JVM).

In short, the list of requirements from the tool would be:

  • Count different kind of metrics at execution time. Counters, Gauges, Meters, Timers, Histograms etc. There's a nice list here
  • Allow easy access to the runtime data through HTTP API. (I can wrap the HTTP layer myself, but if it's already baked in it's a plus)
  • Plugins for graphite in particular, or others. CopperEgg would be nice. Or NewRelic.
  • Baked in instrumentation support for common libs, such as memcached.

So far I'd found PyCounters which does some of the job, but not all of it. It sort of satisfies my first bullet (but it doesn't have all the metric types, just three) and that's all.

Is there a better alternative to PyCounters?

Thanks

È stato utile?

Soluzione 2

Haven't had the chance to try it out, but I came across this one a few days ago: https://github.com/Cue/scales

scales - Metrics for Python Tracks server state and statistics, allowing you to see what your server is doing. It can also send metrics to Graphite for graphing or to a file for crash forensics.

scales is inspired by the fantastic metrics library, though it is by no means a port.

Altri suggerimenti

I came across this library, which is a port of CodaHale metrics for python.

There is some stuff missing i.e. reporters but it does most other things.

https://github.com/omergertel/pyformance/

Shameless plug, here is my fork which adds a hosted graphite reporter. It should be trivial to add reporters to other systems.

https://github.com/usmanismail/pyformance

I'm not aware of something that does exactly that but I did write something a while back for a project that does that by simply adding decorators to the relevant functions.

I created a set of decorators for measuring runtime of functions, measuring time for DB access functions, etc.

An example of such a decorator is this:

def func_runtime(method):
    @functools.wraps(method)
    def wrapper(self, *args, **kwargs):
        start_time = datetime.datetime.utcnow()
        try:
            class_name = type(self).__name__
            method_name = method.__name__
            return method(self, *args, **kwargs)
        finally:
            end_time = datetime.datetime.utcnow() - start_time
            time_taken_ms = end_time.microseconds / 1000
            if _statsd:
                # Send the data to statsD, but you can do that for CopperEgg or anything else
                self.stats.timing("func.runtime.%s.%s" % (class_name, method_name), time_taken_ms)

Later you would use it like this:

@func_runtime
def myfunc(a, b, c):
    pass

I also added a decorator for functions that read from the DB and functions that write to the DB so I can get graphs on how much time the code spent on waiting to read data or write data as well as # of times I called "read" operations and "write" operations.

So, all in all I had the following decorators: - @func_runtime - to measure the runtime of a function - @func_dbread - places on functions that performs reads. Increments a database.reads counter as well as send a timing data to read_timing - @func_dbwrite - the same as @func_dbread but for writes - @func dbruntime - used to measure the runtime of DB specific functions as well as # of calls and total timing of all DB functions

You can combine decorators and they run in the order which is closest to the function, for example:

@func_dbruntime
@func_dbread
def some_db_read_function(a, b, c,d):
    pass

So, @func_dbread runs before @func_dbruntime.

All in all, its easily customisable and VERY powerful and you can extend it to support 3rd party services as well as add code to dynamically turn these counters on and off whenever relevant. As far as I could tell, the performance penalty was minimal at best.

Just a notice about sending data to places like CopperEgg and other services, StatsD uses UDP and since its statistics you can lose some data and still get meaningful insights and it won't block anything. If you want to send data to 3rd party sites like CopperEgg I would consider sending the data to a local queue and then pushing it with a different process to CopperEgg just to decouple 3rd party services issues from your own.

Personally, for such data, StatsD is great and graphite gives you all the things you need including 90th percentile, average, max, graphing abilities, etc and basically have most of the counter types you require.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top