Permalink
Browse files

Record select/update/insert/delete query stats for mysql and postgres

  • Loading branch information...
1 parent 46f0c29 commit 916aa01401b3c61ead1008f86382ebbc4963dd69 @tmm1 tmm1 committed Jan 30, 2011
Showing with 124 additions and 0 deletions.
  1. +31 −0 ext/tracers/mysql.c
  2. +19 −0 ext/tracers/postgres.c
  3. +56 −0 ext/tracers/sql.c
  4. +18 −0 ext/tracers/sql.h
View
@@ -9,12 +9,16 @@
#include "bin_api.h"
#include "json.h"
#include "tracer.h"
+#include "tracers/sql.h"
#include "tramp.h"
#include "util.h"
struct memprof_mysql_stats {
size_t query_calls;
uint32_t query_time;
+
+ size_t query_calls_by_type[sql_UNKNOWN];
+ uint32_t query_time_by_type[sql_UNKNOWN];
};
static struct tracer tracer;
@@ -25,6 +29,7 @@ static int (*orig_send_query)(void *mysql, const char *stmt_str, unsigned long l
static int
real_query_tramp(void *mysql, const char *stmt_str, unsigned long length) {
+ enum memprof_sql_type type;
uint32_t millis = 0;
int ret;
@@ -35,16 +40,24 @@ real_query_tramp(void *mysql, const char *stmt_str, unsigned long length) {
stats.query_time += millis;
stats.query_calls++;
+ type = memprof_sql_query_type(stmt_str, length);
+ stats.query_time_by_type[type] += millis;
+ stats.query_calls_by_type[type]++;
+
return ret;
}
static int
send_query_tramp(void *mysql, const char *stmt_str, unsigned long length) {
+ enum memprof_sql_type type;
int ret;
ret = orig_send_query(mysql, stmt_str, length);
stats.query_calls++;
+ type = memprof_sql_query_type(stmt_str, length);
+ stats.query_calls_by_type[type]++;
+
return ret;
}
@@ -77,12 +90,30 @@ mysql_trace_reset() {
static void
mysql_trace_dump(json_gen gen) {
+ enum memprof_sql_type i;
+
if (stats.query_calls > 0) {
json_gen_cstr(gen, "queries");
json_gen_integer(gen, stats.query_calls);
json_gen_cstr(gen, "time");
json_gen_integer(gen, stats.query_time);
+
+ json_gen_cstr(gen, "types");
+ json_gen_map_open(gen);
+ for (i=0; i<=sql_UNKNOWN; i++) {
+ json_gen_cstr(gen, memprof_sql_type_str(i));
+ json_gen_map_open(gen);
+
+ json_gen_cstr(gen, "queries");
+ json_gen_integer(gen, stats.query_calls_by_type[i]);
+
+ json_gen_cstr(gen, "time");
+ json_gen_integer(gen, stats.query_time_by_type[i]);
+
+ json_gen_map_close(gen);
+ }
+ json_gen_map_close(gen);
}
}
View
@@ -9,11 +9,13 @@
#include "bin_api.h"
#include "json.h"
#include "tracer.h"
+#include "tracers/sql.h"
#include "tramp.h"
#include "util.h"
struct memprof_postgres_stats {
size_t query_calls;
+ size_t query_calls_by_type[sql_UNKNOWN+1];
};
static struct tracer tracer;
@@ -22,11 +24,15 @@ static void * (*orig_PQexec)(void *postgres, const char *stmt);
static void *
PQexec_tramp(void *postgres, const char *stmt) {
+ enum memprof_sql_type type;
void *ret;
ret = orig_PQexec(postgres, stmt);
stats.query_calls++;
+ type = memprof_sql_query_type(stmt, strlen(stmt));
+ stats.query_calls_by_type[type]++;
+
return ret;
}
@@ -55,9 +61,22 @@ postgres_trace_reset() {
static void
postgres_trace_dump(json_gen gen) {
+ enum memprof_sql_type i;
+
if (stats.query_calls > 0) {
json_gen_cstr(gen, "queries");
json_gen_integer(gen, stats.query_calls);
+
+ json_gen_cstr(gen, "types");
+ json_gen_map_open(gen);
+ for (i=0; i<=sql_UNKNOWN; i++) {
+ json_gen_cstr(gen, memprof_sql_type_str(i));
+ json_gen_map_open(gen);
+ json_gen_cstr(gen, "queries");
+ json_gen_integer(gen, stats.query_calls_by_type[i]);
+ json_gen_map_close(gen);
+ }
+ json_gen_map_close(gen);
}
}
View
@@ -0,0 +1,56 @@
+#include <tracers/sql.h>
+
+enum memprof_sql_type
+memprof_sql_query_type(const char *stmt, unsigned long length)
+{
+ int i;
+
+ for (i=0; i<length && i<10; i++) {
+ switch (stmt[i]) {
+ case ' ':
+ case '\n':
+ case '\r':
+ continue;
+ break;
+
+ case 'S':
+ case 's':
+ return sql_SELECT;
+
+ case 'I':
+ case 'i':
+ return sql_INSERT;
+
+ case 'U':
+ case 'u':
+ return sql_UPDATE;
+
+ case 'D':
+ case 'd':
+ return sql_DELETE;
+
+ default:
+ return sql_UNKNOWN;
+ }
+ }
+
+ return sql_UNKNOWN;
+}
+
+const char *
+memprof_sql_type_str(enum memprof_sql_type type)
+{
+ switch (type) {
+ case sql_SELECT:
+ return "select";
+ case sql_UPDATE:
+ return "update";
+ case sql_INSERT:
+ return "insert";
+ case sql_DELETE:
+ return "delete";
+ default:
+ case sql_UNKNOWN:
+ return "unknown";
+ }
+}
View
@@ -0,0 +1,18 @@
+#if !defined(_sql_h_)
+#define _sql_h_
+
+enum memprof_sql_type {
+ sql_SELECT,
+ sql_UPDATE,
+ sql_INSERT,
+ sql_DELETE,
+ sql_UNKNOWN // last
+};
+
+enum memprof_sql_type
+memprof_sql_query_type(const char *stmt, unsigned long length);
+
+const char *
+memprof_sql_type_str(enum memprof_sql_type);
+
+#endif

0 comments on commit 916aa01

Please sign in to comment.