Example #1
0
int lsb_heka_timer_event(lsb_heka_sandbox *hsb, time_t t, bool shutdown)
{
  static const char *func_name = "timer_event";

  if (!hsb || (hsb->type != 'o' && hsb->type != 'a')) {
    return 1;
  }

  lua_State *lua = lsb_get_lua(hsb->lsb);
  if (!lua) return 1;

  if (lsb_pcall_setup(hsb->lsb, func_name)) {
    char err[LSB_ERROR_SIZE];
    snprintf(err, LSB_ERROR_SIZE, "%s() function was not found", func_name);
    lsb_terminate(hsb->lsb, err);
    return 1;
  }
  // todo change if we need more than 1 sec resolution
  lua_pushnumber(lua, t * 1e9);
  lua_pushboolean(lua, shutdown);

  unsigned long long start, end;
  start = lsb_get_time();
  if (lua_pcall(lua, 2, 0, 0) != 0) {
    char err[LSB_ERROR_SIZE];
    size_t len = snprintf(err, LSB_ERROR_SIZE, "%s() %s", func_name,
                          lua_tostring(lua, -1));
    if (len >= LSB_ERROR_SIZE) {
      err[LSB_ERROR_SIZE - 1] = 0;
    }
    lsb_terminate(hsb->lsb, err);
    return 1;
  }
  end = lsb_get_time();
  lsb_update_running_stats(&hsb->stats.te, (double)(end - start));
  lsb_pcall_teardown(hsb->lsb);
  lua_gc(lua, LUA_GCCOLLECT, 0);
  return 0;
}
Example #2
0
static int process_message(lsb_heka_sandbox *hsb, lsb_heka_message *msg,
                           lua_State *lua, int nargs, bool profile)
{
  unsigned long long start, end;

  hsb->msg = msg;
  if (profile) {
    start = lsb_get_time();
  }
  if (lua_pcall(lua, nargs, 2, 0) != 0) {
    char err[LSB_ERROR_SIZE];
    const char *em = lua_tostring(lua, -1);
    if (hsb->type == 'i' && strcmp(em, LSB_SHUTTING_DOWN) == 0) {
      return 0;
    }
    size_t len = snprintf(err, LSB_ERROR_SIZE, "%s() %s", pm_func_name, em);
    if (len >= LSB_ERROR_SIZE) {
      err[LSB_ERROR_SIZE - 1] = 0;
    }
    lsb_terminate(hsb->lsb, err);
    return 1;
  }
  if (profile) {
    end = lsb_get_time();
    lsb_update_running_stats(&hsb->stats.pm, (double)(end - start));
  }
  hsb->msg = NULL;

  if (lua_type(lua, 1) != LUA_TNUMBER) {
    char err[LSB_ERROR_SIZE];
    size_t len = snprintf(err, LSB_ERROR_SIZE,
                          "%s() must return a numeric status code",
                          pm_func_name);
    if (len >= LSB_ERROR_SIZE) {
      err[LSB_ERROR_SIZE - 1] = 0;
    }
    lsb_terminate(hsb->lsb, err);
    return 1;
  }

  int status = (int)lua_tointeger(lua, 1);
  switch (lua_type(lua, 2)) {
  case LUA_TNIL:
    lsb_set_error(hsb->lsb, NULL);
    break;
  case LUA_TSTRING:
    lsb_set_error(hsb->lsb, lua_tostring(lua, 2));
    break;
  default:
    {
      char err[LSB_ERROR_SIZE];
      int len = snprintf(err, LSB_ERROR_SIZE,
                         "%s() must return a nil or string error message",
                         pm_func_name);
      if (len >= LSB_ERROR_SIZE || len < 0) {
        err[LSB_ERROR_SIZE - 1] = 0;
      }
      lsb_terminate(hsb->lsb, err);
      return 1;
    }
    break;
  }
  lua_pop(lua, 2);
  lsb_pcall_teardown(hsb->lsb);

  if (status > 0) {
    char err[LSB_ERROR_SIZE];
    size_t len = snprintf(err, LSB_ERROR_SIZE,
                          "%s() received a termination status code",
                          pm_func_name);
    if (len >= LSB_ERROR_SIZE) {
      err[LSB_ERROR_SIZE - 1] = 0;
    }
    lsb_terminate(hsb->lsb, err);
    return 1;
  } else if (status == LSB_HEKA_PM_FAIL) {
    ++hsb->stats.pm_cnt;
    ++hsb->stats.pm_failures;
  } else  if (hsb->type != 'o' || status != LSB_HEKA_PM_RETRY) {
    ++hsb->stats.pm_cnt;
  }
  return status;
}
Example #3
0
static int output_message(hs_output_plugin *p, lsb_heka_message *msg)
{
  int ret = 0, te_ret = 0;
  bool sample = p->sample;
  time_t current_t = time(NULL);
  unsigned long long start;

  if (msg->raw.s) { // non idle/empty message
    unsigned long long mmdelta = 0;
    if (sample) start = lsb_get_time();
    bool matched = lsb_eval_message_matcher(p->mm, msg);
    if (sample) {
      mmdelta = lsb_get_time() - start;
    }
    if (matched) {
      if (p->async_len) {
        int i = p->sequence_id % p->async_len;
        p->async_cp[i].input.id = p->cur.input.id;
        p->async_cp[i].input.offset = p->cur.input.offset;
        p->async_cp[i].analysis.id = p->cur.analysis.id;
        p->async_cp[i].analysis.offset = p->cur.analysis.offset;
      }
      ret = lsb_heka_pm_output(p->hsb, msg, (void *)p->sequence_id,
                               sample);
      if (ret <= 0) {
        if (ret == LSB_HEKA_PM_SENT) {
          p->batching = false;
        } else if (ret == LSB_HEKA_PM_BATCH) {
          p->batching = true;
        } else if (ret == LSB_HEKA_PM_SENT && !p->async_len) {
          lsb_heka_terminate_sandbox(p->hsb,  "cannot use async checkpointing "
                                     "without a configured buffer");
          ret = 1;
        } else if (ret == LSB_HEKA_PM_FAIL) {
          const char *err = lsb_heka_get_error(p->hsb);
          if (strlen(err) > 0) {
            hs_log(NULL, p->name, 4, "process_message returned: %d %s", ret,
                   err);
          }
        }
        if (ret != LSB_HEKA_PM_RETRY) ++p->sequence_id;
      }
    }

    // advance the checkpoint if not batching/async
    if (ret <= 0 && !p->batching) {
      update_checkpoint(p);
    }

    if (mmdelta) {
      pthread_mutex_lock(&p->cp_lock);
      lsb_update_running_stats(&p->mms, mmdelta);
      p->sample = false;
      pthread_mutex_unlock(&p->cp_lock);
    }
  }

  if (ret <= 0 && p->ticker_interval
      && current_t >= p->ticker_expires) {
    te_ret = lsb_heka_timer_event(p->hsb, current_t, false);
    p->ticker_expires = current_t + p->ticker_interval;
  }

  if (ret > 0 || te_ret > 0) {
    hs_log(NULL, p->name, 3, "terminated: %s", lsb_heka_get_error(p->hsb));
    return 1;
  }
  return ret;
}