PG-193: Comment based tags to identify different parameters.
parent
89614e442b
commit
67b3d961ca
2
Makefile
2
Makefile
|
@ -11,7 +11,7 @@ PGFILEDESC = "pg_stat_monitor - execution statistics of SQL statements"
|
||||||
LDFLAGS_SL += $(filter -lm, $(LIBS))
|
LDFLAGS_SL += $(filter -lm, $(LIBS))
|
||||||
|
|
||||||
REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_monitor/pg_stat_monitor.conf --inputdir=regression
|
REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_monitor/pg_stat_monitor.conf --inputdir=regression
|
||||||
REGRESS = basic version guc counters relations database top_query application_name cmd_type error state rows
|
REGRESS = basic version guc counters relations database top_query application_name cmd_type error state rows tags
|
||||||
|
|
||||||
# Disabled because these tests require "shared_preload_libraries=pg_stat_statements",
|
# Disabled because these tests require "shared_preload_libraries=pg_stat_statements",
|
||||||
# which typical installcheck users do not have (e.g. buildfarm clients).
|
# which typical installcheck users do not have (e.g. buildfarm clients).
|
||||||
|
|
|
@ -77,7 +77,8 @@ CREATE FUNCTION pg_stat_monitor_internal(IN showtext boolean,
|
||||||
OUT cpu_sys_time float8,
|
OUT cpu_sys_time float8,
|
||||||
OUT wal_records int8,
|
OUT wal_records int8,
|
||||||
OUT wal_fpi int8,
|
OUT wal_fpi int8,
|
||||||
OUT wal_bytes numeric
|
OUT wal_bytes numeric,
|
||||||
|
OUT comments TEXT
|
||||||
)
|
)
|
||||||
RETURNS SETOF record
|
RETURNS SETOF record
|
||||||
AS 'MODULE_PATHNAME', 'pg_stat_monitor'
|
AS 'MODULE_PATHNAME', 'pg_stat_monitor'
|
||||||
|
@ -144,6 +145,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
||||||
queryid,
|
queryid,
|
||||||
top_queryid,
|
top_queryid,
|
||||||
query,
|
query,
|
||||||
|
comments,
|
||||||
planid,
|
planid,
|
||||||
query_plan,
|
query_plan,
|
||||||
(SELECT query from pg_stat_monitor_internal(true) s where s.queryid = p.top_queryid) AS top_query,
|
(SELECT query from pg_stat_monitor_internal(true) s where s.queryid = p.top_queryid) AS top_query,
|
||||||
|
|
|
@ -15,13 +15,14 @@
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
#include <regex.h>
|
||||||
#include "commands/explain.h"
|
#include "commands/explain.h"
|
||||||
#include "pg_stat_monitor.h"
|
#include "pg_stat_monitor.h"
|
||||||
|
|
||||||
PG_MODULE_MAGIC;
|
PG_MODULE_MAGIC;
|
||||||
|
|
||||||
#define BUILD_VERSION "devel"
|
#define BUILD_VERSION "devel"
|
||||||
#define PG_STAT_STATEMENTS_COLS 51 /* maximum of above */
|
#define PG_STAT_STATEMENTS_COLS 52 /* maximum of above */
|
||||||
#define PGSM_TEXT_FILE "/tmp/pg_stat_monitor_query"
|
#define PGSM_TEXT_FILE "/tmp/pg_stat_monitor_query"
|
||||||
|
|
||||||
#define PGUNSIXBIT(val) (((val) & 0x3F) + '0')
|
#define PGUNSIXBIT(val) (((val) & 0x3F) + '0')
|
||||||
|
@ -73,6 +74,7 @@ static struct rusage rusage_end;
|
||||||
static unsigned char *pgss_qbuf[MAX_BUCKETS];
|
static unsigned char *pgss_qbuf[MAX_BUCKETS];
|
||||||
static char *pgss_explain(QueryDesc *queryDesc);
|
static char *pgss_explain(QueryDesc *queryDesc);
|
||||||
|
|
||||||
|
static char *extract_query_comments(const char *query);
|
||||||
static int get_histogram_bucket(double q_time);
|
static int get_histogram_bucket(double q_time);
|
||||||
static bool IsSystemInitialized(void);
|
static bool IsSystemInitialized(void);
|
||||||
static void dump_queries_buffer(int bucket_id, unsigned char *buf, int buf_len);
|
static void dump_queries_buffer(int bucket_id, unsigned char *buf, int buf_len);
|
||||||
|
@ -893,6 +895,7 @@ pgss_update_entry(pgssEntry *entry,
|
||||||
int bucketid,
|
int bucketid,
|
||||||
uint64 queryid,
|
uint64 queryid,
|
||||||
const char *query,
|
const char *query,
|
||||||
|
const char *comments,
|
||||||
PlanInfo *plan_info,
|
PlanInfo *plan_info,
|
||||||
CmdType cmd_type,
|
CmdType cmd_type,
|
||||||
SysInfo *sys_info,
|
SysInfo *sys_info,
|
||||||
|
@ -910,6 +913,7 @@ pgss_update_entry(pgssEntry *entry,
|
||||||
pgssSharedState *pgss = pgsm_get_ss();
|
pgssSharedState *pgss = pgsm_get_ss();
|
||||||
double old_mean;
|
double old_mean;
|
||||||
int message_len = error_info ? strlen (error_info->message) : 0;
|
int message_len = error_info ? strlen (error_info->message) : 0;
|
||||||
|
int comments_len = comments ? strlen (comments) : 0;
|
||||||
int sqlcode_len = error_info ? strlen (error_info->sqlcode) : 0;
|
int sqlcode_len = error_info ? strlen (error_info->sqlcode) : 0;
|
||||||
int plan_text_len = plan_info ? strlen (plan_info->plan_text) : 0;
|
int plan_text_len = plan_info ? strlen (plan_info->plan_text) : 0;
|
||||||
|
|
||||||
|
@ -922,6 +926,7 @@ pgss_update_entry(pgssEntry *entry,
|
||||||
if (reset)
|
if (reset)
|
||||||
memset(&entry->counters, 0, sizeof(Counters));
|
memset(&entry->counters, 0, sizeof(Counters));
|
||||||
|
|
||||||
|
_snprintf(e->counters.info.comments, comments, comments_len, COMMENTS_LEN);
|
||||||
e->counters.state = kind;
|
e->counters.state = kind;
|
||||||
if (kind == PGSS_PLAN)
|
if (kind == PGSS_PLAN)
|
||||||
{
|
{
|
||||||
|
@ -1204,13 +1209,15 @@ pgss_store(uint64 queryid,
|
||||||
uint64 dbid = MyDatabaseId;
|
uint64 dbid = MyDatabaseId;
|
||||||
uint64 ip = pg_get_client_addr();
|
uint64 ip = pg_get_client_addr();
|
||||||
uint64 planid = plan_info ? plan_info->planid: 0;
|
uint64 planid = plan_info ? plan_info->planid: 0;
|
||||||
|
char *comments;
|
||||||
/* Monitoring is disabled */
|
/* Monitoring is disabled */
|
||||||
if (!PGSM_ENABLED)
|
if (!PGSM_ENABLED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Assert(query != NULL);
|
Assert(query != NULL);
|
||||||
|
|
||||||
|
comments = extract_query_comments(query);
|
||||||
|
|
||||||
/* Safety check... */
|
/* Safety check... */
|
||||||
if (!IsSystemInitialized() || !pgss_qbuf[pgss->current_wbucket])
|
if (!IsSystemInitialized() || !pgss_qbuf[pgss->current_wbucket])
|
||||||
return;
|
return;
|
||||||
|
@ -1258,6 +1265,7 @@ pgss_store(uint64 queryid,
|
||||||
bucketid, /* bucketid */
|
bucketid, /* bucketid */
|
||||||
queryid, /* queryid */
|
queryid, /* queryid */
|
||||||
query, /* query */
|
query, /* query */
|
||||||
|
comments, /* comments */
|
||||||
plan_info, /* PlanInfo */
|
plan_info, /* PlanInfo */
|
||||||
cmd_type, /* CmdType */
|
cmd_type, /* CmdType */
|
||||||
sys_info, /* SysInfo */
|
sys_info, /* SysInfo */
|
||||||
|
@ -1364,7 +1372,7 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
|
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
|
||||||
elog(ERROR, "pg_stat_monitor: return type must be a row type");
|
elog(ERROR, "pg_stat_monitor: return type must be a row type");
|
||||||
|
|
||||||
if (tupdesc->natts != 48)
|
if (tupdesc->natts != 49)
|
||||||
elog(ERROR, "pg_stat_monitor: incorrect number of output arguments, required %d", tupdesc->natts);
|
elog(ERROR, "pg_stat_monitor: incorrect number of output arguments, required %d", tupdesc->natts);
|
||||||
|
|
||||||
tupstore = tuplestore_begin_heap(true, false, work_mem);
|
tupstore = tuplestore_begin_heap(true, false, work_mem);
|
||||||
|
@ -1658,6 +1666,12 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
Int32GetDatum(-1));
|
Int32GetDatum(-1));
|
||||||
/* wal_bytes at column number 46 */
|
/* wal_bytes at column number 46 */
|
||||||
values[i++] = wal_bytes;
|
values[i++] = wal_bytes;
|
||||||
|
|
||||||
|
/* application_name at column number 47 */
|
||||||
|
if (strlen(tmp.info.comments) > 0)
|
||||||
|
values[i++] = CStringGetTextDatum(tmp.info.comments);
|
||||||
|
else
|
||||||
|
nulls[i++] = true;
|
||||||
}
|
}
|
||||||
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
|
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
|
||||||
}
|
}
|
||||||
|
@ -3049,3 +3063,26 @@ get_histogram_timings(PG_FUNCTION_ARGS)
|
||||||
return CStringGetTextDatum(text_str);
|
return CStringGetTextDatum(text_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
extract_query_comments(const char *query)
|
||||||
|
{
|
||||||
|
regex_t preg;
|
||||||
|
char *pattern = "/\\*.*\\*/";
|
||||||
|
int rc;
|
||||||
|
size_t nmatch = 1;
|
||||||
|
regmatch_t pmatch;
|
||||||
|
char *comments = palloc0(512);
|
||||||
|
|
||||||
|
rc = regcomp(&preg, pattern, 0);
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
printf("regcomp() failed, returning nonzero (%d)\n", rc);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
rc = regexec(&preg, query, nmatch, &pmatch, 0);
|
||||||
|
if (rc != 0)
|
||||||
|
return "";
|
||||||
|
sprintf(comments, "%.*s", pmatch.rm_eo - pmatch.rm_so -4, &query[pmatch.rm_so + 2]);
|
||||||
|
regfree(&preg);
|
||||||
|
return comments;
|
||||||
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@
|
||||||
#define CMD_LST 10
|
#define CMD_LST 10
|
||||||
#define CMD_LEN 20
|
#define CMD_LEN 20
|
||||||
#define APPLICATIONNAME_LEN 100
|
#define APPLICATIONNAME_LEN 100
|
||||||
|
#define COMMENTS_LEN 512
|
||||||
#define PGSM_OVER_FLOW_MAX 10
|
#define PGSM_OVER_FLOW_MAX 10
|
||||||
#define PLAN_TEXT_LEN 1024
|
#define PLAN_TEXT_LEN 1024
|
||||||
/* the assumption of query max nested level */
|
/* the assumption of query max nested level */
|
||||||
|
@ -211,6 +212,7 @@ typedef struct QueryInfo
|
||||||
uint64 parentid; /* parent queryid of current query*/
|
uint64 parentid; /* parent queryid of current query*/
|
||||||
int64 type; /* type of query, options are query, info, warning, error, fatal */
|
int64 type; /* type of query, options are query, info, warning, error, fatal */
|
||||||
char application_name[APPLICATIONNAME_LEN];
|
char application_name[APPLICATIONNAME_LEN];
|
||||||
|
char comments[COMMENTS_LEN];
|
||||||
char relations[REL_LST][REL_LEN]; /* List of relation involved in the query */
|
char relations[REL_LST][REL_LEN]; /* List of relation involved in the query */
|
||||||
int num_relations; /* Number of relation in the query */
|
int num_relations; /* Number of relation in the query */
|
||||||
CmdType cmd_type; /* query command type SELECT/UPDATE/DELETE/INSERT */
|
CmdType cmd_type; /* query command type SELECT/UPDATE/DELETE/INSERT */
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
CREATE EXTENSION pg_stat_monitor;
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT 1 AS num /* { "application", psql_app, "real_ip", 192.168.1.3) */;
|
||||||
|
num
|
||||||
|
-----
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT query, comments FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
query | comments
|
||||||
|
-------------------------------------------------------------------------+------------------------------------------------------
|
||||||
|
SELECT $1 AS num | { "application", psql_app, "real_ip", 192.168.1.3)
|
||||||
|
SELECT pg_stat_monitor_reset(); |
|
||||||
|
SELECT query, comments FROM pg_stat_monitor ORDER BY query COLLATE "C"; |
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
DROP EXTENSION pg_stat_monitor;
|
|
@ -0,0 +1,6 @@
|
||||||
|
CREATE EXTENSION pg_stat_monitor;
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
SELECT 1 AS num /* { "application", psql_app, "real_ip", 192.168.1.3) */;
|
||||||
|
SELECT query, comments FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
DROP EXTENSION pg_stat_monitor;
|
Loading…
Reference in New Issue