Re: [HACKERS] serverlog function (log_destination file)

Поиск
Список
Период
Сортировка
От Andreas Pflug
Тема Re: [HACKERS] serverlog function (log_destination file)
Дата
Msg-id 40C9F4C6.70705@pse-consulting.de
обсуждение исходный текст
Ответ на Re: [HACKERS] serverlog function (log_destination file)  (Bruce Momjian <pgman@candle.pha.pa.us>)
Ответы Re: [HACKERS] serverlog function (log_destination file)  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-patches
Bruce Momjian wrote:

>I was thinking of close/reopen so log files
>could be rotated.
>
>
>
Log file rotation is fine, if we find a consensus quite soon how to
implement it... Seems as if I might find some time to implement it until
feature freeze.

The attached patch has the default filename issue fixed, and
documentation. Since I don't have a doc build system functional, there
might be tag mismatches or other typos; please check. IMHO this should
be committed without waiting for log rotation stuff.

Regards,
Andreas


Index: doc/src/sgml/func.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql-server/doc/src/sgml/func.sgml,v
retrieving revision 1.206
diff -u -r1.206 func.sgml
--- doc/src/sgml/func.sgml    2 Jun 2004 21:34:49 -0000    1.206
+++ doc/src/sgml/func.sgml    11 Jun 2004 17:58:35 -0000
@@ -7308,6 +7308,53 @@
     columns do not have OIDs of their own.
    </para>

+   <indexterm zone="functions-misc">
+   <primary>pg_logfile</primary>
+   </indexterm>
+   <indexterm zone="functions-misc">
+   <primary>pg_logfile_length</primary>
+   </indexterm>
+   <para>
+    The functions shown in <xref linkend="functions-misc-logfile">
+    deal with the server log file if configured with log_destination
+    <quote>file</quote>.
+    previously stored with the <command>COMMENT</command> command.  A
+    null value is returned if no comment could be found matching the
+    specified parameters.
+   </para>
+
+   <table id="functions-misc-logfile">
+    <title>Server Logfile Functions</title>
+    <tgroup cols="3">
+     <thead>
+      <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
+     </thead>
+
+     <tbody>
+      <row>
+       <entry><literal><function>pg_logfile</function>(<parameter>size_int4</parameter>,
<parameter>offset_int4</parameter>)</literal></entry>
+       <entry><type>cstring</type></entry>
+       <entry>get a part of the server log file</entry>
+      </row>
+      <row>
+       <entry><literal><function>pg_logfile_length</function>()</literal></entry>
+       <entry><type>int4</type></entry>
+       <entry>return the current length of the server log file</entry>
+      </row>
+      </tbody>
+</tgroup>
+</table>
+<para>
+The <function>pg_logfile</function> function will return the
+       contents of the server log file, limited by the size
+       parameter. If size is NULL, a server internal limit (currently
+       50000) is applied. The position parameter determines the
+       starting position of the server log chunk to be returned. A
+       positive number or 0 will be counted from the start of the file,
+       a negative number from the end; if NULL, -size is assumed
+       (i.e. the tail of the log file).
+</para>
+
   </sect1>

  <sect1 id="functions-array">
Index: doc/src/sgml/runtime.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql-server/doc/src/sgml/runtime.sgml,v
retrieving revision 1.266
diff -u -r1.266 runtime.sgml
--- doc/src/sgml/runtime.sgml    10 Jun 2004 22:26:17 -0000    1.266
+++ doc/src/sgml/runtime.sgml    11 Jun 2004 17:58:46 -0000
@@ -1721,14 +1721,25 @@
       <listitem>
        <para>
     <productname>PostgreSQL</productname> supports several methods
-     for loggning, including <systemitem>stderr</systemitem> and
-     <systemitem>syslog</systemitem>. On Windows,
-     <systemitem>eventlog</systemitem> is also supported. Set this
+     for logging, including <systemitem>stderr</systemitem>,
+     <systemitem>file</systemitem> and <systemitem>syslog</systemitem>.
+      On Windows, <systemitem>eventlog</systemitem> is also supported. Set this
      option to a list of desired log destinations separated by a
      comma. The default is to log to <systemitem>stderr</systemitem>
      only. This option must be set at server start.
        </para>
       </listitem>
+     </varlistentry>
+
+     <varlistentry id="guc-syslog-facility" xreflabel="log_filename">
+      <term><varname>log_filename</varname> (<type>string</type>)</term>
+       <listitem>
+        <para>
+          This option sets the target filename for the log destination
+          <quote>file</quote> option. It may be specified as absolute
+          path or relative to the <application>cluster directory</application>.
+        </para>
+       </listitem>
      </varlistentry>

      <varlistentry id="guc-syslog-facility" xreflabel="syslog_facility">
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/postmaster/postmaster.c,v
retrieving revision 1.403
diff -u -r1.403 postmaster.c
--- src/backend/postmaster/postmaster.c    11 Jun 2004 03:54:43 -0000    1.403
+++ src/backend/postmaster/postmaster.c    11 Jun 2004 17:58:52 -0000
@@ -532,6 +532,9 @@
     /* If timezone is not set, determine what the OS uses */
     pg_timezone_initialize();

+    /* open alternate logfile, if any */
+    LogFileOpen();
+
 #ifdef EXEC_BACKEND
     write_nondefault_variables(PGC_POSTMASTER);
 #endif
Index: src/backend/storage/ipc/ipc.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/storage/ipc/ipc.c,v
retrieving revision 1.87
diff -u -r1.87 ipc.c
--- src/backend/storage/ipc/ipc.c    12 Dec 2003 18:45:09 -0000    1.87
+++ src/backend/storage/ipc/ipc.c    11 Jun 2004 17:58:52 -0000
@@ -111,6 +111,8 @@
                               on_proc_exit_list[on_proc_exit_index].arg);

     elog(DEBUG3, "exit(%d)", code);
+
+    LogFileClose();
     exit(code);
 }

Index: src/backend/utils/adt/misc.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/adt/misc.c,v
retrieving revision 1.34
diff -u -r1.34 misc.c
--- src/backend/utils/adt/misc.c    2 Jun 2004 21:29:29 -0000    1.34
+++ src/backend/utils/adt/misc.c    11 Jun 2004 17:58:58 -0000
@@ -103,3 +103,70 @@
 {
     PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0),SIGINT));
 }
+
+extern FILE *logfile; // in elog.c
+
+Datum pg_logfile_length(PG_FUNCTION_ARGS)
+{
+    if (logfile)
+    {
+        fflush(logfile);
+        PG_RETURN_INT32(ftell(logfile));
+    }
+    PG_RETURN_INT32(0);
+}
+
+
+#define MAXLOGFILECHUNK 50000
+Datum pg_logfile(PG_FUNCTION_ARGS)
+{
+    size_t size=MAXLOGFILECHUNK;
+    char *buf=0;
+    size_t nbytes;
+
+    char *filename = LogFileName();
+    if (filename)
+    {
+        if (!PG_ARGISNULL(0))
+            size = PG_GETARG_INT32(0);
+        if (size > MAXLOGFILECHUNK)
+        {
+            size = MAXLOGFILECHUNK;
+            ereport(WARNING,
+                    (errcode(ERRCODE_OUT_OF_MEMORY),
+                     errmsg("Maximum size is %d.", MAXLOGFILECHUNK)));
+        }
+
+        FILE *f=fopen(filename, "rb");
+        if (f)
+        {
+            if (logfile)
+                fflush(logfile);
+
+            if (PG_ARGISNULL(1))
+                fseek(f, -size, SEEK_END);
+            else
+            {
+                long pos = PG_GETARG_INT32(1);
+                if (pos >= 0)
+                    fseek(f, pos, SEEK_SET);
+                else
+                    fseek(f, pos, SEEK_END);
+            }
+            buf = palloc(size+1);
+            nbytes = fread(buf, 1, size, f);
+            buf[nbytes] = 0;
+
+            fclose(f);
+        }
+        else
+        {
+            ereport(WARNING,
+                    (errcode(ERRCODE_NO_DATA),
+                     errmsg("Could not open log file %s.", filename)));
+        }
+        free(filename);
+    }
+
+    PG_RETURN_CSTRING(buf);
+}
Index: src/backend/utils/error/elog.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/error/elog.c,v
retrieving revision 1.140
diff -u -r1.140 elog.c
--- src/backend/utils/error/elog.c    3 Jun 2004 02:08:04 -0000    1.140
+++ src/backend/utils/error/elog.c    11 Jun 2004 17:59:01 -0000
@@ -71,8 +71,10 @@
 PGErrorVerbosity Log_error_verbosity = PGERROR_VERBOSE;
 char       *Log_line_prefix = NULL; /* format for extra log line info */
 unsigned int Log_destination = LOG_DESTINATION_STDERR;
+char *Log_filename = NULL;

 bool in_fatal_exit = false;
+FILE *logfile = NULL;

 #ifdef HAVE_SYSLOG
 char       *Syslog_facility;    /* openlog() parameters */
@@ -936,6 +938,69 @@


 /*
+ * Name of configured log file, or NULL
+ * must be freed after usage
+ */
+char*
+LogFileName(void)
+{
+    if (Log_filename && (Log_destination & LOG_DESTINATION_FILE))
+    {
+        if (is_absolute_path(Log_filename))
+            return strdup(Log_filename);
+        else
+        {
+            char *buf = malloc(strlen(DataDir) + strlen(Log_filename) +2);
+            if (!buf)
+                ereport(FATAL,
+                        (errcode(ERRCODE_OUT_OF_MEMORY),
+                         errmsg("out of memory")));
+
+            sprintf(buf, "%s/%s", DataDir, Log_filename);
+
+            return buf;
+        }
+    }
+    return NULL;
+}
+
+
+/*
+ * Open log file, if configured.
+ */
+void
+LogFileOpen(void)
+{
+    char *filename = LogFileName();
+
+    if (filename)
+    {
+        LogFileClose();
+
+        logfile = fopen(filename, "ab");
+
+        if (!logfile)
+            ereport(WARNING,
+                    (errcode(ERRCODE_CONFIG_FILE_ERROR),
+                     errmsg("could not open log file %s", filename)));
+
+        free(filename);
+    }
+}
+
+
+/*
+ * Close log file, if open.
+ */
+void
+LogFileClose(void)
+{
+    if (logfile)
+        fclose(logfile);
+    logfile = NULL;
+}
+
+/*
  * Initialization of error output file
  */
 void
@@ -1445,6 +1510,11 @@
     if ((Log_destination & LOG_DESTINATION_STDERR) || whereToSendOutput == Debug)
     {
         fprintf(stderr, "%s", buf.data);
+    }
+
+    if (logfile && (Log_destination & LOG_DESTINATION_FILE))
+    {
+        fprintf(logfile, "%s", buf.data);
     }

     pfree(buf.data);
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/misc/guc.c,v
retrieving revision 1.211
diff -u -r1.211 guc.c
--- src/backend/utils/misc/guc.c    11 Jun 2004 03:54:54 -0000    1.211
+++ src/backend/utils/misc/guc.c    11 Jun 2004 17:59:09 -0000
@@ -76,6 +76,8 @@
 static const char *assign_log_destination(const char *value,
                 bool doit, GucSource source);

+extern char *Log_filename;
+
 #ifdef HAVE_SYSLOG
 extern char *Syslog_facility;
 extern char *Syslog_ident;
@@ -1644,13 +1646,23 @@
     {
         {"log_destination", PGC_POSTMASTER, LOGGING_WHERE,
          gettext_noop("Sets the target for log output."),
-         gettext_noop("Valid values are combinations of stderr, syslog "
+         gettext_noop("Valid values are combinations of stderr, file, syslog "
                       "and eventlog, depending on platform."),
          GUC_LIST_INPUT | GUC_REPORT
         },
         &log_destination_string,
         "stderr", assign_log_destination, NULL
     },
+    {
+        {"log_filename", PGC_POSTMASTER, LOGGING_WHERE,
+         gettext_noop("Sets the target filename for log output."),
+         gettext_noop("May be specified as relative to the cluster directory "
+                      "or as absolute path."),
+         GUC_LIST_INPUT | GUC_REPORT
+        },
+        &Log_filename,
+        "postgresql.log", NULL, NULL
+    },

 #ifdef HAVE_SYSLOG
     {
@@ -4779,6 +4791,8 @@

         if (pg_strcasecmp(tok,"stderr") == 0)
             newlogdest |= LOG_DESTINATION_STDERR;
+        else if (pg_strcasecmp(tok,"file") == 0)
+            newlogdest |= LOG_DESTINATION_FILE;
 #ifdef HAVE_SYSLOG
         else if (pg_strcasecmp(tok,"syslog") == 0)
             newlogdest |= LOG_DESTINATION_SYSLOG;
Index: src/backend/utils/misc/postgresql.conf.sample
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/misc/postgresql.conf.sample,v
retrieving revision 1.113
diff -u -r1.113 postgresql.conf.sample
--- src/backend/utils/misc/postgresql.conf.sample    7 Apr 2004 05:05:50 -0000    1.113
+++ src/backend/utils/misc/postgresql.conf.sample    11 Jun 2004 17:59:10 -0000
@@ -147,9 +147,10 @@

 # - Where to Log -

-#log_destination = 'stderr'    # Valid values are combinations of stderr,
+#log_destination = 'stderr'    # Valid values are combinations of stderr, file,
                                 # syslog and eventlog, depending on
                                 # platform.
+#log_filename = 'postgresql.log'
 #syslog_facility = 'LOCAL0'
 #syslog_ident = 'postgres'

Index: src/include/catalog/pg_proc.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/catalog/pg_proc.h,v
retrieving revision 1.335
diff -u -r1.335 pg_proc.h
--- src/include/catalog/pg_proc.h    6 Jun 2004 19:07:00 -0000    1.335
+++ src/include/catalog/pg_proc.h    11 Jun 2004 17:59:25 -0000
@@ -3588,6 +3588,15 @@
 DATA(insert OID = 2243 ( bit_or                           PGNSP PGUID 12 t f f f i 1 1560 "1560" _null_
aggregate_dummy- _null_)); 
 DESCR("bitwise-or bit aggregate");

+DATA(insert OID = 2546(  int2array_int2vector_eq       PGNSP PGUID 12 f f t f i 2 16 "1005 22" _null_
int2array_int2vector_eq- _null_ )); 
+DESCR("int2array int2vector equal");
+
+DATA(insert OID = 2550(  pg_logfile_length               PGNSP PGUID 12 f f f f v 0 23 "" _null_ pg_logfile_length -
_null_)); 
+DESCR("length of log file");
+DATA(insert OID = 2551(  pg_logfile                       PGNSP PGUID 12 f f f f v 2 2275 "23 23" _null_ pg_logfile -
_null_)); 
+DESCR("return log file contents");
+
+
 /*
  * Symbolic values for provolatile column: these indicate whether the result
  * of a function is dependent *only* on the values of its explicit arguments,
Index: src/include/utils/builtins.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/utils/builtins.h,v
retrieving revision 1.241
diff -u -r1.241 builtins.h
--- src/include/utils/builtins.h    2 Jun 2004 21:29:29 -0000    1.241
+++ src/include/utils/builtins.h    11 Jun 2004 17:59:27 -0000
@@ -356,6 +356,8 @@
 extern Datum current_database(PG_FUNCTION_ARGS);
 extern Datum pg_terminate_backend(PG_FUNCTION_ARGS);
 extern Datum pg_cancel_backend(PG_FUNCTION_ARGS);
+extern Datum pg_logfile_length(PG_FUNCTION_ARGS);
+extern Datum pg_logfile(PG_FUNCTION_ARGS);

 /* not_in.c */
 extern Datum int4notin(PG_FUNCTION_ARGS);
Index: src/include/utils/elog.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/utils/elog.h,v
retrieving revision 1.68
diff -u -r1.68 elog.h
--- src/include/utils/elog.h    5 Apr 2004 03:02:10 -0000    1.68
+++ src/include/utils/elog.h    11 Jun 2004 17:59:28 -0000
@@ -182,8 +182,12 @@
 #define LOG_DESTINATION_STDERR   1
 #define LOG_DESTINATION_SYSLOG   2
 #define LOG_DESTINATION_EVENTLOG 4
+#define LOG_DESTINATION_FILE     8

 /* Other exported functions */
 extern void DebugFileOpen(void);
+extern char *LogFileName(void);
+extern void LogFileOpen(void);
+extern void LogFileClose(void);

 #endif   /* ELOG_H */

В списке pgsql-patches по дате отправления:

Предыдущее
От: Bruce Momjian
Дата:
Сообщение: Re: pg_ctl using START with paths needing quotes
Следующее
От: Tom Lane
Дата:
Сообщение: Re: [HACKERS] serverlog function (log_destination file)