Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4334639

Browse files
committed
Allow printf-style padding specifications in log_line_prefix.
David Rowley, after a suggestion from Heikki Linnakangas. Reviewed byAlbe Laurenz, and further edited by me.
1 parentd70f8d5 commit4334639

File tree

2 files changed

+210
-39
lines changed

2 files changed

+210
-39
lines changed

‎doc/src/sgml/config.sgml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3941,8 +3941,14 @@ local0.* /var/log/postgresql
39413941
that are replaced with status information as outlined below.
39423942
Unrecognized escapes are ignored. Other
39433943
characters are copied straight to the log line. Some escapes are
3944-
only recognized by session processes, and are ignored by
3945-
background processes such as the main server process.
3944+
only recognized by session processes, and will be treated as empty by
3945+
background processes such as the main server process. Status
3946+
information may be aligned either left or right by specifying a
3947+
numeric literal after the % and before the option. A negative
3948+
value will cause the status information to be padded on the
3949+
right with spaces to give it a minimum width, whereas a positive
3950+
value will pad on the left. Padding can be useful to aid human
3951+
readability in log files.
39463952
This parameter can only be set in the <filename>postgresql.conf</>
39473953
file or on the server command line. The default is an empty string.
39483954

‎src/backend/utils/error/elog.c

Lines changed: 202 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ static char formatted_log_time[FORMATTED_TS_LEN];
167167
} while (0)
168168

169169

170+
staticconstchar*process_log_prefix_padding(constchar*p,int*padding);
170171
staticvoidlog_line_prefix(StringInfobuf,ErrorData*edata);
171172
staticvoidsend_message_to_server_log(ErrorData*edata);
172173
staticvoidsend_message_to_frontend(ErrorData*edata);
@@ -2119,6 +2120,42 @@ setup_formatted_start_time(void)
21192120
pg_localtime(&stamp_time,log_timezone));
21202121
}
21212122

2123+
/*
2124+
* process_log_prefix_padding --- helper function for processing the format
2125+
* string in log_line_prefix
2126+
*
2127+
* Note: This function returns NULL if it finds something which
2128+
* it deems invalid in the format string.
2129+
*/
2130+
staticconstchar*
2131+
process_log_prefix_padding(constchar*p,int*ppadding)
2132+
{
2133+
intpaddingsign=1;
2134+
intpadding=0;
2135+
2136+
if (*p=='-')
2137+
{
2138+
p++;
2139+
2140+
if (*p=='\0')/* Did the buf end in %- ? */
2141+
returnNULL;
2142+
paddingsign=-1;
2143+
}
2144+
2145+
2146+
/* generate an int version of the numerical string */
2147+
while (*p >='0'&&*p <='9')
2148+
padding=padding*10+ (*p++-'0');
2149+
2150+
/* format is invalid if it ends with the padding number */
2151+
if (*p=='\0')
2152+
returnNULL;
2153+
2154+
padding *=paddingsign;
2155+
*ppadding=padding;
2156+
returnp;
2157+
}
2158+
21222159
/*
21232160
* Format tag info for log lines; append to the provided buffer.
21242161
*/
@@ -2130,9 +2167,8 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
21302167

21312168
/* has counter been reset in current process? */
21322169
staticintlog_my_pid=0;
2133-
2134-
intformat_len;
2135-
inti;
2170+
intpadding;
2171+
constchar*p;
21362172

21372173
/*
21382174
* This is one of the few places where we'd rather not inherit a static
@@ -2151,23 +2187,48 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
21512187
if (Log_line_prefix==NULL)
21522188
return;/* in case guc hasn't run yet */
21532189

2154-
format_len=strlen(Log_line_prefix);
2155-
2156-
for (i=0;i<format_len;i++)
2190+
for (p=Log_line_prefix;*p!='\0';p++)
21572191
{
2158-
if (Log_line_prefix[i]!='%')
2192+
if (*p!='%')
21592193
{
21602194
/* literal char, just copy */
2161-
appendStringInfoChar(buf,Log_line_prefix[i]);
2195+
appendStringInfoChar(buf,*p);
21622196
continue;
21632197
}
2164-
/* go to char after '%' */
2165-
i++;
2166-
if (i >=format_len)
2198+
2199+
/* must be a '%', so skip to the next char */
2200+
p++;
2201+
if (*p=='\0')
21672202
break;/* format error - ignore it */
2203+
elseif (*p=='%')
2204+
{
2205+
/* string contains %% */
2206+
appendStringInfoChar(buf,'%');
2207+
continue;
2208+
}
2209+
2210+
2211+
/*
2212+
* Process any formatting which may exist after the '%'. Note that
2213+
* process_log_prefix_padding moves p past the padding number if it
2214+
* exists.
2215+
*
2216+
* Note: Since only '-', '0' to '9' are valid formatting characters
2217+
* we can do a quick check here to pre-check for formatting. If the
2218+
* char is not formatting then we can skip a useless function call.
2219+
*
2220+
* Further note: At least on some platforms, passing %*s rather than
2221+
* %s to appendStringInfo() is substantially slower, so many of the
2222+
* cases below avoid doing that unless non-zero padding is in fact
2223+
* specified.
2224+
*/
2225+
if (*p>'9')
2226+
padding=0;
2227+
elseif ((p=process_log_prefix_padding(p,&padding))==NULL)
2228+
break;
21682229

21692230
/* process the option */
2170-
switch (Log_line_prefix[i])
2231+
switch (*p)
21712232
{
21722233
case'a':
21732234
if (MyProcPort)
@@ -2176,8 +2237,15 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
21762237

21772238
if (appname==NULL||*appname=='\0')
21782239
appname=_("[unknown]");
2179-
appendStringInfoString(buf,appname);
2240+
if (padding!=0)
2241+
appendStringInfo(buf,"%*s",padding,appname);
2242+
else
2243+
appendStringInfoString(buf,appname);
21802244
}
2245+
elseif (padding!=0)
2246+
appendStringInfoSpaces(buf,
2247+
padding>0 ?padding :-padding);
2248+
21812249
break;
21822250
case'u':
21832251
if (MyProcPort)
@@ -2186,8 +2254,14 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
21862254

21872255
if (username==NULL||*username=='\0')
21882256
username=_("[unknown]");
2189-
appendStringInfoString(buf,username);
2257+
if (padding!=0)
2258+
appendStringInfo(buf,"%*s",padding,username);
2259+
else
2260+
appendStringInfoString(buf,username);
21902261
}
2262+
elseif (padding!=0)
2263+
appendStringInfoSpaces(buf,
2264+
padding>0 ?padding :-padding);
21912265
break;
21922266
case'd':
21932267
if (MyProcPort)
@@ -2196,21 +2270,44 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
21962270

21972271
if (dbname==NULL||*dbname=='\0')
21982272
dbname=_("[unknown]");
2199-
appendStringInfoString(buf,dbname);
2273+
if (padding!=0)
2274+
appendStringInfo(buf,"%*s",padding,dbname);
2275+
else
2276+
appendStringInfoString(buf,dbname);
22002277
}
2278+
elseif (padding!=0)
2279+
appendStringInfoSpaces(buf,
2280+
padding>0 ?padding :-padding);
22012281
break;
22022282
case'c':
2203-
appendStringInfo(buf,"%lx.%x", (long) (MyStartTime),MyProcPid);
2283+
if (padding!=0)
2284+
{
2285+
charstrfbuf[128];
2286+
snprintf(strfbuf,sizeof(strfbuf)-1,"%lx.%x",
2287+
(long) (MyStartTime),MyProcPid);
2288+
appendStringInfo(buf,"%*s",padding,strfbuf);
2289+
}
2290+
else
2291+
appendStringInfo(buf,"%lx.%x", (long) (MyStartTime),MyProcPid);
22042292
break;
22052293
case'p':
2206-
appendStringInfo(buf,"%d",MyProcPid);
2294+
if (padding!=0)
2295+
appendStringInfo(buf,"%*d",padding,MyProcPid);
2296+
else
2297+
appendStringInfo(buf,"%d",MyProcPid);
22072298
break;
22082299
case'l':
2209-
appendStringInfo(buf,"%ld",log_line_number);
2300+
if (padding!=0)
2301+
appendStringInfo(buf,"%*ld",padding,log_line_number);
2302+
else
2303+
appendStringInfo(buf,"%ld",log_line_number);
22102304
break;
22112305
case'm':
22122306
setup_formatted_log_time();
2213-
appendStringInfoString(buf,formatted_log_time);
2307+
if (padding!=0)
2308+
appendStringInfo(buf,"%*s",padding,formatted_log_time);
2309+
else
2310+
appendStringInfoString(buf,formatted_log_time);
22142311
break;
22152312
case't':
22162313
{
@@ -2220,13 +2317,19 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
22202317
pg_strftime(strfbuf,sizeof(strfbuf),
22212318
"%Y-%m-%d %H:%M:%S %Z",
22222319
pg_localtime(&stamp_time,log_timezone));
2223-
appendStringInfoString(buf,strfbuf);
2320+
if (padding!=0)
2321+
appendStringInfo(buf,"%*s",padding,strfbuf);
2322+
else
2323+
appendStringInfoString(buf,strfbuf);
22242324
}
22252325
break;
22262326
case's':
22272327
if (formatted_start_time[0]=='\0')
22282328
setup_formatted_start_time();
2229-
appendStringInfoString(buf,formatted_start_time);
2329+
if (padding!=0)
2330+
appendStringInfo(buf,"%*s",padding,formatted_start_time);
2331+
else
2332+
appendStringInfoString(buf,formatted_start_time);
22302333
break;
22312334
case'i':
22322335
if (MyProcPort)
@@ -2235,43 +2338,105 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
22352338
intdisplen;
22362339

22372340
psdisp=get_ps_display(&displen);
2238-
appendBinaryStringInfo(buf,psdisp,displen);
2341+
if (padding!=0)
2342+
appendStringInfo(buf,"%*s",padding,psdisp);
2343+
else
2344+
appendBinaryStringInfo(buf,psdisp,displen);
2345+
22392346
}
2347+
elseif (padding!=0)
2348+
appendStringInfoSpaces(buf,
2349+
padding>0 ?padding :-padding);
22402350
break;
22412351
case'r':
22422352
if (MyProcPort&&MyProcPort->remote_host)
22432353
{
2244-
appendStringInfoString(buf,MyProcPort->remote_host);
2245-
if (MyProcPort->remote_port&&
2246-
MyProcPort->remote_port[0]!='\0')
2247-
appendStringInfo(buf,"(%s)",
2248-
MyProcPort->remote_port);
2354+
if (padding!=0)
2355+
{
2356+
if (MyProcPort->remote_port&&MyProcPort->remote_port[0]!='\0')
2357+
{
2358+
/*
2359+
* This option is slightly special as the port number
2360+
* may be appended onto the end. Here we need to build
2361+
* 1 string which contains the remote_host and optionally
2362+
* the remote_port (if set) so we can properly align the
2363+
* string.
2364+
*/
2365+
2366+
char*hostport;
2367+
intalloclen=strlen(MyProcPort->remote_host)+
2368+
strlen(MyProcPort->remote_port)+3;
2369+
hostport=palloc(alloclen);
2370+
sprintf(hostport,"%s(%s)",MyProcPort->remote_host,MyProcPort->remote_port);
2371+
appendStringInfo(buf,"%*s",padding,hostport);
2372+
pfree(hostport);
2373+
}
2374+
else
2375+
appendStringInfo(buf,"%*s",padding,MyProcPort->remote_host);
2376+
2377+
}
2378+
else
2379+
{
2380+
/* padding is 0, so we don't need a temp buffer */
2381+
appendStringInfoString(buf,MyProcPort->remote_host);
2382+
if (MyProcPort->remote_port&&
2383+
MyProcPort->remote_port[0]!='\0')
2384+
appendStringInfo(buf,"(%s)",
2385+
MyProcPort->remote_port);
2386+
}
2387+
22492388
}
2389+
elseif (padding!=0)
2390+
appendStringInfoSpaces(buf,
2391+
padding>0 ?padding :-padding);
22502392
break;
22512393
case'h':
2252-
if (MyProcPort&&MyProcPort->remote_host)
2253-
appendStringInfoString(buf,MyProcPort->remote_host);
2394+
if (MyProcPort&&MyProcPort->remote_host)
2395+
{
2396+
if (padding!=0)
2397+
appendStringInfo(buf,"%*s",padding,MyProcPort->remote_host);
2398+
else
2399+
appendStringInfoString(buf,MyProcPort->remote_host);
2400+
}
2401+
elseif (padding!=0)
2402+
appendStringInfoSpaces(buf,
2403+
padding>0 ?padding :-padding);
22542404
break;
22552405
case'q':
22562406
/* in postmaster and friends, stop if %q is seen */
22572407
/* in a backend, just ignore */
22582408
if (MyProcPort==NULL)
2259-
i=format_len;
2409+
return;
22602410
break;
22612411
case'v':
22622412
/* keep VXID format in sync with lockfuncs.c */
22632413
if (MyProc!=NULL&&MyProc->backendId!=InvalidBackendId)
2264-
appendStringInfo(buf,"%d/%u",
2265-
MyProc->backendId,MyProc->lxid);
2414+
{
2415+
if (padding!=0)
2416+
{
2417+
charstrfbuf[128];
2418+
snprintf(strfbuf,sizeof(strfbuf)-1,"%d/%u",
2419+
MyProc->backendId,MyProc->lxid);
2420+
appendStringInfo(buf,"%*s",padding,strfbuf);
2421+
}
2422+
else
2423+
appendStringInfo(buf,"%d/%u",MyProc->backendId,MyProc->lxid);
2424+
}
2425+
elseif (padding!=0)
2426+
appendStringInfoSpaces(buf,
2427+
padding>0 ?padding :-padding);
22662428
break;
22672429
case'x':
2268-
appendStringInfo(buf,"%u",GetTopTransactionIdIfAny());
2430+
if (padding!=0)
2431+
appendStringInfo(buf,"%*u",padding,GetTopTransactionIdIfAny());
2432+
else
2433+
appendStringInfo(buf,"%u",GetTopTransactionIdIfAny());
22692434
break;
22702435
case'e':
2271-
appendStringInfoString(buf,unpack_sql_state(edata->sqlerrcode));
2272-
break;
2273-
case'%':
2274-
appendStringInfoChar(buf,'%');
2436+
if (padding!=0)
2437+
appendStringInfo(buf,"%*s",padding,unpack_sql_state(edata->sqlerrcode));
2438+
else
2439+
appendStringInfoString(buf,unpack_sql_state(edata->sqlerrcode));
22752440
break;
22762441
default:
22772442
/* format error - ignore it */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp