diff options
-rw-r--r-- | include/dbcache.h | 2 | ||||
-rw-r--r-- | include/service_protocol.h | 4 | ||||
-rw-r--r-- | include/zbxservice.h | 1 | ||||
-rw-r--r-- | src/libs/zbxdbcache/dbcache.c | 2 | ||||
-rw-r--r-- | src/libs/zbxservice/service_protocol.c | 85 | ||||
-rw-r--r-- | src/zabbix_server/alerter/alert_syncer.c | 45 | ||||
-rw-r--r-- | src/zabbix_server/service/service_manager.c | 48 |
7 files changed, 168 insertions, 19 deletions
diff --git a/include/dbcache.h b/include/dbcache.h index c7bcc8f5766..b875c7b1f91 100644 --- a/include/dbcache.h +++ b/include/dbcache.h @@ -213,6 +213,8 @@ typedef struct } zbx_tag_t; +ZBX_PTR_VECTOR_DECL(tags, zbx_tag_t*) + typedef struct { zbx_uint64_t hostid; diff --git a/include/service_protocol.h b/include/service_protocol.h index 47011ddf207..556448321b1 100644 --- a/include/service_protocol.h +++ b/include/service_protocol.h @@ -23,8 +23,12 @@ #include "common.h" #include "db.h" #include "zbxalgo.h" +#include "dbcache.h" void zbx_service_serialize(unsigned char **data, size_t *data_alloc, size_t *data_offset, zbx_uint64_t eventid, int clock, int value, int severity, const zbx_vector_ptr_t *tags); void zbx_service_deserialize(const unsigned char *data, zbx_uint32_t size, zbx_vector_ptr_t *events); +void zbx_service_serialize_problem_tags(unsigned char **data, size_t *data_alloc, size_t *data_offset, + zbx_uint64_t eventid, const zbx_vector_tags_t *tags); +void zbx_service_deserialize_problem_tags(const unsigned char *data, zbx_uint32_t size, zbx_vector_ptr_t *events); #endif diff --git a/include/zbxservice.h b/include/zbxservice.h index 59dfc594a94..3b22c1462aa 100644 --- a/include/zbxservice.h +++ b/include/zbxservice.h @@ -26,6 +26,7 @@ #define ZBX_IPC_SERVICE_SERVICE "service" #define ZBX_IPC_SERVICE_SERVICE_PROBLEMS 1 +#define ZBX_IPC_SERVICE_SERVICE_PROBLEMS_TAGS 2 void zbx_service_flush(zbx_uint32_t code, unsigned char *data, zbx_uint32_t size); diff --git a/src/libs/zbxdbcache/dbcache.c b/src/libs/zbxdbcache/dbcache.c index d64a48ca6fc..5127791d514 100644 --- a/src/libs/zbxdbcache/dbcache.c +++ b/src/libs/zbxdbcache/dbcache.c @@ -193,6 +193,8 @@ static int hc_get_history_compression_age(void); ZBX_PTR_VECTOR_DECL(item_tag, zbx_tag_t) ZBX_PTR_VECTOR_IMPL(item_tag, zbx_tag_t) +ZBX_PTR_VECTOR_IMPL(tags, zbx_tag_t*) + /****************************************************************************** * * * Function: DCget_stats_all * diff --git a/src/libs/zbxservice/service_protocol.c b/src/libs/zbxservice/service_protocol.c index de5d468e2c5..bbe6ad2fa0f 100644 --- a/src/libs/zbxservice/service_protocol.c +++ b/src/libs/zbxservice/service_protocol.c @@ -79,7 +79,6 @@ void zbx_service_serialize(unsigned char **data, size_t *data_alloc, size_t *dat zbx_free(len); } - void zbx_service_deserialize(const unsigned char *data, zbx_uint32_t size, zbx_vector_ptr_t *events) { const unsigned char *end = data + size; @@ -118,3 +117,87 @@ void zbx_service_deserialize(const unsigned char *data, zbx_uint32_t size, zbx_v } } +void zbx_service_serialize_problem_tags(unsigned char **data, size_t *data_alloc, size_t *data_offset, + zbx_uint64_t eventid, const zbx_vector_tags_t *tags) +{ + zbx_uint32_t data_len = 0, *len = NULL; + int i; + unsigned char *ptr; + + zbx_serialize_prepare_value(data_len, eventid); + zbx_serialize_prepare_value(data_len, tags->values_num); + + if (0 != tags->values_num) + { + len = (zbx_uint32_t *)zbx_malloc(NULL, sizeof(zbx_uint32_t) * 2 * tags->values_num); + for (i = 0; i < tags->values_num; i++) + { + zbx_tag_t *tag = (zbx_tag_t *)tags->values[i]; + + zbx_serialize_prepare_str_len(data_len, tag->tag, len[i * 2]); + zbx_serialize_prepare_str_len(data_len, tag->value, len[i * 2 + 1]); + } + } + + if (NULL != *data) + { + while (data_len > *data_alloc - *data_offset) + { + *data_alloc *= 2; + *data = (unsigned char *)zbx_realloc(*data, *data_alloc); + } + } + else + *data = (unsigned char *)zbx_malloc(NULL, (*data_alloc = MAX(1024, data_len))); + + ptr = *data + *data_offset; + *data_offset += data_len; + + ptr += zbx_serialize_value(ptr, eventid); + ptr += zbx_serialize_value(ptr, tags->values_num); + + for (i = 0; i < tags->values_num; i++) + { + zbx_tag_t *tag = (zbx_tag_t *)tags->values[i]; + + ptr += zbx_serialize_str(ptr, tag->tag, len[i * 2]); + ptr += zbx_serialize_str(ptr, tag->value, len[i * 2 + 1]); + } + + zbx_free(len); +} + +void zbx_service_deserialize_problem_tags(const unsigned char *data, zbx_uint32_t size, zbx_vector_ptr_t *events) +{ + const unsigned char *end = data + size; + + while (data < end) + { + zbx_event_t *event; + int values_num, i; + + event = (zbx_event_t *)zbx_malloc(NULL, sizeof(zbx_event_t)); + zbx_vector_ptr_create(&event->tags); + zbx_vector_ptr_append(events, event); + + data += zbx_deserialize_value(data, &event->eventid); + data += zbx_deserialize_value(data, &values_num); + + if (0 != values_num) + { + zbx_vector_ptr_reserve(&event->tags, values_num); + + for (i = 0; i < values_num; i++) + { + zbx_tag_t *tag; + zbx_uint32_t len; + + tag = (zbx_tag_t *)zbx_malloc(NULL, sizeof(zbx_tag_t)); + data += zbx_deserialize_str(data, &tag->tag, len); + data += zbx_deserialize_str(data, &tag->value, len); + + zbx_vector_ptr_append(&event->tags, tag); + } + } + } +} diff --git a/src/zabbix_server/alerter/alert_syncer.c b/src/zabbix_server/alerter/alert_syncer.c index c985fb9436d..216c5d3f2c8 100644 --- a/src/zabbix_server/alerter/alert_syncer.c +++ b/src/zabbix_server/alerter/alert_syncer.c @@ -28,6 +28,7 @@ #include "alert_manager.h" #include "alert_syncer.h" #include "alerter_protocol.h" +#include "zbxservice.h" #include "../../libs/zbxalgo/vectorimpl.h" @@ -464,9 +465,6 @@ static int am_db_compare_tags(const void *d1, const void *d2) return strcmp(tag1->value, tag2->value); } -ZBX_PTR_VECTOR_DECL(tags, zbx_tag_t*) -ZBX_PTR_VECTOR_IMPL(tags, zbx_tag_t*) - static void tag_free(zbx_tag_t *tag) { zbx_free(tag->tag); @@ -669,6 +667,27 @@ static void am_db_validate_tags_for_update(zbx_vector_events_tags_t *update_even zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__); } +static void am_service_add_event_tags(zbx_vector_events_tags_t *events_tags) +{ + unsigned char *data = NULL; + size_t data_alloc = 0, data_offset = 0; + int i; + + for (i = 0; i < events_tags->values_num; i++) + { + zbx_event_tags_t *event_tag = events_tags->values[i]; + + zbx_service_serialize_problem_tags(&data, &data_alloc, &data_offset, event_tag->eventid, + &event_tag->tags); + } + + if (NULL == data) + return; + + zbx_service_flush(ZBX_IPC_SERVICE_SERVICE_PROBLEMS_TAGS, data, data_offset); + zbx_free(data); +} + /****************************************************************************** * * * Function: am_db_flush_results * @@ -695,18 +714,22 @@ static int am_db_flush_results(zbx_am_db_t *amdb) return 0; } + zbx_vector_events_tags_create(&update_events_tags); + zbx_alerter_deserialize_results(message.data, &results, &results_num); if (0 != results_num) { - int i; + int i, ret; char *sql; size_t sql_alloc = results_num * 128, sql_offset; zbx_db_insert_t db_event, db_problem; sql = (char *)zbx_malloc(NULL, sql_alloc); - do { + do + { + zbx_vector_events_tags_clear_ext(&update_events_tags, event_tags_free); sql_offset = 0; DBbegin(); @@ -715,8 +738,6 @@ static int am_db_flush_results(zbx_am_db_t *amdb) zbx_db_insert_prepare(&db_problem, "problem_tag", "problemtagid", "eventid", "tag", "value", NULL); - zbx_vector_events_tags_create(&update_events_tags); - for (i = 0; i < results_num; i++) { zbx_am_db_mediatype_t *mediatype; @@ -764,11 +785,11 @@ static int am_db_flush_results(zbx_am_db_t *amdb) zbx_db_insert_autoincrement(&db_problem, "problemtagid"); zbx_db_insert_execute(&db_problem); zbx_db_insert_clean(&db_problem); - - zbx_vector_events_tags_clear_ext(&update_events_tags, event_tags_free); - zbx_vector_events_tags_destroy(&update_events_tags); } - while (ZBX_DB_DOWN == DBcommit()); + while (ZBX_DB_DOWN == (ret = DBcommit())); + + if (ZBX_DB_OK == ret) + am_service_add_event_tags(&update_events_tags); for (i = 0; i < results_num; i++) { @@ -782,6 +803,8 @@ static int am_db_flush_results(zbx_am_db_t *amdb) zbx_free(sql); } + zbx_vector_events_tags_clear_ext(&update_events_tags, event_tags_free); + zbx_vector_events_tags_destroy(&update_events_tags); zbx_free(results); zbx_ipc_message_clean(&message); diff --git a/src/zabbix_server/service/service_manager.c b/src/zabbix_server/service/service_manager.c index 7fdbd7b58a8..b02b66b0e82 100644 --- a/src/zabbix_server/service/service_manager.c +++ b/src/zabbix_server/service/service_manager.c @@ -1115,11 +1115,10 @@ static void db_update_services(zbx_hashset_t *services, zbx_hashset_t *service_d zbx_service_problem_t *service_problem; service_problem = (zbx_service_problem_t *)service_diff->service_problems.values[i]; - zbx_vector_ptr_remove_noorder(&service_diff->service_problems, i); - i--; add_service_problem(service, service_problems_index, service_problem); zbx_vector_ptr_append(&service_problems_new, service_problem); } + service_diff->service_problems.values_num = 0; for (i = 0; i < service_diff->service_problems_recovered.values_num; i++) { @@ -1246,6 +1245,37 @@ static void recover_services_problem(zbx_service_manager_t *service_manager, con } } +static void process_problem_tags(zbx_vector_ptr_t *events, zbx_service_manager_t *service_manager) +{ + int i, j; + + for (i = 0; i < events->values_num; i++) + { + zbx_event_t *event, **ptr; + + event = (zbx_event_t *)events->values[i]; + + if (NULL == (ptr = zbx_hashset_search(&service_manager->problem_events, &event))) + { + event_free(event); + continue; + } + + for (j = 0; j < event->tags.values_num; j++) + zbx_vector_ptr_append(&(*ptr)->tags, event->tags.values[j]); + + event->tags.values_num = 0; + event_free(event); + + match_event_to_service_problem_tags(*ptr, &service_manager->service_problem_tags_index, + &service_manager->service_diffs, ZBX_FLAG_SERVICE_RECALCULATE); + } + + db_update_services(&service_manager->services, &service_manager->service_diffs, + &service_manager->service_problems_index); + zbx_hashset_clear(&service_manager->service_diffs); +} + static void process_events(zbx_vector_ptr_t *events, zbx_service_manager_t *service_manager) { int i; @@ -1495,20 +1525,24 @@ ZBX_THREAD_ENTRY(service_manager_thread, args) { zbx_vector_ptr_t events; + zbx_vector_ptr_create(&events); + switch (message->code) { case ZBX_IPC_SERVICE_SERVICE_PROBLEMS: - zbx_vector_ptr_create(&events); - zbx_service_deserialize(message->data, message->size, &events); - zbx_ipc_message_free(message); process_events(&events, &service_manager); - - zbx_vector_ptr_destroy(&events); + break; + case ZBX_IPC_SERVICE_SERVICE_PROBLEMS_TAGS: + zbx_service_deserialize_problem_tags(message->data, message->size, &events); + process_problem_tags(&events, &service_manager); break; default: THIS_SHOULD_NEVER_HAPPEN; } + + zbx_ipc_message_free(message); + zbx_vector_ptr_destroy(&events); } if (NULL != client) |