Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit ac7c807

Browse files
committed
Refactor set of routines specific to elog.c
This refactors the following routines and facilities coming from elog.c, to ease their use across multiple log destinations: - Start timestamp, including its reset, to store when a process has been started. - The log timestamp, associated to an entry (the same timestamp is used when logging across multiple destinations). - Routine deciding if a query can be logged or not. - The backend type names, depending on the process that logs any information (postmaster, bgworker name or just GetBackendTypeDesc() with a regular backend). - Write of logs using the logging piped protocol, with the log collector enabled. - Error severity converted to a string. These refactored routines will be used for some follow-up changes to move all the csvlog logic into its own file and to potentially add JSON as log destination, reducing the overall size of elog.c as the end result. Author: Michael Paquier, Sehrope Sarkuni Reviewed-by: Nathan Bossart Discussion: https://postgr.es/m/CAH7T-aqswBM6JWe4pDehi1uOiufqe06DJWaU5=X7dDLyqUExHg@mail.gmail.com
1 parent 9a3d8e1 commit ac7c807

File tree

2 files changed

+112
-59
lines changed

2 files changed

+112
-59
lines changed

src/backend/utils/error/elog.c

Lines changed: 100 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,10 @@ static const char *err_gettext(const char *str) pg_attribute_format_arg(1);
175175
static pg_noinline void set_backtrace(ErrorData *edata, int num_skip);
176176
static void set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str);
177177
static void write_console(const char *line, int len);
178-
static void setup_formatted_log_time(void);
179-
static void setup_formatted_start_time(void);
180178
static const char *process_log_prefix_padding(const char *p, int *padding);
181179
static void log_line_prefix(StringInfo buf, ErrorData *edata);
182-
static void write_csvlog(ErrorData *edata);
183180
static void send_message_to_server_log(ErrorData *edata);
184-
static void write_pipe_chunks(char *data, int len, int dest);
185181
static void send_message_to_frontend(ErrorData *edata);
186-
static const char *error_severity(int elevel);
187182
static 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
27622825
write_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
32373278
write_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 *
34733514
error_severity(int elevel)
34743515
{
34753516
const char *prefix;

src/include/utils/elog.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,18 @@ extern void DebugFileOpen(void);
442442
extern char *unpack_sql_state(int sql_state);
443443
extern bool in_error_recursion_trouble(void);
444444

445+
/* Common functions shared across destinations */
446+
extern void reset_formatted_start_time(void);
447+
extern char *get_formatted_start_time(void);
448+
extern char *get_formatted_log_time(void);
449+
extern const char *get_backend_type_for_log(void);
450+
extern bool check_log_of_query(ErrorData *edata);
451+
extern const char *error_severity(int elevel);
452+
extern void write_pipe_chunks(char *data, int len, int dest);
453+
454+
/* Destination-specific functions */
455+
extern void write_csvlog(ErrorData *edata);
456+
445457
#ifdef HAVE_SYSLOG
446458
extern void set_syslog_parameters(const char *ident, int facility);
447459
#endif

0 commit comments

Comments
 (0)