void amqp_cache_purge(struct chained_cache *queue[], int index, int safe_action) { struct pkt_primitives *data = NULL; struct pkt_bgp_primitives *pbgp = NULL; struct pkt_nat_primitives *pnat = NULL; struct pkt_mpls_primitives *pmpls = NULL; struct pkt_tunnel_primitives *ptun = NULL; char *pcust = NULL; struct pkt_vlen_hdr_primitives *pvlen = NULL; struct pkt_bgp_primitives empty_pbgp; struct pkt_nat_primitives empty_pnat; struct pkt_mpls_primitives empty_pmpls; struct pkt_tunnel_primitives empty_ptun; char *empty_pcust = NULL; char src_mac[18], dst_mac[18], src_host[INET6_ADDRSTRLEN], dst_host[INET6_ADDRSTRLEN], ip_address[INET6_ADDRSTRLEN]; char rd_str[SRVBUFLEN], misc_str[SRVBUFLEN], dyn_amqp_routing_key[SRVBUFLEN], *orig_amqp_routing_key = NULL; int i, j, stop, batch_idx, is_routing_key_dyn = FALSE, qn = 0, ret, saved_index = index; int mv_num = 0, mv_num_save = 0; time_t start, duration; pid_t writer_pid = getpid(); char *json_buf = NULL; int json_buf_off = 0; #ifdef WITH_AVRO avro_writer_t avro_writer; char *avro_buf = NULL; int avro_buffer_full = FALSE; #endif /* setting some defaults */ if (!config.sql_host) config.sql_host = default_amqp_host; if (!config.sql_db) config.sql_db = default_amqp_exchange; if (!config.amqp_exchange_type) config.amqp_exchange_type = default_amqp_exchange_type; if (!config.amqp_vhost) config.amqp_vhost = default_amqp_vhost; if (!config.sql_table) config.sql_table = default_amqp_routing_key; else { if (strchr(config.sql_table, '$')) { is_routing_key_dyn = TRUE; orig_amqp_routing_key = config.sql_table; config.sql_table = dyn_amqp_routing_key; } } if (config.amqp_routing_key_rr) { orig_amqp_routing_key = config.sql_table; config.sql_table = dyn_amqp_routing_key; } p_amqp_set_exchange(&amqpp_amqp_host, config.sql_db); p_amqp_set_routing_key(&amqpp_amqp_host, config.sql_table); p_amqp_set_exchange_type(&amqpp_amqp_host, config.amqp_exchange_type); p_amqp_set_host(&amqpp_amqp_host, config.sql_host); p_amqp_set_vhost(&amqpp_amqp_host, config.amqp_vhost); p_amqp_set_persistent_msg(&amqpp_amqp_host, config.amqp_persistent_msg); p_amqp_set_frame_max(&amqpp_amqp_host, config.amqp_frame_max); if (config.message_broker_output & PRINT_OUTPUT_JSON) p_amqp_set_content_type_json(&amqpp_amqp_host); else if (config.message_broker_output & PRINT_OUTPUT_AVRO) p_amqp_set_content_type_binary(&amqpp_amqp_host); else { Log(LOG_ERR, "ERROR ( %s/%s ): Unsupported amqp_output value specified. Exiting.\n", config.name, config.type); exit_plugin(1); } p_amqp_init_routing_key_rr(&amqpp_amqp_host); p_amqp_set_routing_key_rr(&amqpp_amqp_host, config.amqp_routing_key_rr); empty_pcust = malloc(config.cpptrs.len); if (!empty_pcust) { Log(LOG_ERR, "ERROR ( %s/%s ): Unable to malloc() empty_pcust. Exiting.\n", config.name, config.type); exit_plugin(1); } memset(&empty_pbgp, 0, sizeof(struct pkt_bgp_primitives)); memset(&empty_pnat, 0, sizeof(struct pkt_nat_primitives)); memset(&empty_pmpls, 0, sizeof(struct pkt_mpls_primitives)); memset(&empty_ptun, 0, sizeof(struct pkt_tunnel_primitives)); memset(empty_pcust, 0, config.cpptrs.len); ret = p_amqp_connect_to_publish(&amqpp_amqp_host); if (ret) return; for (j = 0, stop = 0; (!stop) && P_preprocess_funcs[j]; j++) stop = P_preprocess_funcs[j](queue, &index, j); Log(LOG_INFO, "INFO ( %s/%s ): *** Purging cache - START (PID: %u) ***\n", config.name, config.type, writer_pid); start = time(NULL); if (config.print_markers) { if (config.message_broker_output & PRINT_OUTPUT_JSON || config.message_broker_output & PRINT_OUTPUT_AVRO) { void *json_obj; char *json_str; json_obj = compose_purge_init_json(config.name, writer_pid); if (json_obj) json_str = compose_json_str(json_obj); if (json_str) { Log(LOG_DEBUG, "DEBUG ( %s/%s ): %s\n\n", config.name, config.type, json_str); ret = p_amqp_publish_string(&amqpp_amqp_host, json_str); free(json_str); json_str = NULL; } } } if (config.message_broker_output & PRINT_OUTPUT_JSON) { if (config.sql_multi_values) { json_buf = malloc(config.sql_multi_values); if (!json_buf) { Log(LOG_ERR, "ERROR ( %s/%s ): malloc() failed (json_buf). Exiting ..\n", config.name, config.type); exit_plugin(1); } else memset(json_buf, 0, config.sql_multi_values); } } else if (config.message_broker_output & PRINT_OUTPUT_AVRO) { #ifdef WITH_AVRO if (!config.avro_buffer_size) config.avro_buffer_size = LARGEBUFLEN; avro_buf = malloc(config.avro_buffer_size); if (!avro_buf) { Log(LOG_ERR, "ERROR ( %s/%s ): malloc() failed (avro_buf). Exiting ..\n", config.name, config.type); exit_plugin(1); } avro_writer = avro_writer_memory(avro_buf, config.avro_buffer_size); #endif } for (j = 0; j < index; j++) { void *json_obj; char *json_str; if (queue[j]->valid != PRINT_CACHE_COMMITTED) continue; data = &queue[j]->primitives; if (queue[j]->pbgp) pbgp = queue[j]->pbgp; else pbgp = &empty_pbgp; if (queue[j]->pnat) pnat = queue[j]->pnat; else pnat = &empty_pnat; if (queue[j]->pmpls) pmpls = queue[j]->pmpls; else pmpls = &empty_pmpls; if (queue[j]->ptun) ptun = queue[j]->ptun; else ptun = &empty_ptun; if (queue[j]->pcust) pcust = queue[j]->pcust; else pcust = empty_pcust; if (queue[j]->pvlen) pvlen = queue[j]->pvlen; else pvlen = NULL; if (queue[j]->valid == PRINT_CACHE_FREE) continue; if (config.message_broker_output & PRINT_OUTPUT_JSON) { #ifdef WITH_JANSSON json_t *json_obj = json_object(); int idx; for (idx = 0; idx < N_PRIMITIVES && cjhandler[idx]; idx++) cjhandler[idx](json_obj, queue[j]); add_writer_name_and_pid_json(json_obj, config.name, writer_pid); json_str = compose_json_str(json_obj); #endif } else if (config.message_broker_output & PRINT_OUTPUT_AVRO) { #ifdef WITH_AVRO avro_value_iface_t *avro_iface = avro_generic_class_from_schema(avro_acct_schema); avro_value_t avro_value = compose_avro(config.what_to_count, config.what_to_count_2, queue[j]->flow_type, &queue[j]->primitives, pbgp, pnat, pmpls, ptun, pcust, pvlen, queue[j]->bytes_counter, queue[j]->packet_counter, queue[j]->flow_counter, queue[j]->tcp_flags, &queue[j]->basetime, queue[j]->stitch, avro_iface); size_t avro_value_size; add_writer_name_and_pid_avro(avro_value, config.name, writer_pid); avro_value_sizeof(&avro_value, &avro_value_size); if (avro_value_size > config.avro_buffer_size) { Log(LOG_ERR, "ERROR ( %s/%s ): AVRO; insufficient buffer size (avro_buffer_size=%u)\n", config.name, config.type, config.avro_buffer_size); Log(LOG_ERR, "ERROR ( %s/%s ): AVRO: increase value or look for avro_buffer_size in CONFIG-KEYS document.\n\n", config.name, config.type); exit_plugin(1); } else if (avro_value_size >= (config.avro_buffer_size - avro_writer_tell(avro_writer))) { avro_buffer_full = TRUE; j--; } else if (avro_value_write(avro_writer, &avro_value)) { Log(LOG_ERR, "ERROR ( %s/%s ): ARVO: unable to write value: %s\n", config.name, config.type, avro_strerror()); exit_plugin(1); } else { mv_num++; } avro_value_decref(&avro_value); avro_value_iface_decref(avro_iface); #else if (config.debug) Log(LOG_DEBUG, "DEBUG ( %s/%s ): compose_avro(): AVRO object not created due to missing --enable-avro\n", config.name, config.type); #endif } if (config.message_broker_output & PRINT_OUTPUT_JSON) { char *tmp_str = NULL; if (json_str && config.sql_multi_values) { int json_strlen = (strlen(json_str) ? (strlen(json_str) + 1) : 0); if (json_strlen >= (config.sql_multi_values - json_buf_off)) { if (json_strlen >= config.sql_multi_values) { Log(LOG_ERR, "ERROR ( %s/%s ): amqp_multi_values not large enough to store JSON elements. Exiting ..\n", config.name, config.type); exit(1); } tmp_str = json_str; json_str = json_buf; } else { strcat(json_buf, json_str); mv_num++; string_add_newline(json_buf); json_buf_off = strlen(json_buf); free(json_str); json_str = NULL; } } if (json_str) { if (is_routing_key_dyn) { P_handle_table_dyn_strings(dyn_amqp_routing_key, SRVBUFLEN, orig_amqp_routing_key, queue[j]); p_amqp_set_routing_key(&amqpp_amqp_host, dyn_amqp_routing_key); } if (config.amqp_routing_key_rr) { P_handle_table_dyn_rr(dyn_amqp_routing_key, SRVBUFLEN, orig_amqp_routing_key, &amqpp_amqp_host.rk_rr); p_amqp_set_routing_key(&amqpp_amqp_host, dyn_amqp_routing_key); } Log(LOG_DEBUG, "DEBUG ( %s/%s ): %s\n\n", config.name, config.type, json_str); ret = p_amqp_publish_string(&amqpp_amqp_host, json_str); if (config.sql_multi_values) { json_str = tmp_str; strcpy(json_buf, json_str); mv_num_save = mv_num; mv_num = 1; string_add_newline(json_buf); json_buf_off = strlen(json_buf); } free(json_str); json_str = NULL; if (!ret) { if (!config.sql_multi_values) qn++; else qn += mv_num_save; } else break; } } else if (config.message_broker_output & PRINT_OUTPUT_AVRO) { #ifdef WITH_AVRO if (!config.sql_multi_values || (mv_num >= config.sql_multi_values) || avro_buffer_full) { if (is_routing_key_dyn) { P_handle_table_dyn_strings(dyn_amqp_routing_key, SRVBUFLEN, orig_amqp_routing_key, queue[j]); p_amqp_set_routing_key(&amqpp_amqp_host, dyn_amqp_routing_key); } if (config.amqp_routing_key_rr) { P_handle_table_dyn_rr(dyn_amqp_routing_key, SRVBUFLEN, orig_amqp_routing_key, &amqpp_amqp_host.rk_rr); p_amqp_set_routing_key(&amqpp_amqp_host, dyn_amqp_routing_key); } ret = p_amqp_publish_binary(&amqpp_amqp_host, avro_buf, avro_writer_tell(avro_writer)); avro_writer_reset(avro_writer); avro_buffer_full = FALSE; mv_num_save = mv_num; mv_num = 0; if (!ret) qn += mv_num_save; else break; } #endif } } if (config.sql_multi_values) { if (config.message_broker_output & PRINT_OUTPUT_JSON) { if (json_buf && json_buf_off) { /* no handling of dyn routing keys here: not compatible */ Log(LOG_DEBUG, "DEBUG ( %s/%s ): %s\n\n", config.name, config.type, json_buf); ret = p_amqp_publish_string(&amqpp_amqp_host, json_buf); if (!ret) qn += mv_num; } } else if (config.message_broker_output & PRINT_OUTPUT_AVRO) { #ifdef WITH_AVRO if (avro_writer_tell(avro_writer)) { ret = p_amqp_publish_binary(&amqpp_amqp_host, avro_buf, avro_writer_tell(avro_writer)); avro_writer_free(avro_writer); if (!ret) qn += mv_num; } #endif } } duration = time(NULL)-start; if (config.print_markers) { if (config.message_broker_output & PRINT_OUTPUT_JSON || config.message_broker_output & PRINT_OUTPUT_AVRO) { void *json_obj; char *json_str; json_obj = compose_purge_close_json(config.name, writer_pid, qn, saved_index, duration); if (json_obj) json_str = compose_json_str(json_obj); if (json_str) { Log(LOG_DEBUG, "DEBUG ( %s/%s ): %s\n\n", config.name, config.type, json_str); ret = p_amqp_publish_string(&amqpp_amqp_host, json_str); free(json_str); json_str = NULL; } } } p_amqp_close(&amqpp_amqp_host, FALSE); Log(LOG_INFO, "INFO ( %s/%s ): *** Purging cache - END (PID: %u, QN: %u/%u, ET: %u) ***\n", config.name, config.type, writer_pid, qn, saved_index, duration); if (config.sql_trigger_exec && !safe_action) P_trigger_exec(config.sql_trigger_exec); if (empty_pcust) free(empty_pcust); if (json_buf) free(json_buf); #ifdef WITH_AVRO if (avro_buf) free(avro_buf); #endif }
void amqp_cache_purge(struct chained_cache *queue[], int index) { struct pkt_primitives *data = NULL; struct pkt_bgp_primitives *pbgp = NULL; struct pkt_nat_primitives *pnat = NULL; struct pkt_mpls_primitives *pmpls = NULL; char *pcust = NULL; struct pkt_vlen_hdr_primitives *pvlen = NULL; struct pkt_bgp_primitives empty_pbgp; struct pkt_nat_primitives empty_pnat; struct pkt_mpls_primitives empty_pmpls; char *empty_pcust = NULL; char src_mac[18], dst_mac[18], src_host[INET6_ADDRSTRLEN], dst_host[INET6_ADDRSTRLEN], ip_address[INET6_ADDRSTRLEN]; char rd_str[SRVBUFLEN], misc_str[SRVBUFLEN], dyn_amqp_routing_key[SRVBUFLEN], *orig_amqp_routing_key = NULL; int i, j, stop, batch_idx, is_routing_key_dyn = FALSE, qn = 0, ret, saved_index = index; int mv_num = 0, mv_num_save = 0; time_t start, duration; pid_t writer_pid = getpid(); #ifdef WITH_JANSSON json_t *array = json_array(); #endif /* setting some defaults */ if (!config.sql_host) config.sql_host = default_amqp_host; if (!config.sql_db) config.sql_db = default_amqp_exchange; if (!config.amqp_exchange_type) config.amqp_exchange_type = default_amqp_exchange_type; if (!config.amqp_vhost) config.amqp_vhost = default_amqp_vhost; if (!config.sql_table) config.sql_table = default_amqp_routing_key; else { if (strchr(config.sql_table, '$')) { is_routing_key_dyn = TRUE; orig_amqp_routing_key = config.sql_table; config.sql_table = dyn_amqp_routing_key; } } if (config.amqp_routing_key_rr) { orig_amqp_routing_key = config.sql_table; config.sql_table = dyn_amqp_routing_key; } p_amqp_set_exchange(&amqpp_amqp_host, config.sql_db); p_amqp_set_routing_key(&amqpp_amqp_host, config.sql_table); p_amqp_set_exchange_type(&amqpp_amqp_host, config.amqp_exchange_type); p_amqp_set_host(&amqpp_amqp_host, config.sql_host); p_amqp_set_vhost(&amqpp_amqp_host, config.amqp_vhost); p_amqp_set_persistent_msg(&amqpp_amqp_host, config.amqp_persistent_msg); p_amqp_set_frame_max(&amqpp_amqp_host, config.amqp_frame_max); p_amqp_set_content_type_json(&amqpp_amqp_host); p_amqp_init_routing_key_rr(&amqpp_amqp_host); p_amqp_set_routing_key_rr(&amqpp_amqp_host, config.amqp_routing_key_rr); empty_pcust = malloc(config.cpptrs.len); if (!empty_pcust) { Log(LOG_ERR, "ERROR ( %s/%s ): Unable to malloc() empty_pcust. Exiting.\n", config.name, config.type); exit_plugin(1); } memset(&empty_pbgp, 0, sizeof(struct pkt_bgp_primitives)); memset(&empty_pnat, 0, sizeof(struct pkt_nat_primitives)); memset(&empty_pmpls, 0, sizeof(struct pkt_mpls_primitives)); memset(empty_pcust, 0, config.cpptrs.len); ret = p_amqp_connect_to_publish(&amqpp_amqp_host); if (ret) return; for (j = 0, stop = 0; (!stop) && P_preprocess_funcs[j]; j++) stop = P_preprocess_funcs[j](queue, &index, j); Log(LOG_INFO, "INFO ( %s/%s ): *** Purging cache - START (PID: %u) ***\n", config.name, config.type, writer_pid); start = time(NULL); for (j = 0; j < index; j++) { void *json_obj; char *json_str; if (queue[j]->valid != PRINT_CACHE_COMMITTED) continue; data = &queue[j]->primitives; if (queue[j]->pbgp) pbgp = queue[j]->pbgp; else pbgp = &empty_pbgp; if (queue[j]->pnat) pnat = queue[j]->pnat; else pnat = &empty_pnat; if (queue[j]->pmpls) pmpls = queue[j]->pmpls; else pmpls = &empty_pmpls; if (queue[j]->pcust) pcust = queue[j]->pcust; else pcust = empty_pcust; if (queue[j]->pvlen) pvlen = queue[j]->pvlen; else pvlen = NULL; if (queue[j]->valid == PRINT_CACHE_FREE) continue; json_obj = compose_json(config.what_to_count, config.what_to_count_2, queue[j]->flow_type, &queue[j]->primitives, pbgp, pnat, pmpls, pcust, pvlen, queue[j]->bytes_counter, queue[j]->packet_counter, queue[j]->flow_counter, queue[j]->tcp_flags, &queue[j]->basetime, queue[j]->stitch); json_str = compose_json_str(json_obj); #ifdef WITH_JANSSON if (json_str && config.sql_multi_values) { json_t *elem = NULL; char *tmp_str = json_str; int do_free = FALSE; if (json_array_size(array) >= config.sql_multi_values) { json_str = json_dumps(array, 0); json_array_clear(array); mv_num_save = mv_num; mv_num = 0; } else do_free = TRUE; elem = json_loads(tmp_str, 0, NULL); json_array_append_new(array, elem); mv_num++; if (do_free) { free(json_str); json_str = NULL; } } #endif if (json_str) { if (is_routing_key_dyn) { P_handle_table_dyn_strings(dyn_amqp_routing_key, SRVBUFLEN, orig_amqp_routing_key, queue[j]); p_amqp_set_routing_key(&amqpp_amqp_host, dyn_amqp_routing_key); } if (config.amqp_routing_key_rr) { P_handle_table_dyn_rr(dyn_amqp_routing_key, SRVBUFLEN, orig_amqp_routing_key, &amqpp_amqp_host.rk_rr); p_amqp_set_routing_key(&amqpp_amqp_host, dyn_amqp_routing_key); } ret = p_amqp_publish_string(&amqpp_amqp_host, json_str); free(json_str); json_str = NULL; if (!ret) { if (!config.sql_multi_values) qn++; else qn += mv_num_save; } else break; } } #ifdef WITH_JANSSON if (config.sql_multi_values && json_array_size(array)) { char *json_str; json_str = json_dumps(array, 0); json_array_clear(array); json_decref(array); if (json_str) { /* no handling of dyn routing keys here: not compatible */ ret = p_amqp_publish_string(&amqpp_amqp_host, json_str); free(json_str); json_str = NULL; if (!ret) qn += mv_num; } } #endif p_amqp_close(&amqpp_amqp_host, FALSE); duration = time(NULL)-start; Log(LOG_INFO, "INFO ( %s/%s ): *** Purging cache - END (PID: %u, QN: %u/%u, ET: %u) ***\n", config.name, config.type, writer_pid, qn, saved_index, duration); if (config.sql_trigger_exec) P_trigger_exec(config.sql_trigger_exec); if (empty_pcust) free(empty_pcust); }
int bgp_peer_log_init(struct bgp_peer *peer, int output, int type) { int peer_idx, have_it, ret = 0, amqp_ret = 0; char log_filename[SRVBUFLEN], event_type[] = "log_init"; char peer_ip_src[] = "peer_ip_src", bmp_router[] = "bmp_router"; /* pointers to BGP or BMP vars */ struct bgp_peer_log **bpl; char *file, *amqp_routing_key, *lts, *pa_str; int amqp_routing_key_rr, max_peers; u_int64_t *ls; if (type == FUNC_TYPE_BGP) { file = config.nfacctd_bgp_msglog_file; amqp_routing_key = config.nfacctd_bgp_msglog_amqp_routing_key; amqp_routing_key_rr = config.nfacctd_bgp_msglog_amqp_routing_key_rr; max_peers = config.nfacctd_bgp_max_peers; pa_str = peer_ip_src; lts = log_tstamp_str; ls = &log_seq; bpl = &peers_log; } else if (type == FUNC_TYPE_BMP) { file = config.nfacctd_bmp_msglog_file; amqp_routing_key = config.nfacctd_bmp_msglog_amqp_routing_key; amqp_routing_key_rr = config.nfacctd_bmp_msglog_amqp_routing_key_rr; max_peers = config.nfacctd_bmp_max_peers; pa_str = bmp_router; lts = bmp_log_tstamp_str; ls = &bmp_log_seq; bpl = &bmp_peers_log; } else if (type == FUNC_TYPE_SFLOW_COUNTER) { file = config.sfacctd_counter_file; amqp_routing_key = NULL; /* AMQP not supported */ amqp_routing_key_rr = 0; /* AMQP not supported */ max_peers = config.sfacctd_counter_max_nodes; pa_str = peer_ip_src; lts = sf_cnt_log_tstamp_str; ls = &sf_cnt_log_seq; bpl = &sf_cnt_log; } else return ret; if (!(*bpl) || !peer || peer->log) return ret; if (file) bgp_peer_log_dynname(log_filename, SRVBUFLEN, file, peer); if (amqp_routing_key) { bgp_peer_log_dynname(log_filename, SRVBUFLEN, amqp_routing_key, peer); } for (peer_idx = 0, have_it = 0; peer_idx < max_peers; peer_idx++) { if (!(*bpl)[peer_idx].refcnt) { if (file) (*bpl)[peer_idx].fd = open_logfile(log_filename, "a"); #ifdef WITH_RABBITMQ if (amqp_routing_key) (*bpl)[peer_idx].amqp_host = &bgp_daemon_msglog_amqp_host; #endif strcpy((*bpl)[peer_idx].filename, log_filename); have_it = TRUE; break; } else if (!strcmp(log_filename, (*bpl)[peer_idx].filename)) { have_it = TRUE; break; } } if (have_it) { peer->log = &(*bpl)[peer_idx]; (*bpl)[peer_idx].refcnt++; #ifdef WITH_RABBITMQ if (amqp_routing_key) p_amqp_set_routing_key(peer->log->amqp_host, peer->log->filename); if (amqp_routing_key_rr && !p_amqp_get_routing_key_rr(peer->log->amqp_host)) { p_amqp_init_routing_key_rr(peer->log->amqp_host); p_amqp_set_routing_key_rr(peer->log->amqp_host, amqp_routing_key_rr); } #endif if (output == PRINT_OUTPUT_JSON) { #ifdef WITH_JANSSON char ip_address[INET6_ADDRSTRLEN]; json_t *obj = json_object(), *kv; kv = json_pack("{sI}", "seq", (*ls)); json_object_update_missing(obj, kv); json_decref(kv); bgp_peer_log_seq_increment(ls); kv = json_pack("{ss}", "timestamp", lts); json_object_update_missing(obj, kv); json_decref(kv); addr_to_str(ip_address, &peer->addr); kv = json_pack("{ss}", pa_str, ip_address); json_object_update_missing(obj, kv); json_decref(kv); kv = json_pack("{ss}", "event_type", event_type); json_object_update_missing(obj, kv); json_decref(kv); if (file) write_and_free_json(peer->log->fd, obj); #ifdef WITH_RABBITMQ if (amqp_routing_key) { amqp_ret = write_and_free_json_amqp(peer->log->amqp_host, obj); p_amqp_unset_routing_key(peer->log->amqp_host); } #endif #endif } } return (ret | amqp_ret); }
int bgp_peer_log_init(struct bgp_peer *peer, int output, int type) { struct bgp_misc_structs *bms = bgp_select_misc_db(type); int peer_idx, have_it, ret = 0, amqp_ret = 0, kafka_ret = 0; char log_filename[SRVBUFLEN], event_type[] = "log_init"; pid_t writer_pid = getpid(); if (!bms || !peer) return ERR; if (bms->msglog_file) bgp_peer_log_dynname(log_filename, SRVBUFLEN, bms->msglog_file, peer); if (bms->msglog_amqp_routing_key) { bgp_peer_log_dynname(log_filename, SRVBUFLEN, bms->msglog_amqp_routing_key, peer); } if (bms->msglog_kafka_topic) { bgp_peer_log_dynname(log_filename, SRVBUFLEN, bms->msglog_kafka_topic, peer); } for (peer_idx = 0, have_it = 0; peer_idx < bms->max_peers; peer_idx++) { if (!bms->peers_log[peer_idx].refcnt) { if (bms->msglog_file) { bms->peers_log[peer_idx].fd = open_output_file(log_filename, "a", FALSE); setlinebuf(bms->peers_log[peer_idx].fd); } #ifdef WITH_RABBITMQ if (bms->msglog_amqp_routing_key) bms->peers_log[peer_idx].amqp_host = bms->msglog_amqp_host; #endif #ifdef WITH_KAFKA if (bms->msglog_kafka_topic) bms->peers_log[peer_idx].kafka_host = bms->msglog_kafka_host; #endif strcpy(bms->peers_log[peer_idx].filename, log_filename); have_it = TRUE; break; } else if (!strcmp(log_filename, bms->peers_log[peer_idx].filename)) { have_it = TRUE; break; } } if (have_it) { peer->log = &bms->peers_log[peer_idx]; bms->peers_log[peer_idx].refcnt++; #ifdef WITH_RABBITMQ if (bms->msglog_amqp_routing_key) p_amqp_set_routing_key(peer->log->amqp_host, peer->log->filename); if (bms->msglog_amqp_routing_key_rr && !p_amqp_get_routing_key_rr(peer->log->amqp_host)) { p_amqp_init_routing_key_rr(peer->log->amqp_host); p_amqp_set_routing_key_rr(peer->log->amqp_host, bms->msglog_amqp_routing_key_rr); } #endif #ifdef WITH_KAFKA if (bms->msglog_kafka_topic) p_kafka_set_topic(peer->log->kafka_host, peer->log->filename); if (bms->msglog_kafka_topic_rr && !p_kafka_get_topic_rr(peer->log->kafka_host)) { p_kafka_init_topic_rr(peer->log->kafka_host); p_kafka_set_topic_rr(peer->log->kafka_host, bms->msglog_kafka_topic_rr); } #endif if (output == PRINT_OUTPUT_JSON) { #ifdef WITH_JANSSON char ip_address[INET6_ADDRSTRLEN]; json_t *obj = json_object(); json_object_set_new_nocheck(obj, "seq", json_integer((json_int_t)bms->log_seq)); bgp_peer_log_seq_increment(&bms->log_seq); json_object_set_new_nocheck(obj, "timestamp", json_string(bms->log_tstamp_str)); if (bms->bgp_peer_logdump_initclose_extras) bms->bgp_peer_logdump_initclose_extras(peer, output, obj); addr_to_str(ip_address, &peer->addr); json_object_set_new_nocheck(obj, bms->peer_str, json_string(ip_address)); json_object_set_new_nocheck(obj, "event_type", json_string(event_type)); if (bms->bgp_peer_log_msg_extras) bms->bgp_peer_log_msg_extras(peer, output, obj); if (bms->msglog_file) write_and_free_json(peer->log->fd, obj); #ifdef WITH_RABBITMQ if (bms->msglog_amqp_routing_key) { add_writer_name_and_pid_json(obj, config.proc_name, writer_pid); amqp_ret = write_and_free_json_amqp(peer->log->amqp_host, obj); p_amqp_unset_routing_key(peer->log->amqp_host); } #endif #ifdef WITH_KAFKA if (bms->msglog_kafka_topic) { add_writer_name_and_pid_json(obj, config.proc_name, writer_pid); kafka_ret = write_and_free_json_kafka(peer->log->kafka_host, obj); p_kafka_unset_topic(peer->log->kafka_host); } #endif #endif } } return (ret | amqp_ret | kafka_ret); }