graphite-pymetrics is a lightweight Python framework which makes it super simple to add application metrics that is sent to a remote graphite/carbon server.
All that is needed is this package (which also includes pystatsd) and access to a remote graphite server.
To install it just run Pip as usual:
$ pip install graphite-pymetrics
- Package requirements:
- pystatsd==0.1.6
- gevent
Make sure there is a local graphite proxy running - start it at an early point in your application:
from metrics.graphite import start_graphite_proxy
start_graphite_proxy({"host": "graphite.mycompany.com", "port": 2003})
The proxy is pystatsd, a local server that receives UDP packets from the metrics client and periodically emits data to graphite over TCP.
To add a counter for anything anywhere in your code, use Metric.add:
from metrics import Metric
Metric.add("foo.bar")
Use the @metric decorator to count specific method invocations:
from metrics import metric
@metric("bar.baz")
def foo():
# do stuff here
There are several ways to log timing. The most naive way is to first measure time manually and then submit it:
from metrics import Metric
import time
start = time.time()
# do stuff
elapsed = time.time() - start
Metric.timing("do.stuff", elapsed)
An easier way is to to let the metric client keep track of time with Metric.start_timing and call done() on the returned timing instance. Following is an example for measuring time consumed for every endpoint individually in a Flask webapp:
from metrics import Metric
from flask import Blueprint, current_app, request, g
app = Blueprint("myapp", __name__)
@app.before_request
def before_request():
try:
g.timing = Metric.start_timing(str(request.endpoint)) # start timing
except:
current_app.logger.error("Unable to time call for 'request.endpoint'")
@app.teardown_request
def teardown_request(exc):
try:
g.timing.done() # stop timing
except:
current_app.logger.error("Timing not available")
Similar to the @metric decorator there is a @timing decorator which is used to measure time for specific methods:
from metrics import timing
@timing("heavy.task")
def heavy_task(x, y, z):
# do heavy stuff here