Le 07/04/2016 08:30, Karl O. Pinc a écrit :
> On Thu, 7 Apr 2016 01:13:51 -0500
> "Karl O. Pinc" <k...@meme.com> wrote:
>
>> On Wed, 6 Apr 2016 23:37:09 -0500
>> "Karl O. Pinc" <k...@meme.com> wrote:
>>
>>> On Wed, 6 Apr 2016 22:26:13 -0500
>>> "Karl O. Pinc" <k...@meme.com> wrote:  
>>>> On Wed, 23 Mar 2016 23:22:26 +0100
>>>> Gilles Darold <gilles.dar...@dalibo.com> 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 <k...@meme.com>
> 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 (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to