37
37
*
38
38
*
39
39
* 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 $
41
41
*
42
42
*-------------------------------------------------------------------------
43
43
*/
@@ -69,7 +69,7 @@ ErrorContextCallback *error_context_stack = NULL;
69
69
70
70
/* GUC parameters */
71
71
PGErrorVerbosity 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 */
73
73
74
74
#ifdef HAVE_SYSLOG
75
75
/*
@@ -136,13 +136,14 @@ static int recursion_depth = 0; /* to detect actual recursion */
136
136
} while (0)
137
137
138
138
139
+ static void log_line_prefix (StringInfo buf );
139
140
static void send_message_to_server_log (ErrorData * edata );
140
141
static void send_message_to_frontend (ErrorData * edata );
141
142
static char * expand_fmt_string (const char * fmt , ErrorData * edata );
142
143
static const char * useful_strerror (int errnum );
143
144
static const char * error_severity (int elevel );
144
145
static void append_with_tabs (StringInfo buf , const char * str );
145
- static const char * log_line_prefix ( void );
146
+
146
147
147
148
/*
148
149
* errstart --- begin an error-reporting cycle
@@ -1019,135 +1020,139 @@ write_syslog(int level, const char *line)
1019
1020
#endif /* HAVE_SYSLOG */
1020
1021
1021
1022
/*
1022
- * Format tag info for log lines
1023
+ * Format tag info for log lines; append to the provided buffer.
1023
1024
*/
1024
- static const char *
1025
- log_line_prefix (void )
1025
+ static void
1026
+ log_line_prefix (StringInfo buf )
1026
1027
{
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 ++ ;
1027
1047
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 */
1036
1050
1037
- if (result == NULL )
1038
- result = malloc (result_len );
1039
- result [0 ] = '\0' ;
1051
+ format_len = strlen (Log_line_prefix );
1040
1052
1041
- if ( format_len > 0 )
1053
+ for ( i = 0 ; i < format_len ; i ++ )
1042
1054
{
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 ] != '%' )
1049
1056
{
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 ;
1056
1067
}
1057
1068
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 ])
1067
1071
{
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 ;
1081
1076
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 ;
1084
1086
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 ];
1095
1110
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" ,
1119
1112
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 );
1132
1137
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 ;
1148
1154
}
1149
1155
}
1150
- return result ;
1151
1156
}
1152
1157
1153
1158
@@ -1161,8 +1166,8 @@ send_message_to_server_log(ErrorData *edata)
1161
1166
1162
1167
initStringInfo (& buf );
1163
1168
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 ));
1166
1171
1167
1172
if (Log_error_verbosity >= PGERROR_VERBOSE )
1168
1173
{
@@ -1195,21 +1200,21 @@ send_message_to_server_log(ErrorData *edata)
1195
1200
{
1196
1201
if (edata -> detail )
1197
1202
{
1198
- appendStringInfoString (& buf , log_line_prefix () );
1203
+ log_line_prefix (& buf );
1199
1204
appendStringInfoString (& buf , gettext ("DETAIL: " ));
1200
1205
append_with_tabs (& buf , edata -> detail );
1201
1206
appendStringInfoChar (& buf , '\n' );
1202
1207
}
1203
1208
if (edata -> hint )
1204
1209
{
1205
- appendStringInfoString (& buf , log_line_prefix () );
1210
+ log_line_prefix (& buf );
1206
1211
appendStringInfoString (& buf , gettext ("HINT: " ));
1207
1212
append_with_tabs (& buf , edata -> hint );
1208
1213
appendStringInfoChar (& buf , '\n' );
1209
1214
}
1210
1215
if (edata -> context )
1211
1216
{
1212
- appendStringInfoString (& buf , log_line_prefix () );
1217
+ log_line_prefix (& buf );
1213
1218
appendStringInfoString (& buf , gettext ("CONTEXT: " ));
1214
1219
append_with_tabs (& buf , edata -> context );
1215
1220
appendStringInfoChar (& buf , '\n' );
@@ -1218,14 +1223,18 @@ send_message_to_server_log(ErrorData *edata)
1218
1223
{
1219
1224
/* assume no newlines in funcname or filename... */
1220
1225
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" ),
1223
1229
edata -> funcname , edata -> filename ,
1224
1230
edata -> lineno );
1231
+ }
1225
1232
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" ),
1228
1236
edata -> filename , edata -> lineno );
1237
+ }
1229
1238
}
1230
1239
}
1231
1240
@@ -1234,7 +1243,7 @@ send_message_to_server_log(ErrorData *edata)
1234
1243
*/
1235
1244
if (edata -> elevel >= log_min_error_statement && debug_query_string != NULL )
1236
1245
{
1237
- appendStringInfoString (& buf , log_line_prefix () );
1246
+ log_line_prefix (& buf );
1238
1247
appendStringInfoString (& buf , gettext ("STATEMENT: " ));
1239
1248
append_with_tabs (& buf , debug_query_string );
1240
1249
appendStringInfoChar (& buf , '\n' );
@@ -1284,11 +1293,7 @@ send_message_to_server_log(ErrorData *edata)
1284
1293
/* Write to stderr, if enabled */
1285
1294
if (Use_syslog <= 1 || whereToSendOutput == Debug )
1286
1295
{
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 );
1292
1297
}
1293
1298
1294
1299
pfree (buf .data );
0 commit comments