一、目的

最近研究了一下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的更多相关文章

  1. Openstack Ceilometer监控项扩展

    Openstack ceilometer主要用于监控虚拟机.服务(glance.image.network等)和事件.虚拟机的监控项主要包括CPU.磁盘.网络.instance.本文在现有监控项的基础 ...

  2. &lt;转&gt;Openstack Ceilometer监控项扩展

    Openstack ceilometer主要用于监控虚拟机.服务(glance.image.network等)和事件.虚拟机的监控项主要包含CPU.磁盘.网络.instance.本文在现有监控项的基础 ...

  3. Android系统定制和源码开发以及源码编译(附视频)

    Android系统定制配套视频: 为了把Android系统源码定制和编译的课程讲完,从准备到录制完所有的视频,一共花去了近半年的时间,前前后后各种下载源码,编译源码,系统不兼容,版本适配,虚拟机配置困 ...

  4. &lt;转&gt;Openstack ceilometer 宿主机监控模块扩展

    <Openstack ceilometer监控项扩展>( http://eccp.csdb.cn/blog/?p=352 )主要介绍了对虚拟机监控项扩展, 比較简单.怎样在ceilomet ...

  5. lixuxmint系统定制与配置(1)-系统初始配置

    小书匠Linux 经常安装新的系统,每次安装完都得去搜索一边如何将系统部署为之前的环境,不仅耗费时间,还不一定能弄回之前的环境,现在把从裸机->到工作环境的系统定制及配置过程记录下来,期间的配置 ...

  6. CentOS 6.5 iso系统定制

    前言 更改CentOS6.5背景图片.CentOS标题为DntOS,总之就是用ISO安装或者安装后的系统启动时不能有CentOS标志. ISO光盘目录介绍: (1)isolinux 目录存放光盘启动时 ...

  7. 各种开源Android 系统定制

    MIUI MIUI是由小米科技开发的Android装置系统.2016年2月24日,MIUI全球用户超过1.7亿.部分开源代码托管在GitHub 官网 国际网站 http://miuiandroid.c ...

  8. Windows Embedded Standard 7 (WES7)系统定制遇到的问题(摄像头,喇叭,无线wifi)

    由于项目需要,需要对WES7系统进行定制,删除所有Windows字样基本没有什么问题,主要遇到如下3个问题: 1. 摄像头在Application模板下不能正常使用,即使安装驱动: 2. Jabra喇 ...

  9. 基于busybox和LFS的linux系统定制

    自从在大学知道了Linux这玩意是可以定制的之后,一直想做出一版属于自己的Linux系统.最近工作比较闲,终于塌下心来好好学习了一下.   目前来说,我接触的定制Linux的方法主要有两种:   1. ...

随机推荐

  1. 如何让div中的内容垂直居中

    虽然Div布局已经基本上取代了表格布局,但表格布局和Div布局仍然各有千秋,互有长处.比如表格布局中的垂直居中就是Div布局的一大弱项,不过好在千变万化的CSS可以灵活运用,可以制作出准垂直居中效果, ...

  2. require.js学习笔记(内容属于转载总结)

    <script data-main="src/app" src="src/lib/require.js"></script> backb ...

  3. fatal error: openssl/sha.h: No such file or directory 解决方案

    出现这个或者fatal error: openssl/名单.h: No such file or directory.都是没有安装libssl-dev- libssl-dev包含libraries, ...

  4. Java NIO框架Mina、Netty、Grizzly介绍与对比

    Mina:Mina(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用 ...

  5. Mysql多表关联删除操作

    直接看Sql即可: ;

  6. mac 无法ssh localhost

    mac 无法ssh localhost,错误提示:bash: /usr/local/bin/ssh_session: Permission denied在网上找了很久也没有找到解决方案,最后根据提示自 ...

  7. HDU 1681 Frobenius

    题目链接:Frobenius 思路:想了很久还是没转过弯来. 递推. 初始化vis[0] = 1,每次有四种方法扩展,这样能扩展到所有能被表示的数.上界的判定,如果一万以内的数都能被表示,那以后的数肯 ...

  8. JavaOne 2016——观众得以一睹JShell的威力

    导读 在JavaOne 2016的主题演讲中,Java平台组的首席架构师Mark Reinhold指出Java 9并不仅仅是Jigsaw,针对Java 9,一共包含了85个JEP.我在这里会关注一个他 ...

  9. eclipse ee 装oepe(Oracle Enterprise Pack for Eclipse)插件

    eclipse j2ee 安装weblogic插件Oracle Enterprise Pack for Eclipse(oepe) eclipse j2ee已经集成了常见的几个服务器容器,比如tomc ...

  10. Junit4的简单使用

    junit4的简单使用 测试套件的使用 测试类1 package com.westward; import static org.junit.Assert.*; import org.junit.Te ...