Improve the debugging infrastructure by adding mechanism to dynamically
authorPavan Deolasee <[email protected]>
Thu, 11 Feb 2016 10:31:14 +0000 (16:01 +0530)
committerPavan Deolasee <[email protected]>
Thu, 11 Feb 2016 10:31:14 +0000 (16:01 +0530)
increase/decrease log levels

This new pg_msgmodule_change() function can be used to increment or decrement
compile time defined log levels by the given step. Of course, this is only
applicable to DEBUG1-5 and LOG messages and the resulting new level is also
within the same range. This only affects whats gets logged on the server log
and not what gets sent to the client

src/backend/utils/error/elog.c
src/include/catalog/pg_proc.h

index d85a22e4f19ac4c66c133cb6a59b009812563abd..dabe5c2c6020c0a64ef4d8d404bd2b5078b3556f 100644 (file)
@@ -2637,7 +2637,7 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
                                break;
 
                        case 'S':
-                               if (padding != NULL)
+                               if (padding != 0)
                                        appendStringInfo(buf, "%*s", padding, global_session_string);
                                else
                                        appendStringInfo(buf, "%s", global_session_string);
@@ -3750,6 +3750,7 @@ static int
 get_overriden_log_level(int moduleid, int fileid, int msgid, int origlevel)
 {
        uint32 position;
+       int value, relative, change, elevel;
 
        /*
         * The shared memory may not set during init processing or in a stand alone
@@ -3766,6 +3767,11 @@ get_overriden_log_level(int moduleid, int fileid, int msgid, int origlevel)
                (msgid <= 0 || msgid >= PGXL_MSG_MAX_MSGIDS_PER_FILE))
                return origlevel;
 
+       if (origlevel < DEBUG5 || origlevel >= LOG)
+               return origlevel;
+
+       elevel = origlevel;
+
        /*
         * Get the overridden log level and return it back
         */
@@ -3773,7 +3779,28 @@ get_overriden_log_level(int moduleid, int fileid, int msgid, int origlevel)
                        PGXL_MSG_MAX_MSGIDS_PER_FILE +
                        (fileid - 1) * PGXL_MSG_MAX_MSGIDS_PER_FILE +
                        (msgid - 1);
-       return MsgModuleCtl[position] ? MsgModuleCtl[position] : origlevel;
+       
+       /* Read once */
+       value = MsgModuleCtl[position];
+
+       relative = value & 0x80;
+       change = value & 0x7f;
+
+       if (value)
+       {
+               if (relative)
+               {
+                       elevel = elevel + change;
+                       if (elevel < DEBUG5)
+                               elevel = DEBUG5;
+                       else if (elevel >= LOG)
+                               elevel = LOG;
+               }
+               else
+                       elevel = change;
+               return elevel;
+       }
+       return origlevel;
 }
 #endif
 
@@ -3794,20 +3821,6 @@ is_log_level_output(int elevel,
 #endif
                int log_min_level)
 {
-       if (elevel == LOG || elevel == COMMERROR)
-       {
-               if (log_min_level == LOG || log_min_level <= ERROR)
-                       return true;
-       }
-       else if (log_min_level == LOG)
-       {
-               /* elevel != LOG */
-               if (elevel >= FATAL)
-                       return true;
-       }
-       /* Neither is LOG */
-       else if (elevel >= log_min_level)
-               return true;
 #ifdef USE_MODULE_MSGIDS
        /* 
         * Check if the message's compile time value has been changed during the
@@ -3823,19 +3836,24 @@ is_log_level_output(int elevel,
         * especially be useful to turn some specific ERROR messages into FATAL or
         * PANIC to be able to get a core dump for analysis.
         */
-       else
+       elevel = get_overriden_log_level(moduleid, fileid, msgid,
+                       elevel);
+#endif
+
+       if (elevel == LOG || elevel == COMMERROR)
        {
-               int newlevel = get_overriden_log_level(moduleid, fileid, msgid,
-                               elevel);
-               if (newlevel == LOG)
-               {
-                       if (log_min_level == LOG || log_min_level <= ERROR)
-                               return true;
-               }
-               else if (newlevel >= log_min_level)
+               if (log_min_level == LOG || log_min_level <= ERROR)
                        return true;
        }
-#endif
+       else if (log_min_level == LOG)
+       {
+               /* elevel != LOG */
+               if (elevel >= FATAL)
+                       return true;
+       }
+       /* Neither is LOG */
+       else if (elevel >= log_min_level)
+               return true;
 
        return false;
 }
@@ -3905,14 +3923,9 @@ MsgModuleShmemInit(void)
                                                                   &found);
 }
 
-Datum
-pg_msgmodule_set(PG_FUNCTION_ARGS)
+static bool
+pg_msgmodule_internal(int32 moduleid, int32 fileid, int32 msgid, char value)
 {
-       int32 moduleid = PG_GETARG_INT32(0);
-       int32 fileid = PG_GETARG_INT32(1);
-       int32 msgid = PG_GETARG_INT32(2);
-       const char *levelstr = PG_GETARG_CSTRING(3);
-       int32 level;
        uint32 start_position;
        uint32 len;
 
@@ -3921,28 +3934,6 @@ pg_msgmodule_set(PG_FUNCTION_ARGS)
                                (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                         (errmsg("must be superuser to change elog message level"))));
 
-       /*
-        * The only accepted values for the log levels are - LOG, DEBUG[1-5] and
-        * DEFAULT
-        */
-       if (strcasecmp(levelstr, "LOG") == 0)
-               level = LOG;
-       else if (strcasecmp(levelstr, "DEFAULT") == 0)
-               level = 0;
-       else if (strcasecmp(levelstr, "DEBUG1") == 0)
-               level = DEBUG1;
-       else if (strcasecmp(levelstr, "DEBUG2") == 0)
-               level = DEBUG2;
-       else if (strcasecmp(levelstr, "DEBUG3") == 0)
-               level = DEBUG3;
-       else if (strcasecmp(levelstr, "DEBUG4") == 0)
-               level = DEBUG4;
-       else if (strcasecmp(levelstr, "DEBUG5") == 0)
-               level = DEBUG5;
-       else
-               ereport(ERROR,
-                               (errcode(ERRCODE_INTERNAL_ERROR),
-                                (errmsg("Invalid value \"%s\" for log level", levelstr))));
 
        if (moduleid <= 0 || moduleid >= PGXL_MSG_MAX_MODULES)
                ereport(ERROR, (errmsg_internal("Invalid module id %d, allowed values 1-%d",
@@ -3956,8 +3947,8 @@ pg_msgmodule_set(PG_FUNCTION_ARGS)
                 */
                len = PGXL_MSG_MAX_FILEIDS_PER_MODULE * PGXL_MSG_MAX_MSGIDS_PER_FILE;
                start_position = (moduleid - 1) * len;
-               memset(MsgModuleCtl + start_position, level, len);
-               PG_RETURN_BOOL(true);
+               memset(MsgModuleCtl + start_position, value, len);
+               return true;
        }
        else
        {
@@ -3974,8 +3965,8 @@ pg_msgmodule_set(PG_FUNCTION_ARGS)
                        len = PGXL_MSG_MAX_MSGIDS_PER_FILE;
                        start_position = ((moduleid - 1) * PGXL_MSG_MAX_FILEIDS_PER_MODULE * PGXL_MSG_MAX_MSGIDS_PER_FILE) +
                                                (fileid - 1) * PGXL_MSG_MAX_MSGIDS_PER_FILE;
-                       memset(MsgModuleCtl + start_position, level, len);
-                       PG_RETURN_BOOL(true);
+                       memset(MsgModuleCtl + start_position, value, len);
+                       return true;
                }
 
                if (msgid <= 0 || msgid >= PGXL_MSG_MAX_MSGIDS_PER_FILE)
@@ -3989,10 +3980,75 @@ pg_msgmodule_set(PG_FUNCTION_ARGS)
                start_position = ((moduleid - 1) * PGXL_MSG_MAX_FILEIDS_PER_MODULE * PGXL_MSG_MAX_MSGIDS_PER_FILE) +
                        ((fileid - 1) * PGXL_MSG_MAX_MSGIDS_PER_FILE) +
                        (msgid - 1);
-               memset(MsgModuleCtl + start_position, level, len);
-               PG_RETURN_BOOL(true);
+               memset(MsgModuleCtl + start_position, value, len);
+               return true;
        }
-       PG_RETURN_BOOL(true);
+       return true;
+}
+
+Datum
+pg_msgmodule_set(PG_FUNCTION_ARGS)
+{
+       int32 moduleid = PG_GETARG_INT32(0);
+       int32 fileid = PG_GETARG_INT32(1);
+       int32 msgid = PG_GETARG_INT32(2);
+       const char *levelstr = PG_GETARG_CSTRING(3);
+       int32 level;
+
+       if (!superuser())
+               ereport(ERROR,
+                               (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                        (errmsg("must be superuser to change elog message level"))));
+
+       /*
+        * The only accepted values for the log levels are - LOG, DEBUG[1-5] and
+        * DEFAULT
+        */
+       if (strcasecmp(levelstr, "LOG") == 0)
+               level = LOG;
+       else if (strcasecmp(levelstr, "DEFAULT") == 0)
+               level = 0;
+       else if (strcasecmp(levelstr, "DEBUG1") == 0)
+               level = DEBUG1;
+       else if (strcasecmp(levelstr, "DEBUG2") == 0)
+               level = DEBUG2;
+       else if (strcasecmp(levelstr, "DEBUG3") == 0)
+               level = DEBUG3;
+       else if (strcasecmp(levelstr, "DEBUG4") == 0)
+               level = DEBUG4;
+       else if (strcasecmp(levelstr, "DEBUG5") == 0)
+               level = DEBUG5;
+       else
+               ereport(ERROR,
+                               (errcode(ERRCODE_INTERNAL_ERROR),
+                                (errmsg("Invalid value \"%s\" for log level", levelstr))));
+
+       PG_RETURN_BOOL(pg_msgmodule_internal(moduleid, fileid, msgid, level));
+}
+
+Datum
+pg_msgmodule_change(PG_FUNCTION_ARGS)
+{
+       int32 moduleid = PG_GETARG_INT32(0);
+       int32 fileid = PG_GETARG_INT32(1);
+       int32 msgid = PG_GETARG_INT32(2);
+       int32 change = PG_GETARG_INT32(3);
+       int level;
+
+       if (!superuser())
+               ereport(ERROR,
+                               (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                        (errmsg("must be superuser to change elog message level"))));
+       
+       if ((change < (DEBUG5 - LOG)) || (change > (LOG - DEBUG5)))
+               ereport(ERROR,
+                               (errcode(ERRCODE_INTERNAL_ERROR),
+                        (errmsg("accepted values are between %d and +%d", DEBUG5 - LOG, LOG -
+                                        DEBUG5))));
+
+       level = 0x80 | change;
+
+       PG_RETURN_BOOL(pg_msgmodule_internal(moduleid, fileid, msgid, level));
 }
 #else
 Datum
@@ -4001,4 +4057,10 @@ pg_msgmodule_set(PG_FUNCTION_ARGS)
        ereport(ERROR, (errmsg_internal("Module msgid support not available. "
                                        "Please recompile with --enable-genmsgids")));
 }
+Datum
+pg_msgmodule_change(PG_FUNCTION_ARGS)
+{
+       ereport(ERROR, (errmsg_internal("Module msgid support not available. "
+                                       "Please recompile with --enable-genmsgids")));
+}
 #endif
index e5e77b41c84ec81c4d493eaf8ca31b79b52a15c8..10313fe1a9bf5f99823b3d8dc106f4c7bcc03eb1 100644 (file)
@@ -5383,6 +5383,8 @@ DESCR("get progress for all replication origins");
 #ifdef USE_MODULE_MSGIDS
 DATA(insert OID = 6015 ( pg_msgmodule_set PGNSP PGUID 12 1 1 0 0 f f f f t t i 4 0 16 "20 20 20 2275" _null_ _null_ _null_ _null_ _null_ pg_msgmodule_set _null_ _null_ _null_ ));
 DESCR("set debugging level for module/file/msg");
+DATA(insert OID = 6016 ( pg_msgmodule_change PGNSP PGUID 12 1 1 0 0 f f f f t t i 4 0 16 "20 20 20 20" _null_ _null_ _null_ _null_ _null_ pg_msgmodule_change _null_ _null_ _null_ ));
+DESCR("change debugging level for module/file/msg");
 #endif
 
 /*