static int inject_message_analysis(lua_State *lua) { luaL_checktype(lua, 1, LUA_TTABLE); lsb_lua_sandbox *lsb = lua_touserdata(lua, lua_upvalueindex(1)); if (NULL == lsb) { return luaL_error(lua, "%s() invalid lightuserdata", im_func_name); } lsb_heka_sandbox *hsb = lsb_get_parent(lsb); lua_pushstring(lua, hsb->name); lua_setfield(lua, 1, LSB_LOGGER); lua_pushstring(lua, hsb->hostname); lua_setfield(lua, 1, LSB_HOSTNAME); if (heka_encode_message_table(lsb, 1)) { return luaL_error(lua, "%s() failed: %s", im_func_name, lsb_get_error(lsb)); } size_t output_len = 0; const char *output = lsb_get_output(lsb, &output_len); if (hsb->cb.aim(hsb->parent, output, output_len) != 0) { return luaL_error(lua, "%s() failed: rejected by the callback", im_func_name); } ++hsb->stats.im_cnt; hsb->stats.im_bytes += output_len; return 0; }
int heka_encode_message(lua_State *lua) { int n = lua_gettop(lua); bool framed = false; switch (n) { case 2: luaL_checktype(lua, 2, LUA_TBOOLEAN); framed = lua_toboolean(lua, 2); // fall thru case 1: luaL_checktype(lua, 1, LUA_TTABLE); break; default: return luaL_argerror(lua, n, "incorrect number of arguments"); } lsb_lua_sandbox *lsb = lua_touserdata(lua, lua_upvalueindex(1)); if (!lsb) { return luaL_error(lua, "encode_message() invalid upvalueindex"); } lsb_heka_sandbox *hsb = lsb_get_parent(lsb); set_missing_headers(lua, 1, hsb); lsb->output.pos = 0; lsb_err_value ret = heka_encode_message_table(lsb, 1); if (ret) { const char *err = lsb_get_error(lsb); if (strlen(err) == 0) err = ret; return luaL_error(lua, "encode_message() failed: %s", err); } size_t len = 0; const char *output = lsb_get_output(lsb, &len); lsb->usage[LSB_UT_OUTPUT][LSB_US_CURRENT] = len; if (framed) { char header[14] = "\x1e\x00\x08"; // up to 10 varint bytes and a \x1f int hlen = lsb_pb_output_varint(header + 3, len) + 1; lsb->usage[LSB_UT_OUTPUT][LSB_US_CURRENT] = len + hlen + LSB_HDR_FRAME_SIZE; header[1] = (char)hlen; header[hlen + 2] = '\x1f'; luaL_Buffer b; luaL_buffinit(lua, &b); luaL_addlstring(&b, header, hlen + LSB_HDR_FRAME_SIZE); luaL_addlstring(&b, output, len); luaL_pushresult(&b); } else { lua_pushlstring(lua, output, len); } if (lsb->usage[LSB_UT_OUTPUT][LSB_US_CURRENT] > lsb->usage[LSB_UT_OUTPUT][LSB_US_MAXIMUM]) { lsb->usage[LSB_UT_OUTPUT][LSB_US_MAXIMUM] = lsb->usage[LSB_UT_OUTPUT][LSB_US_CURRENT]; } return 1; }
static int inject_payload(lua_State *lua) { static const char *default_type = "txt"; lsb_lua_sandbox *lsb = lua_touserdata(lua, lua_upvalueindex(1)); if (!lsb) { return luaL_error(lua, "%s invalid lightuserdata", __FUNCTION__); } int n = lua_gettop(lua); if (n > 2) { lsb_output(lsb, 3, n, 1); lua_pop(lua, n - 2); } size_t len = 0; const char *output = lsb_get_output(lsb, &len); if (!len) return 0; if (n > 0) { if (lua_type(lua, 1) != LUA_TSTRING) { return luaL_error(lua, "%s() payload_type argument must be a string", __FUNCTION__); } } if (n > 1) { if (lua_type(lua, 2) != LUA_TSTRING) { return luaL_error(lua, "%s() payload_name argument must be a string", __FUNCTION__); } } // build up a heka message table lua_createtable(lua, 0, 2); // message lua_createtable(lua, 0, 2); // Fields if (n > 0) { lua_pushvalue(lua, 1); } else { lua_pushstring(lua, default_type); } lua_setfield(lua, -2, "payload_type"); if (n > 1) { lua_pushvalue(lua, 2); lua_setfield(lua, -2, "payload_name"); } lua_setfield(lua, -2, LSB_FIELDS); lua_pushstring(lua, "inject_payload"); lua_setfield(lua, -2, LSB_TYPE); lua_pushlstring(lua, output, len); lua_setfield(lua, -2, LSB_PAYLOAD); if (lua_gettop(lua) > 1) lua_replace(lua, 1); inject_message_analysis(lua); return 0; }
static int inject_message(lua_State* L) { static unsigned char header[14]; void* luserdata = lua_touserdata(L, lua_upvalueindex(1)); if (NULL == luserdata) { return luaL_error(L, "inject_message() invalid lightuserdata"); } lua_sandbox* lsb = (lua_sandbox*)luserdata; hs_analysis_plugin* p = (hs_analysis_plugin*)lsb_get_parent(lsb); if (lua_type(L, 1) == LUA_TTABLE) { lua_pushstring(L, p->sb->name); lua_setfield(L, 1, "Logger"); lua_pushstring(L, p->at->plugins->cfg->hostname); lua_setfield(L, 1, "Hostname"); lua_pushinteger(L, p->at->plugins->cfg->pid); lua_setfield(L, 1, "Pid"); } if (lsb_output_protobuf(lsb, 1, 0) != 0) { return luaL_error(L, "inject_message() could not encode protobuf - %s", lsb_get_error(lsb)); } size_t output_len = 0; const char* output = lsb_get_output(lsb, &output_len); pthread_mutex_lock(&p->at->plugins->output.lock); int len = hs_write_varint(header + 3, output_len); int tlen = 4 + len + output_len; ++p->sb->stats.im_cnt; p->sb->stats.im_bytes += tlen; header[0] = 0x1e; header[1] = (char)(len + 1); header[2] = 0x08; header[3 + len] = 0x1f; fwrite(header, 4 + len, 1, p->at->plugins->output.fh); fwrite(output, output_len, 1, p->at->plugins->output.fh); p->at->plugins->output.offset += tlen; if (p->at->plugins->output.offset >= (size_t)p->at->plugins->cfg->output_size) { ++p->at->plugins->output.id; hs_open_output_file(&p->at->plugins->output); } pthread_mutex_unlock(&p->at->plugins->output.lock); return 0; }
int write_output(lua_State* lua) { static const char* default_type = "txt"; // static const char* default_name = ""; void* luserdata = lua_touserdata(lua, lua_upvalueindex(1)); if (NULL == luserdata) { luaL_error(lua, "write() invalid lightuserdata"); } lua_sandbox* lsb = (lua_sandbox*)luserdata; // void* ud = NULL; const char* type = default_type; // const char* name = default_name; switch (lua_gettop(lua)) { case 0: break; case 2: // name = luaL_checkstring(lua, 2); // fallthru case 1: switch (lua_type(lua, 1)) { case LUA_TSTRING: type = lua_tostring(lua, 1); if (strlen(type) == 0) type = default_type; break; case LUA_TTABLE: type = ""; if (lsb_output_protobuf(lsb, 1, 0) != 0) { luaL_error(lua, "write() cound not encode protobuf - %s", lsb_get_error(lsb)); } break; case LUA_TUSERDATA: type = lsb_output_userdata(lsb, 1, 0); break; default: luaL_typerror(lua, 1, "string, table, or circular_buffer"); break; } break; default: luaL_error(lua, "write() takes a maximum of 2 arguments"); break; } written_data = lsb_get_output(lsb, &written_data_len); return 0; }
static int inject_message_input(lua_State *lua) { lsb_lua_sandbox *lsb = lua_touserdata(lua, lua_upvalueindex(1)); if (NULL == lsb) { return luaL_error(lua, "%s() invalid lightuserdata", im_func_name); } const char *scp = NULL; double ncp = NAN; int t = lua_type(lua, 2); switch (t) { case LUA_TNUMBER: ncp = lua_tonumber(lua, 2); break; case LUA_TSTRING: scp = lua_tostring(lua, 2); break; case LUA_TNONE: case LUA_TNIL: break; default: return luaL_error(lua, "%s() unsupported checkpoint type: %s", im_func_name, lua_typename(lua, t)); } lsb_const_string output; t = lua_type(lua, 1); switch (t) { case LUA_TUSERDATA: { heka_stream_reader *hsr = luaL_checkudata(lua, 1, mozsvc_heka_stream_reader); if (hsr->msg.raw.s) { output.len = hsr->msg.raw.len; output.s = hsr->msg.raw.s; } else { return luaL_error(lua, "%s() attempted to inject a nil message", im_func_name); } } break; case LUA_TSTRING: { lsb_heka_message m; lsb_init_heka_message(&m, 8); output.s = lua_tolstring(lua, 1, &output.len); bool ok = lsb_decode_heka_message(&m, output.s, output.len, NULL); lsb_free_heka_message(&m); if (!ok) { return luaL_error(lua, "%s() attempted to inject a invalid protobuf " "string", im_func_name); } } break; case LUA_TTABLE: if (heka_encode_message_table(lsb, 1)) { const char *err = lsb_get_error(lsb); if (strlen(err) == 0) err = "exceeded output_limit"; return luaL_error(lua, "%s() failed: %s", im_func_name, err); } output.len = 0; output.s = lsb_get_output(lsb, &output.len); break; default: return luaL_error(lua, "%s() unsupported message type: %s", im_func_name, lua_typename(lua, t)); } lsb_heka_sandbox *hsb = lsb_get_parent(lsb); if (hsb->cb.iim(hsb->parent, output.s, output.len, ncp, scp) != 0) { return luaL_error(lua, "%s() failed: rejected by the callback", im_func_name); } ++hsb->stats.im_cnt; hsb->stats.im_bytes += output.len; return 0; }
static int inject_payload(lua_State* lua) { static const char* default_type = "txt"; static const char* func_name = "inject_payload"; void* luserdata = lua_touserdata(lua, lua_upvalueindex(1)); if (NULL == luserdata) { return luaL_error(lua, "%s invalid lightuserdata", func_name); } lua_sandbox* lsb = (lua_sandbox*)luserdata; int n = lua_gettop(lua); if (n > 2) { lsb_output(lsb, 3, n, 1); lua_pop(lua, n - 2); } size_t len = 0; const char* output = lsb_get_output(lsb, &len); if (!len) return 0; if (n > 0) { if (lua_type(lua, 1) != LUA_TSTRING) { return luaL_error(lua, "%s() payload_type argument must be a string", func_name); } } if (n > 1) { if (lua_type(lua, 2) != LUA_TSTRING) { return luaL_error(lua, "%s() payload_name argument must be a string", func_name); } } // build up a heka message table lua_createtable(lua, 0, 2); // message lua_createtable(lua, 0, 2); // Fields if (n > 0) { lua_pushvalue(lua, 1); } else { lua_pushstring(lua, default_type); } lua_setfield(lua, -2, "payload_type"); if (n > 1) { lua_pushvalue(lua, 2); lua_setfield(lua, -2, "payload_name"); } lua_setfield(lua, -2, "Fields"); lua_pushstring(lua, "inject_payload"); lua_setfield(lua, -2, "Type"); lua_pushlstring(lua, output, len); lua_setfield(lua, -2, "Payload"); lua_replace(lua, 1); // use inject_message to actually deliver it lua_getglobal(lua, "inject_message"); lua_CFunction fp = lua_tocfunction(lua, -1); lua_pop(lua, 1); // remove function pointer if (fp) { fp(lua); } else { return luaL_error(lua, "%s() failed to call inject_message", func_name); } return 0; }