@@ -87,7 +87,7 @@ static bool rotation_disabled = false;
8787static FILE * syslogFile = NULL ;
8888static FILE * csvlogFile = NULL ;
8989NON_EXEC_STATIC pg_time_t first_syslogger_file_time = 0 ;
90- static char * last_file_name = NULL ;
90+ static char * last_sys_file_name = NULL ;
9191static char * last_csv_file_name = NULL ;
9292
9393/*
@@ -145,6 +145,10 @@ static FILE *logfile_open(const char *filename, const char *mode,
145145static unsigned int __stdcall pipeThread (void * arg );
146146#endif
147147static void logfile_rotate (bool time_based_rotation , int size_rotation_for );
148+ static bool logfile_rotate_dest (bool time_based_rotation ,
149+ int size_rotation_for , pg_time_t fntime ,
150+ int target_dest , char * * last_file_name ,
151+ FILE * * logFile );
148152static char * logfile_getname (pg_time_t timestamp , const char * suffix );
149153static void set_next_rotation_time (void );
150154static void sigUsr1Handler (SIGNAL_ARGS );
@@ -274,7 +278,7 @@ SysLoggerMain(int argc, char *argv[])
274278 * time because passing down just the pg_time_t is a lot cheaper than
275279 * passing a whole file path in the EXEC_BACKEND case.
276280 */
277- last_file_name = logfile_getname (first_syslogger_file_time , NULL );
281+ last_sys_file_name = logfile_getname (first_syslogger_file_time , NULL );
278282 if (csvlogFile != NULL )
279283 last_csv_file_name = logfile_getname (first_syslogger_file_time , ".csv" );
280284
@@ -1242,145 +1246,138 @@ logfile_open(const char *filename, const char *mode, bool allow_errors)
12421246}
12431247
12441248/*
1245- * perform logfile rotation
1249+ * Do logfile rotation for a single destination, as specified by target_dest.
1250+ * The information stored in *last_file_name and *logFile is updated on a
1251+ * successful file rotation.
1252+ *
1253+ * Returns false if the rotation has been stopped, or true to move on to
1254+ * the processing of other formats.
12461255 */
1247- static void
1248- logfile_rotate (bool time_based_rotation , int size_rotation_for )
1256+ static bool
1257+ logfile_rotate_dest (bool time_based_rotation , int size_rotation_for ,
1258+ pg_time_t fntime , int target_dest ,
1259+ char * * last_file_name , FILE * * logFile )
12491260{
1261+ char * logFileExt ;
12501262 char * filename ;
1251- char * csvfilename = NULL ;
1252- pg_time_t fntime ;
12531263 FILE * fh ;
12541264
1255- rotation_requested = false;
1265+ /*
1266+ * If the target destination was just turned off, close the previous file
1267+ * and unregister its data. This cannot happen for stderr as syslogFile
1268+ * is assumed to be always opened even if stderr is disabled in
1269+ * log_destination.
1270+ */
1271+ if ((Log_destination & target_dest ) == 0 &&
1272+ target_dest != LOG_DESTINATION_STDERR )
1273+ {
1274+ if (* logFile != NULL )
1275+ fclose (* logFile );
1276+ * logFile = NULL ;
1277+ if (* last_file_name != NULL )
1278+ pfree (* last_file_name );
1279+ * last_file_name = NULL ;
1280+ return true;
1281+ }
12561282
12571283 /*
1258- * When doing a time-based rotation, invent the new logfile name based on
1259- * the planned rotation time, not current time, to avoid "slippage" in the
1260- * file name when we don't do the rotation immediately.
1284+ * Leave if it is not time for a rotation or if the target destination has
1285+ * no need to do a rotation based on the size of its file.
12611286 */
1262- if (time_based_rotation )
1263- fntime = next_rotation_time ;
1287+ if (!time_based_rotation && (size_rotation_for & target_dest ) == 0 )
1288+ return true;
1289+
1290+ /* file extension depends on the destination type */
1291+ if (target_dest == LOG_DESTINATION_STDERR )
1292+ logFileExt = NULL ;
1293+ else if (target_dest == LOG_DESTINATION_CSVLOG )
1294+ logFileExt = ".csv" ;
12641295 else
1265- fntime = time (NULL );
1266- filename = logfile_getname (fntime , NULL );
1267- if (Log_destination & LOG_DESTINATION_CSVLOG )
1268- csvfilename = logfile_getname (fntime , ".csv" );
1296+ {
1297+ /* cannot happen */
1298+ Assert (false);
1299+ }
1300+
1301+ /* build the new file name */
1302+ filename = logfile_getname (fntime , logFileExt );
12691303
12701304 /*
12711305 * Decide whether to overwrite or append. We can overwrite if (a)
12721306 * Log_truncate_on_rotation is set, (b) the rotation was triggered by
12731307 * elapsed time and not something else, and (c) the computed file name is
12741308 * different from what we were previously logging into.
1275- *
1276- * Note: last_file_name should never be NULL here, but if it is, append.
12771309 */
1278- if (time_based_rotation || (size_rotation_for & LOG_DESTINATION_STDERR ))
1279- {
1280- if (Log_truncate_on_rotation && time_based_rotation &&
1281- last_file_name != NULL &&
1282- strcmp (filename , last_file_name ) != 0 )
1283- fh = logfile_open (filename , "w" , true);
1284- else
1285- fh = logfile_open (filename , "a" , true);
1310+ if (Log_truncate_on_rotation && time_based_rotation &&
1311+ * last_file_name != NULL &&
1312+ strcmp (filename , * last_file_name ) != 0 )
1313+ fh = logfile_open (filename , "w" , true);
1314+ else
1315+ fh = logfile_open (filename , "a" , true);
12861316
1287- if (!fh )
1317+ if (!fh )
1318+ {
1319+ /*
1320+ * ENFILE/EMFILE are not too surprising on a busy system; just keep
1321+ * using the old file till we manage to get a new one. Otherwise,
1322+ * assume something's wrong with Log_directory and stop trying to
1323+ * create files.
1324+ */
1325+ if (errno != ENFILE && errno != EMFILE )
12881326 {
1289- /*
1290- * ENFILE/EMFILE are not too surprising on a busy system; just
1291- * keep using the old file till we manage to get a new one.
1292- * Otherwise, assume something's wrong with Log_directory and stop
1293- * trying to create files.
1294- */
1295- if (errno != ENFILE && errno != EMFILE )
1296- {
1297- ereport (LOG ,
1298- (errmsg ("disabling automatic rotation (use SIGHUP to re-enable)" )));
1299- rotation_disabled = true;
1300- }
1301-
1302- if (filename )
1303- pfree (filename );
1304- if (csvfilename )
1305- pfree (csvfilename );
1306- return ;
1327+ ereport (LOG ,
1328+ (errmsg ("disabling automatic rotation (use SIGHUP to re-enable)" )));
1329+ rotation_disabled = true;
13071330 }
13081331
1309- fclose (syslogFile );
1310- syslogFile = fh ;
1311-
1312- /* instead of pfree'ing filename, remember it for next time */
1313- if (last_file_name != NULL )
1314- pfree (last_file_name );
1315- last_file_name = filename ;
1316- filename = NULL ;
1332+ if (filename )
1333+ pfree (filename );
1334+ return false;
13171335 }
13181336
1319- /*
1320- * Same as above, but for csv file. Note that if LOG_DESTINATION_CSVLOG
1321- * was just turned on, we might have to open csvlogFile here though it was
1322- * not open before. In such a case we'll append not overwrite (since
1323- * last_csv_file_name will be NULL); that is consistent with the normal
1324- * rules since it's not a time-based rotation.
1325- */
1326- if ((Log_destination & LOG_DESTINATION_CSVLOG ) &&
1327- (csvlogFile == NULL ||
1328- time_based_rotation || (size_rotation_for & LOG_DESTINATION_CSVLOG )))
1329- {
1330- if (Log_truncate_on_rotation && time_based_rotation &&
1331- last_csv_file_name != NULL &&
1332- strcmp (csvfilename , last_csv_file_name ) != 0 )
1333- fh = logfile_open (csvfilename , "w" , true);
1334- else
1335- fh = logfile_open (csvfilename , "a" , true);
1337+ /* fill in the new information */
1338+ if (* logFile != NULL )
1339+ fclose (* logFile );
1340+ * logFile = fh ;
13361341
1337- if (!fh )
1338- {
1339- /*
1340- * ENFILE/EMFILE are not too surprising on a busy system; just
1341- * keep using the old file till we manage to get a new one.
1342- * Otherwise, assume something's wrong with Log_directory and stop
1343- * trying to create files.
1344- */
1345- if (errno != ENFILE && errno != EMFILE )
1346- {
1347- ereport (LOG ,
1348- (errmsg ("disabling automatic rotation (use SIGHUP to re-enable)" )));
1349- rotation_disabled = true;
1350- }
1342+ /* instead of pfree'ing filename, remember it for next time */
1343+ if (* last_file_name != NULL )
1344+ pfree (* last_file_name );
1345+ * last_file_name = filename ;
13511346
1352- if (filename )
1353- pfree (filename );
1354- if (csvfilename )
1355- pfree (csvfilename );
1356- return ;
1357- }
1347+ return true;
1348+ }
1349+
1350+ /*
1351+ * perform logfile rotation
1352+ */
1353+ static void
1354+ logfile_rotate (bool time_based_rotation , int size_rotation_for )
1355+ {
1356+ pg_time_t fntime ;
13581357
1359- if (csvlogFile != NULL )
1360- fclose (csvlogFile );
1361- csvlogFile = fh ;
1358+ rotation_requested = false;
13621359
1363- /* instead of pfree'ing filename, remember it for next time */
1364- if (last_csv_file_name != NULL )
1365- pfree (last_csv_file_name );
1366- last_csv_file_name = csvfilename ;
1367- csvfilename = NULL ;
1368- }
1369- else if (!(Log_destination & LOG_DESTINATION_CSVLOG ) &&
1370- csvlogFile != NULL )
1371- {
1372- /* CSVLOG was just turned off, so close the old file */
1373- fclose (csvlogFile );
1374- csvlogFile = NULL ;
1375- if (last_csv_file_name != NULL )
1376- pfree (last_csv_file_name );
1377- last_csv_file_name = NULL ;
1378- }
1360+ /*
1361+ * When doing a time-based rotation, invent the new logfile name based on
1362+ * the planned rotation time, not current time, to avoid "slippage" in the
1363+ * file name when we don't do the rotation immediately.
1364+ */
1365+ if (time_based_rotation )
1366+ fntime = next_rotation_time ;
1367+ else
1368+ fntime = time (NULL );
13791369
1380- if (filename )
1381- pfree (filename );
1382- if (csvfilename )
1383- pfree (csvfilename );
1370+ /* file rotation for stderr */
1371+ if (!logfile_rotate_dest (time_based_rotation , size_rotation_for , fntime ,
1372+ LOG_DESTINATION_STDERR , & last_sys_file_name ,
1373+ & syslogFile ))
1374+ return ;
1375+
1376+ /* file rotation for csvlog */
1377+ if (!logfile_rotate_dest (time_based_rotation , size_rotation_for , fntime ,
1378+ LOG_DESTINATION_CSVLOG , & last_csv_file_name ,
1379+ & csvlogFile ))
1380+ return ;
13841381
13851382 update_metainfo_datafile ();
13861383
@@ -1501,9 +1498,9 @@ update_metainfo_datafile(void)
15011498 return ;
15021499 }
15031500
1504- if (last_file_name && (Log_destination & LOG_DESTINATION_STDERR ))
1501+ if (last_sys_file_name && (Log_destination & LOG_DESTINATION_STDERR ))
15051502 {
1506- if (fprintf (fh , "stderr %s\n" , last_file_name ) < 0 )
1503+ if (fprintf (fh , "stderr %s\n" , last_sys_file_name ) < 0 )
15071504 {
15081505 ereport (LOG ,
15091506 (errcode_for_file_access (),
0 commit comments