summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2025-04-07 14:57:26 +0000
committerTom Lane2025-04-07 15:06:05 +0000
commit3516ea768c92ad0abc16dc4dd97e5eef6eab4237 (patch)
treed15a5f73490851f950891dee762786e330c1a975
parent8f5e419484c3efb613d971ec25b9bf344db3d0b0 (diff)
Add local-address escape "%L" to log_line_prefix.
This escape shows the numeric server IP address that the client has connected to. Unix-socket connections will show "[local]". Non-client processes (e.g. background processes) will show "[none]". We expect that this option will be of interest to only a fairly small number of users. Therefore the implementation is optimized for the case where it's not used (that is, we don't do the string conversion until we have to), and we've not added the field to csvlog or jsonlog formats. Author: Greg Sabino Mullane <[email protected]> Reviewed-by: Cary Huang <[email protected]> Reviewed-by: David Steele <[email protected]> Reviewed-by: Jim Jones <[email protected]> Reviewed-by: Tom Lane <[email protected]> Discussion: https://postgr.es/m/CAKAnmmK-U+UicE-qbNU23K--Q5XTLdM6bj+gbkZBZkjyjrd3Ow@mail.gmail.com
-rw-r--r--doc/src/sgml/config.sgml6
-rw-r--r--src/backend/utils/error/elog.c33
-rw-r--r--src/backend/utils/misc/postgresql.conf.sample1
-rw-r--r--src/include/libpq/libpq-be.h3
4 files changed, 43 insertions, 0 deletions
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index fea683cb49c..a8542fe41ce 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -7690,6 +7690,12 @@ local0.* /var/log/postgresql
<entry>yes</entry>
</row>
<row>
+ <entry><literal>%L</literal></entry>
+ <entry>Local address (the IP address on the server that the
+ client connected to)</entry>
+ <entry>yes</entry>
+ </row>
+ <row>
<entry><literal>%b</literal></entry>
<entry>Backend type</entry>
<entry>no</entry>
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 8a6b6905079..d6299633ab7 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -67,6 +67,7 @@
#endif
#include "access/xact.h"
+#include "common/ip.h"
#include "libpq/libpq.h"
#include "libpq/pqformat.h"
#include "mb/pg_wchar.h"
@@ -3084,6 +3085,38 @@ log_status_format(StringInfo buf, const char *format, ErrorData *edata)
appendStringInfoSpaces(buf,
padding > 0 ? padding : -padding);
break;
+ case 'L':
+ {
+ const char *local_host;
+
+ if (MyProcPort)
+ {
+ if (MyProcPort->local_host[0] == '\0')
+ {
+ /*
+ * First time through: cache the lookup, since it
+ * might not have trivial cost.
+ */
+ (void) pg_getnameinfo_all(&MyProcPort->laddr.addr,
+ MyProcPort->laddr.salen,
+ MyProcPort->local_host,
+ sizeof(MyProcPort->local_host),
+ NULL, 0,
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ }
+ local_host = MyProcPort->local_host;
+ }
+ else
+ {
+ /* Background process, or connection not yet made */
+ local_host = "[none]";
+ }
+ if (padding != 0)
+ appendStringInfo(buf, "%*s", padding, local_host);
+ else
+ appendStringInfoString(buf, local_host);
+ }
+ break;
case 'r':
if (MyProcPort && MyProcPort->remote_host)
{
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index bcd4e67f43e..25fe90a430f 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -604,6 +604,7 @@
# %d = database name
# %r = remote host and port
# %h = remote host
+ # %L = local address
# %b = backend type
# %p = process ID
# %P = process ID of parallel group leader
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index 0d1f1838f73..d6e671a6382 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -139,6 +139,9 @@ typedef struct Port
int remote_hostname_errcode; /* see above */
char *remote_port; /* text rep of remote port */
+ /* local_host is filled only if needed (see log_status_format) */
+ char local_host[64]; /* ip addr of local socket for client conn */
+
/*
* Information that needs to be saved from the startup packet and passed
* into backend execution. "char *" fields are NULL if not set.