事件机制在nagios中的应用
2010年11月
修订控制页
章节名称 |
修订内容简述 |
修订日期 |
版本 |
拟稿人 |
已评审 |
ALL |
文档编写 |
2010.11.22 |
V0.0.1 |
万振杰 |
走查 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
目 录
目 录... 3
1 引言... 4
1.1 编写目的... 4
1.2 项目背景... 4
1.3 基本定义和术... 4
1.4 参考资料... 4
2 事件机制介绍... 5
3 事件类型... 7
4 调用函数类型... 10
5 调用函数可执行选项... 13
6 neb_module_list链表介绍... 15
7................................................................................. neb_callback_list链表介绍... 17
是作者万振杰在分析nagios代码后,发现代码中很多地方有事件机制,这种思想可以应用在很多地方,特地拿出分析。
针对版本:nagios-2.3
nagios-2.3源码
1、谈到事件,我们涉及到两个角色:事件发布者(Publisher)和事件订阅者(Scriber),也可以说是事件发送者(Sender)和事件接收者(Receiver)的关系。举个例子来说,市面上目前有许多杂志,杂志的种类也很多。而我只对其中的某些感兴趣,那么我就可以向杂志发行商提出订阅。之后,每当杂志发行时,我就会收到我在杂志发行商那儿订阅的杂志。在这个关系中,杂志发行商就相当于事件发行者,而我就是事件订阅者。每当杂志发行时,就触发了一个发行事件。
用面向对象的语言解释,这两者的意义如下:
2、事件发行者(Publisher)
它是一个对象,且会维护自身的状态信息。每当状态信息发生变动时,便触发一个事件,并通知所有的事件订阅者。对于杂志发行商来说,每本杂志都有自己的信息在里面,当杂志发行时,我要通知订阅该杂志的人:杂志已经发行啦,请注意查收!
在nagios中事件的发行者就是函数:
这些函数在程序执行到指定的地方时,发送指定的消息到那些订阅者那里 。
3、事件接收者(Receiver)
这个对象要注册它感兴趣的对象,也就是订阅它自己喜欢的杂志啦。另外,这个对象通常要提供一个事件处理方法,在事件发行者触发一个事件后,会自动执行这个方法。对于上面所举的例子来说,也就是我收到杂志后要做什么事情,比如,你可以满世界地大喊:我收到杂志啦!也可以将杂志收藏起来慢慢欣赏,具体怎么实现完全取决你自己的喜好。
在nagios中事件的订阅者就是:
此在配置文件nagios.cfg中配置。
1、 在nagios称EVENT TYPES
2、 EVENT TYPES:
/****** EVENT TYPES ************************/
#define NEBTYPE_NONE 0
#define NEBTYPE_HELLO 1
#define NEBTYPE_GOODBYE 2
#define NEBTYPE_INFO 3
#define NEBTYPE_PROCESS_START 100
#define NEBTYPE_PROCESS_DAEMONIZE 101
#define NEBTYPE_PROCESS_RESTART 102
#define NEBTYPE_PROCESS_SHUTDOWN 103
#define NEBTYPE_PROCESS_PRELAUNCH 104 /* before objects are read or verified */
#define NEBTYPE_PROCESS_EVENTLOOPSTART 105
#define NEBTYPE_PROCESS_EVENTLOOPEND 106
#define NEBTYPE_TIMEDEVENT_ADD 200
#define NEBTYPE_TIMEDEVENT_REMOVE 201
#define NEBTYPE_TIMEDEVENT_EXECUTE 202
#define NEBTYPE_TIMEDEVENT_DELAY 203 /* NOT IMPLEMENTED */
#define NEBTYPE_TIMEDEVENT_SKIP 204 /* NOT IMPLEMENTED */
#define NEBTYPE_TIMEDEVENT_SLEEP 205
#define NEBTYPE_LOG_DATA 300
#define NEBTYPE_LOG_ROTATION 301
#define NEBTYPE_SYSTEM_COMMAND_START 400
#define NEBTYPE_SYSTEM_COMMAND_END 401
#define NEBTYPE_EVENTHANDLER_START 500
#define NEBTYPE_EVENTHANDLER_END 501
#define NEBTYPE_NOTIFICATION_START 600
#define NEBTYPE_NOTIFICATION_END 601
#define NEBTYPE_CONTACTNOTIFICATION_START 602
#define NEBTYPE_CONTACTNOTIFICATION_END 603
#define NEBTYPE_CONTACTNOTIFICATIONMETHOD_START 604
#define NEBTYPE_CONTACTNOTIFICATIONMETHOD_END 605
#define NEBTYPE_SERVICECHECK_INITIATE 700
#define NEBTYPE_SERVICECHECK_PROCESSED 701
#define NEBTYPE_SERVICECHECK_RAW_START 702 /* NOT IMPLEMENTED */
#define NEBTYPE_SERVICECHECK_RAW_END 703 /* NOT IMPLEMENTED */
#define NEBTYPE_HOSTCHECK_INITIATE 800 /* a check of the route to the host has been initiated */
#define NEBTYPE_HOSTCHECK_PROCESSED 801 /* the processed/final result of a host check */
#define NEBTYPE_HOSTCHECK_RAW_START 802 /* the start of a "raw" host check */
#define NEBTYPE_HOSTCHECK_RAW_END 803 /* a finished "raw" host check */
#define NEBTYPE_COMMENT_ADD 900
#define NEBTYPE_COMMENT_DELETE 901
#define NEBTYPE_COMMENT_LOAD 902
#define NEBTYPE_FLAPPING_START 1000
#define NEBTYPE_FLAPPING_STOP 1001
#define NEBTYPE_DOWNTIME_ADD 1100
#define NEBTYPE_DOWNTIME_DELETE 1101
#define NEBTYPE_DOWNTIME_LOAD 1102
#define NEBTYPE_DOWNTIME_START 1103
#define NEBTYPE_DOWNTIME_STOP 1104
#define NEBTYPE_PROGRAMSTATUS_UPDATE 1200
#define NEBTYPE_HOSTSTATUS_UPDATE 1201
#define NEBTYPE_SERVICESTATUS_UPDATE 1202
#define NEBTYPE_ADAPTIVEPROGRAM_UPDATE 1300
#define NEBTYPE_ADAPTIVEHOST_UPDATE 1301
#define NEBTYPE_ADAPTIVESERVICE_UPDATE 1302
#define NEBTYPE_EXTERNALCOMMAND_START 1400
#define NEBTYPE_EXTERNALCOMMAND_END 1401
#define NEBTYPE_AGGREGATEDSTATUS_STARTDUMP 1500
#define NEBTYPE_AGGREGATEDSTATUS_ENDDUMP 1501
#define NEBTYPE_RETENTIONDATA_STARTLOAD 1600
#define NEBTYPE_RETENTIONDATA_ENDLOAD 1601
#define NEBTYPE_RETENTIONDATA_STARTSAVE 1602
#define NEBTYPE_RETENTIONDATA_ENDSAVE 1603
#define NEBTYPE_ACKNOWLEDGEMENT_ADD 1700
#define NEBTYPE_ACKNOWLEDGEMENT_REMOVE 1701 /* NOT IMPLEMENTED */
#define NEBTYPE_ACKNOWLEDGEMENT_LOAD 1702 /* NOT IMPLEMENTED */
#define NEBTYPE_STATECHANGE_START 1800 /* NOT IMPLEMENTED */
#define NEBTYPE_STATECHANGE_END
分别表示各个事件的状态,有事件开始、事件介绍….但是每个事件的不同状态对应一个调用函数类型(CALLBACK TYPES),而没一个调用函数类型(CALLBACK TYPES)会有很多订阅函数。
事件类型是系统发出的类型,而调用函数类型是订阅者订阅的类型。
1、 在nagios称CALLBACK TYPES
2、 CALLBACK TYPES:
/***** CALLBACK TYPES *****/
#define NEBCALLBACK_NUMITEMS 31 /* total number of callback types we have */
#define NEBCALLBACK_RESERVED0 0 /* reserved for future use */
#define NEBCALLBACK_RESERVED1 1
#define NEBCALLBACK_RESERVED2 2
#define NEBCALLBACK_RESERVED3 3
#define NEBCALLBACK_RESERVED4 4
#define NEBCALLBACK_RAW_DATA 5
#define NEBCALLBACK_NEB_DATA 6
#define NEBCALLBACK_PROCESS_DATA 7
#define NEBCALLBACK_TIMED_EVENT_DATA 8
#define NEBCALLBACK_LOG_DATA 9
#define NEBCALLBACK_SYSTEM_COMMAND_DATA 10
#define NEBCALLBACK_EVENT_HANDLER_DATA 11
#define NEBCALLBACK_NOTIFICATION_DATA 12
#define NEBCALLBACK_SERVICE_CHECK_DATA 13
#define NEBCALLBACK_HOST_CHECK_DATA 14
#define NEBCALLBACK_COMMENT_DATA 15
#define NEBCALLBACK_DOWNTIME_DATA 16
#define NEBCALLBACK_FLAPPING_DATA 17
#define NEBCALLBACK_PROGRAM_STATUS_DATA 18
#define NEBCALLBACK_HOST_STATUS_DATA 19
#define NEBCALLBACK_SERVICE_STATUS_DATA 20
#define NEBCALLBACK_ADAPTIVE_PROGRAM_DATA 21
#define NEBCALLBACK_ADAPTIVE_HOST_DATA 22
#define NEBCALLBACK_ADAPTIVE_SERVICE_DATA 23
#define NEBCALLBACK_EXTERNAL_COMMAND_DATA 24
#define NEBCALLBACK_AGGREGATED_STATUS_DATA 25
#define NEBCALLBACK_RETENTION_DATA 26
#define NEBCALLBACK_CONTACT_NOTIFICATION_DATA 27
#define NEBCALLBACK_CONTACT_NOTIFICATION_METHOD_DATA 28
#define NEBCALLBACK_ACKNOWLEDGEMENT_DATA 29
#define NEBCALLBACK_STATE_CHANGE_DATA 30
每一个CALLBACK TYPES对应一个:
1、在nagios中称为EVENT BROKER OPTIONS
2、EVENT BROKER OPTIONS:
/*************** EVENT BROKER OPTIONS *****************/
#define BROKER_NOTHING 0(表示:不执行所有调用函数)
#define BROKER_EVERYTHING 1048575(表示:执行所有调用函数)
#define BROKER_PROGRAM_STATE 1 /* DONE */
#define BROKER_TIMED_EVENTS 2 /* DONE */
#define BROKER_SERVICE_CHECKS 4 /* DONE */
#define BROKER_HOST_CHECKS 8 /* DONE */
#define BROKER_EVENT_HANDLERS 16 /* DONE */
#define BROKER_LOGGED_DATA 32 /* DONE */
#define BROKER_NOTIFICATIONS 64 /* DONE */
#define BROKER_FLAPPING_DATA 128 /* DONE */
#define BROKER_COMMENT_DATA 256 /* DONE */
#define BROKER_DOWNTIME_DATA 512 /* DONE */
#define BROKER_SYSTEM_COMMANDS 1024 /* DONE */
#define BROKER_OCP_DATA 2048 /* DONE */
#define BROKER_STATUS_DATA 4096 /* DONE */
#define BROKER_ADAPTIVE_DATA 8192 /* DONE */
#define BROKER_EXTERNALCOMMAND_DATA 16384 /* DONE */
#define BROKER_RETENTION_DATA 32768 /* DONE */
#define BROKER_ACKNOWLEDGEMENT_DATA 65536
#define BROKER_STATECHANGE_DATA 131072
#define BROKER_RESERVED18 262144
#define BROKER_RESERVED19 524288
没个调用函数都有这样一段代码:
event_broker_options:在全局变量中设定,可以BROKER_NOTHING、BROKER_EVERYTHING也可以任何一个指定的一个选项。
A. nebmodule结构体定义:
B. nebmodule结构体介绍
nebmodule是存储于内存中的指针;当nagios.c执行读取配置文件nagios.cfg时,读取到,就会调用neb_add_module,增加一个结点到nebmodule链表中。
1、定义:nebmodule *neb_module_list=NULL;
2、初始化:边读取配置文件nagios.c,调用函数neb_add_module边增加nebcallback结点。
3、主程序执行加载所有模块函数: 。
4、neb_load_all_modules根据neb_module_list链表上所有的结点执行neb_load_module函数。
5、每个neb_load_module函数会执行约定好的函数nebmodule_init。
6、在nebmodule_init函数中会执行函数neb_register_callback。
7、neb_register_callback函数会在neb_callback_list链表指针中增加新的回调函数结点。
A. nebcallback结构体定义:
B. nebcallback结构体介绍:
nebcallback是存储于内存中的指针的指针;每当事件发布者执行:
,查找neb_callback_lis链表中的位置,然后执行订阅此类型的所有订阅者的回调函数。
C. neb_callback_lis链表介绍:
1、定义:nebcallback **neb_callback_list=NULL
2、初始化:
3、回调函数注册:
每个新的模块需要调用neb_register_callback注册回调函数(参考module目录);
在neb_register_callback函数中会根据callback_type、priority找到结点应该在的位置。