3737 *
3838 *
3939 * IDENTIFICATION
40- * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.128 2004/03/15 15:56:23 momjian Exp $
40+ * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.129 2004/03/19 02:23:59 tgl Exp $
4141 *
4242 *-------------------------------------------------------------------------
4343 */
@@ -69,7 +69,7 @@ ErrorContextCallback *error_context_stack = NULL;
6969
7070/* GUC parameters */
7171PGErrorVerbosity Log_error_verbosity = PGERROR_VERBOSE ;
72- char * Log_line_prefix = "" ; /* format for extra log line info */
72+ char * Log_line_prefix = NULL ; /* format for extra log line info */
7373
7474#ifdef HAVE_SYSLOG
7575/*
@@ -136,13 +136,14 @@ static int recursion_depth = 0; /* to detect actual recursion */
136136 } while (0)
137137
138138
139+ static void log_line_prefix (StringInfo buf );
139140static void send_message_to_server_log (ErrorData * edata );
140141static void send_message_to_frontend (ErrorData * edata );
141142static char * expand_fmt_string (const char * fmt , ErrorData * edata );
142143static const char * useful_strerror (int errnum );
143144static const char * error_severity (int elevel );
144145static void append_with_tabs (StringInfo buf , const char * str );
145- static const char * log_line_prefix ( void );
146+
146147
147148/*
148149 * errstart --- begin an error-reporting cycle
@@ -1019,135 +1020,139 @@ write_syslog(int level, const char *line)
10191020#endif /* HAVE_SYSLOG */
10201021
10211022/*
1022- * Format tag info for log lines
1023+ * Format tag info for log lines; append to the provided buffer.
10231024 */
1024- static const char *
1025- log_line_prefix (void )
1025+ static void
1026+ log_line_prefix (StringInfo buf )
10261027{
1028+ /* static counter for line numbers */
1029+ static long log_line_number = 0 ;
1030+ /* has counter been reset in current process? */
1031+ static int log_my_pid = 0 ;
1032+
1033+ int format_len ;
1034+ int i ;
1035+
1036+ /*
1037+ * This is one of the few places where we'd rather not inherit a
1038+ * static variable's value from the postmaster. But since we will,
1039+ * reset it when MyProcPid changes.
1040+ */
1041+ if (log_my_pid != MyProcPid )
1042+ {
1043+ log_line_number = 0 ;
1044+ log_my_pid = MyProcPid ;
1045+ }
1046+ log_line_number ++ ;
10271047
1028- /* static accumulator for line numbers */
1029- static int log_line_number = 0 ;
1030-
1031- /* space for option string + one of each option, plus some room to spare */
1032- /* Note: if more identifiers are built in this will have to increase */
1033- static char * result = NULL ;
1034- int format_len = strlen (Log_line_prefix );
1035- int result_len = 2 * NAMEDATALEN + format_len + 120 ;
1048+ if (Log_line_prefix == NULL )
1049+ return ; /* in case guc hasn't run yet */
10361050
1037- if (result == NULL )
1038- result = malloc (result_len );
1039- result [0 ] = '\0' ;
1051+ format_len = strlen (Log_line_prefix );
10401052
1041- if ( format_len > 0 )
1053+ for ( i = 0 ; i < format_len ; i ++ )
10421054 {
1043- int i ,j ;
1044- char * dbname = NULL ;
1045- char * username = NULL ;
1046- time_t stamp_time ;
1047- log_line_number ++ ;
1048- if (MyProcPort != NULL )
1055+ if (Log_line_prefix [i ] != '%' )
10491056 {
1050- dbname = MyProcPort -> database_name ;
1051- username = MyProcPort -> user_name ;
1052- if (dbname == NULL || * dbname == '\0' )
1053- dbname = gettext ("[unknown]" );
1054- if (username == NULL || * username == '\0' )
1055- username = gettext ("[unknown]" );
1057+ /* literal char, just copy */
1058+ appendStringInfoChar (buf , Log_line_prefix [i ]);
1059+ continue ;
1060+ }
1061+ /* go to char after '%' */
1062+ i ++ ;
1063+ if (i >= format_len )
1064+ {
1065+ /* format error - ignore it */
1066+ break ;
10561067 }
10571068
1058- /*
1059- * invariant through each iteration of this loop:
1060- * . j is the index of the trailing null on result
1061- * . result_len - j is the number of chars we have room for
1062- * including the trailing null
1063- * . there is room to write at least one more non-null char plus the
1064- * trailing null
1065- */
1066- for (i = 0 , j = 0 ; i < format_len && j < result_len - 1 ; i ++ )
1069+ /* process the option */
1070+ switch (Log_line_prefix [i ])
10671071 {
1068- if (Log_line_prefix [i ] != '%' )
1069- {
1070- /* literal char, just copy */
1071- result [j ]= Log_line_prefix [i ];
1072- j ++ ;
1073- result [j ] = '\0' ;
1074- continue ;
1075- }
1076- else if (i == format_len - 1 )
1077- {
1078- /* format error - skip it */
1079- continue ;
1080- }
1072+ case 'u' :
1073+ if (MyProcPort )
1074+ {
1075+ const char * username = MyProcPort -> user_name ;
10811076
1082- /* go to char after '%' */
1083- i ++ ;
1077+ if (username == NULL || * username == '\0' )
1078+ username = gettext ("[unknown]" );
1079+ appendStringInfo (buf , "%s" , username );
1080+ }
1081+ break ;
1082+ case 'd' :
1083+ if (MyProcPort )
1084+ {
1085+ const char * dbname = MyProcPort -> database_name ;
10841086
1085- /* in postmaster and friends, skip non-applicable options,
1086- * stop if %x is seen
1087- */
1088- if (MyProcPort == NULL )
1089- {
1090- if (Log_line_prefix [i ] == 'x' )
1091- break ;
1092- if (strchr ("udcsir" ,Log_line_prefix [i ]) != NULL )
1093- continue ;
1094- }
1087+ if (dbname == NULL || * dbname == '\0' )
1088+ dbname = gettext ("[unknown]" );
1089+ appendStringInfo (buf , "%s" , dbname );
1090+ }
1091+ break ;
1092+ case 'c' :
1093+ if (MyProcPort )
1094+ {
1095+ appendStringInfo (buf , "%lx.%lx" ,
1096+ (long )(MyProcPort -> session_start .tv_sec ),
1097+ (long )MyProcPid );
1098+ }
1099+ break ;
1100+ case 'p' :
1101+ appendStringInfo (buf , "%ld" , (long )MyProcPid );
1102+ break ;
1103+ case 'l' :
1104+ appendStringInfo (buf , "%ld" , log_line_number );
1105+ break ;
1106+ case 't' :
1107+ {
1108+ time_t stamp_time = time (NULL );
1109+ char strfbuf [32 ];
10951110
1096- /* process the option */
1097- switch (Log_line_prefix [i ])
1098- {
1099- case 'u' :
1100- j += snprintf (result + j ,result_len - j ,"%s" ,username );
1101- break ;
1102- case 'd' :
1103- j += snprintf (result + j ,result_len - j ,"%s" ,dbname );
1104- break ;
1105- case 'c' :
1106- j += snprintf (result + j ,result_len - j ,"%lx.%lx" ,
1107- (long )(MyProcPort -> session_start .tv_sec ),
1108- (long )MyProcPid );
1109- break ;
1110- case 'p' :
1111- j += snprintf (result + j ,result_len - j ,"%ld" ,(long )MyProcPid );
1112- break ;
1113- case 'l' :
1114- j += snprintf (result + j ,result_len - j ,"%d" ,log_line_number );
1115- break ;
1116- case 't' :
1117- stamp_time = time (NULL );
1118- j += strftime (result + j , result_len - j , "%Y-%m-%d %H:%M:%S" ,
1111+ strftime (strfbuf , sizeof (strfbuf ), "%Y-%m-%d %H:%M:%S" ,
11191112 localtime (& stamp_time ));
1120- break ;
1121- case 's' :
1122- j += strftime (result + j , result_len - j , "%Y-%m-%d %H:%M:%S" ,
1123- localtime (& (MyProcPort -> session_start .tv_sec )));
1124- break ;
1125- case 'i' :
1126- j += snprintf (result + j ,result_len - j ,"%s" ,
1127- MyProcPort -> commandTag );
1128- break ;
1129- case 'r' :
1130- j += snprintf (result + j ,result_len - j ,"%s" ,
1131- MyProcPort -> remote_host );
1113+ appendStringInfoString (buf , strfbuf );
1114+ }
1115+ break ;
1116+ case 's' :
1117+ if (MyProcPort )
1118+ {
1119+ time_t stamp_time = MyProcPort -> session_start .tv_sec ;
1120+ char strfbuf [32 ];
1121+
1122+ strftime (strfbuf , sizeof (strfbuf ), "%Y-%m-%d %H:%M:%S" ,
1123+ localtime (& stamp_time ));
1124+ appendStringInfoString (buf , strfbuf );
1125+ }
1126+ break ;
1127+ case 'i' :
1128+ if (MyProcPort )
1129+ {
1130+ appendStringInfo (buf , "%s" , MyProcPort -> commandTag );
1131+ }
1132+ break ;
1133+ case 'r' :
1134+ if (MyProcPort )
1135+ {
1136+ appendStringInfo (buf , "%s" , MyProcPort -> remote_host );
11321137 if (strlen (MyProcPort -> remote_port ) > 0 )
1133- j += snprintf (result + j ,result_len - j ,"(%s)" ,
1134- MyProcPort -> remote_port );
1135- break ;
1136- case 'x' :
1137- /* non-postmaster case - just ignore */
1138- break ;
1139- case '%' :
1140- result [j ] = '%' ;
1141- j ++ ;
1142- result [j ] = '\0' ;
1143- break ;
1144- default :
1145- /* format error - skip it */
1146- break ;
1147- }
1138+ appendStringInfo (buf , "(%s)" ,
1139+ MyProcPort -> remote_port );
1140+ }
1141+ break ;
1142+ case 'x' :
1143+ /* in postmaster and friends, stop if %x is seen */
1144+ /* in a backend, just ignore */
1145+ if (MyProcPort == NULL )
1146+ i = format_len ;
1147+ break ;
1148+ case '%' :
1149+ appendStringInfoChar (buf , '%' );
1150+ break ;
1151+ default :
1152+ /* format error - ignore it */
1153+ break ;
11481154 }
11491155 }
1150- return result ;
11511156}
11521157
11531158
@@ -1161,8 +1166,8 @@ send_message_to_server_log(ErrorData *edata)
11611166
11621167 initStringInfo (& buf );
11631168
1164- appendStringInfo (& buf , "%s%s: " ,
1165- log_line_prefix () , error_severity (edata -> elevel ));
1169+ log_line_prefix (& buf );
1170+ appendStringInfo ( & buf , "%s: " , error_severity (edata -> elevel ));
11661171
11671172 if (Log_error_verbosity >= PGERROR_VERBOSE )
11681173 {
@@ -1195,21 +1200,21 @@ send_message_to_server_log(ErrorData *edata)
11951200 {
11961201 if (edata -> detail )
11971202 {
1198- appendStringInfoString (& buf , log_line_prefix () );
1203+ log_line_prefix (& buf );
11991204 appendStringInfoString (& buf , gettext ("DETAIL: " ));
12001205 append_with_tabs (& buf , edata -> detail );
12011206 appendStringInfoChar (& buf , '\n' );
12021207 }
12031208 if (edata -> hint )
12041209 {
1205- appendStringInfoString (& buf , log_line_prefix () );
1210+ log_line_prefix (& buf );
12061211 appendStringInfoString (& buf , gettext ("HINT: " ));
12071212 append_with_tabs (& buf , edata -> hint );
12081213 appendStringInfoChar (& buf , '\n' );
12091214 }
12101215 if (edata -> context )
12111216 {
1212- appendStringInfoString (& buf , log_line_prefix () );
1217+ log_line_prefix (& buf );
12131218 appendStringInfoString (& buf , gettext ("CONTEXT: " ));
12141219 append_with_tabs (& buf , edata -> context );
12151220 appendStringInfoChar (& buf , '\n' );
@@ -1218,14 +1223,18 @@ send_message_to_server_log(ErrorData *edata)
12181223 {
12191224 /* assume no newlines in funcname or filename... */
12201225 if (edata -> funcname && edata -> filename )
1221- appendStringInfo (& buf , gettext ("%sLOCATION: %s, %s:%d\n" ),
1222- log_line_prefix (),
1226+ {
1227+ log_line_prefix (& buf );
1228+ appendStringInfo (& buf , gettext ("LOCATION: %s, %s:%d\n" ),
12231229 edata -> funcname , edata -> filename ,
12241230 edata -> lineno );
1231+ }
12251232 else if (edata -> filename )
1226- appendStringInfo (& buf , gettext ("%sLOCATION: %s:%d\n" ),
1227- log_line_prefix (),
1233+ {
1234+ log_line_prefix (& buf );
1235+ appendStringInfo (& buf , gettext ("LOCATION: %s:%d\n" ),
12281236 edata -> filename , edata -> lineno );
1237+ }
12291238 }
12301239 }
12311240
@@ -1234,7 +1243,7 @@ send_message_to_server_log(ErrorData *edata)
12341243 */
12351244 if (edata -> elevel >= log_min_error_statement && debug_query_string != NULL )
12361245 {
1237- appendStringInfoString (& buf , log_line_prefix () );
1246+ log_line_prefix (& buf );
12381247 appendStringInfoString (& buf , gettext ("STATEMENT: " ));
12391248 append_with_tabs (& buf , debug_query_string );
12401249 appendStringInfoChar (& buf , '\n' );
@@ -1284,11 +1293,7 @@ send_message_to_server_log(ErrorData *edata)
12841293 /* Write to stderr, if enabled */
12851294 if (Use_syslog <= 1 || whereToSendOutput == Debug )
12861295 {
1287- /*
1288- * Timestamp and PID are only used for stderr output --- we assume
1289- * the syslog daemon will supply them for us in the other case.
1290- */
1291- fprintf (stderr , "%s" ,buf .data );
1296+ fprintf (stderr , "%s" , buf .data );
12921297 }
12931298
12941299 pfree (buf .data );
0 commit comments