7
7
*-------------------------------------------------------------------------
8
8
*/
9
9
10
- #include "postgres_fe.h"
11
- #include "pgtime.h"
12
-
13
10
#include <errno.h>
14
11
#include <pthread.h>
15
12
#include <stdio.h>
16
13
#include <string.h>
14
+ #include <sys/stat.h>
17
15
#include <time.h>
18
16
19
17
#include "logger.h"
@@ -25,6 +23,7 @@ int log_level = INFO;
25
23
char * log_filename = NULL ;
26
24
char * error_log_filename = NULL ;
27
25
char * log_directory = NULL ;
26
+ char log_path [MAXPGPATH ] = "" ;
28
27
29
28
int log_rotation_size = 0 ;
30
29
int log_rotation_age = 0 ;
@@ -47,7 +46,7 @@ static void elog_internal(int elevel, const char *fmt, va_list args)
47
46
/* Functions to work with log files */
48
47
static void open_logfile (void );
49
48
static void release_logfile (void );
50
- static char * logfile_getname (pg_time_t timestamp );
49
+ static char * logfile_getname (time_t timestamp );
51
50
static FILE * logfile_open (const char * filename , const char * mode );
52
51
53
52
/* Static variables */
@@ -60,43 +59,47 @@ static bool logging_to_file = false;
60
59
61
60
static pthread_mutex_t log_file_mutex = PTHREAD_MUTEX_INITIALIZER ;
62
61
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
- */
68
62
static void
69
- elog_internal ( int elevel , const char * fmt , va_list args )
63
+ write_elevel ( FILE * stream , int elevel )
70
64
{
71
- bool wrote_to_file = false;
72
-
73
65
switch (elevel )
74
66
{
75
67
case LOG :
76
- fputs ("LOG: " , stderr );
68
+ fputs ("LOG: " , stream );
77
69
break ;
78
70
case INFO :
79
- fputs ("INFO: " , stderr );
71
+ fputs ("INFO: " , stream );
80
72
break ;
81
73
case NOTICE :
82
- fputs ("NOTICE: " , stderr );
74
+ fputs ("NOTICE: " , stream );
83
75
break ;
84
76
case WARNING :
85
- fputs ("WARNING: " , stderr );
77
+ fputs ("WARNING: " , stream );
86
78
break ;
87
79
case ERROR :
88
- fputs ("ERROR: " , stderr );
80
+ fputs ("ERROR: " , stream );
89
81
break ;
90
82
case FATAL :
91
- fputs ("FATAL: " , stderr );
83
+ fputs ("FATAL: " , stream );
92
84
break ;
93
85
case PANIC :
94
- fputs ("PANIC: " , stderr );
86
+ fputs ("PANIC: " , stream );
95
87
break ;
96
88
default :
97
89
elog (ERROR , "invalid logging level: %d" , elevel );
98
90
break ;
99
91
}
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;
100
103
101
104
pthread_mutex_lock (& log_file_mutex );
102
105
@@ -112,6 +115,8 @@ elog_internal(int elevel, const char *fmt, va_list args)
112
115
if (log_file == NULL )
113
116
open_logfile ();
114
117
118
+ write_elevel (log_file , elevel );
119
+
115
120
vfprintf (log_file , fmt , args );
116
121
fputc ('\n' , log_file );
117
122
fflush (log_file );
@@ -127,6 +132,8 @@ elog_internal(int elevel, const char *fmt, va_list args)
127
132
if (!wrote_to_file ||
128
133
elevel >= ERROR )
129
134
{
135
+ write_elevel (stderr , elevel );
136
+
130
137
vfprintf (stderr , fmt , args );
131
138
fputc ('\n' , stderr );
132
139
fflush (stderr );
@@ -203,20 +210,24 @@ pg_log(eLogType type, const char *fmt, ...)
203
210
* Result is palloc'd.
204
211
*/
205
212
static char *
206
- logfile_getname (pg_time_t timestamp )
213
+ logfile_getname (time_t timestamp )
207
214
{
208
215
char * filename ;
209
216
size_t len ;
217
+ struct tm * tm = localtime (& timestamp );
218
+
219
+ if (log_path [0 ] == '\0' )
220
+ elog (ERROR , "logging path is not set" );
210
221
211
222
filename = (char * ) palloc (MAXPGPATH );
212
223
213
- snprintf (filename , MAXPGPATH , "%s/" , log_directory );
224
+ snprintf (filename , MAXPGPATH , "%s/" , log_path );
214
225
215
226
len = strlen (filename );
216
227
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 ));
220
231
221
232
return filename ;
222
233
}
@@ -229,6 +240,11 @@ logfile_open(const char *filename, const char *mode)
229
240
{
230
241
FILE * fh ;
231
242
243
+ /*
244
+ * Create log directory if not present; ignore errors
245
+ */
246
+ mkdir (log_path , S_IRWXU );
247
+
232
248
fh = fopen (filename , mode );
233
249
234
250
if (fh )
@@ -257,7 +273,7 @@ open_logfile(void)
257
273
258
274
log_file = logfile_open (filename , "a" );
259
275
260
- if (last_file_name != NULL ) /* probably shouldn't happen */
276
+ if (last_file_name != NULL )
261
277
pfree (last_file_name );
262
278
263
279
last_file_name = filename ;
0 commit comments