diff --git a/src/box/box.cc b/src/box/box.cc index 3288794d3738458581e006cb88cebbd722835667..56421e23992f5d48f16d53b7270d39f1cabeb305 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -583,6 +583,7 @@ box_free(void) tuple_free(); port_free(); engine_shutdown(); + rmean_delete(rmean_error); rmean_delete(rmean_box); } } @@ -616,6 +617,7 @@ box_init(void) cfg_getd("slab_alloc_factor")); rmean_box = rmean_new(iproto_type_strs, IPROTO_TYPE_STAT_MAX); + rmean_error = rmean_new(rmean_error_strings, RMEAN_ERROR_LAST); engine_init(); diff --git a/src/box/error.cc b/src/box/error.cc index 789ffc6f6287941fb7fbb7e0d06b9f9180d14e6f..ce13f90c757ef42b1e771827572fdd577511f3f1 100644 --- a/src/box/error.cc +++ b/src/box/error.cc @@ -32,6 +32,11 @@ #include <stdio.h> #include <fiber.h> +struct rmean *rmean_error = NULL; + +const char *rmean_error_strings[RMEAN_ERROR_LAST] = { + "EXCEPTION" +}; static struct method clienterror_methods[] = { make_method(&type_ClientError, "code", &ClientError::errcode), @@ -49,6 +54,8 @@ ClientError::ClientError(const char *file, unsigned line, va_start(ap, errcode); vsnprintf(m_errmsg, sizeof(m_errmsg), tnt_errcode_desc(m_errcode), ap); + if (rmean_error) + rmean_collect(rmean_error, RMEAN_ERROR_EXCEPTION, 1); va_end(ap); } @@ -59,6 +66,8 @@ ClientError::ClientError(const char *file, unsigned line, const char *msg, m_errcode = errcode; strncpy(m_errmsg, msg, sizeof(m_errmsg) - 1); m_errmsg[sizeof(m_errmsg) - 1] = 0; + if (rmean_error) + rmean_collect(rmean_error, RMEAN_ERROR_EXCEPTION, 1); } void diff --git a/src/box/error.h b/src/box/error.h index 1e3deab61be4ee4e725fff40a113ef180a165c5b..21146815ec3134b9ed690d7264243a5009c2bb2b 100644 --- a/src/box/error.h +++ b/src/box/error.h @@ -32,6 +32,17 @@ */ #include "errcode.h" #include "exception.h" +#include "rmean.h" + +extern struct rmean *rmean_error; + +enum rmean_error_name { + RMEAN_ERROR_EXCEPTION, + + RMEAN_ERROR_LAST +}; +extern const char *rmean_error_strings[RMEAN_ERROR_LAST]; + extern const struct type type_ClientError; class ClientError: public Exception { diff --git a/src/box/index.cc b/src/box/index.cc index 8d52481c73aa7f028169348242a90686c0299cac..7b5e31456bd15b14e401f86b9960d8280e544d5e 100644 --- a/src/box/index.cc +++ b/src/box/index.cc @@ -34,6 +34,8 @@ #include "schema.h" #include "user_def.h" #include "space.h" +#include "iproto_constants.h" +#include "request.h" const char *iterator_type_strs[] = { /* [ITER_EQ] = */ "EQ", @@ -305,6 +307,9 @@ box_index_get(uint32_t space_id, uint32_t index_id, const char *key, uint32_t part_count = key ? mp_decode_array(&key) : 0; primary_key_validate(index->key_def, key, part_count); struct tuple *tuple = index->findByKey(key, part_count); + /* Count statistics */ + rmean_collect(rmean_box, IPROTO_SELECT, 1); + *result = tuple_bless_null(tuple); return 0; } catch (Exception *) { diff --git a/src/box/iproto.cc b/src/box/iproto.cc index e9612def32056bf02c4943fb3a82270ef634c355..1c422f9a8c4804368beae39b7e1ae8c3a36c131c 100644 --- a/src/box/iproto.cc +++ b/src/box/iproto.cc @@ -55,13 +55,6 @@ /* {{{ iproto_msg - declaration */ -const char *rmean_net_names[RMEAN_NET_LAST] = { - "EVENTS", - "LOCKS", - "RECEIVED", - "SENT" -}; - /** * A single msg from io thread. All requests @@ -865,8 +858,7 @@ net_cord_f(va_list /* ap */) /* Init statistics counter */ - rmean_net = rmean_new(rmean_net_names, RMEAN_NET_LAST); - rmean_cbus_is_count = true; + rmean_net = rmean_new(rmean_net_strings, RMEAN_NET_LAST); if (rmean_net == NULL) tnt_raise(OutOfMemory, @@ -884,7 +876,6 @@ net_cord_f(va_list /* ap */) */ fiber_yield(); - rmean_cbus_is_count = false; rmean_delete(rmean_net); } diff --git a/src/box/lua/stat.cc b/src/box/lua/stat.cc index add58243f19ad5768f2f9cb321d16a0c06e90bf2..efdc1d3121de07c0fda45aa7239361c53ad7187b 100644 --- a/src/box/lua/stat.cc +++ b/src/box/lua/stat.cc @@ -35,6 +35,7 @@ #include <rmean.h> #include <box/request.h> #include <cbus.h> +#include <box/error.h> extern "C" { #include <lua.h> @@ -92,7 +93,10 @@ static int lbox_stat_index(struct lua_State *L) { luaL_checkstring(L, -1); - return rmean_foreach(rmean_box, seek_stat_item, L); + int res = rmean_foreach(rmean_box, seek_stat_item, L); + if (res) + return res; + return rmean_foreach(rmean_error, seek_stat_item, L); } static int @@ -100,6 +104,7 @@ lbox_stat_call(struct lua_State *L) { lua_newtable(L); rmean_foreach(rmean_box, set_stat_item, L); + rmean_foreach(rmean_error, set_stat_item, L); return 1; } diff --git a/src/cbus.cc b/src/cbus.cc index b6267905d42167662357b2546b0fd3e973164434..abfb6c2bccddd9ea01e0f18393afbff34fc53026 100644 --- a/src/cbus.cc +++ b/src/cbus.cc @@ -31,9 +31,15 @@ #include "cbus.h" #include "scoped_guard.h" -struct rmean *rmean_net; +struct rmean *rmean_net = NULL; +const char *rmean_net_strings[RMEAN_NET_LAST] = { + "EVENTS", + "LOCKS", + "RECEIVED", + "SENT" +}; + -bool rmean_cbus_is_count = 0; static void cbus_flush_cb(ev_loop * /* loop */, struct ev_async *watcher, @@ -191,7 +197,7 @@ cbus_flush_cb(ev_loop * /* loop */, struct ev_async *watcher, pipe->n_input = 0; if (pipe_was_empty) { /* Count statistics */ - if (rmean_cbus_is_count) + if (rmean_net) rmean_collect(rmean_net, RMEAN_NET_EVENTS, 1); ev_async_send(pipe->consumer, &pipe->fetch_output); @@ -223,7 +229,7 @@ cpipe_peek_impl(struct cpipe *pipe) if (peer_pipe_was_empty) { /* Count statistics */ - if (rmean_cbus_is_count) + if (rmean_net) rmean_collect(rmean_net, RMEAN_NET_EVENTS, 1); ev_async_send(peer->consumer, &peer->fetch_output); diff --git a/src/cbus.h b/src/cbus.h index 650d54dd6dd900133cfd6ac6fc786178395c821b..3b717d369950e79ea007dd7211e3a98b420ab343 100644 --- a/src/cbus.h +++ b/src/cbus.h @@ -42,7 +42,6 @@ typedef void (*cmsg_f)(struct cmsg *); /** rmean_net - network statistics (iproto & cbus) */ extern struct rmean *rmean_net; -extern bool rmean_cbus_is_count; enum rmean_net_name { RMEAN_NET_EVENTS, @@ -53,6 +52,8 @@ enum rmean_net_name { RMEAN_NET_LAST }; +extern const char *rmean_net_strings[RMEAN_NET_LAST]; + /** * One hop in a message travel route. A message may need to be * delivered to many destinations before it can be dispensed with. @@ -379,7 +380,7 @@ static inline void cbus_lock(struct cbus *bus) { /* Count statistics */ - if (rmean_cbus_is_count) + if (rmean_net) rmean_collect(rmean_net, RMEAN_NET_LOCKS, 1); tt_pthread_mutex_lock(&bus->mutex); diff --git a/src/rmean.h b/src/rmean.h index 5b980b620c06d03694ef658ca9a5b4de54203275..b6dd5848a933aa40a14abf8775a19ffcd094a037 100644 --- a/src/rmean.h +++ b/src/rmean.h @@ -39,6 +39,7 @@ #define PERF_SECS 5 + struct stats { const char *name; int64_t value[PERF_SECS + 1]; diff --git a/test/box/misc.result b/test/box/misc.result index 24a3d4705eb3004b0849050db3f0f2dbce7285fb..900b2c89de038e932b8f867a4fce5bc1c3c78239 100644 --- a/test/box/misc.result +++ b/test/box/misc.result @@ -142,6 +142,7 @@ t; - SELECT - INSERT - EVAL + - EXCEPTION - CALL - REPLACE - UPSERT diff --git a/test/box/stat.result b/test/box/stat.result index f497bce2950ac9ed7361cea9924209f0c141f798..4d706748eac7dacf54a9ddc20d5953163028adb4 100644 --- a/test/box/stat.result +++ b/test/box/stat.result @@ -21,6 +21,10 @@ box.stat.SELECT.total --- - 0 ... +box.stat.EXCEPTION.total +--- +- 0 +... space = box.schema.space.create('tweedledum') --- ... @@ -50,6 +54,15 @@ box.stat.REPLACE.total ... box.stat.SELECT.total --- +- 2 +... +-- check exceptions +space:get('Impossible value') +--- +- error: 'Supplied key type of part 0 does not match index part type: expected NUM' +... +box.stat.EXCEPTION.total +--- - 1 ... --# stop server default @@ -75,6 +88,10 @@ box.stat.SELECT.total --- - 0 ... +box.stat.EXCEPTION.total +--- +- 0 +... -- cleanup box.space.tweedledum:drop() --- diff --git a/test/box/stat.test.lua b/test/box/stat.test.lua index 5ff384a4d19608c9320d71fc863e4dd644691b95..834c06b18c9796c6f4505ce572b19e45eeeadc47 100644 --- a/test/box/stat.test.lua +++ b/test/box/stat.test.lua @@ -6,6 +6,7 @@ box.stat.DELETE.total box.stat.UPDATE.total box.stat.REPLACE.total box.stat.SELECT.total +box.stat.EXCEPTION.total space = box.schema.space.create('tweedledum') index = space:create_index('primary', { type = 'hash' }) @@ -19,6 +20,10 @@ box.stat.UPDATE.total box.stat.REPLACE.total box.stat.SELECT.total +-- check exceptions +space:get('Impossible value') +box.stat.EXCEPTION.total + --# stop server default --# start server default @@ -28,6 +33,7 @@ box.stat.DELETE.total box.stat.UPDATE.total box.stat.REPLACE.total box.stat.SELECT.total +box.stat.EXCEPTION.total -- cleanup box.space.tweedledum:drop() diff --git a/test/box/stat_net.result b/test/box/stat_net.result index 5b5866c738b198fb5888340d4b52c819b380e013..fa3ca518dc1e1bcc7e60df7182aead09184c664e 100644 --- a/test/box/stat_net.result +++ b/test/box/stat_net.result @@ -1,3 +1,6 @@ +-- clear statistics +--# stop server default +--# start server default box.stat.net.SENT -- zero --- - total: 0 diff --git a/test/box/stat_net.test.lua b/test/box/stat_net.test.lua index 87049db69cd96262e974e0d2f1830d3672337c1a..62eaf09ecf3425de172711d5671be0ef5680f751 100644 --- a/test/box/stat_net.test.lua +++ b/test/box/stat_net.test.lua @@ -1,3 +1,6 @@ +-- clear statistics +--# stop server default +--# start server default box.stat.net.SENT -- zero box.stat.net.RECEIVED -- zero diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 384fc7674ffa4fd93e752fe4cbf54a9ecb3bce75..c86a062ad7d52fce7758d5b0d33995a342e1032e 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -60,7 +60,8 @@ target_link_libraries(light.test small) add_executable(vclock.test vclock.cc unit.c ${CMAKE_SOURCE_DIR}/src/box/vclock.c ${CMAKE_SOURCE_DIR}/src/box/errcode.c - ${CMAKE_SOURCE_DIR}/src/box/error.cc) + ${CMAKE_SOURCE_DIR}/src/box/error.cc + ${CMAKE_SOURCE_DIR}/src/rmean.cc) target_link_libraries(vclock.test core small) add_executable(quota.test quota.cc unit.c) target_link_libraries(quota.test pthread)