Package: py-timeexecution
This package is designed to record metrics of the application into a backend.
With the help ofgrafanayou can easily create dashboards with themFeaturesSending data to multiple backendsCustom backendsHooksBackendsInfluxDB 0.8Elasticsearch 2.1Installation$pipinstallpy-timeexecutionUsageTo use this package you decorate the functions you want to time its execution.
Every wrapped function will create a metric consisting of 3 default values:name- The name of the series the metric will be stored invalue- The time it took in ms for the wrapped function to completehostname- The hostname of the machine the code is running onSee the following examplefromtime_executionimportconfigure,time_executionfromtime_execution.backends.influxdbimportInfluxBackendfromtime_execution.backends.elasticsearchimportElasticsearchBackend# Setup the desired backendinflux=InfluxBackend(host='influx',database='metrics',use_udp=False)elasticsearch=ElasticsearchBackend('elasticsearch',index='metrics')# Configure the time_execution decoratorconfigure(backends=[influx,elasticsearch])# Wrap the methods where u want the metrics@time_executiondefhello():return'World'# Now when we call hello() and we will get metrics in our backendshello()This will result in an entry in the influxdb[{"name":"__main__.hello","columns":["time","sequence_number","value","hostname",],"points":[[1449739813939,1111950001,312,"machine.name",]]}]And the following in Elasticsearch[{"_index":"metrics-2016.01.28","_type":"metric","_id":"AVKIp9DpnPWamvqEzFB3","_score":null,"_source":{"timestamp":"2016-01-28T14:34:05.416968","hostname":"dfaa4928109f","name":"__main__.hello","value":312},"sort":[1453991645416]}]Hookstime_executionsupports hooks where you can change the metric before its
being send to the backend.With a hook you can add additional and change existing fields. This can be
useful for cases where you would like to add a column to the metric based on
the response of the wrapped function.A hook will always get 3 arguments:response- The returned value of the wrapped functionexception- The raised exception of the wrapped functionmetric- A dict containing the data to be send to the backendfunc_args- Original args received by the wrapped function.func_kwargs- Original kwargs received by the wrapped function.From within a hook you can change thenameif you want the metrics to be split
into multiple series.See the following example how to setup hooks.# Now lets create a hookdefmy_hook(response,exception,metric,func_args,func_kwargs):status_code=getattr(response,'status_code',None)ifstatus_code:returndict(name='{}.{}'.format(metric['name'],status_code),extra_field='foo bar')# Configure the time_execution decorator, but now with hooksconfigure(backends=[backend],hooks=[my_hook])Manually sending metricsYou can also send any metric you have manually to the backend. These will not
add the default values and will not hit the hooks.See the following example.loadavg=os.getloadavg()write_metric('cpu.load.1m',value=loadavg[0])write_metric('cpu.load.5m',value=loadavg[1])write_metric('cpu.load.15m',value=loadavg[2])Custom BackendWriting a custom backend is very simple, all you need to do is create a class
with awritemethod. It is not required to extendBaseMetricsBackendbut in order to easily upgrade I recommend u do.fromtime_execution.backends.baseimportBaseMetricsBackendclassMetricsPrinter(BaseMetricsBackend):defwrite(self,name,**data):print(name,data)ContributeYou have something to contribute ? Great !
A few things that may come in handy.Testing in this project is done via docker. There is a docker-compose to easily
get all the required containers up and running.There is a Makefile with a few targets that we use often:make testmake isortmake lintmake buildmake setup.pyAll of these make targets can be prefixed bydocker/. This will execute
the target inside the docker container instead of on your local machine.
For examplemake docker/build.