diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 3f627dc..7100881 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -15293,6 +15293,12 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n);
+ pg_current_logfile()
+ text
+ current log file used by the logging collector
+
+
+
session_user
name
session user name
@@ -15499,6 +15505,17 @@ SET search_path TO schema> , schema>, ..
pg_notification_queue_usage
+
+ pg_current_logfile
+
+
+
+ pg_current_logfile returns the name of the
+ current log file used by the logging collector, as
+ text. Log collection must be active or the
+ return value is undefined.
+
+
pg_listening_channels returns a set of names of
asynchronous notification channels that the current session is listening
diff --git a/doc/src/sgml/storage.sgml b/doc/src/sgml/storage.sgml
index 1b812bd..7dae000 100644
--- a/doc/src/sgml/storage.sgml
+++ b/doc/src/sgml/storage.sgml
@@ -170,6 +170,13 @@ last started with
(this file is not present after server shutdown)
+
+ pg_log_file>
+ A file recording the current log file used by the syslogger
+ when log collection is active
+
+
+
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c
index e7e488a..0e25aa6 100644
--- a/src/backend/postmaster/syslogger.c
+++ b/src/backend/postmaster/syslogger.c
@@ -145,6 +145,7 @@ static char *logfile_getname(pg_time_t timestamp, const char *suffix);
static void set_next_rotation_time(void);
static void sigHupHandler(SIGNAL_ARGS);
static void sigUsr1Handler(SIGNAL_ARGS);
+static void logfile_writename(char *filename);
/*
@@ -571,6 +572,8 @@ SysLogger_Start(void)
syslogFile = logfile_open(filename, "a", false);
+ logfile_writename(filename);
+
pfree(filename);
#ifdef EXEC_BACKEND
@@ -1209,6 +1212,8 @@ logfile_rotate(bool time_based_rotation, int size_rotation_for)
fclose(syslogFile);
syslogFile = fh;
+ logfile_writename(filename);
+
/* instead of pfree'ing filename, remember it for next time */
if (last_file_name != NULL)
pfree(last_file_name);
@@ -1253,6 +1258,8 @@ logfile_rotate(bool time_based_rotation, int size_rotation_for)
fclose(csvlogFile);
csvlogFile = fh;
+ logfile_writename(csvfilename);
+
/* instead of pfree'ing filename, remember it for next time */
if (last_csv_file_name != NULL)
pfree(last_csv_file_name);
@@ -1362,3 +1369,47 @@ sigUsr1Handler(SIGNAL_ARGS)
errno = save_errno;
}
+
+
+/*
+ * Store the name of the file where current log messages are written when
+ * log collector is enabled. Useful to find the name of the current log file
+ * when a time-based rotation is defined. Filename is first stored into a
+ * temporary file and renamed into the final destination.
+ */
+static void
+logfile_writename(char *filename)
+{
+ FILE *fh;
+ char tempfn[MAXPGPATH];
+ char logpathfilename[MAXPGPATH];
+
+ snprintf(tempfn, sizeof(tempfn), "%s",
+ CURRENT_LOG_FILENAME);
+ strcat(tempfn, ".tmp");
+ snprintf(logpathfilename, sizeof(logpathfilename), "%s",
+ CURRENT_LOG_FILENAME);
+ if ((fh = logfile_open(tempfn, "w", true) ) == NULL)
+ {
+ return;
+ }
+ if (fprintf(fh, "%s\n", filename) < 0)
+ {
+ ereport(LOG,
+ (errcode_for_file_access(),
+ errmsg("could not write log file \"%s\": %m",
+ tempfn)));
+ fclose(fh);
+ return;
+ }
+ fclose(fh);
+
+ if (rename(tempfn, logpathfilename) != 0)
+ {
+ ereport(LOG,
+ (errcode_for_file_access(),
+ errmsg("could not rename file \"%s\": %m",
+ tempfn)));
+ return;
+ }
+}
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index a44fa38..c67e07b 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -890,3 +890,59 @@ parse_ident(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(makeArrayResult(astate, CurrentMemoryContext));
}
+
+/*
+ * Report current log file used by log collector
+ */
+Datum
+pg_current_logfile(PG_FUNCTION_ARGS)
+{
+ FILE *fd;
+ char log_filename[MAXPGPATH];
+
+ if (!Logging_collector)
+ {
+ PG_RETURN_NULL();
+ }
+
+ /*
+ * See if current log file is present
+ */
+ fd = AllocateFile(CURRENT_LOG_FILENAME, "r");
+ if (fd == NULL)
+ {
+ if (errno != ENOENT)
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not read file \"%s\": %m",
+ CURRENT_LOG_FILENAME)));
+ PG_RETURN_NULL();
+ }
+
+ /*
+ * Read first line of the file to gather current log filename
+ * registered by the syslogger.
+ */
+ fgets(log_filename, sizeof(log_filename), fd);
+
+ /* Check for a read error. */
+ if (ferror(fd))
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not read file \"%s\": %m", CURRENT_LOG_FILENAME)));
+
+ /* Close the current log filename file. */
+ if (FreeFile(fd))
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not close file \"%s\": %m", CURRENT_LOG_FILENAME)));
+
+ /* remove trailing newline */
+ if (strchr(log_filename, '\n') != NULL)
+ *strchr(log_filename, '\n') = '\0';
+
+ if (log_filename[0] == '\0')
+ PG_RETURN_NULL();
+
+ PG_RETURN_TEXT_P(cstring_to_text(log_filename));
+}
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index d94943b..32b419a 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -3159,6 +3159,8 @@ DATA(insert OID = 2621 ( pg_reload_conf PGNSP PGUID 12 1 0 0 0 f f f f t f v s
DESCR("reload configuration files");
DATA(insert OID = 2622 ( pg_rotate_logfile PGNSP PGUID 12 1 0 0 0 f f f f t f v s 0 0 16 "" _null_ _null_ _null_ _null_ _null_ pg_rotate_logfile _null_ _null_ _null_ ));
DESCR("rotate log file");
+DATA(insert OID = 3794 ( pg_current_logfile PGNSP PGUID 12 1 0 0 0 f f f f t f v s 0 0 25 "" _null_ _null_ _null_ _null_ _null_ pg_current_logfile _null_ _null_ _null_ ));
+DESCR("current logging collector file location");
DATA(insert OID = 2623 ( pg_stat_file PGNSP PGUID 12 1 0 0 0 f f f f t f v s 1 0 2249 "25" "{25,20,1184,1184,1184,1184,16}" "{i,o,o,o,o,o,o}" "{filename,size,access,modification,change,creation,isdir}" _null_ _null_ pg_stat_file_1arg _null_ _null_ _null_ ));
DESCR("get information about file");
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 356fcc6..4b3f0e9 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -466,4 +466,12 @@ extern bool has_rolreplication(Oid roleid);
extern bool BackupInProgress(void);
extern void CancelBackup(void);
+/* in backend/utils/adt/misc.c and backend/postmaster/syslogger.c */
+/*
+ * Name of file where current log messages are written when log collector is
+ * enabled. Useful to find the name of the current log file when a time-based
+ * rotation is defined.
+ */
+#define CURRENT_LOG_FILENAME "pg_log_file"
+
#endif /* MISCADMIN_H */
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 01976a1..c27f6a8 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -516,6 +516,7 @@ extern Datum pg_collation_for(PG_FUNCTION_ARGS);
extern Datum pg_relation_is_updatable(PG_FUNCTION_ARGS);
extern Datum pg_column_is_updatable(PG_FUNCTION_ARGS);
extern Datum parse_ident(PG_FUNCTION_ARGS);
+extern Datum pg_current_logfile(PG_FUNCTION_ARGS);
/* oid.c */
extern Datum oidin(PG_FUNCTION_ARGS);