后端程序员之路 4、一种monitor的做法

record_t
包含_sum、_count、_time_stamp、_max、_min
最基础的一条记录,可以用来记录最大值、最小值、计数、总和
metric_t含有RECORD_NUM(6)份record_t,当metric_t::add调用时更新record_t的内容

metric_t
包含_name、_records[6]、_sample_vals[500]、_threshold_rate、_cursor、_operation、_cur_time_stamp
monitor_data_t含有METRICS_NUM(1500)份metric_t,当monitor_data_t::add调用时更新,调用在monitor的_thread_main里发生

monitor_data_t
包含_mutex、_metrics[1500]、_cursor、_init_flag
monitor_t含有一份monitor_data_t,mmap到指定的db_file
在_thread_main里修改内容时,会使用PTHREAD_PROCESS_SHARED、PTHREAD_MUTEX_ADAPTIVE_NP的_mutex

update_para_t
包含key、val、threshold_rate、op{AVG、INC、MIN、MAX、SMP(取样)}
封装每一次对记录的更新操作,会放到monitor_t的_data_q队列,在线程里定时处理

monitor_t
包含_p_monitor_data、_map_file、_lock_file、_init_flag、_data_q、_processor、_update_interval
_data_q是boost::lockfree::queue<update_para_t_ptr, boost::lockfree::capacity<DEFAULT_MAX_QUEUE_SIZE> >

程序启动时,指定映射的文件和间隔时间,创建处理线程。
monitor_t::get_instance().init(db_file, interval);
monitor_t::get_instance().start();

int monitor_t::inc(const std::string& key, double value) {
    return monitor_t::get_instance().update(key, value, 1, INC);
}
int monitor_t::max(const std::string& key, double value) {
    return monitor_t::get_instance().update(key, value, 1, MAX);
}
int monitor_t::min(const std::string& key, double value) {
    return monitor_t::get_instance().update(key, value, 1, MIN);
}
int monitor_t::avg(const std::string& key, double value, double threshold_rate) {
    return monitor_t::get_instance().update(key, value, threshold_rate, AVG);
}
int monitor_t::smp(const std::string& key, double value, double threshold_rate) {
    return monitor_t::get_instance().update(key, value, threshold_rate, SMP);
}
monitor_t::update将数据处理成update_para_t,放入_data_q
_thread_main将_data_q刷到mmap和buffer

总结:
1、提供峰值、平均值、计数统计等监控形式
2、监控结果写到内存映射文件
3、通过脚本调其它小程序将监控数据转成zabbix统计数据

原文地址:https://www.cnblogs.com/zapline/p/6482913.html