diff --git a/pg_stat_monitor--1.0.sql.in b/pg_stat_monitor--1.0.sql.in index 06d0c9a..106106d 100644 --- a/pg_stat_monitor--1.0.sql.in +++ b/pg_stat_monitor--1.0.sql.in @@ -245,6 +245,7 @@ $$ language plpgsql; -- FROM pg_stat_monitor_hook_stats(); CREATE FUNCTION pg_stat_monitor_errors( + OUT severity int, OUT message text, OUT msgtime text, OUT calls int8 @@ -253,8 +254,19 @@ RETURNS SETOF record AS 'MODULE_PATHNAME', 'pg_stat_monitor_errors' LANGUAGE C STRICT VOLATILE PARALLEL SAFE; +CREATE OR REPLACE FUNCTION pgsm_log_severity_as_text(severity int) RETURNS TEXT AS +$$ +SELECT + CASE + WHEN severity = 0 THEN 'INFO' + WHEN severity = 1 THEN 'WARNING' + WHEN severity = 2 THEN 'ERROR' + END +$$ +LANGUAGE SQL PARALLEL SAFE; + CREATE VIEW pg_stat_monitor_errors AS SELECT - message, msgtime, calls + pgsm_log_severity_as_text(severity) as severity, message, msgtime, calls FROM pg_stat_monitor_errors(); CREATE FUNCTION pg_stat_monitor_reset_errors() diff --git a/pgsm_errors.c b/pgsm_errors.c index 5706748..0a4bcde 100644 --- a/pgsm_errors.c +++ b/pgsm_errors.c @@ -63,7 +63,7 @@ size_t pgsm_errors_size(void) return hash_estimate_size(PSGM_ERRORS_MAX, sizeof(ErrorEntry)); } -void pgsm_log_error(const char *format, ...) +void pgsm_log(PgsmLogSeverity severity, const char *format, ...) { char key[ERROR_MSG_MAX_LEN]; ErrorEntry *entry; @@ -97,7 +97,10 @@ void pgsm_log_error(const char *format, ...) } if (!found) + { + entry->severity = severity; entry->calls = 0; + } /* Update message timestamp. */ gettimeofday(&tv, NULL); @@ -179,7 +182,7 @@ pg_stat_monitor_errors(PG_FUNCTION_ARGS) if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "pg_stat_monitor: return type must be a row type"); - if (tupdesc->natts != 3) + if (tupdesc->natts != 4) elog(ERROR, "pg_stat_monitor: incorrect number of output arguments, required 3, found %d", tupdesc->natts); tupstore = tuplestore_begin_heap(true, false, work_mem); @@ -194,12 +197,13 @@ pg_stat_monitor_errors(PG_FUNCTION_ARGS) hash_seq_init(&hash_seq, pgsm_errors_ht); while ((error_entry = hash_seq_search(&hash_seq)) != NULL) { - Datum values[3]; - bool nulls[3]; + Datum values[4]; + bool nulls[4]; int i = 0; memset(values, 0, sizeof(values)); memset(nulls, 0, sizeof(nulls)); + values[i++] = Int64GetDatumFast(error_entry->severity); values[i++] = CStringGetTextDatum(error_entry->message); values[i++] = CStringGetTextDatum(error_entry->time); values[i++] = Int64GetDatumFast(error_entry->calls); diff --git a/pgsm_errors.h b/pgsm_errors.h index 9956fdf..8f2865d 100644 --- a/pgsm_errors.h +++ b/pgsm_errors.h @@ -26,8 +26,16 @@ /* Maximum allowed error message length. */ #define ERROR_MSG_MAX_LEN 128 +/* Log message severity. */ +typedef enum { + PSGM_LOG_INFO, + PGSM_LOG_WARNING, + PGSM_LOG_ERROR +} PgsmLogSeverity; + typedef struct { char message[ERROR_MSG_MAX_LEN]; /* message is also the hash key (MUST BE FIRST). */ + PgsmLogSeverity severity; char time[60]; /* last timestamp in which this error was reported. */ int64 calls; /* how many times this error was reported. */ } ErrorEntry; @@ -45,9 +53,13 @@ void psgm_errors_init(void); size_t pgsm_errors_size(void); /* - * Add an error message to the hash table. + * Add a message to the hash table. * Increment no. of calls if message already exists. */ -void pgsm_log_error(const char *format, ...); +void pgsm_log(PgsmLogSeverity severity, const char *format, ...); + +#define pgsm_log_info(msg, ...) pgsm_log(PGSM_LOG_INFO, msg, ##__VA_ARGS__) +#define pgsm_log_warning(msg, ...) pgsm_log(PGSM_LOG_WARNING, msg, ##__VA_ARGS__) +#define pgsm_log_error(msg, ...) pgsm_log(PGSM_LOG_ERROR, msg, ##__VA_ARGS__) #endif /* PGSM_ERRORS_H */ \ No newline at end of file