LogMessage * synthetic_message_generate_with_context(SyntheticMessage *self, CorrellationContext *context, GString *buffer) { LogMessage *genmsg; genmsg = _generate_default_message_from_context(self->inherit_mode, context); switch (context->key.scope) { case RCS_PROCESS: log_msg_set_value(genmsg, LM_V_PID, context->key.pid, -1); case RCS_PROGRAM: log_msg_set_value(genmsg, LM_V_PROGRAM, context->key.program, -1); case RCS_HOST: log_msg_set_value(genmsg, LM_V_HOST, context->key.host, -1); case RCS_GLOBAL: break; default: g_assert_not_reached(); break; } g_ptr_array_add(context->messages, genmsg); synthetic_message_apply(self, context, genmsg, buffer); g_ptr_array_remove_index_fast(context->messages, context->messages->len - 1); return genmsg; }
LogMessage * synthetic_message_generate_without_context(SyntheticMessage *self, LogMessage *msg, GString *buffer) { LogMessage *genmsg; genmsg = _generate_default_message(self->inherit_mode, msg); /* no context, which means no correllation. The action * rule contains the generated message at @0 and the one * which triggered the rule in @1. * * We emulate a context having only these two * messages, but without allocating a full-blown * structure. */ LogMessage *dummy_msgs[] = { msg, genmsg, NULL }; GPtrArray dummy_ptr_array = { .pdata = (void **) dummy_msgs, .len = 2 }; CorrellationContext dummy_context = { .messages = &dummy_ptr_array, 0 }; synthetic_message_apply(self, &dummy_context, genmsg, buffer); return genmsg; } void synthetic_message_init(SyntheticMessage *self) { memset(self, 0, sizeof(*self)); } void synthetic_message_deinit(SyntheticMessage *self) { gint i; if (self->tags) g_array_free(self->tags, TRUE); if (self->values) { for (i = 0; i < self->values->len; i++) log_template_unref(g_ptr_array_index(self->values, i)); g_ptr_array_free(self->values, TRUE); } }
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); }