Le 11/03/2016 15:22, Tom Lane a écrit :
> Gilles Darold <[email protected]> writes:
>> Le 11/03/2016 10:49, Shulgin, Oleksandr a écrit :
>>> Would it make sense to have it as a symlink instead?
>> The only cons I see is that it can be more "difficult" with some
>> language to gather the real path, but do we really need it? There is
>> also little time where the symlink doesn't exist, this is when it needs
>> to be removed before being recreated to point to the new log file.
> Yeah, a symlink is impossible to update atomically (on most platforms
> anyway). Plain file containing the pathname seems better.
>
> Another point is that we might not necessarily want *only* the pathname in
> there. postmaster.pid has accreted more stuff over time, and this file
> might too. I can see wanting the syslogger PID in there, for example,
> so that onlookers can detect a totally stale file. (Not proposing this
> right now, just pointing out that it's a conceivable future feature.)
>
> regards, tom lane
Here is the patch rewritten to use alternate file
$PGDATA/pg_log_filename to store the current log filename used by
syslogger. All examples used in the first mail of this thread work the
exact same way. If there's no other remarks, I will add the patch to the
next commit fest.
Here are some additional examples with this feature.
To obtain the filling percentage of the log file when log_rotation_size
is used:
postgres=# SELECT pg_current_logfile(), (select setting::int*1000 from
pg_settings where name='log_rotation_size'), a.size size,
((a.size*100)/(select setting::int*1000 from pg_settings where
name='log_rotation_size')) percent_used FROM
pg_stat_file(pg_current_logfile())
a(size,access,modification,change,creation,isdir);
-[ RECORD 1 ]------+----------------------------------------
pg_current_logfile | pg_log/postgresql-2016-03-11_160817.log
log_rotation_size | 10240000
size | 1246000
percent_used | 12
This can help to know if the file is near to be rotated. Or if you use
time based rotation:
postgres=# select pg_current_logfile(), (select setting::int*60 from
pg_settings where name='log_rotation_age')
log_rotation_age,a.access,a.modification, (((extract(epoch from
a.modification) - extract(epoch from a.access)) * 100) / (select
setting::int*60 from pg_settings where name='log_rotation_age'))
percent_used FROM pg_stat_file(pg_current_logfile())
a(size,access,modification,change,creation,isdir);
-[ RECORD 1 ]------+----------------------------------------
pg_current_logfile | pg_log/postgresql-2016-03-11_162143.log
log_rotation_age | 3600
access | 2016-03-11 16:21:43+01
modification | 2016-03-11 16:33:12+01
percent_used | 19.1388888888889
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 4b5ee81..e6a18fc 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -15026,6 +15026,11 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n);
<entry>channel names that the session is currently listening on</entry>
</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>pg_notification_queue_usage()</function></literal></entry>
<entry><type>double</type></entry>
@@ -15264,6 +15269,16 @@ SET search_path TO <replaceable>schema</> <optional>, <replaceable>schema</>, ..
</para>
<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 a <type>text</type>. Log collection
+ must be active.
+ </para>
+
+ <indexterm>
<primary>pg_postmaster_start_time</primary>
</indexterm>
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c
index e7e488a..4769dc5 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(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not open log file \"%s\": %m",
+ logpathfilename)));
+ return;
+ }
+ if (fprintf(fh, "%s\n", filename) < 0)
+ {
+ ereport(ERROR,
+ (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 43f36db..d9b6435 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -719,3 +719,62 @@ pg_column_is_updatable(PG_FUNCTION_ARGS)
PG_RETURN_BOOL((events & REQ_EVENTS) == REQ_EVENTS);
}
+
+/*
+ * 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(WARNING,
+ (errmsg("current log can not be reported because 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 451bad7..0dc44cf 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 cc7833e..5a388ba 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -464,4 +464,13 @@ 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_filename"
+
+
#endif /* MISCADMIN_H */
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 115f8af..fd2c4ea 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -509,6 +509,7 @@ extern Datum pg_typeof(PG_FUNCTION_ARGS);
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 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