You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2020/12/10 21:28:58 UTC

[couchdb-erlfdb] 01/01: Add metrics for tracking futures

This is an automated email from the ASF dual-hosted git repository.

davisp pushed a commit to branch add-stats
in repository https://gitbox.apache.org/repos/asf/couchdb-erlfdb.git

commit 187b585b0bc7c2bcc27fd875f3d59e54a9c028ac
Author: Paul J. Davis <da...@us.ibm.com>
AuthorDate: Thu Dec 10 13:14:22 2020 -0600

    Add metrics for tracking futures
---
 c_src/atom_names.h |  6 +++++
 c_src/main.c       | 38 +++++++++++++++++++++++++++-
 c_src/metrics.cc   | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c_src/metrics.h    | 28 +++++++++++++++++++++
 c_src/resources.c  |  3 +++
 rebar.config       |  4 +--
 src/erlfdb.erl     |  7 +++++-
 src/erlfdb_nif.erl |  8 +++++-
 8 files changed, 163 insertions(+), 5 deletions(-)

diff --git a/c_src/atom_names.h b/c_src/atom_names.h
index 98b5c4f..377df1f 100644
--- a/c_src/atom_names.h
+++ b/c_src/atom_names.h
@@ -143,3 +143,9 @@ ATOM_MAP(write);
 ATOM_MAP(retryable);
 ATOM_MAP(maybe_committed);
 ATOM_MAP(retryable_not_committed);
+
+// Metrics
+ATOM_MAP(futures_created);
+ATOM_MAP(futures_destroyed);
+ATOM_MAP(futures_fired);
+ATOM_MAP(futures_read);
\ No newline at end of file
diff --git a/c_src/main.c b/c_src/main.c
index b1db949..e7ac014 100644
--- a/c_src/main.c
+++ b/c_src/main.c
@@ -18,6 +18,7 @@
 #include "fdb.h"
 
 #include "atoms.h"
+#include "metrics.h"
 #include "resources.h"
 #include "util.h"
 
@@ -95,6 +96,8 @@ erlfdb_future_cb(FDBFuture* fdb_future, void* data)
 
     enif_release_resource(future);
 
+    erlfdb_future_fired();
+
     return;
 }
 
@@ -159,6 +162,8 @@ erlfdb_create_future(ErlNifEnv* env, FDBFuture* future, ErlFDBFutureType ftype)
     // thread has a reference. If its 1 then only
     // Erlang has a reference.
 
+    erlfdb_future_created();
+
     return T3(env, ATOM_erlfdb_future, ref, ret);
 }
 
@@ -173,6 +178,8 @@ erlfdb_future_get_void(ErlNifEnv* env, ErlFDBFuture* f)
         return erlfdb_erlang_error(env, err);
     }
 
+    erlfdb_future_read();
+
     return ATOM_ok;
 }
 
@@ -191,6 +198,8 @@ erlfdb_future_get_int64(ErlNifEnv* env, ErlFDBFuture* f)
 
     nif_res = fdb_res;
 
+    erlfdb_future_read();
+
     return enif_make_int64(env, nif_res);
 }
 
@@ -212,6 +221,8 @@ erlfdb_future_get_key(ErlNifEnv* env, ErlFDBFuture* f)
     buf = enif_make_new_binary(env, len, &ret);
     memcpy(buf, key, len);
 
+    erlfdb_future_read();
+
     return ret;
 }
 
@@ -238,6 +249,8 @@ erlfdb_future_get_value(ErlNifEnv* env, ErlFDBFuture* f)
     buf = enif_make_new_binary(env, len, &ret);
     memcpy(buf, val, len);
 
+    erlfdb_future_read();
+
     return ret;
 }
 
@@ -266,6 +279,8 @@ erlfdb_future_get_string_array(ErlNifEnv* env, ErlFDBFuture* f)
         ret = enif_make_list_cell(env, bin, ret);
     }
 
+    erlfdb_future_read();
+
     return ret;
 }
 
@@ -298,6 +313,8 @@ erlfdb_future_get_keyvalue_array(ErlNifEnv* env, ErlFDBFuture* f)
         ret = enif_make_list_cell(env, T2(env, key, val), ret);
     }
 
+    erlfdb_future_read();
+
     if(more) {
         return T3(env, ret, enif_make_int(env, count), ATOM_true);
     } else {
@@ -2145,6 +2162,23 @@ erlfdb_error_predicate(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
     }
 }
 
+static ERL_NIF_TERM
+erlfdb_get_metrics(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+    ERL_NIF_TERM metrics[4];
+
+    ERL_NIF_TERM created = enif_make_uint64(env, erlfdb_num_futures_created());
+    ERL_NIF_TERM destroyed = enif_make_uint64(env, erlfdb_num_futures_destroyed());
+    ERL_NIF_TERM fired = enif_make_uint64(env, erlfdb_num_futures_fired());
+    ERL_NIF_TERM read = enif_make_uint64(env, erlfdb_num_futures_read());
+
+    metrics[0] = T2(env, ATOM_futures_created, created);
+    metrics[1] = T2(env, ATOM_futures_destroyed, destroyed);
+    metrics[2] = T2(env, ATOM_futures_fired, fired);
+    metrics[3] = T2(env, ATOM_futures_read, read);
+
+    return enif_make_list_from_array(env, metrics, 4);
+}
 
 #define NIF_FUNC(name, arity) {#name, arity, name}
 static ErlNifFunc funcs[] =
@@ -2192,7 +2226,9 @@ static ErlNifFunc funcs[] =
     NIF_FUNC(erlfdb_transaction_get_writes_allowed, 1),
 
     NIF_FUNC(erlfdb_get_error, 1),
-    NIF_FUNC(erlfdb_error_predicate, 2)
+    NIF_FUNC(erlfdb_error_predicate, 2),
+
+    NIF_FUNC(erlfdb_get_metrics, 0)
 };
 #undef NIF_FUNC
 
diff --git a/c_src/metrics.cc b/c_src/metrics.cc
new file mode 100644
index 0000000..35f73b4
--- /dev/null
+++ b/c_src/metrics.cc
@@ -0,0 +1,74 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#include <atomic>
+
+#define BEGIN_C extern "C" {
+#define END_C }
+
+std::atomic<uint64_t> ERLFDB_FUTURES_CREATED{0};
+std::atomic<uint64_t> ERLFDB_FUTURES_DESTROYED{0};
+std::atomic<uint64_t> ERLFDB_FUTURES_FIRED{0};
+std::atomic<uint64_t> ERLFDB_FUTURES_READ{0};
+
+BEGIN_C
+
+
+void
+erlfdb_future_created()
+{
+    ERLFDB_FUTURES_CREATED++;
+}
+
+void
+erlfdb_future_destroyed()
+{
+    ERLFDB_FUTURES_DESTROYED++;
+}
+
+void
+erlfdb_future_fired()
+{
+    ERLFDB_FUTURES_FIRED++;
+}
+
+void
+erlfdb_future_read()
+{
+    ERLFDB_FUTURES_READ++;
+}
+
+uint64_t
+erlfdb_num_futures_created()
+{
+    return ERLFDB_FUTURES_CREATED;
+}
+
+uint64_t
+erlfdb_num_futures_destroyed()
+{
+    return ERLFDB_FUTURES_DESTROYED;
+}
+
+uint64_t
+erlfdb_num_futures_fired()
+{
+    return ERLFDB_FUTURES_FIRED;
+}
+
+uint64_t
+erlfdb_num_futures_read()
+{
+    return ERLFDB_FUTURES_READ;
+}
+
+END_C
\ No newline at end of file
diff --git a/c_src/metrics.h b/c_src/metrics.h
new file mode 100644
index 0000000..2a0e3f9
--- /dev/null
+++ b/c_src/metrics.h
@@ -0,0 +1,28 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#ifndef ERLFDB_METRICS_H
+#define ERLFDB_METRICS_H
+
+#include <stdint.h>
+
+void erlfdb_future_created();
+void erlfdb_future_destroyed();
+void erlfdb_future_fired();
+void erlfdb_future_read();
+
+uint64_t erlfdb_num_futures_created();
+uint64_t erlfdb_num_futures_destroyed();
+uint64_t erlfdb_num_futures_fired();
+uint64_t erlfdb_num_futures_read();
+
+#endif // Included metrics.h
diff --git a/c_src/resources.c b/c_src/resources.c
index 88f402a..9d2603d 100644
--- a/c_src/resources.c
+++ b/c_src/resources.c
@@ -10,6 +10,7 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
+#include "metrics.h"
 #include "resources.h"
 
 
@@ -74,6 +75,8 @@ erlfdb_future_dtor(ErlNifEnv* env, void* obj)
     if(f->msg_env != NULL) {
         enif_free_env(f->msg_env);
     }
+
+    erlfdb_future_destroyed();
 }
 
 
diff --git a/rebar.config b/rebar.config
index d72bc82..8276d3c 100644
--- a/rebar.config
+++ b/rebar.config
@@ -1,5 +1,5 @@
 {port_specs, [
-    {"priv/erlfdb_nif.so", ["c_src/*.c"]}
+    {"priv/erlfdb_nif.so", ["c_src/*.c", "c_src/*.cc"]}
 ]}.
 
 {plugins, [rebar_gdb_plugin]}.
@@ -8,7 +8,7 @@
     {"(linux|solaris|freebsd|netbsd|openbsd|dragonfly|darwin|gnu)",
         "CFLAGS", "$CFLAGS -Ic_src/ -g -Wall -Werror"},
     {"(linux|solaris|freebsd|netbsd|openbsd|dragonfly|darwin|gnu)",
-        "CXXFLAGS", "$CXXFLAGS -Ic_src/ -g -Wall -Werror"},
+        "CXXFLAGS", "$CXXFLAGS -Ic_src/ -g -Wall -Werror -std=c++14"},
 
     {"(linux|solaris|freebsd|netbsd|openbsd|dragonfly|darwin|gnu)",
         "LDFLAGS", "$LDFLAGS -lfdb_c"}
diff --git a/src/erlfdb.erl b/src/erlfdb.erl
index d2ddb1f..b04fea8 100644
--- a/src/erlfdb.erl
+++ b/src/erlfdb.erl
@@ -122,7 +122,8 @@
     on_error/2,
     error_predicate/2,
     get_last_error/0,
-    get_error_string/1
+    get_error_string/1,
+    get_metrics/0
 ]).
 
 
@@ -669,6 +670,10 @@ get_error_string(ErrorCode) when is_integer(ErrorCode) ->
     erlfdb_nif:get_error(ErrorCode).
 
 
+get_metrics() ->
+    erlfdb_nif:get_metrics().
+
+
 clear_erlfdb_error() ->
     put(?ERLFDB_ERROR, undefined).
 
diff --git a/src/erlfdb_nif.erl b/src/erlfdb_nif.erl
index 7ec8e52..e25cd01 100644
--- a/src/erlfdb_nif.erl
+++ b/src/erlfdb_nif.erl
@@ -57,7 +57,9 @@
     transaction_get_approximate_size/1,
 
     get_error/1,
-    error_predicate/2
+    error_predicate/2,
+
+    get_metrics/0
 ]).
 
 
@@ -449,6 +451,9 @@ get_error(Error) ->
 error_predicate(Predicate, Error) ->
     erlfdb_error_predicate(Predicate, Error).
 
+-spec get_metrics() -> [{atom(), non_neg_integer()}].
+get_metrics() ->
+    erlfdb_get_metrics().
 
 -spec option_val_to_binary(binary() | integer()) -> binary().
 option_val_to_binary(Val) when is_binary(Val) ->
@@ -595,3 +600,4 @@ erlfdb_transaction_get_approximate_size(_Transaction) -> ?NOT_LOADED.
 % Misc
 erlfdb_get_error(_Error) -> ?NOT_LOADED.
 erlfdb_error_predicate(_Predicate, _Error) -> ?NOT_LOADED.
+erlfdb_get_metrics() -> ?NOT_LOADED.