77 *-------------------------------------------------------------------------
88 */
99
10- #include "postgres_fe.h"
11- #include "pgtime.h"
12-
1310#include <errno.h>
1411#include <pthread.h>
1512#include <stdio.h>
1613#include <string.h>
14+ #include <sys/stat.h>
1715#include <time.h>
1816
1917#include "logger.h"
@@ -25,6 +23,7 @@ intlog_level = INFO;
2523char * log_filename = NULL ;
2624char * error_log_filename = NULL ;
2725char * log_directory = NULL ;
26+ char log_path [MAXPGPATH ]= "" ;
2827
2928int log_rotation_size = 0 ;
3029int log_rotation_age = 0 ;
@@ -47,7 +46,7 @@ static void elog_internal(int elevel, const char *fmt, va_list args)
4746/* Functions to work with log files */
4847static void open_logfile (void );
4948static void release_logfile (void );
50- static char * logfile_getname (pg_time_t timestamp );
49+ static char * logfile_getname (time_t timestamp );
5150static FILE * logfile_open (const char * filename ,const char * mode );
5251
5352/* Static variables */
@@ -60,43 +59,47 @@ static bool logging_to_file = false;
6059
6160static pthread_mutex_t log_file_mutex = PTHREAD_MUTEX_INITIALIZER ;
6261
63- /*
64- * Logs to stderr or to log file and exit if ERROR or FATAL.
65- *
66- * Actual implementation for elog() and pg_log().
67- */
6862static void
69- elog_internal ( int elevel , const char * fmt , va_list args )
63+ write_elevel ( FILE * stream , int elevel )
7064{
71- bool wrote_to_file = false;
72-
7365switch (elevel )
7466{
7567case LOG :
76- fputs ("LOG: " ,stderr );
68+ fputs ("LOG: " ,stream );
7769break ;
7870case INFO :
79- fputs ("INFO: " ,stderr );
71+ fputs ("INFO: " ,stream );
8072break ;
8173case NOTICE :
82- fputs ("NOTICE: " ,stderr );
74+ fputs ("NOTICE: " ,stream );
8375break ;
8476case WARNING :
85- fputs ("WARNING: " ,stderr );
77+ fputs ("WARNING: " ,stream );
8678break ;
8779case ERROR :
88- fputs ("ERROR: " ,stderr );
80+ fputs ("ERROR: " ,stream );
8981break ;
9082case FATAL :
91- fputs ("FATAL: " ,stderr );
83+ fputs ("FATAL: " ,stream );
9284break ;
9385case PANIC :
94- fputs ("PANIC: " ,stderr );
86+ fputs ("PANIC: " ,stream );
9587break ;
9688default :
9789elog (ERROR ,"invalid logging level: %d" ,elevel );
9890break ;
9991}
92+ }
93+
94+ /*
95+ * Logs to stderr or to log file and exit if ERROR or FATAL.
96+ *
97+ * Actual implementation for elog() and pg_log().
98+ */
99+ static void
100+ elog_internal (int elevel ,const char * fmt ,va_list args )
101+ {
102+ bool wrote_to_file = false;
100103
101104pthread_mutex_lock (& log_file_mutex );
102105
@@ -112,6 +115,8 @@ elog_internal(int elevel, const char *fmt, va_list args)
112115if (log_file == NULL )
113116open_logfile ();
114117
118+ write_elevel (log_file ,elevel );
119+
115120vfprintf (log_file ,fmt ,args );
116121fputc ('\n' ,log_file );
117122fflush (log_file );
@@ -127,6 +132,8 @@ elog_internal(int elevel, const char *fmt, va_list args)
127132if (!wrote_to_file ||
128133elevel >=ERROR )
129134{
135+ write_elevel (stderr ,elevel );
136+
130137vfprintf (stderr ,fmt ,args );
131138fputc ('\n' ,stderr );
132139fflush (stderr );
@@ -203,20 +210,24 @@ pg_log(eLogType type, const char *fmt, ...)
203210 * Result is palloc'd.
204211 */
205212static char *
206- logfile_getname (pg_time_t timestamp )
213+ logfile_getname (time_t timestamp )
207214{
208215char * filename ;
209216size_t len ;
217+ struct tm * tm = localtime (& timestamp );
218+
219+ if (log_path [0 ]== '\0' )
220+ elog (ERROR ,"logging path is not set" );
210221
211222filename = (char * )palloc (MAXPGPATH );
212223
213- snprintf (filename ,MAXPGPATH ,"%s/" ,log_directory );
224+ snprintf (filename ,MAXPGPATH ,"%s/" ,log_path );
214225
215226len = strlen (filename );
216227
217- /*treat pgaudit. log_filename as a strftime pattern */
218- pg_strftime ( filename + len ,MAXPGPATH - len ,log_filename ,
219- pg_localtime ( & timestamp , log_timezone ));
228+ /*Treat log_filename as a strftime pattern */
229+ if ( strftime ( filename + len ,MAXPGPATH - len ,log_filename ,tm ) <= 0 )
230+ elog ( ERROR , "strftime(%s) failed: %s" , log_filename , strerror ( errno ));
220231
221232return filename ;
222233}
@@ -229,6 +240,11 @@ logfile_open(const char *filename, const char *mode)
229240{
230241FILE * fh ;
231242
243+ /*
244+ * Create log directory if not present; ignore errors
245+ */
246+ mkdir (log_path ,S_IRWXU );
247+
232248fh = fopen (filename ,mode );
233249
234250if (fh )
@@ -257,7 +273,7 @@ open_logfile(void)
257273
258274log_file = logfile_open (filename ,"a" );
259275
260- if (last_file_name != NULL )/* probably shouldn't happen */
276+ if (last_file_name != NULL )
261277pfree (last_file_name );
262278
263279last_file_name = filename ;