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

Commit 2d3fe86

Browse files
committed
Add:
#log_line_prefix = '' # e.g. '<%u%%%d> ' # %u=user name %d=database name # %r=remote host and port # %p=PID %t=timestamp %i=command tag # %c=session id %l=session line number # %s=session start timestamp # %x=stop here in non-session processes # %%='%' Andrew Dunstan
1 parent af96aa9 commit 2d3fe86

File tree

9 files changed

+274
-15
lines changed

9 files changed

+274
-15
lines changed

doc/src/sgml/runtime.sgml

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.245 2004/03/07 01:02:55 neilc Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.246 2004/03/09 04:43:06 momjian Exp $
33
-->
44

55
<Chapter Id="runtime">
@@ -1972,6 +1972,98 @@ SET ENABLE_SEQSCAN TO OFF;
19721972
</listitem>
19731973
</varlistentry>
19741974

1975+
<varlistentry>
1976+
<term><varname>log_line_prefix</varname> (<type>string</type>)</term>
1977+
<listitem>
1978+
<para>
1979+
This is a <literal>printf</>-style string that is output at the
1980+
beginning of each log line. The default is an empty string.
1981+
Each recognized escape is replaced as outlined
1982+
below - anything else that looks like an escape is ignored. Other
1983+
characters are copied straight to the log line. Some escapes are
1984+
only recognised by session processes, and do not apply to
1985+
processes without controlling sessions. <application>Syslog</> produces its own
1986+
timestamp and process ID information, so you probably do not want to
1987+
use those escapes if you are using <application>syslog</>.
1988+
<informaltable>
1989+
<tgroup cols="3">
1990+
<thead>
1991+
<row>
1992+
<entry>Escape</entry>
1993+
<entry>Effect</entry>
1994+
<entry>Session only</entry>
1995+
</row>
1996+
</thead>
1997+
<tbody>
1998+
<row>
1999+
<entry><literal>%u</literal></entry>
2000+
<entry>User Name</entry>
2001+
<entry>Yes</entry>
2002+
</row>
2003+
<row>
2004+
<entry><literal>%d</literal></entry>
2005+
<entry>Database Name</entry>
2006+
<entry>Yes</entry>
2007+
</row>
2008+
<row>
2009+
<entry><literal>%r</literal></entry>
2010+
<entry>Remote Hostname or IP address, and Remote Port</entry>
2011+
<entry>Yes</entry>
2012+
</row>
2013+
<row>
2014+
<entry><literal>%p</literal></entry>
2015+
<entry>Process ID</entry>
2016+
<entry>No</entry>
2017+
</row>
2018+
<row>
2019+
<entry><literal>%t</literal></entry>
2020+
<entry>Timestamp</entry>
2021+
<entry>No</entry>
2022+
</row>
2023+
<row>
2024+
<entry><literal>%i</literal></entry>
2025+
<entry>Command Tag. This is the command which generated the log
2026+
line.</entry>
2027+
<entry>Yes</entry>
2028+
</row>
2029+
<row>
2030+
<entry><literal>%c</literal></entry>
2031+
<entry>Session ID. A unique identifier for each session.
2032+
It is 2 4-byte hexadecimal numbers separated by a dot. The numbers
2033+
are the Session Start Time and the Process ID, so this can also
2034+
be used as a space saving way of printing these items.</entry>
2035+
<entry>Yes</entry>
2036+
</row>
2037+
<row>
2038+
<entry><literal>%l</literal></entry>
2039+
<entry>Number of the log line for each process,
2040+
starting at 1</entry>
2041+
<entry>No</entry>
2042+
</row>
2043+
<row>
2044+
<entry><literal>%s</literal></entry>
2045+
<entry>Session Start Timestamp</entry>
2046+
<entry>Yes</entry>
2047+
</row>
2048+
<row>
2049+
<entry><literal>%x</literal></entry>
2050+
<entry>Does not produce any output, but tells non-session
2051+
processes to stop at this point in the string. Ignored by
2052+
session backends.</entry>
2053+
<entry>No</entry>
2054+
</row>
2055+
<row>
2056+
<entry><literal>%%</literal></entry>
2057+
<entry>literal <literal>%</></entry>
2058+
<entry>No</entry>
2059+
</row>
2060+
</tbody>
2061+
</tgroup>
2062+
</informaltable>
2063+
</para>
2064+
</listitem>
2065+
</varlistentry>
2066+
19752067
<varlistentry>
19762068
<term><varname>log_pid</varname> (<type>boolean</type>)</term>
19772069
<listitem>

src/backend/postmaster/postmaster.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
*
3838
*
3939
* IDENTIFICATION
40-
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.370 2004/03/05 01:11:04 momjian Exp $
40+
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.371 2004/03/09 04:43:06 momjian Exp $
4141
*
4242
* NOTES
4343
*
@@ -2437,6 +2437,7 @@ BackendInit(Port *port)
24372437
/* set these to empty in case they are needed before we set them up */
24382438
port->remote_host = "";
24392439
port->remote_port = "";
2440+
port->commandTag = "";
24402441

24412442
/* Save port etc. for ps status */
24422443
MyProcPort = port;
@@ -2489,7 +2490,7 @@ BackendInit(Port *port)
24892490
/* modify remote_host for use in ps status */
24902491
char tmphost[NI_MAXHOST];
24912492

2492-
snprintf(tmphost, sizeof(tmphost), "%s:%s", remote_host, remote_port);
2493+
snprintf(tmphost, sizeof(tmphost), "%s(%s)", remote_host, remote_port);
24932494
StrNCpy(remote_host, tmphost, sizeof(remote_host));
24942495
}
24952496

src/backend/tcop/postgres.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.393 2004/02/21 06:29:58 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.394 2004/03/09 04:43:07 momjian Exp $
1212
*
1313
* NOTES
1414
* this is the "main" module of the postgres backend and
@@ -3198,7 +3198,7 @@ ShowUsage(const char *title)
31983198
static void
31993199
log_disconnections(int code, Datum arg)
32003200
{
3201-
Port * port = MyProcPort;
3201+
Port *port = MyProcPort;
32023202
struct timeval end;
32033203
int hours, minutes, seconds;
32043204

src/backend/utils/error/elog.c

Lines changed: 145 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
*
3838
*
3939
* IDENTIFICATION
40-
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.126 2003/11/29 19:52:01 pgsql Exp $
40+
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.127 2004/03/09 04:43:07 momjian Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -72,6 +72,7 @@ PGErrorVerbosity Log_error_verbosity = PGERROR_VERBOSE;
7272
bool Log_timestamp = false; /* show timestamps in stderr
7373
* output */
7474
bool Log_pid = false; /* show PIDs in stderr output */
75+
char *Log_line_prefix = ""; /* format for extra log line info */
7576

7677
#ifdef HAVE_SYSLOG
7778
/*
@@ -146,7 +147,7 @@ static const char *error_severity(int elevel);
146147
static const char *print_timestamp(void);
147148
static const char *print_pid(void);
148149
static void append_with_tabs(StringInfo buf, const char *str);
149-
150+
static const char *log_line_prefix(void);
150151

151152
/*
152153
* errstart --- begin an error-reporting cycle
@@ -1022,6 +1023,138 @@ write_syslog(int level, const char *line)
10221023
}
10231024
#endif /* HAVE_SYSLOG */
10241025

1026+
/*
1027+
* Format tag info for log lines
1028+
*/
1029+
static const char *
1030+
log_line_prefix(void)
1031+
{
1032+
1033+
/* static accumulator for line numbers */
1034+
static int log_line_number = 0;
1035+
1036+
/* space for option string + one of each option, plus some room to spare */
1037+
/* Note: if more identifiers are built in this will have to increase */
1038+
static char *result = NULL;
1039+
int format_len = strlen(Log_line_prefix);
1040+
int result_len = 2*NAMEDATALEN + format_len +120 ;
1041+
1042+
if (result == NULL)
1043+
result = malloc(result_len);
1044+
result[0] = '\0';
1045+
1046+
if (format_len > 0)
1047+
{
1048+
int i,j;
1049+
char * dbname = NULL;
1050+
char * username = NULL;
1051+
time_t stamp_time;
1052+
log_line_number++;
1053+
if (MyProcPort != NULL)
1054+
{
1055+
dbname = MyProcPort->database_name;
1056+
username = MyProcPort->user_name;
1057+
if (dbname == NULL || *dbname == '\0')
1058+
dbname = gettext("[unknown]");
1059+
if (username == NULL || *username == '\0')
1060+
username = gettext("[unknown]");
1061+
}
1062+
1063+
/*
1064+
* invariant through each iteration of this loop:
1065+
* . j is the index of the trailing null on result
1066+
* . result_len - j is the number of chars we have room for
1067+
* including the trailing null
1068+
* . there is room to write at least one more non-null char plus the
1069+
* trailing null
1070+
*/
1071+
for (i = 0, j=0; i < format_len && j < result_len-1; i++)
1072+
{
1073+
if(Log_line_prefix[i] != '%')
1074+
{
1075+
/* literal char, just copy */
1076+
result[j]=Log_line_prefix[i];
1077+
j++;
1078+
result[j] = '\0';
1079+
continue;
1080+
}
1081+
else if (i == format_len - 1)
1082+
{
1083+
/* format error - skip it */
1084+
continue;
1085+
}
1086+
1087+
/* go to char after '%' */
1088+
i++;
1089+
1090+
/* in postmaster and friends, skip non-applicable options,
1091+
* stop if %x is seen
1092+
*/
1093+
if (MyProcPort == NULL)
1094+
{
1095+
if (Log_line_prefix[i] == 'x')
1096+
break;
1097+
if (strchr("udcsir",Log_line_prefix[i]) != NULL)
1098+
continue;
1099+
}
1100+
1101+
/* process the option */
1102+
switch (Log_line_prefix[i])
1103+
{
1104+
case 'u':
1105+
j += snprintf(result+j,result_len-j,"%s",username);
1106+
break;
1107+
case 'd':
1108+
j += snprintf(result+j,result_len-j,"%s",dbname);
1109+
break;
1110+
case 'c':
1111+
j += snprintf(result+j,result_len-j,"%lx.%lx",
1112+
(long)(MyProcPort->session_start.tv_sec),
1113+
(long)MyProcPid);
1114+
break;
1115+
case 'p':
1116+
j += snprintf(result+j,result_len-j,"%ld",(long)MyProcPid);
1117+
break;
1118+
case 'l':
1119+
j += snprintf(result+j,result_len-j,"%d",log_line_number);
1120+
break;
1121+
case 't':
1122+
stamp_time = time(NULL);
1123+
j += strftime(result+j, result_len-j, "%Y-%m-%d %H:%M:%S",
1124+
localtime(&stamp_time));
1125+
break;
1126+
case 's':
1127+
j += strftime(result+j, result_len-j, "%Y-%m-%d %H:%M:%S",
1128+
localtime(&(MyProcPort->session_start.tv_sec)));
1129+
break;
1130+
case 'i':
1131+
j += snprintf(result+j,result_len-j,"%s",
1132+
MyProcPort->commandTag);
1133+
break;
1134+
case 'r':
1135+
j += snprintf(result+j,result_len-j,"%s",
1136+
MyProcPort->remote_host);
1137+
if (!LogSourcePort && strlen(MyProcPort->remote_port))
1138+
j += snprintf(result+j,result_len-j,"(%s)",
1139+
MyProcPort->remote_port);
1140+
break;
1141+
case 'x':
1142+
/* non-postmaster case - just ignore */
1143+
break;
1144+
case '%':
1145+
result[j] = '%';
1146+
j++;
1147+
result[j] = '\0';
1148+
break;
1149+
default:
1150+
/* format error - skip it */
1151+
break;
1152+
}
1153+
}
1154+
}
1155+
return result;
1156+
}
1157+
10251158

10261159
/*
10271160
* Write error report to server's log
@@ -1033,7 +1166,8 @@ send_message_to_server_log(ErrorData *edata)
10331166

10341167
initStringInfo(&buf);
10351168

1036-
appendStringInfo(&buf, "%s: ", error_severity(edata->elevel));
1169+
appendStringInfo(&buf, "%s%s: ",
1170+
log_line_prefix(), error_severity(edata->elevel));
10371171

10381172
if (Log_error_verbosity >= PGERROR_VERBOSE)
10391173
{
@@ -1066,18 +1200,21 @@ send_message_to_server_log(ErrorData *edata)
10661200
{
10671201
if (edata->detail)
10681202
{
1203+
appendStringInfoString(&buf, log_line_prefix() );
10691204
appendStringInfoString(&buf, gettext("DETAIL: "));
10701205
append_with_tabs(&buf, edata->detail);
10711206
appendStringInfoChar(&buf, '\n');
10721207
}
10731208
if (edata->hint)
10741209
{
1210+
appendStringInfoString(&buf, log_line_prefix() );
10751211
appendStringInfoString(&buf, gettext("HINT: "));
10761212
append_with_tabs(&buf, edata->hint);
10771213
appendStringInfoChar(&buf, '\n');
10781214
}
10791215
if (edata->context)
10801216
{
1217+
appendStringInfoString(&buf, log_line_prefix() );
10811218
appendStringInfoString(&buf, gettext("CONTEXT: "));
10821219
append_with_tabs(&buf, edata->context);
10831220
appendStringInfoChar(&buf, '\n');
@@ -1086,11 +1223,13 @@ send_message_to_server_log(ErrorData *edata)
10861223
{
10871224
/* assume no newlines in funcname or filename... */
10881225
if (edata->funcname && edata->filename)
1089-
appendStringInfo(&buf, gettext("LOCATION: %s, %s:%d\n"),
1226+
appendStringInfo(&buf, gettext("%sLOCATION: %s, %s:%d\n"),
1227+
log_line_prefix(),
10901228
edata->funcname, edata->filename,
10911229
edata->lineno);
10921230
else if (edata->filename)
1093-
appendStringInfo(&buf, gettext("LOCATION: %s:%d\n"),
1231+
appendStringInfo(&buf, gettext("%sLOCATION: %s:%d\n"),
1232+
log_line_prefix(),
10941233
edata->filename, edata->lineno);
10951234
}
10961235
}
@@ -1100,6 +1239,7 @@ send_message_to_server_log(ErrorData *edata)
11001239
*/
11011240
if (edata->elevel >= log_min_error_statement && debug_query_string != NULL)
11021241
{
1242+
appendStringInfoString(&buf, log_line_prefix() );
11031243
appendStringInfoString(&buf, gettext("STATEMENT: "));
11041244
append_with_tabs(&buf, debug_query_string);
11051245
appendStringInfoChar(&buf, '\n');

src/backend/utils/misc/guc.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Written by Peter Eisentraut <peter_e@gmx.net>.
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.188 2004/02/23 20:45:59 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.189 2004/03/09 04:43:07 momjian Exp $
1414
*
1515
*--------------------------------------------------------------------
1616
*/
@@ -1495,6 +1495,16 @@ static struct config_string ConfigureNamesString[] =
14951495
"panic", assign_min_error_statement, NULL
14961496
},
14971497

1498+
{
1499+
{"log_line_prefix", PGC_SIGHUP, LOGGING_WHAT,
1500+
gettext_noop("Controls information prefixed to each log line"),
1501+
gettext_noop("if blank no prefix is used")
1502+
},
1503+
&Log_line_prefix,
1504+
"", NULL, NULL
1505+
},
1506+
1507+
14981508
{
14991509
{"DateStyle", PGC_USERSET, CLIENT_CONN_LOCALE,
15001510
gettext_noop("Sets the display format for date and time values."),

0 commit comments

Comments
 (0)