static void log_multiplexer_queue(LogPipe *s, LogMessage *msg, const LogPathOptions *path_options, gpointer user_data) { LogMultiplexer *self = (LogMultiplexer *) s; gint i; LogPathOptions local_options = *path_options; gboolean matched; gboolean delivered = FALSE; gboolean last_delivery; gint fallback; local_options.matched = &matched; for (fallback = 0; (fallback == 0) || (fallback == 1 && self->fallback_exists && !delivered); fallback++) { for (i = 0; i < self->next_hops->len; i++) { LogPipe *next_hop = g_ptr_array_index(self->next_hops, i); if (G_UNLIKELY(fallback == 0 && (next_hop->flags & PIF_BRANCH_FALLBACK) != 0)) { continue; } else if (G_UNLIKELY(fallback && (next_hop->flags & PIF_BRANCH_FALLBACK) == 0)) { continue; } matched = TRUE; log_msg_add_ack(msg, &local_options); /* NOTE: this variable indicates that the upcoming message * delivery is the last one, thus we don't need to retain an an * unmodified copy to be sent to further paths. The current * delivery may modify the message at will. */ last_delivery = (self->super.pipe_next == NULL) && (i == self->next_hops->len - 1) && (!self->fallback_exists || delivered || fallback == 1); if (!last_delivery) log_msg_write_protect(msg); log_pipe_queue(next_hop, log_msg_ref(msg), &local_options); if (!last_delivery) log_msg_write_unprotect(msg); if (matched) { delivered = TRUE; if (G_UNLIKELY(next_hop->flags & PIF_BRANCH_FINAL)) break; } } } log_pipe_forward_msg(s, msg, path_options); }
static void _init(AckRecord *self) { self->acked = FALSE; log_msg_ref(self->original); log_msg_refcache_start_producer(self->original); log_msg_add_ack(self->original, &self->path_options); log_msg_ref(self->original); log_msg_write_protect(self->original); }
static void _pattern_db_process_matching_rule(PatternDB *self, PDBProcessParams *process_params) { PDBContext *context = NULL; PDBRule *rule = process_params->rule; LogMessage *msg = process_params->msg; GString *buffer = g_string_sized_new(32); g_static_rw_lock_writer_lock(&self->lock); _advance_time_based_on_message(self, process_params, &msg->timestamps[LM_TS_STAMP]); if (rule->context.id_template) { CorrellationKey key; log_template_format(rule->context.id_template, msg, NULL, LTZ_LOCAL, 0, NULL, buffer); log_msg_set_value(msg, context_id_handle, buffer->str, -1); correllation_key_setup(&key, rule->context.scope, msg, buffer->str); context = g_hash_table_lookup(self->correllation.state, &key); if (!context) { msg_debug("Correllation context lookup failure, starting a new context", evt_tag_str("rule", rule->rule_id), evt_tag_str("context", buffer->str), evt_tag_int("context_timeout", rule->context.timeout), evt_tag_int("context_expiration", timer_wheel_get_time(self->timer_wheel) + rule->context.timeout)); context = pdb_context_new(&key); g_hash_table_insert(self->correllation.state, &context->super.key, context); g_string_steal(buffer); } else { msg_debug("Correllation context lookup successful", evt_tag_str("rule", rule->rule_id), evt_tag_str("context", buffer->str), evt_tag_int("context_timeout", rule->context.timeout), evt_tag_int("context_expiration", timer_wheel_get_time(self->timer_wheel) + rule->context.timeout), evt_tag_int("num_messages", context->super.messages->len)); } g_ptr_array_add(context->super.messages, log_msg_ref(msg)); if (context->super.timer) { timer_wheel_mod_timer(self->timer_wheel, context->super.timer, rule->context.timeout); } else { context->super.timer = timer_wheel_add_timer(self->timer_wheel, rule->context.timeout, pattern_db_expire_entry, correllation_context_ref(&context->super), (GDestroyNotify) correllation_context_unref); } if (context->rule != rule) { if (context->rule) pdb_rule_unref(context->rule); context->rule = pdb_rule_ref(rule); } } else { context = NULL; } process_params->context = context; process_params->buffer = buffer; synthetic_message_apply(&rule->msg, &context->super, msg, buffer); _emit_message(self, process_params, FALSE, msg); _execute_rule_actions(self, process_params, RAT_MATCH); pdb_rule_unref(rule); g_static_rw_lock_writer_unlock(&self->lock); if (context) log_msg_write_protect(msg); g_string_free(buffer, TRUE); }