RRDTool的对象化Python接口
项目描述
特性
PyRRD允许您从Python代码中使用RRDTool,该代码利用标准面向对象模式。这使得程序化使用RRDTool变得更容易且可重用。
简介
PyRRD是命令行图形和循环冗余数据库实用程序rrdtool的对象化包装器[3]。PyRRD最初有两个设计目标
为rrdtool提供一个Python程序员会喜欢的接口,并且
不依赖于rrdtool的Python绑定。
前者的原因很明显。后者的动机是许多人难以在所选操作系统上编译rrdtool绑定。
尽管PyRRD最初的目的在于帮助那些没有绑定的人,但该项目现在为已安装绑定的人提供支持。因此,用户可以同时享受到绑定的速度优势以及PyRRD的API可用性。
关于文档,请查看每个类(以及许多函数)开头处的文档字符串。它们不仅包含许多标准RRDTool文档,还包含doctests,这些doctests可以让你亲身体验实际用法,了解其工作原理。
对于那些对创建PyRRD的动机感兴趣的人,可能需要一些背景信息。最初,从Python使用RRDTool只有两种方法:
使用Python绑定,这很难编译和使用,或者
2. 从Python中调用“rrdtool”可执行文件,并将所有需要的参数传递给它。
第一种方法对于许多人来说在他们的首选操作系统上运行常常很困难或不可能。即使能够编译并运行它,使用也非常繁琐,设计为像命令行工具和C接口一样工作,而不是像大多数人通常使用Python那样。
现在,有了PyRRD,还有两种从Python使用RRDTool的方法:
3. 一个面向对象的接口,它封装了对rrdtool二进制的系统调用(Popen),
4. 同样的面向对象的接口,它封装了繁琐的rrdtool Python绑定。
依赖关系
PyRRD的一些部分使用了ElementTree进行XML处理。如果您有Python 2.5或更高版本,PyRRD将使用xml.etree。如果您的Python版本低于2.5,并且您想使用依赖于XML处理的功能(例如,dump函数和fetch/info方法),则需要安装ElementTree库[4]。
安装
PyRRD的安装方式与通常一样
python setup.py install
只要您的PYTHONPATH中有./,并且您位于顶级目录(其中包含pyrrd子目录),您也可以不安装PyRRD就使用它。
用法
以编程方式创建RRD文件
>>> from pyrrd.rrd import DataSource, RRA, RRD >>> filename = '/tmp/test.rrd' >>> dataSources = [] >>> roundRobinArchives = [] >>> dataSource = DataSource( ... dsName='speed', dsType='COUNTER', heartbeat=600) >>> dataSources.append(dataSource) >>> roundRobinArchives.append(RRA(cf='AVERAGE', xff=0.5, steps=1, rows=24)) >>> roundRobinArchives.append(RRA(cf='AVERAGE', xff=0.5, steps=6, rows=10)) >>> myRRD = RRD( ... filename, ds=dataSources, rra=roundRobinArchives, start=920804400) >>> myRRD.create()
让我们检查该文件是否存在
>>> import os >>> os.path.isfile(filename) True
让我们看看它有多大(根据RRDTool版本,字节数可能会变化,所以我们将得到一个大致的感觉)
>>> bytes = len(open(filename).read()) >>> 800 < bytes < 1200 True
为了节省磁盘写入,PyRRD将值缓冲起来,然后一次性将值写入RRD文件
>>> myRRD.bufferValue('920805600', '12363') >>> myRRD.bufferValue('920805900', '12363') >>> myRRD.bufferValue('920806200', '12373') >>> myRRD.bufferValue('920806500', '12383') >>> myRRD.update()
让我们添加一些更多数据
>>> myRRD.bufferValue('920806800', '12393') >>> myRRD.bufferValue('920807100', '12399') >>> myRRD.bufferValue('920807400', '12405') >>> myRRD.bufferValue('920807700', '12411') >>> myRRD.bufferValue('920808000', '12415') >>> myRRD.bufferValue('920808300', '12420') >>> myRRD.bufferValue('920808600', '12422') >>> myRRD.bufferValue('920808900', '12423') >>> myRRD.update()
如果您好奇,可以使用以下方式查看您的rrd文件
myRRD.info()
这里没有打印输出,因为它太占空间。然而,它非常类似于同名rrdtool命令的输出。
为了创建图表,我们需要一些数据定义。我们还将添加一些计算定义和变量定义,以供参考
>>> from pyrrd.graph import DEF, CDEF, VDEF, LINE, AREA, GPRINT >>> def1 = DEF(rrdfile=myRRD.filename, vname='myspeed', ... dsName=dataSource.name) >>> cdef1 = CDEF(vname='kmh', rpn='%s,3600,*' % def1.vname) >>> cdef2 = CDEF(vname='fast', rpn='kmh,100,GT,kmh,0,IF') >>> cdef3 = CDEF(vname='good', rpn='kmh,100,GT,0,kmh,IF') >>> vdef1 = VDEF(vname='mymax', rpn='%s,MAXIMUM' % def1.vname) >>> vdef2 = VDEF(vname='myavg', rpn='%s,AVERAGE' % def1.vname) >>> line1 = LINE(value=100, color='#990000', legend='Maximum Allowed') >>> area1 = AREA(defObj=cdef3, color='#006600', legend='Good Speed') >>> area2 = AREA(defObj=cdef2, color='#CC6633', legend='Too Fast') >>> line2 = LINE(defObj=vdef2, color='#000099', legend='My Average', ... stack=True) >>> gprint1 = GPRINT(vdef2, '%6.2lf kph')
色彩是生活的调味品。让我们让它变得更有趣一点
>>> from pyrrd.graph import ColorAttributes >>> ca = ColorAttributes() >>> ca.back = '#333333' >>> ca.canvas = '#333333' >>> ca.shadea = '#000000' >>> ca.shadeb = '#111111' >>> ca.mgrid = '#CCCCCC' >>> ca.axis = '#FFFFFF' >>> ca.frame = '#AAAAAA' >>> ca.font = '#FFFFFF' >>> ca.arrow = '#FFFFFF'
现在我们可以为我们的RRD文件中的数据创建一个图表
>>> from pyrrd.graph import Graph >>> graphfile = "/tmp/rrdgraph.png" >>> g = Graph(graphfile, start=920805000, end=920810000, ... vertical_label='km/h', color=ca) >>> g.data.extend([def1, cdef1, cdef2, cdef3, vdef1, vdef2, line1, area1, ... area2, line2, gprint1]) >>> g.write()
让我们确保它在那里
>>> os.path.isfile(graphfile) True
让我们了解一下其字节大小
>>> bytes = len(open(graphfile).read()) >>> bytes != 0 True >>> 8000 < bytes < 10400 True
在您最喜欢的图片浏览器中打开它,并确认已生成适当的RRD图表。
让我们清理我们在临时目录中放置的文件
>>> os.unlink(filename) >>> os.unlink(graphfile)
Python绑定
除了命令行工具之外,PyRRD还支持使用Python绑定,如果您已安装。让我们设置一些像上一个例子中一样的东西
>>> filename = '/tmp/test.rrd' >>> dataSources = [] >>> roundRobinArchives = [] >>> dataSource = DataSource( ... dsName='speed', dsType='COUNTER', heartbeat=600) >>> dataSources.append(dataSource) >>> roundRobinArchives.append(RRA(cf='AVERAGE', xff=0.5, steps=1, rows=24)) >>> roundRobinArchives.append(RRA(cf='AVERAGE', xff=0.5, steps=6, rows=10))
使用方法与标准PyRRD使用方法相同,只是对象构造不同
>>> from pyrrd.backend import bindings >>> myRRD = RRD(filename, ds=dataSources, rra=roundRobinArchives, ... backend=bindings) >>> myRRD.create()
请注意,由于Graph模块是其自身的实体,当您绘图时,您需要指明您想使用绑定还是外部后端
>>> from pyrrd.graph import Graph >>> graphfile = "/tmp/rrdgraph.png" >>> g = Graph(graphfile, start=920805000, end=920810000, ... vertical_label='km/h', color=ca, backend=bindings) >>> g.data.extend([def1, cdef1, cdef2, cdef3, vdef1, vdef2, line1, area1, ... area2, line2, gprint1]) >>> g.write()
其他都是相同的。让我们检查文件是否存在,然后我们将清理
>>> import os >>> os.path.isfile(filename) True >>> os.unlink(filename)
已知错误
待办事项
近期
移动测试代码(测试和admin/testRunner)。
修复破坏性测试。
为使用info和fetch添加wiki示例
改进Python RRDTool绑定的包装器
PyRRD中许多代码都是很久以前编写的(大约是2004年),需要进行重构(去除冗余,使用更好的语法等)
允许用户为pyrrd.graph提供自己的fd
更新所有示例,例如示例4已更新。
停止使用实际文件写入和doctests进行文件测试;使用单元测试(和StringIO)代替。
未来
添加RPN类。
添加具有通过名称获取特定DS的get()方法的DS集合类。
添加对原子操作的支持。
变更
从0.0.7到0.1.0
这个版本标志着代码库的重大更新。自2009年3月至2011年9月,主干分支已提交了70多个提交。其中一些最显著的变化包括以下内容
添加了Python绑定的包装器。
改进了测试和测试基础设施。
改进了异常处理。
对RRD -> Python对象映射器进行了许多更改和改进。
改进了Windows支持。
图形格式修复。
许多来自社区成员的bug修复。
从0.0.6到0.0.7
包装改进和大量文档。
从0.0.5到0.0.6
错误修复版本(源包中缺少文件)。
从0.0.4到0.0.5
添加了对从RRD文件检索和显示RRD的支持。
添加了RRD数据的对象映射器(通过XML文件)。
添加了社区贡献的改进。
从0.0.3到0.0.4
更新所有示例以与最新代码兼容。
为Windows用户添加了社区贡献的bug修复。
从0.0.2到0.0.3
微调代码结构。
修复doctests。
各种bug修复。
示例更新。
从0.0.1到0.0.2
添加了许可证。
添加了单元测试。
添加了更多示例。
从0到0.0.1
将RRD代码作为从CoyMon项目捐赠的内容进行了重组。
将基本的rrdtool功能表示为Python类。
代码清理。
致谢
以下社区成员为该项目做出了宝贵的贡献
Ravi Bhalotia、Allen Lerner、Mike Carrick和美国退伍军人事务部
AdytumSolutions Inc.、E-Secure Systems
nasvos、Leem Smit、Aaron Westendorf和Agora Games
Mladen Milankovic、Denis Fortin
Joseph Heck、Jean-Baptiste Quenot
Pavel Shramov、Brad Beattie、Colin Horsington
谢谢!