diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index ae93e69..155e76b 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -15158,6 +15158,11 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); (0 if not called, directly or indirectly, from inside a trigger) + pg_current_logfile() + text + current log file used by the logging collector + + session_user name @@ -15365,6 +15370,16 @@ 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 a text. Log collection + must be active. + + 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 9b2e09e..6284d54 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..c3bf672 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 store_current_log_filename(char *filename); /* @@ -571,6 +572,9 @@ SysLogger_Start(void) syslogFile = logfile_open(filename, "a", false); + /* store information about current log filename used by log collection */ + store_current_log_filename(filename); + pfree(filename); #ifdef EXEC_BACKEND @@ -1209,6 +1213,9 @@ logfile_rotate(bool time_based_rotation, int size_rotation_for) fclose(syslogFile); syslogFile = fh; + /* store information about current log filename used by log collection */ + store_current_log_filename(filename); + /* instead of pfree'ing filename, remember it for next time */ if (last_file_name != NULL) pfree(last_file_name); @@ -1253,6 +1260,9 @@ logfile_rotate(bool time_based_rotation, int size_rotation_for) fclose(csvlogFile); csvlogFile = fh; + /* store information about current log filename used by log collection */ + store_current_log_filename(csvfilename); + /* instead of pfree'ing filename, remember it for next time */ if (last_csv_file_name != NULL) pfree(last_csv_file_name); @@ -1362,3 +1372,35 @@ 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. + */ +static void +store_current_log_filename(char *filename) +{ + FILE *fh; + char logpathfilename[MAXPGPATH]; + + snprintf(logpathfilename, sizeof(logpathfilename), "%s", + CURRENT_LOG_FILENAME); + if ((fh = fopen(logpathfilename, "w")) == NULL) + { + ereport(WARNING, + (errcode_for_file_access(), + errmsg("could not open log file \"%s\": %m", + logpathfilename))); + return; + } + if (fprintf(fh, "%s\n", filename) < 0) + { + ereport(WARNING, + (errcode_for_file_access(), + errmsg("could not write log file \"%s\": %m", + logpathfilename))); + } + fclose(fh); +} diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index 4dcc5a6..fbcd1d4 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -943,3 +943,61 @@ 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) + { + ereport(NOTICE, + (errmsg("current log can not be reported, log collection is not active"))); + 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 a595327..f0caf6f 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -3125,6 +3125,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 9200f04..a25cd5e 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -465,4 +465,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 206288d..bdc3922 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -511,6 +511,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);