Hi -
>From 0b61f4c758a507fcc2243357363e44140bd13d82 Mon Sep 17 00:00:00 2001 ?!??!!
From: "Frank Ch. Eigler" <f...@redhat.com>
Date: Mon, 23 Nov 2020 19:58:10 -0500
Subject: [PATCH] debuginfod: sqlite3 metrics
Add metrics for tracking sqlite3 error counts and query performance.
The former looks like a new sibling of the "error_count" family, and
is tested by dd-corrupting a live database file then triggering some
debuginfod activity.
error_count{sqlite3="file is not a database"} 1
The latter looks like _count/_sum pairs for each type of sqlite
prepared-statement used in the code, and is grep smoke-tested. They
should assist a sysadmin in tuning db storage. This example shows a
6.4 ms/operation cost:
sqlite3_milliseconds_count{step-done="rpm-file-intern"} 318
sqlite3_milliseconds_sum{reset="rpm-file-intern"} 2033
Signed-off-by: Frank Ch. Eigler <f...@redhat.com>
---
debuginfod/ChangeLog | 6 ++++++
debuginfod/debuginfod.cxx | 31 ++++++++++++++++++++++++++++---
tests/ChangeLog | 4 ++++
tests/run-debuginfod-find.sh | 16 ++++++++++++++++
4 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/debuginfod/ChangeLog b/debuginfod/ChangeLog
index bd4dbf403f30..a81e3781986d 100644
--- a/debuginfod/ChangeLog
+++ b/debuginfod/ChangeLog
@@ -1,3 +1,9 @@
+2020-11-23 Frank Ch. Eigler <f...@redhat.com>
+
+ * debuginfod.cxx (tmp_ms_metric): New class for RAII timing metrics.
+ (sqlite_ps::reset, step*): Call it to track sqlite3 performance.
+ (sqlite_exception ctor): Increment sqlite3 error_count.
+
2020-11-11 Mark Wielaard <m...@klomp.org>
* debuginfod-client.c (debuginfod_set_verbose_fd): New function.
diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index 61c778b10893..618620b4c478 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -435,6 +435,27 @@ class tmp_inc_metric { // a RAII style wrapper for
exception-safe scoped increme
}
};
+class tmp_ms_metric { // a RAII style wrapper for exception-safe scoped timing
+ string m, n, v;
+ struct timeval tv_start;
+public:
+ tmp_ms_metric(const string& mname, const string& lname, const string&
lvalue):
+ m(mname), n(lname), v(lvalue)
+ {
+ gettimeofday (& tv_start, NULL);
+ }
+ ~tmp_ms_metric()
+ {
+ struct timeval tv_end;
+ gettimeofday (& tv_end, NULL);
+ double deltas = (tv_end.tv_sec - tv_start.tv_sec)
+ + (tv_end.tv_usec - tv_start.tv_usec)*0.000001;
+
+ add_metric (m + "_milliseconds_sum", n, v, (deltas*1000));
+ inc_metric (m + "_milliseconds_count", n, v);
+ }
+};
+
/* Handle program arguments. */
static error_t
@@ -559,7 +580,9 @@ struct reportable_exception
struct sqlite_exception: public reportable_exception
{
sqlite_exception(int rc, const string& msg):
- reportable_exception(string("sqlite3 error: ") + msg + ": " +
string(sqlite3_errstr(rc) ?: "?")) {}
+ reportable_exception(string("sqlite3 error: ") + msg + ": " +
string(sqlite3_errstr(rc) ?: "?")) {
+ inc_metric("error_count","sqlite3",sqlite3_errstr(rc));
+ }
};
struct libc_exception: public reportable_exception
@@ -755,6 +778,7 @@ struct sqlite_ps
public:
sqlite_ps (sqlite3* d, const string& n, const string& s): db(d),
nickname(n), sql(s) {
+ // tmp_ms_metric tick("sqlite3","prep",nickname);
if (verbose > 4)
obatched(clog) << nickname << " prep " << sql << endl;
int rc = sqlite3_prepare_v2 (db, sql.c_str(), -1 /* to \0 */, & this->pp,
NULL);
@@ -764,6 +788,7 @@ struct sqlite_ps
sqlite_ps& reset()
{
+ tmp_ms_metric tick("sqlite3","reset",nickname);
sqlite3_reset(this->pp);
return *this;
}
@@ -800,6 +825,7 @@ struct sqlite_ps
void step_ok_done() {
+ tmp_ms_metric tick("sqlite3","step-done",nickname);
int rc = sqlite3_step (this->pp);
if (verbose > 4)
obatched(clog) << nickname << " step-ok-done(" << sqlite3_errstr(rc) <<
") " << sql << endl;
@@ -810,14 +836,13 @@ struct sqlite_ps
int step() {
+ tmp_ms_metric tick("sqlite3","step",nickname);
int rc = sqlite3_step (this->pp);
if (verbose > 4)
obatched(clog) << nickname << " step(" << sqlite3_errstr(rc) << ") " <<
sql << endl;
return rc;
}
-
-
~sqlite_ps () { sqlite3_finalize (this->pp); }
operator sqlite3_stmt* () { return this->pp; }
};
diff --git a/tests/ChangeLog b/tests/ChangeLog
index c130ce049caa..f5adc315ae38 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,7 @@
+2020-11-23 Frank Ch. Eigler <f...@redhat.com>
+
+ * run-debuginfod-find.sh: Add sqlite error injection & stats.
+
2020-11-02 Mark Wielaard <m...@klomp.org>
* run-debuginfod-find.sh: Create bogus R/nothing.rpm with cyclic
diff --git a/tests/run-debuginfod-find.sh b/tests/run-debuginfod-find.sh
index 28aa4263c500..7fd3420ab20a 100755
--- a/tests/run-debuginfod-find.sh
+++ b/tests/run-debuginfod-find.sh
@@ -490,6 +490,22 @@ curl -s http://127.0.0.1:$PORT2/badapi > /dev/null || true
curl -s http://127.0.0.1:$PORT2/buildid/deadbeef/debuginfo > /dev/null || true
+########################################################################
+# Corrupt the sqlite database and get debuginfod to trip across its errors
+curl -s http://127.0.0.1:$PORT1/metrics | grep 'sqlite3.*reset'
+ls -al $DB
+dd if=/dev/zero of=$DB bs=1 count=1
+ls -al $DB
+# trigger some random activity that's Sure to get sqlite3 upset
+kill -USR1 $PID1
+wait_ready $PORT1 'thread_work_total{role="traverse"}' 9
+wait_ready $PORT1 'thread_work_pending{role="scan"}' 0
+wait_ready $PORT1 'thread_busy{role="scan"}' 0
+kill -USR2 $PID1
+wait_ready $PORT1 'thread_work_total{role="groom"}' 4
+curl -s http://127.0.0.1:$PORT1/buildid/beefbeefbeefd00dd00d/debuginfo >
/dev/null || true
+curl -s http://127.0.0.1:$PORT1/metrics | grep 'error_count.*sqlite'
+
########################################################################
# Run the tests again without the servers running. The target file should
--
2.28.0