ellios's blog

ellios's trivial story.

Ganglia Python

| Comments

老大想把我们放在mongdodb的一些统计数据,在Ganglia展示出来,想到Ganglia支持用python来写扩展模块,于是欣然应下,正好也学习下怎么写Ganglia的python扩展模块。

Ganglia要集成python模块是非常容易的,简单的数据展示,只需要写个pyconf后缀的文件和一个python的脚本就好了。Ganglia自身的源码里面也有很多python的模块的源码,其中有一个是专门用来做示例用的,我们就从他开始吧。

首先要弄清楚你需要收集哪些各数据,在pyconf文件中配置你要收集的数据的名称,像下面这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
modules {
  module {
    name = "example"
    language = "python"
    enabled = "yes"
    param RandomMax {
        value = 600
    }
    param ConstantValue {
        value = 112
    }
  }
}

collection_group {
  collect_every = 10
  time_threshold = 50
  metric {
    name = "PyRandom_Numbers"
    value_threshold = 1.0
  }
}

collection_group {
  collect_once = yes
  time_threshold = 20
  metric {
    name = "PyConstant_Number"
  }
}

很简单,modules里面配置了要加载的模块的名称,具体的配置项这里就不纠结了,collection_group里面可以配置你要收集的数据,metric项就是了。

配置文件写好了,下面看看真真干活的模块吧,ganglia的python模块是有一定的规范的,每个模块必要要有 metric_init, metric_cleanup方法,metric_cleanup做些收尾的工作,当gmond关闭时释放资源。metric_init方法做初始化操作,gmond在加载模块时,会先调用metric_init方法。这里你需要定义要收集的数据的详细参数,以及数据的call_back方法。具体看下面吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import random
descriptors = list()
Random_Max = 50
Constant_Value = 50

def Random_Numbers(name):
    '''Return a random number.'''
    return int(random.uniform(0, Random_Max))

def Constant_Number(name):
    '''Return a constant number.'''
    return int(Constant_Value)

def metric_init(params):
    '''Initialize the random number generator and create the
    metric definition dictionary object for each metric.'''
    global descriptors
    global Random_Max
    global Constant_Value
    random.seed()

    print '[pyexample] Received the following parameters'
    print params

    if 'RandomMax' in params:
        Random_Max = int(params['RandomMax'])
    if 'ConstantValue' in params:
        Constant_Value = int(params['ConstantValue'])

    d1 = {'name': 'PyRandom_Numbers',
        'call_back': Random_Numbers,
        'time_max': 90,
        'value_type': 'uint',
        'units': 'N',
        'slope': 'both',
        'format': '%u',
        'description': 'Example module metric (random numbers)',
        'groups': 'example,random'}

    d2 = {'name': 'PyConstant_Number',
        'call_back': Constant_Number,
        'time_max': 90,
        'value_type': 'uint',
        'units': 'N',
        'slope': 'zero',
        'format': '%hu',
      'description': 'Example module metric (constant number)'}

    descriptors = [d1, d2]
    return descriptors

def metric_cleanup():
    '''Clean up the metric module.'''
    pass

#This code is for debugging and unit testing
if __name__ == '__main__':
    params = {'RandomMax': '500',
        'ConstantValue': '322'}
    metric_init(params)
    for d in descriptors:
        v = d['call_back'](d['name'])
        print 'value for %s is %u' % (d['name'],  v)

其他还需要做些简单的配置,不过看下gmond.conf的配置文件基本上就都搞好了。这里就不啰嗦了,这两天感冒的厉害,需要好好休息。

参考资料

Comments