@@ -175,15 +175,10 @@ static const char *err_gettext(const char *str) pg_attribute_format_arg(1);
175175static pg_noinline void set_backtrace (ErrorData * edata , int num_skip );
176176static void set_errdata_field (MemoryContextData * cxt , char * * ptr , const char * str );
177177static void write_console (const char * line , int len );
178- static void setup_formatted_log_time (void );
179- static void setup_formatted_start_time (void );
180178static const char * process_log_prefix_padding (const char * p , int * padding );
181179static void log_line_prefix (StringInfo buf , ErrorData * edata );
182- static void write_csvlog (ErrorData * edata );
183180static void send_message_to_server_log (ErrorData * edata );
184- static void write_pipe_chunks (char * data , int len , int dest );
185181static void send_message_to_frontend (ErrorData * edata );
186- static const char * error_severity (int elevel );
187182static void append_with_tabs (StringInfo buf , const char * str );
188183
189184
@@ -2289,14 +2284,23 @@ write_console(const char *line, int len)
22892284}
22902285
22912286/*
2292- * setup formatted_log_time, for consistent times between CSV and regular logs
2287+ * get_formatted_log_time -- compute and get the log timestamp.
2288+ *
2289+ * The timestamp is computed if not set yet, so as it is kept consistent
2290+ * among all the log destinations that require it to be consistent. Note
2291+ * that the computed timestamp is returned in a static buffer, not
2292+ * palloc()'d.
22932293 */
2294- static void
2295- setup_formatted_log_time (void )
2294+ char *
2295+ get_formatted_log_time (void )
22962296{
22972297 pg_time_t stamp_time ;
22982298 char msbuf [13 ];
22992299
2300+ /* leave if already computed */
2301+ if (formatted_log_time [0 ] != '\0' )
2302+ return formatted_log_time ;
2303+
23002304 if (!saved_timeval_set )
23012305 {
23022306 gettimeofday (& saved_timeval , NULL );
@@ -2318,16 +2322,34 @@ setup_formatted_log_time(void)
23182322 /* 'paste' milliseconds into place... */
23192323 sprintf (msbuf , ".%03d" , (int ) (saved_timeval .tv_usec / 1000 ));
23202324 memcpy (formatted_log_time + 19 , msbuf , 4 );
2325+
2326+ return formatted_log_time ;
23212327}
23222328
23232329/*
2324- * setup formatted_start_time
2330+ * reset_formatted_start_time -- reset the start timestamp
23252331 */
2326- static void
2327- setup_formatted_start_time (void )
2332+ void
2333+ reset_formatted_start_time (void )
2334+ {
2335+ formatted_start_time [0 ] = '\0' ;
2336+ }
2337+
2338+ /*
2339+ * get_formatted_start_time -- compute and get the start timestamp.
2340+ *
2341+ * The timestamp is computed if not set yet. Note that the computed
2342+ * timestamp is returned in a static buffer, not palloc()'d.
2343+ */
2344+ char *
2345+ get_formatted_start_time (void )
23282346{
23292347 pg_time_t stamp_time = (pg_time_t ) MyStartTime ;
23302348
2349+ /* leave if already computed */
2350+ if (formatted_start_time [0 ] != '\0' )
2351+ return formatted_start_time ;
2352+
23312353 /*
23322354 * Note: we expect that guc.c will ensure that log_timezone is set up (at
23332355 * least with a minimal GMT value) before Log_line_prefix can become
@@ -2336,6 +2358,49 @@ setup_formatted_start_time(void)
23362358 pg_strftime (formatted_start_time , FORMATTED_TS_LEN ,
23372359 "%Y-%m-%d %H:%M:%S %Z" ,
23382360 pg_localtime (& stamp_time , log_timezone ));
2361+
2362+ return formatted_start_time ;
2363+ }
2364+
2365+ /*
2366+ * check_log_of_query -- check if a query can be logged
2367+ */
2368+ bool
2369+ check_log_of_query (ErrorData * edata )
2370+ {
2371+ /* log required? */
2372+ if (!is_log_level_output (edata -> elevel , log_min_error_statement ))
2373+ return false;
2374+
2375+ /* query log wanted? */
2376+ if (edata -> hide_stmt )
2377+ return false;
2378+
2379+ /* query string available? */
2380+ if (debug_query_string == NULL )
2381+ return false;
2382+
2383+ return true;
2384+ }
2385+
2386+ /*
2387+ * get_backend_type_for_log -- backend type for log entries
2388+ *
2389+ * Returns a pointer to a static buffer, not palloc()'d.
2390+ */
2391+ const char *
2392+ get_backend_type_for_log (void )
2393+ {
2394+ const char * backend_type_str ;
2395+
2396+ if (MyProcPid == PostmasterPid )
2397+ backend_type_str = "postmaster" ;
2398+ else if (MyBackendType == B_BG_WORKER )
2399+ backend_type_str = MyBgworkerEntry -> bgw_type ;
2400+ else
2401+ backend_type_str = GetBackendTypeDesc (MyBackendType );
2402+
2403+ return backend_type_str ;
23392404}
23402405
23412406/*
@@ -2397,7 +2462,7 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
23972462 {
23982463 log_line_number = 0 ;
23992464 log_my_pid = MyProcPid ;
2400- formatted_start_time [ 0 ] = '\0' ;
2465+ reset_formatted_start_time () ;
24012466 }
24022467 log_line_number ++ ;
24032468
@@ -2466,14 +2531,7 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
24662531 break ;
24672532 case 'b' :
24682533 {
2469- const char * backend_type_str ;
2470-
2471- if (MyProcPid == PostmasterPid )
2472- backend_type_str = "postmaster" ;
2473- else if (MyBackendType == B_BG_WORKER )
2474- backend_type_str = MyBgworkerEntry -> bgw_type ;
2475- else
2476- backend_type_str = GetBackendTypeDesc (MyBackendType );
2534+ const char * backend_type_str = get_backend_type_for_log ();
24772535
24782536 if (padding != 0 )
24792537 appendStringInfo (buf , "%*s" , padding , backend_type_str );
@@ -2561,7 +2619,10 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
25612619 appendStringInfo (buf , "%ld" , log_line_number );
25622620 break ;
25632621 case 'm' :
2564- setup_formatted_log_time ();
2622+ /* force a log timestamp reset */
2623+ formatted_log_time [0 ] = '\0' ;
2624+ (void ) get_formatted_log_time ();
2625+
25652626 if (padding != 0 )
25662627 appendStringInfo (buf , "%*s" , padding , formatted_log_time );
25672628 else
@@ -2602,12 +2663,14 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
26022663 }
26032664 break ;
26042665 case 's' :
2605- if (formatted_start_time [0 ] == '\0' )
2606- setup_formatted_start_time ();
2607- if (padding != 0 )
2608- appendStringInfo (buf , "%*s" , padding , formatted_start_time );
2609- else
2610- appendStringInfoString (buf , formatted_start_time );
2666+ {
2667+ char * start_time = get_formatted_start_time ();
2668+
2669+ if (padding != 0 )
2670+ appendStringInfo (buf , "%*s" , padding , start_time );
2671+ else
2672+ appendStringInfoString (buf , start_time );
2673+ }
26112674 break ;
26122675 case 'i' :
26132676 if (MyProcPort )
@@ -2758,7 +2821,7 @@ appendCSVLiteral(StringInfo buf, const char *data)
27582821 * Constructs the error message, depending on the Errordata it gets, in a CSV
27592822 * format which is described in doc/src/sgml/config.sgml.
27602823 */
2761- static void
2824+ void
27622825write_csvlog (ErrorData * edata )
27632826{
27642827 StringInfoData buf ;
@@ -2779,23 +2842,14 @@ write_csvlog(ErrorData *edata)
27792842 {
27802843 log_line_number = 0 ;
27812844 log_my_pid = MyProcPid ;
2782- formatted_start_time [ 0 ] = '\0' ;
2845+ reset_formatted_start_time () ;
27832846 }
27842847 log_line_number ++ ;
27852848
27862849 initStringInfo (& buf );
27872850
2788- /*
2789- * timestamp with milliseconds
2790- *
2791- * Check if the timestamp is already calculated for the syslog message,
2792- * and use it if so. Otherwise, get the current timestamp. This is done
2793- * to put same timestamp in both syslog and csvlog messages.
2794- */
2795- if (formatted_log_time [0 ] == '\0' )
2796- setup_formatted_log_time ();
2797-
2798- appendStringInfoString (& buf , formatted_log_time );
2851+ /* timestamp with milliseconds */
2852+ appendStringInfoString (& buf , get_formatted_log_time ());
27992853 appendStringInfoChar (& buf , ',' );
28002854
28012855 /* username */
@@ -2853,9 +2907,7 @@ write_csvlog(ErrorData *edata)
28532907 appendStringInfoChar (& buf , ',' );
28542908
28552909 /* session start timestamp */
2856- if (formatted_start_time [0 ] == '\0' )
2857- setup_formatted_start_time ();
2858- appendStringInfoString (& buf , formatted_start_time );
2910+ appendStringInfoString (& buf , get_formatted_start_time ());
28592911 appendStringInfoChar (& buf , ',' );
28602912
28612913 /* Virtual transaction id */
@@ -2906,10 +2958,7 @@ write_csvlog(ErrorData *edata)
29062958 appendStringInfoChar (& buf , ',' );
29072959
29082960 /* user query --- only reported if not disabled by the caller */
2909- if (is_log_level_output (edata -> elevel , log_min_error_statement ) &&
2910- debug_query_string != NULL &&
2911- !edata -> hide_stmt )
2912- print_stmt = true;
2961+ print_stmt = check_log_of_query (edata );
29132962 if (print_stmt )
29142963 appendCSVLiteral (& buf , debug_query_string );
29152964 appendStringInfoChar (& buf , ',' );
@@ -2943,13 +2992,7 @@ write_csvlog(ErrorData *edata)
29432992 appendStringInfoChar (& buf , ',' );
29442993
29452994 /* backend type */
2946- if (MyProcPid == PostmasterPid )
2947- appendCSVLiteral (& buf , "postmaster" );
2948- else if (MyBackendType == B_BG_WORKER )
2949- appendCSVLiteral (& buf , MyBgworkerEntry -> bgw_type );
2950- else
2951- appendCSVLiteral (& buf , GetBackendTypeDesc (MyBackendType ));
2952-
2995+ appendCSVLiteral (& buf , get_backend_type_for_log ());
29532996 appendStringInfoChar (& buf , ',' );
29542997
29552998 /* leader PID */
@@ -3101,9 +3144,7 @@ send_message_to_server_log(ErrorData *edata)
31013144 /*
31023145 * If the user wants the query that generated this error logged, do it.
31033146 */
3104- if (is_log_level_output (edata -> elevel , log_min_error_statement ) &&
3105- debug_query_string != NULL &&
3106- !edata -> hide_stmt )
3147+ if (check_log_of_query (edata ))
31073148 {
31083149 log_line_prefix (& buf , edata );
31093150 appendStringInfoString (& buf , _ ("STATEMENT: " ));
@@ -3233,7 +3274,7 @@ send_message_to_server_log(ErrorData *edata)
32333274 * warning from ignoring write()'s result, so do a little dance with casting
32343275 * rc to void to shut up the compiler.
32353276 */
3236- static void
3277+ void
32373278write_pipe_chunks (char * data , int len , int dest )
32383279{
32393280 PipeProtoChunk p ;
@@ -3469,7 +3510,7 @@ send_message_to_frontend(ErrorData *edata)
34693510 * The string is not localized here, but we mark the strings for translation
34703511 * so that callers can invoke _() on the result.
34713512 */
3472- static const char *
3513+ const char *
34733514error_severity (int elevel )
34743515{
34753516 const char * prefix ;
0 commit comments