static void _execute_action_create_context(PatternDB *db, PDBProcessParams *process_params) { CorrellationKey key; PDBAction *action = process_params->action; PDBRule *rule = process_params->rule; PDBContext *triggering_context = process_params->context; LogMessage *triggering_msg = process_params->msg; GString *buffer = process_params->buffer; PDBContext *new_context; LogMessage *context_msg; SyntheticContext *syn_context; SyntheticMessage *syn_message; syn_context = &action->content.create_context.context; syn_message = &action->content.create_context.message; if (triggering_context) { context_msg = synthetic_message_generate_with_context(syn_message, &triggering_context->super, buffer); log_template_format_with_context(syn_context->id_template, (LogMessage **) triggering_context->super.messages->pdata, triggering_context->super.messages->len, NULL, LTZ_LOCAL, 0, NULL, buffer); } else { context_msg = synthetic_message_generate_without_context(syn_message, triggering_msg, buffer); log_template_format(syn_context->id_template, triggering_msg, NULL, LTZ_LOCAL, 0, NULL, buffer); } msg_debug("Explicit create-context action, starting a new context", evt_tag_str("rule", rule->rule_id), evt_tag_str("context", buffer->str), evt_tag_int("context_timeout", syn_context->timeout), evt_tag_int("context_expiration", timer_wheel_get_time(db->timer_wheel) + syn_context->timeout)); correllation_key_setup(&key, syn_context->scope, context_msg, buffer->str); new_context = pdb_context_new(&key); g_hash_table_insert(db->correllation.state, &new_context->super.key, new_context); g_string_steal(buffer); g_ptr_array_add(new_context->super.messages, context_msg); new_context->super.timer = timer_wheel_add_timer(db->timer_wheel, rule->context.timeout, pattern_db_expire_entry, correllation_context_ref(&new_context->super), (GDestroyNotify) correllation_context_unref); new_context->rule = pdb_rule_ref(rule); }
void test_wheel(gint seed) { TimerWheel *wheel; gint i; guint64 latest = 0; gint expected_callbacks; prev_now = 0; num_callbacks = 0; expected_callbacks = 0; srand(seed); wheel = timer_wheel_new(); _test_assoc_data(wheel); timer_wheel_set_time(wheel, 1); for (i = 0; i < NUM_TIMERS; i++) { guint64 expires; TWEntry *timer1, *timer2, *timer3; gint r; expires = rand() & ((1 << 24) - 1); if (expires <= 1) expires = 1; if (expires > latest) latest = expires; timer1 = timer_wheel_add_timer(wheel, expires - 1, timer_callback, g_memdup(&expires, sizeof(expires)), (GDestroyNotify) g_free); timer2 = timer_wheel_add_timer(wheel, expires - 1, timer_callback, g_memdup(&expires, sizeof(expires)), (GDestroyNotify) g_free); timer3 = timer_wheel_add_timer(wheel, expires - 1, timer_callback, g_memdup(&expires, sizeof(expires)), (GDestroyNotify) g_free); expected_callbacks += 3; r = rand() & 0xFF; if (r < 64) { /* delete the timer with 25% chance */ timer_wheel_del_timer(wheel, timer1); expected_callbacks--; } else if (r < 128) { /* delete the timer with 25% chance */ timer_wheel_del_timer(wheel, timer2); expected_callbacks--; } else if (r < 192) { /* delete the timer with 25% chance */ timer_wheel_del_timer(wheel, timer3); expected_callbacks--; } } timer_wheel_set_time(wheel, latest + 1); if (num_callbacks != expected_callbacks) { fprintf(stderr, "Error: not enough callbacks received, " "num_callbacks=%d, expected=%d\n", num_callbacks, expected_callbacks); exit(1); } timer_wheel_free(wheel); }
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); }