python项目

timeexecution的Python项目详细描述


https://secure.travis-ci.org/kpn-digital/py-timeexecution.svg?branch=masterhttps://img.shields.io/codecov/c/github/kpn-digital/py-timeexecution/master.svghttps://img.shields.io/pypi/v/timeexecution.svghttps://img.shields.io/pypi/pyversions/timeexecution.svghttps://readthedocs.org/projects/py-timeexecution/badge/?version=latesthttps://img.shields.io/pypi/l/timeexecution.svghttps://img.shields.io/badge/code%20style-black-000000.svg

这个包旨在将应用程序度量记录到特定的后端。 在GrafanaKibana的帮助下,您可以轻松地使用这些度量来创建有意义的监视仪表板。

功能

  • 将数据发送到多个后端(例如ElasticSearch)
  • 自定义后端
  • 钩子包括每个度量的附加数据。

可用后端

  • 流入量b 0.8
  • 弹性搜索>;=5,<;7
  • 卡夫卡

安装

如果要与ElasticSearchBackend一起使用:

$ pip install timeexecution[elasticsearch]

使用InfluxBackend

$ pip install timeexecution[influxdb]

使用KafkaBackend

$ pip install timeexecution[kafka]

或者,如果您希望所有后端都可用并且可以在它们之间轻松切换:

$ pip install timeexecution[all]

用法

若要使用此包,请装饰要计时其执行时间的函数。 每个包装的函数都将创建一个由3个默认值组成的度量:

  • name-度量将存储在其中的序列的名称。默认情况下,TimeExecution将使用修饰方法或函数的完全限定名(例如)。
  • value-包装函数完成所用的时间(毫秒)
  • hostname-运行代码的计算机的主机名

请参见以下示例

fromtime_executionimportsettings,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 decoratorsettings.configure(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()

这将导致输入infloxdb

[{"name":"__main__.hello","columns":["time","sequence_number","value","hostname",],"points":[[1449739813939,1111950001,312,"machine.name",]]}]

以及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]}]

也可以在不同的线程中运行后端,并在其后面使用逻辑,以批量模式发送度量。

例如:

fromtime_executionimportsettings,time_executionfromtime_execution.backends.threadedimportThreadedBackend# Setup threaded backend which will be run on separate threadthreaded_backend=ThreadedBackend(backend=ElasticsearchBackend,backend_kwargs={"host":"elasticsearch","index":"metrics",})# there is also possibility to configure backend by import path, like:threaded_backend=ThreadedBackend(backend="time_execution.backends.kafka.KafkaBackend",#: any other configuration belongs to backendbackend_kwargs={"hosts":"kafka","topic":"metrics"})# Configure the time_execution decoratorsettings.configure(backends=[threaded_backend])# Wrap the methods where u want the metrics@time_executiondefhello():return'World'# Now when we call hello() we put metrics in queue to send it either in some configurable time later# or when queue will reach configurable limit.hello()

还可以在python>;=3.5中装饰协程或可等待项。

例如:

importasynciofromtime_executionimporttime_execution_async# ... Setup the desired backend(s) as described above ...# Wrap the methods where you want the metrics@time_execution_asyncasyncdefhello():awaitasyncio.sleep(1)return'World'# Now when we schedule hello() we will get metrics in our backendsloop=asyncio.get_event_loop()loop.run_until_complete(hello())

挂钩

time_execution支持挂钩,在挂钩之前可以更改度量 正在发送到后端。

使用钩子可以添加并更改现有字段。这可能是 对于希望根据以下条件向度量添加列的情况非常有用 包装函数的响应。

钩子总是有3个参数:

  • response-包装函数的返回值
  • exception-包装函数的引发异常
  • metric-包含要发送到后端的数据的dict
  • func_args-包装函数接收的原始参数。
  • func_kwargs-包装函数接收的原始Kwargs。

如果希望拆分度量,可以从钩子中更改名称。 分成多个系列。

请参阅以下示例如何设置挂钩。

# Now lets create a hookdefmy_hook(response,exception,metric,func,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 hookssettings.configure(backends=[backend],hooks=[my_hook])

还可以使用自定义钩子集创建decorator。例如,需要跟踪芹菜任务。

frommultiprocessingimportcurrent_process# Hook for celery tasksdefcelery_hook(response,exception,metric,func,func_args,func_kwargs):"""
    Add celery worker-specific details into response.
    """p=current_process()hook={'name':metric.get('name'),'value':metric.get('value'),'success':exceptionisNone,'process_name':p.name,'process_pid':p.pid,}returnhook# Create time_execution decorator with extra hookstime_execution_celery=time_execution(extra_hooks=[celery_hook])@celery.task@time_execution_celerydefcelery_task(self,**kwargs):returnTrue# Or do it in place where it is needed@celery.task@time_execution(extra_hooks=[celery_hook])defcelery_task(self,**kwargs):returnTrue# Or override default hooks by custom ones. Just setup `disable_default_hooks` flag@celery.task@time_execution(extra_hooks=[celery_hook],disable_default_hooks=True)defcelery_task(self,**kwargs):returnTrue

手动发送指标

您还可以将任何手动度量发送到后端。这些不会 添加默认值,不会命中钩子。

请参见以下示例。

fromtime_executionimportwrite_metricloadavg=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])

自定义后端

编写自定义后端非常简单,只需创建一个类 使用write方法。不需要扩展baseMetricsBackend 但是,为了便于升级,我们建议您这样做。

fromtime_execution.backends.baseimportBaseMetricsBackendclassMetricsPrinter(BaseMetricsBackend):defwrite(self,name,**data):print(name,data)

示例场景

为了读取度量,例如使用elasticsearch作为后端,可以使用以下lucene查询:

name:"__main__.hello" AND hostname:dfaa4928109f

有关更高级的查询语法,请查看Lucene documentationElasticSearch Query DSL引用。

贡献

你有什么要贡献的吗?伟大的!有些东西可能会派上用场。

这个项目的测试是通过Docker完成的。有一个码头工人作曲很容易 启动并运行所有必需的容器。

有一个带有几个目标的makefile我们经常使用:

  • make test
  • make isort
  • make lint
  • make build
  • make setup.py

所有这些make目标的前缀都可以是docker/。这将执行 目标在Docker容器中,而不是在本地计算机上。 例如make docker/build

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java如何生成格式化文件。xml文件?   java向Vaadin布局添加模糊侦听器   Java中的默认构造函数内容   java Eclipse错误:“无法找到jre7的可执行文件”   Java8,如何使用流实现switch语句?   java在CDH4示例上运行map reduce作业   java在servlet中获取文件名   如何禁止在所有浏览器中加载脚本“Selenium Java”   java Play框架和gradle   如果DifferencedName有引号,java无法从组中获取成员   java如何在使用链表实现的堆栈中实现pop操作?   java如何在网络视图中全屏制作YouTube视频?   如何在java中为分配的时间或固定的时间执行循环   java如何使用Android SDK在onCreate语句中动态更改活动的背景颜色?   java如何理解客户端没有来自IBM MQ的消息的原因?   java使用表查找用户最多出现的字母   java中的数组多维数据结构   java如何将一个值设置为一个类中的变量,并从另一个类中获取该变量的值?   java在创建新AVD后无法运行Android应用程序   java使用广度优先搜索算法存储迷宫求解路径