Le 07/04/2016 08:30, Karl O. Pinc a écrit :
> On Thu, 7 Apr 2016 01:13:51 -0500
> "Karl O. Pinc" <[email protected]> wrote:
>
>> On Wed, 6 Apr 2016 23:37:09 -0500
>> "Karl O. Pinc" <[email protected]> wrote:
>>
>>> On Wed, 6 Apr 2016 22:26:13 -0500
>>> "Karl O. Pinc" <[email protected]> wrote:
>>>> On Wed, 23 Mar 2016 23:22:26 +0100
>>>> Gilles Darold <[email protected]> wrote:
>>>>
>>>>> Thanks for the reminder, here is the v3 of the patch after a
>>>>> deeper review and testing. It is now registered to the next
>>>>> commit fest under the System Administration topic.
>> This is what I see at the moment. I'll wait for replies
>> before looking further and writing more.
> Er, one more thing. Isn't it true that in logfile_rotate()
> you only need to call store_current_log_filename() when
> logfile_open() is called with a "w" mode, and never need to
> call it when logfile_open() is called with an "a" mode?
>
>
> Karl <[email protected]>
> Free Software: "You don't pay back, you pay forward."
> -- Robert A. Heinlein
>
>
Hi Karl,
Thank you very much for the patch review and please apologies this too
long response delay. I was traveling since end of April and totally
forgotten this patch. I have applied all your useful feedbacks on the
patch and attached a new one (v4) to this email :
- Fix the missing <row> in doc/src/sgml/func.sgml
- Rewrite pg_current_logfile descritption as suggested
- Remove comment in src/backend/postmaster/syslogger.c
- Use pgrename to first write the filename to a temporary file
before overriding the last log file.
- Rename store_current_log_filename() into logfile_writename() -
logfile_getname is used to retrieve the filename.
- Use logfile_open() to enable CRLF line endings on Windows
- Change log level for when it can't create pg_log_file, from
WARNING to LOG
- Remove NOTICE message when the syslogger is not enabled, the
function return null.
On other questions:
> "src/backend/postmaster/syslogger.c expects to see fopen() fail with
ENFILE and EMFILE. What will you do if you get these?"
- Nothing, if the problem occurs during the log rotate call, then
log rotation file is disabled so logfile_writename() will not be called.
Case where the problem occurs between the rotation call and the
logfile_writename() call is possible but I don't think that it will be
useful to try again. In this last case log filename will be updated
during next rotation.
> "Have you given any thought as to when logfile_rotate() is called?
Since logfile_rotate() itself logs with ereport(), it would _seem_ safe
to ereport() from within your store_current_log_filename(), called from
within logfile_rotate()."
- Other part of logfile_rotate() use ereport() so I guess it is safe
to use it.
> "The indentation of the ereport(), in the part that continues over
multiple lines"
- This was my first thought but seeing what is done in the other
call to ereport() I think I have done it the right way.
> "Isn't it true that in logfile_rotate() you only need to call
store_current_log_filename() when logfile_open() is called with a "w"
mode, and never need to call it when logfile_open() is called with an
"a" mode?"
- No, it is false, append mode is used when logfile_rotate used an
existing file but the filename still change.
Best regards,
--
Gilles Darold
Consultant PostgreSQL
http://dalibo.com - http://dalibo.org
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);
</row>
<row>
+ <entry><literal><function>pg_current_logfile()</function></literal></entry>
+ <entry><type>text</type></entry>
+ <entry>current log file used by the logging collector</entry>
+ </row>
+
+ <row>
<entry><literal><function>session_user</function></literal></entry>
<entry><type>name</type></entry>
<entry>session user name</entry>
@@ -15499,6 +15505,17 @@ SET search_path TO <replaceable>schema</> <optional>, <replaceable>schema</>, ..
<primary>pg_notification_queue_usage</primary>
</indexterm>
+ <indexterm>
+ <primary>pg_current_logfile</primary>
+ </indexterm>
+
+ <para>
+ <function>pg_current_logfile</function> returns the name of the
+ current log file used by the logging collector, as
+ <type>text</type>. Log collection must be active or the
+ return value is undefined.
+ </para>
+
<para>
<function>pg_listening_channels</function> 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</entry>
(this file is not present after server shutdown)</entry>
</row>
+<row>
+ <entry><filename>pg_log_file</></entry>
+ <entry>A file recording the current log file used by the syslogger
+ when log collection is active</entry>
+</row>
+
+
</tbody>
</tgroup>
</table>
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);
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers