zabbix源代码阅读--zabbix_agent

来源:互联网 发布:淘宝人群分析 编辑:程序博客网 时间:2024/05/24 05:34
转载自:http://blog.csdn.net/liujian0616/article/details/7932323

        zabbix是一个实时监控系统,可以监控服务器的运行状态(cpu,内存,端口),并且可以发送报警邮件和短信,或者执行远程命令.由于工作上需要对zabbix进行二次开发,所以借此机会阅读了一下zabbix的源代码.zabbix前台是PHP实现的,后台是用c写的,按功能分为几个部分:agent,server,proxy,sender. zabbix_agent负责收集机器上的数据(比如cpu利用率,内存剩余量等)发送给zabbix_server,zabbix_server负责收集zabbix_agent或者zabbix_proxy发送过来的数据,更新数据库,而前台的php代码就可以从数据库内拿出这些数据进行显示。

先看zabbix_agent,它默认会启动三个进程:collector_thread、listener_thread、active_checks_thread

[cpp] view plain copy
print?
  1. /* start the collector thread */  
  2. thread_args = (zbx_thread_args_t *)zbx_malloc(NULL, sizeof(zbx_thread_args_t));  
  3. thread_args->thread_num = thread_num;  
  4. thread_args->args = NULL;  
  5. threads[thread_num++] = zbx_thread_start(collector_thread, thread_args);  
  6. /* start listeners */  
  7. for (i = 0; i < CONFIG_ZABBIX_FORKS; i++)  
  8. {  
  9.     thread_args = (zbx_thread_args_t *)zbx_malloc(NULL, sizeof(zbx_thread_args_t));  
  10.     thread_args->thread_num = thread_num;  
  11.     thread_args->args = &listen_sock;  
  12.     threads[thread_num++] = zbx_thread_start(listener_thread, thread_args);  
  13. }  
  14. /* start active check */  
  15. if (0 == CONFIG_DISABLE_ACTIVE)  
  16. {  
  17.     activechk_args.host = CONFIG_HOSTS_ALLOWED;  
  18.     activechk_args.port = (unsigned short)CONFIG_SERVER_PORT;  
  19.     thread_args = (zbx_thread_args_t *)zbx_malloc(NULL, sizeof(zbx_thread_args_t));  
  20.     thread_args->thread_num = thread_num;  
  21.     thread_args->args = &activechk_args;  
  22.     threads[thread_num++] = zbx_thread_start(active_checks_thread, thread_args);  
  23. }  


其中collector_thread会每隔1s收集本机的cpu状态存入结构体ZBX_CPUS_STAT_DATA中,将磁盘的状态存入结构体ZBX_DISKDEVICES_DATA

[cpp] view plain copy
print?
  1. typedef struct  
  2. {  
  3.     zbx_uint64_t    h_counter[ZBX_CPU_STATE_COUNT][MAX_COLLECTOR_HISTORY];  
  4.     unsigned char   h_status[MAX_COLLECTOR_HISTORY];  
  5.     int     h_first;  
  6.     int     h_count;  
  7.     int     cpu_num;  
  8. }  
  9. ZBX_SINGLE_CPU_STAT_DATA;  
  10.   
  11. typedef struct  
  12. {  
  13.     ZBX_SINGLE_CPU_STAT_DATA    *cpu;  
  14.     int             count;  
  15. }  
  16. ZBX_CPUS_STAT_DATA;  


 

[cpp] view plain copy
print?
  1. typedef struct c_single_diskdevice_data  
  2. {  
  3.     char        name[32];  
  4.     int     index;  
  5.     time_t      clock[MAX_COLLECTOR_HISTORY];  
  6.     zbx_uint64_t    r_sect[MAX_COLLECTOR_HISTORY];  
  7.     zbx_uint64_t    r_oper[MAX_COLLECTOR_HISTORY];  
  8.     zbx_uint64_t    r_byte[MAX_COLLECTOR_HISTORY];  
  9.     zbx_uint64_t    w_sect[MAX_COLLECTOR_HISTORY];  
  10.     zbx_uint64_t    w_oper[MAX_COLLECTOR_HISTORY];  
  11.     zbx_uint64_t    w_byte[MAX_COLLECTOR_HISTORY];  
  12.     double      r_sps[ZBX_AVG_COUNT];  
  13.     double      r_ops[ZBX_AVG_COUNT];  
  14.     double      r_bps[ZBX_AVG_COUNT];  
  15.     double      w_sps[ZBX_AVG_COUNT];  
  16.     double      w_ops[ZBX_AVG_COUNT];  
  17.     double      w_bps[ZBX_AVG_COUNT];  
  18. } ZBX_SINGLE_DISKDEVICE_DATA;  
  19.   
  20. typedef struct c_diskdevices_data  
  21. {  
  22.     int             count;  
  23.     ZBX_SINGLE_DISKDEVICE_DATA  device[MAX_DISKDEVICES];  
  24. } ZBX_DISKDEVICES_DATA;  


zabbix_agent和zabbix_server通信有两种方式:主动和被动,即它可以主动的发送信息给zabbix_server,也可以等zabbix_server请求时在发送相关的信息进行响应。默认情况这两个方式都开启了。另外,zabbix_server和zabbix_agent通信的协议是json格式的,详细格式请查阅官网文档。

    listener_thread进程是负责被动方式,它负责监听10050端口,然后等待server端的请求并进行响应,请看下面的代码(listener.c)

[cpp] view plain copy
print?
  1. static void process_listener(zbx_sock_t *s)  
  2. {  
  3.     AGENT_RESULT    result;  
  4.     char        *command;  
  5.     char        **value = NULL;  
  6.     int     ret;  
  7.   
  8.     if (SUCCEED == (ret = zbx_tcp_recv_to(s, &command, CONFIG_TIMEOUT)))  
  9.     {  
  10.         zbx_rtrim(command, "\r\n");  
  11.   
  12.         zabbix_log(LOG_LEVEL_DEBUG, "Requested [%s]", command);  
  13.   
  14.         init_result(&result);  
  15.         process(command, 0, &result);  
  16.   
  17.         if (NULL == (value = GET_TEXT_RESULT(&result)))  
  18.             value = GET_MSG_RESULT(&result);  
  19.   
  20.         if (NULL != value)  
  21.         {  
  22.             zabbix_log(LOG_LEVEL_DEBUG, "Sending back [%s]", *value);  
  23.             ret = zbx_tcp_send_to(s, *value, CONFIG_TIMEOUT);  
  24.         }  
  25.   
  26.         free_result(&result);  
  27.     }  
  28.   
  29.     if (FAIL == ret)  
  30.         zabbix_log(LOG_LEVEL_DEBUG, "Process listener error: %s", zbx_tcp_strerror());  
  31. }  

值得一提的是从服务器接收的变量command,它其实就是我们在前台页面添加item时填的key,接下来有这么一个结构

[cpp] view plain copy
print?
  1. ZBX_METRIC  parameters_common[] =  
  2. /*      KEY                     FLAG        FUNCTION        ADD_PARAM       TEST_PARAM */  
  3. {  
  4.     {"agent.ping",      0,      AGENT_PING,         0,  0},  
  5.     {"agent.version",   0,      AGENT_VERSION,      0,  0},  
  6.   
  7.     {"system.localtime",    0,      SYSTEM_LOCALTIME,   0,  0},  
  8.     {"system.run",      CF_USEUPARAM,   SYSTEM_RUN,     0,  "echo test"},  
  9.   
  10.     {"web.page.get",    CF_USEUPARAM,   WEB_PAGE_GET,       0,  "localhost,,80"},  
  11.     {"web.page.perf",   CF_USEUPARAM,   WEB_PAGE_PERF,      0,  "localhost,,80"},  
  12.     {"web.page.regexp", CF_USEUPARAM,   WEB_PAGE_REGEXP,    0,  "localhost,,80,OK"},  
  13. }  

这个结构体将key和agent接收到key后执行的function联系到了一起

    active_checks_thread进程是负责主动发送收集到的信息给zabbix_server的。除此之外,他还负责发送心跳包已经更新自己维护的一个active_checks条目表,部分代码(active.c:ZBX_THREAD_ENTRY(active_checks_thread, args))如下:

[cpp] view plain copy
print?
  1. while (ZBX_IS_RUNNING())  
  2. {  
  3.     if (time(NULL) >= nextsend)  
  4.     {  
  5.         send_buffer(activechk_args.host, activechk_args.port); //负责发送心跳包  
  6.         nextsend = (int)time(NULL) + 1;  
  7.     }  
  8.     if (time(NULL) >= nextrefresh)  
  9.     {  
  10.         zbx_setproctitle("poller [getting list of active checks]");  
  11.   
  12.         if (FAIL == refresh_active_checks(activechk_args.host, activechk_args.port))  //更新自己维护的一个active_checks条目表  
  13.         {  
  14.             nextrefresh = (int)time(NULL) + 60;  
  15.         }  
  16.         else  
  17.         {  
  18.             nextrefresh = (int)time(NULL) + CONFIG_REFRESH_ACTIVE_CHECKS;  
  19.         }  
  20.     }  
  21.   
  22.     if (time(NULL) >= nextcheck && CONFIG_BUFFER_SIZE / 2 > buffer.pcount)  
  23.     {  
  24.         zbx_setproctitle("poller [processing active checks]");  
  25.   
  26.         process_active_checks(activechk_args.host, activechk_args.port); //主动发送收集到的信息给zabbix_server  
  27.         if (CONFIG_BUFFER_SIZE / 2 <= buffer.pcount) /* failed to complete processing active checks */  
  28.             continue;  
  29.   
  30.         nextcheck = get_min_nextcheck();  
  31.         if (FAIL == nextcheck)  
  32.             nextcheck = (int)time(NULL) + 60;  
  33.     }  
  34.     else  
  35.     {  
  36.         zabbix_log(LOG_LEVEL_DEBUG, "Sleeping for %d second(s)", 1);  
  37.         zbx_setproctitle("poller [sleeping for %d second(s)]", 1);  
  38.         zbx_sleep(1);  
  39.     }  
  40. }  


 转载请注明出处:http://blog.csdn.net/liujian0616/article/details/7932323

 

原创粉丝点击