为自己的系统定制openstack ceilometer
一、目的
最近研究了一下ceilometer,目的做一个监控系统,对系统中发生的事件进行处理。ceilometer对openstack各个组件信息的收集方式主要由 推 和 拉 两种。
“推”: 就是openstack的各个组件将信息以notification的形式发送到message bus,然后有agent_notification对消息进行监听,agent_notification 在接收到消息后,经过一个pipeline的处理,然后再通过rpc发送给collector,
collector负责将接收这些消息并且存储到持久化介质中,如 database,file等;这样中间会经过两次rpc的发送;
“拉”: openstack ceilometer会部署compute agent 还有 central agent 来主动的轮询(polling)一些组件的信息,compute agent主要负责收集虚拟机 cpu 内存、io等信息,compute agent会部署到每个虚拟机上,compute agent定期通过hyperviser api去获取信息。central agent 只部署在控制节点上,负责收集其他的信息image ,network等等,是通过restfulapi的方式调用;两种agent收集到消息后也是发送到rpc,然后collector收集;
二、设计方案
回到我们项目的需求上,我们只需要收集系统中的事件(event),其实ceilometer对收集信息的定义包括event和sample,event 就是一件发生的事情(例如: intance.create),sample是事件发生过程的产生的具体数据,(例如,为了instance分配了多少memory)。我们的系统中只需要处理event不用处理sample。所以删除了对sampe部分的处理。
第二个改动是,我们这边只有notification发出的消息,也就是只有推的机制,没有拉的机制,这样,其实就可以考虑不用对notification两次rpc传输了。考虑agent_notification接受到消息后直接存储到数据库,将collector做的事情放到agent_notification中,但最终程序的名字还是叫collector。。。。上图

系统中的各个组件通过notification api 发送消息到message bus(rabbit mq),collector通过监听一定的exchange和topic来获取notification信息,
然后交给预先定义好的函数(event process pipeline)来处理,最后通过dispatcher转存储到持久化介质中;其中的event definition部分通过event_definition.yaml 来进行控制;
三、示例sample
(1) 发送notification消息,
具体请参见higgs/sample/manager.py中的_sample_notify_period函数
from openstack.common.notifier import api as notifier_api
…...
payload = {
'samples': [
{
'name': 'test_notify_sample',
'type': 'gauge',
'unit': 'ns',
'volume': 1,
}
],
'reason': 'delete',
'user_id': 'test',
'tenant_id':'test',
'instance_id':'1234567890',
}
publisher_id = notifier_api.publisher_id('higgs_sample')
notifier_api.notify(context,publisher_id,'compute.instance.test.samples',notifier_api.CONF.default_notification_level,payload)
……
字段的具体定义如下:
a) publisher_id 是数据的发送方,openstack中是指"the source worker_type.host of the message, e.g. ‘compute.host1’ “,
获取值的顺序是 CONF.host > CONF.default_publisher_id > socket.gethostname(),也可以通过notifier_api的publisher_id来进行设置;
b) ‘compute.instance.test.samples’: 这个值是event_type,是string类型;如果要定义和发送一个新的事件,就起一个新的名字,例如:’scheduler.trigger’
c) payload:中文释义是“装载” 顾名思义,就是发送一个事件时附带的详细信息,这个参数比较重要,collector中对事件的处理大部分的信息都是从payload中获取的;
d) CONF.default_notification_level 默认的notification级别,级别为 DEBUG < INFO < WARNING < ERROR < CRITICAL;
(2)collector中对事件的处理
collector对事件的处理是通过yaml文件可配置的,具体的定义在event_definition.yaml中,截取一部分如下:
- event_type: compute.instance.*
traits: &instance_traits
tenant_id:
fields: payload.tenant_id
user_id:
fields: payload.user_id
instance_id:
fields: payload.instance_id
host:
fields: publisher_id
plugin:
name: split
parameters:
segment: 1
max_split: 1
service:
fields: publisher_id
plugin: split
memory_mb:
type: int
fields: payload.memory_mb
disk_gb:
type: int
fields: payload.disk_gb
.......
具体含义:
a) event_type: 被识别的event_type名称,支持通配符,这里的意思是,凡是以compute.instance.开头的事件都会有这段逻辑来处理;
traits: trait的中文是“特点”,可以理解为是一个event所携带的一个特点或者属性;例如trait下面的tenant_id、user_id......等都是一个trait;
b) tenant_id:
fields: payload.tenant_id
这两行一起看,表示这个trait的名字是tenant_id,它的值从你发送的event所携带的payload中的tenant_id中提取,payload.tenant_id的写法符合jsonpath https://pypi.python.org/pypi/jsonpath/
c) host:
fields: publisher_id
plugin:
name: split
parameters:
segment: 1
max_split: 1
这七行一起看,这个trait的名字是host,它的值是从event的payload中的publisher_id这一项提取,不同的是,它要对提取的值进行一定的处理,调用name 为split的插件,给插件提供两个参数:
segment和max_split;collector使用了stevedore来增加可拓展性,split的具体定义可以在setup.cfg中进行查看;
如果需要自己发送的event进行特殊的处理,可以自己仿照着写插件;
d) memory_mb:
type: int
fields: payload.memory_mb
这三行一起看,与前两个不同的是,有一个type参数。这个type是针对trait而言的,trait有四种类型,string、int、float、datetime;如果没有实际写明type的类型,默认是string类型;
总之,如果你有一个新的event要处理,首先你要定义这个event中的重要信息,然后在event_definition.yaml中写一个类似的将event转成trait的处理单元;
四、数据库结构
简单的介绍下 event 和 trait的数据库结构,对于理解这个两个概念更有好处;
event
+---------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| message_id | varchar(50) | YES | UNI | NULL | |
| event_type_id | int(11) | YES | MUL | NULL | |
| generated | decimal(20,6) | YES | MUL | NULL | |
+---------------+---------------+------+-----+---------+----------------+
每一个 event 都会有一个message_id,系统会默认生成,通过uuid;
event_type_id是与另外一张event_type表相关联;
generated是时间戳;
event_type
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| desc | varchar(255) | YES | UNI | NULL | |
+-------+--------------+------+-----+---------+----------------+
id表示event的type id,与event表中的event_type_id是外键关联;
trait
+---------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| t_string | text | YES | | NULL | |
| t_float | double | YES | MUL | NULL | |
| t_int | int(11) | YES | MUL | NULL | |
| event_id | int(11) | YES | MUL | NULL | |
| trait_type_id | int(11) | YES | MUL | NULL | |
| t_datetime | decimal(20,6) | YES | MUL | NULL | |
+---------------+---------------+------+-----+---------+————————+
t_ 开头表示trait的类型,在openstack中t_string是varchar(255),bsp考虑到可能会发送比较长的字符值,所以改成了text;
event_id与event表中的id是外键关联;
trait_type_id与trait_type表中的id是外键关联;
trait_type
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| desc | varchar(255) | YES | MUL | NULL | |
| data_type | int(11) | YES | | NULL | |
+-----------+--------------+------+-----+---------+————————+
id 与 trait表中的trait_type_id是外键关联;
为自己的系统定制openstack ceilometer的更多相关文章
- Openstack Ceilometer监控项扩展
Openstack ceilometer主要用于监控虚拟机.服务(glance.image.network等)和事件.虚拟机的监控项主要包括CPU.磁盘.网络.instance.本文在现有监控项的基础 ...
- <转>Openstack Ceilometer监控项扩展
Openstack ceilometer主要用于监控虚拟机.服务(glance.image.network等)和事件.虚拟机的监控项主要包含CPU.磁盘.网络.instance.本文在现有监控项的基础 ...
- Android系统定制和源码开发以及源码编译(附视频)
Android系统定制配套视频: 为了把Android系统源码定制和编译的课程讲完,从准备到录制完所有的视频,一共花去了近半年的时间,前前后后各种下载源码,编译源码,系统不兼容,版本适配,虚拟机配置困 ...
- <转>Openstack ceilometer 宿主机监控模块扩展
<Openstack ceilometer监控项扩展>( http://eccp.csdb.cn/blog/?p=352 )主要介绍了对虚拟机监控项扩展, 比較简单.怎样在ceilomet ...
- lixuxmint系统定制与配置(1)-系统初始配置
小书匠Linux 经常安装新的系统,每次安装完都得去搜索一边如何将系统部署为之前的环境,不仅耗费时间,还不一定能弄回之前的环境,现在把从裸机->到工作环境的系统定制及配置过程记录下来,期间的配置 ...
- CentOS 6.5 iso系统定制
前言 更改CentOS6.5背景图片.CentOS标题为DntOS,总之就是用ISO安装或者安装后的系统启动时不能有CentOS标志. ISO光盘目录介绍: (1)isolinux 目录存放光盘启动时 ...
- 各种开源Android 系统定制
MIUI MIUI是由小米科技开发的Android装置系统.2016年2月24日,MIUI全球用户超过1.7亿.部分开源代码托管在GitHub 官网 国际网站 http://miuiandroid.c ...
- Windows Embedded Standard 7 (WES7)系统定制遇到的问题(摄像头,喇叭,无线wifi)
由于项目需要,需要对WES7系统进行定制,删除所有Windows字样基本没有什么问题,主要遇到如下3个问题: 1. 摄像头在Application模板下不能正常使用,即使安装驱动: 2. Jabra喇 ...
- 基于busybox和LFS的linux系统定制
自从在大学知道了Linux这玩意是可以定制的之后,一直想做出一版属于自己的Linux系统.最近工作比较闲,终于塌下心来好好学习了一下. 目前来说,我接触的定制Linux的方法主要有两种: 1. ...
随机推荐
- 理论与实践中的 C# 内存模型,第 2 部分
转载自:https://msdn.microsoft.com/zh-cn/magazine/jj883956.aspx 这是介绍 C# 内存模型的系列文章的第二篇(共两篇). 正如在 MSDN 杂志十 ...
- jmeter笔记7
一.脚本录制(Jmeter): Jmeter 脚本(.jmx)为 xml 格式,树形结构,由元件组成,使用“取样器”产生请求. 在“工作台”添加“HTTP 代理服务器” 端口: 代理服务器的端口,默认 ...
- DSP EPWM学习笔记2 - EPWM相关寄存器设置问题解析
DSP EPWM学习笔记2 - EPWM相关寄存器设置问题解析 彭会锋 本篇主要针对不太熟悉的TZ 故障捕获 和 DB 死区产生两个子模块进行学习研究 感觉TI的寄存器命名还是有一定规律可循的 SEL ...
- Valid Palindrome [LeetCode]
Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...
- 164. Maximum Gap *HARD* -- 无序数组找出排序后连续元素的最大间隔
Given an unsorted array, find the maximum difference between the successive elements in its sorted f ...
- 绝对应当收藏的10个实用HTML5代码片段(转)
HTML5绝对是一个流行元素,受到如此多的公司组织的追捧,作为极客来说,岂能错过呢?在今天这篇文章中,我们将分享一些超实用的HTML5的代码片段,相信大家一定会喜欢! 正确的嵌入flash 如果你经常 ...
- hdu 4632 Palindrome subsequence
http://acm.hdu.edu.cn/showproblem.php?pid=4632 简单DP 代码: #include<iostream> #include<cstdio& ...
- win7下python安装pyquery
安装pyquery之前首先要明确一点,easyinstall 是一款python包管理器,类似于node的npm,用于安装python的扩展包,它安装的包是以*.egg的方式. 要安装pq需要经历以下 ...
- linux下xampp集成包安装配置方法
1.查看你linux系统的位数,是32位的还是64位的.使用uname -a命令查看. 显示有 x86_64则说明你是64位内核, 跑的是64位的系统. i386, i686说明你是32位的内核, 跑 ...
- C++-标准输入输出
1,cout 1) 用来向标准输出打印. 2) 如果参数是char*类型,则直接输出字符串.如果想要输出地址,则需要强制转换: <<static_cast<void*>(con ...