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);
    }
}
Beispiel #3
0
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);
}