collectd python
描述
python插件将python解释器嵌入到collectd中并且提供了collectd插件系统接口。这使得为collectd编写python插件成为了可能。这样做的效率要大大超过你每次想通过exec插件取值而执行python脚本的效率,并且也提供了更多的功能。支持python2.3以上版本。
编写配置文件
LoadPlugin python
# ...
<Plugin python>
ModulePath "/path/to/your/python/modules"
LogTraces true
Interactive false
Import "spam"
<Module spam>
spam "wonderful" "lovely"
</Module>
</Plugin>
LoadPlugin Plugin
载入python插件
Encoding name
Unicode对象的编码。如果忽略该选项,在python中为accii码,在python3中为utf-8。
ModulePath Name
默认是sys.path。可以使用多行ModulePath来导入更多的目录
LogTraces bool
如果python脚本报错,是否要记录下来。如果设置为true,它将记录下和在python解释器中一样的所有报错。大多数情况设置为false,除非是在测试新的module的时候。
Interactive bool
这个选项将使module打开一个python解释器在终端显示读与写。要注意的是如果你想作为一个守护进程来打开collectd的话,collectd开启的时候就关闭了。所以开启这个选项时务必使用-f命令。
collectd module不会导入到解释器全局变量中。你需要手动操作。确保阅读module的帮助文档,在编码的时候可以作为一个参考。
这个交互对话与守护进程式的collectd和标准的python解释器都略有差异:
1.collectd将试图导入readline类型的module来提供给你一个敲入命令的方式。而守护进程式的collectd是不会做的。
2.collectd将阻塞SIGINT。敲入Ctrl+C将停止collectd。在一个交互会话里这可能会引起问题,因此这个信号将被阻塞。你可以依旧使用它来打断syscalls比如sleep和pause,但是它也不会产生KeyboardInterrupt exception。
3.collectd处理SIGCHLD信号。这意味着python将不能决定system(),popen()进程的返回码。这将导致python不能显示帮助文档。
如果你却是需要从python中开启新进程,你可以在init回调函数中注册一个并且重设默认SIGCHLD的默认行为。请注意这个将打断exec插件。如果你想这么做,请不要载入exec插件。
contrib/python/etsigchld.py
中有一个例子这么做。你可以从collectd.conf中导入,SIGCHLD将正常处理而python产生的进程也将正常工作。
<Module Name> block
这个块可以用来传递配置设置给Python module。配置被转成Config类的一个实例,该实例是用来注册配置回调函数的。name标识了回调函数。
字符串
有许多地方字符串从collectd传到了python,也从python传回collectd。工作原理取决于使用的是byte和Unicode字符串或者python2和python3。
python2有str,这是bytes类型,以及Unicode。python3有str,这是Unicode对象,还有bytes类型。
当从python传值到collectd时所有的对象都被支持,然而如有可能,使用str。【注意】这些string都不可以有NUL字节。忽视这个将会产生TypeError异常。如果一个byte类型的string被使用,它将被collectd使用。如果一个Unicode类型的对象被使用,它将按照上述规则使用默认编码。如果因为string在该编码下不是一个valid序列而失败,那么一个bytes类型的对象将会被返回
编写你自己的插件
编写自己的插件非常简单。collectd管理插件通过dispatch功能,这个功能调用了在插件中注册的合适的回调函数。任何产检基本上由实现这些回调函数和注册collectd中的功能的初始化代码而组成。
configuration functions
如果碰到正确的module块,这些函数将在配置时被调用一次。对每个Module块,通过register_config函数根据module块匹配回调函数名调用一次。
python线程支持在这里禁止初始化,所以不要在这里调用任何线程的功能。
init function
导入module后,读和写之前,这些函数会被调用一次。应该用来初始化插件的内部状态(例如,建立socket)。这是你可以使用线程最早的地方。
read function
这些函数是collectd用来收集真实数据的地方。每隔一个间隔(Interval)就会调用一次。通常它将调用plugin_dispatch_values来分发值到collectd,而collectd将把数据发送到所有注册的write函数上。如果这个函数抛出任何异常将会停留更长的时间间隔直到恢复为止。
write function
这是用来写分发的值。对被插件分发的每一个值调用一次。
flush function
这个用来flush插件中的内部缓存。通常只有用户触发。任何插件在写入磁盘前缓存数据必须提供这种回调函数。
log function
这些是用来传递插件或者守护进程本身信息给用户的。
notification function
这些用来通知。一般而言,一个通知是一个数据实例相关的状态信息。通常,如果一个配置的阈值超出了,守护进程会产生一个通知。然而,所有插件也可以分发通知。
shutdown function
这些是在守护进程关闭之前一次调用。它应该用来清理插件(例如,关闭socket)。
任何函数(除了log函数)一旦出错都有可能抛出异常。异常应该通过collectd的日志机制传递给用户。如果一个log回调跑出异常,那么则应该将其打印到标准错误处理上standard err。
启动一个module,将其拷贝到python能访问的位置(如sys.path中的目录)正如其他python插件一样并且添加一个正确的Import选项到配置文档中。然后启动collectd就完成了。
类
以下复合类型是用来在python插件和collectd中传递值的:
Signed
Signed类就是一个long。它和long无异,拥有其方法和行为。它被用来表征一个整数已经或者应该被存储为一个signed或者unsigned对象中。这是long的另一个名字。使用它在元数据字典中选择元数据存储方式。
Unsigned
unsigned就是一个long。它和long无异,拥有其方法和行为。它被用来表征一个整数已经或者应该被存储为一个signed或者unsigned对象中。这是long的另一个名字。使用它在元数据字典中选择元数据存储方式。
Config
Config类是一个对象保存配置文件信息的对象。子类的顺序是每个配置选择的记录。每个这样的记录都是另一个Config实例,如果嵌套了block块则该实例也会被嵌套。
class Config(object)
这个代表了collectd配置文件的一部分。它被传递到注册回调函数(参见register_config)并且在创建后其他地方很少使用。它的方法只为数据成员存在。
数据成员定义如下:
parent
代表该节点的父节点。在Config树的顶层节点是None。
key
这一项的关键字,比如配置文件中所有行的第一个词。类型为string。
values
这是一个所有值的元组(可能为空),比如跟在配置文件任意行的关键词后的词组。元组中每一项要么是string,要么是float或boolean,而这取决于配置文件的内容。
children
这是一个子节点的元组。大多数节点将会为空。如何该节点代表了一个block块而非配置文件中的一行,那么它将包含该区块中所有的节点。
PluginData
不可以直接使用,它是Values和Notification的基类。用来识别值或者通知源。
class PluginData(Object)
这是一个内部类,是Values和Notification的基类。它本身作用不大因此不要将其导出到collectd的module中。
host
读取该值的来自于的host名。在调度中它可以设置为空字符串,这意味着在collectd.conf中定义的是本地host名。
plugin
读取数据的插件名。在调度中如果为空字符串则将’python’插入其中
plugin_instance
plugin实例字符串,可能为0
time
这是该值读取时Unix 时间戳。在调度中,如果改值设置为0则意味着’now’。
type
该值的类型。这个类型必须在type.db
中定义。试图给任何值设置它都将抛出TypeErr异常。设置类型是强制的,调用调度函数式如果不这么做就会抛出RuntimeError异常。
type_instance
类型实例字符串。可能为空。
Values
Values是一个对象标识值的序列。它继承于PluginData类型并使用它的成员来标识值。
class Value(PluginData)
Values对象是用来调度值到collectd中和接收从writer回调函数中的值。
方法消解顺序(Method resolution order):
Values
PluginData
object
定义的方法如下:
dispatch([type][, values][, plugin_instance][, type_instance][, plugin][, host][, time][, interval]) -> None.
调度这个实例到collectd进程。这个对象在这个方法中包含了所有可能的参数。详细的参数解释参见上述部分。不动将提交默认的,如果动了将提交你想提交的,但是不会修改对象中的成员参数值。
write([destination][, type][, values][, plugin_instance][, type_instance][, plugin][, host][, time][, interval]) -> None.
将该实例写到单独的插件中,或者如果destination省略的话,写到所有的插件中。这将迂回collectd主进程以及所有的过滤和缓存。除了这个之外,它和dispatch工作原理类似。
数据描述符定义如下:
interval
是以秒计算的在两次提交相同数据源之间的时间间隔。这个值必须为一个正整数,因此你不可以提交每秒超过一次的数。如果这个参数设置为一个非整数,将会使用默认值10。
如果你提交值频率超过指定间隔,那么将会取平均值,如果少于平均间隔,那么画出来的图将会有沟。
values
这些是真实的值传送给collectd。必须是一个序列(元组或列表)。序列的大小和内容的类型依赖于你在types.db
中定义的。更多的信息阅读types.db
主页。
如果这个序列大小错误则会发送RuntimeError错误。如果序列内容不是数值,TypeError将会抛出。
meta
这是Value对象的元数据。必须是numbers、strings或者bools的字典。所有的keys必须是string。int和对象将会被解析为signed
除非他们在2^63至2^64-1之间,那样的话将被解析为unsigned。你可以使用collectd.Signed
和collectd.Unsigned
强制转换。write的回调函数的元数据对象将保持Signed和Unsigned。
Notification
Notification对象定义了错误程度和消息的消息状态还有它基于的PluginData成员方法的数据实例。
类Notification (PluginData)是一个collectd通知的包裹类。可以用来通知错误信息给其他插件。与Values工作方式类似但是有serverity和message而不是间隔和时间作为值。Notification可以在任何时间传输并且可以被register_notification函数接收。
方法消解顺序:
Notification
PluginData
object
方法详述:
dispatch([type][, values][, plugin_instance][, type_instance][, plugin][, host][, time][, interval]) -> None. Dispatch a value list.
发送这个实例到collectd进程。该对象对每个可能的参数都有对应的成员。如果你不主动指定就默认提交对象里存储的成员,如果主动指定,则提交你想提交的,但是不会改变存储的值。
数据描述符定义如下:
message
某种描述正在发生什么和产生这个通知的原因
severity
通知的程度。赋值或者比较,NOTIF_FAILURE,NOTIF_WARNING,NOTIF_OKAY。
函数
以下函数对python-module提供C接口。
register_*(callback[, data][, name]) -> identifier
callback 是回调对象,每次事件触发时会被调用。
data是可选的对象,每次调用时被传送回给回调函数。如果你省略了该参数,就没有对象发送给回调函数了,即使是None。
name是可选的标识符。默认的name是python.module。module是从你回调函数的__module__属性中取得。每一个回调函数都需要一个唯一的标识符,因此如果你想在同一个module中注册相同的回调函数你需要指定一个name。否则就忽略这个参数
identifier是赋给这个回调函数的全部标识符。
对8种不同事件,有8个不同的注册函数,共有一个异常事件。
register_config
唯一的参数值是配置对象。注意你不能通过这种方式取得所有配置文件,只能取得python配置块中的module块。另外当你的回调标识符匹配python.blockname时,也将只接收到块信息。
register_init
调用时没有参数
register_read(callback[, interval][, data][, name]) -> identifier
回调函数需要一个额外的参数:时间间隔。指定了两次调用之间的时间。回调函数没有参数。
register_shutdown
回调调用没有参数
register_write
回调函数调用时有一个参数,是Values对象。如果回调函数抛出异常,下一次调用将延迟更长时间。
register_flush
对于回调函数来说,这个和register_config一样重要,因为它决定flush。
传递的参数是timeout和identifier。timeout表明老数据在多少秒之后需要flush。identifier表明哪一个Values需要被flush。
register_log
参数是serverity和message。serverity是一个正整数,越小越重要的,越大越不重要。最不重要等级是LOG_DEBUG,最重要的等级是LOG_ERR。在这之间有LOG_INFO,LOG_NOTICE,LOG_WARNNING(从不重要到重要)。message是一个结尾不带换行的字符串。
如果这个回调函数抛出了一个错误,则将被记录。默认忽略的则被打印到sys.stderr上。
register_notification
唯一的参数是Notification对象。
unregister_*(identifier) -> None
从collectd内部回调函数列表中移除一个回调函数或者数据集。每一个register_*函数都对应了一个unregister_*函数。identifier要么是register函数返回的字符串,要么是一个回调函数。identifier 是用和register函数中同样的方式构造出来的。
get_dataset(name) -> definition
返回通过name指定的数据集definition。definition是一个元组列表,每一个都代表一个数据源。每个元组有四个值:
name
字符串,数据集的名字
type
字符串,值为DS_TYPE_COUNTER, DS_TYPE_GAUGE, DS_TYPE_DERIVE or DS_TYPE_ABSOLUTE
min
一个浮点数或者None,最小值
max
一个浮点数或者None,最大值
flush(plugin[, timeout][, identifier]) -> None
flush一个或者所有的Plugin。timeout和指定的标识符被传递给配置的flush回调函数中。如果省略了,timeout将默认置为-1。标识符默认为None。如果一个Plugin的参数被指定,则flush该Plugin。
error, warning, notice, info, debug(message)
按照不同的严重程度Log消息
例子
Any Python module will start similar to:
import collectd
A very simple read function might look like:
def read(data=None):
vl = collectd.Values(type='gauge')
vl.plugin='python.spam'
vl.dispatch(values=[random.random() * 100])
A very simple write function might look like:
def write(vl, data=None):
for i in vl.values:
print "%s (%s): %f" % (vl.plugin, vl.type, i)
To register those functions with collectd:
collectd.register_read(read);
collectd.register_write(write);
See the section CLASSES above for a complete documentation of the data types used by the read, write and match functions.