Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 626e36a

Browse files
author
Alexander Perepelkin
committed
bug-145: fix daily rolling; add manual test to see rolling
1 parent fe4ed07 commit 626e36a

File tree

2 files changed

+174
-20
lines changed

2 files changed

+174
-20
lines changed

src/DailyRollingFileAppender.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -100,42 +100,42 @@ namespace log4cpp {
100100
return;
101101
for (int i = 0; i < nentries; i++) {
102102
struct stat statBuf;
103-
int res = ::stat(entries[i]->d_name, &statBuf);
103+
const std::string fullfilename = dirname + PATHDELIMITER + entries[i]->d_name;
104+
int res = ::stat(fullfilename.c_str(), &statBuf);
104105
if ((res == -1) || (!S_ISREG(statBuf.st_mode))) {
105106
free(entries[i]);
106107
continue;
107108
}
108109
if (statBuf.st_mtime < oldest && strstr(entries[i]->d_name, filname.c_str())) {
109-
const std::string fullfilename = dirname + PATHDELIMITER + entries[i]->d_name;
110-
::unlink(fullfilename.c_str());
111110
std::cout << " Deleting " << fullfilename.c_str() << std::endl;
111+
::unlink(fullfilename.c_str());
112112
}
113113
free(entries[i]);
114114
}
115115
free(entries);
116116
#else
117-
HANDLE hFind = INVALID_HANDLE_VALUE;
118-
WIN32_FIND_DATA ffd;
119-
const std::string pattern = _fileName + "*";
120-
121-
hFind = FindFirstFile(pattern.c_str(), &ffd);
122-
if (hFind != INVALID_HANDLE_VALUE) {
123-
do {
117+
HANDLE hFind = INVALID_HANDLE_VALUE;
118+
WIN32_FIND_DATA ffd;
119+
const std::string pattern = _fileName + "*";
120+
121+
hFind = FindFirstFile(pattern.c_str(), &ffd);
122+
if (hFind != INVALID_HANDLE_VALUE) {
123+
do {
124124
struct stat statBuf;
125125
const std::string fullfilename = dirname + PATHDELIMITER + ffd.cFileName;
126126
int res = ::stat(fullfilename.c_str(), &statBuf);
127-
if (res != -1 && statBuf.st_mtime < oldest && !(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
128-
std::cout << "Deleting " << fullfilename << "\n";
127+
if (res != -1 && statBuf.st_mtime < oldest && !(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
128+
std::cout << "Deleting " << fullfilename << "\n";
129129
::unlink(fullfilename.c_str());
130-
}
131-
} while (FindNextFile(hFind, &ffd) != 0);
132-
133-
if (GetLastError() != ERROR_NO_MORE_FILES) {
134-
// [XXX] some kind of error happened
135-
}
136-
FindClose(hFind);
130+
}
131+
} while (FindNextFile(hFind, &ffd) != 0);
132+
133+
if (GetLastError() != ERROR_NO_MORE_FILES) {
134+
// [XXX] some kind of error happened
135+
}
136+
FindClose(hFind);
137137
hFind = INVALID_HANDLE_VALUE;
138-
}
138+
}
139139
#endif
140140
}
141141

tests/testDailyRollingFileAppender.cpp

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,29 @@
11
#include <log4cpp/Category.hh>
22
#include <log4cpp/PropertyConfigurator.hh>
33
#include <log4cpp/DailyRollingFileAppender.hh>
4+
#include <log4cpp/PatternLayout.hh>
5+
#include <log4cpp/OstreamAppender.hh>
46
#include <stdio.h>
57
#include <stdlib.h>
68
#include <errno.h>
79
#include <iostream>
10+
#include <ctime>
11+
#include <sys/stat.h>
12+
#include <fcntl.h>
13+
#include <memory>
14+
#include <cstring>
15+
16+
#include "PortabilityImpl.hh"
17+
#ifdef LOG4CPP_HAVE_IO_H
18+
# include <io.h>
19+
#endif
20+
#ifdef LOG4CPP_HAVE_UNISTD_H
21+
# include <unistd.h>
22+
#endif
23+
24+
#ifndef WIN32 // only available on Win32
25+
#include <dirent.h>
26+
#endif
827

928
#ifdef WIN32
1029
#pragma comment(lib, "Ws2_32.lib")
@@ -148,11 +167,146 @@ int testConfigDailyRollingFileAppender()
148167
return 0;
149168
}
150169

170+
// Note: this test changes system time. Run it only manually
171+
namespace OnlyManualTesting {
172+
173+
const char* absolutePathCategoryName = "absolutePathCategory";
174+
const int maxDaysToKeep = 3;
175+
176+
#if defined(WIN32)
177+
const char *logFilename = "C:/Temp/log4cpp/dailyrolling_abs_path_file.log";
178+
const char *logPathname = "C:/Temp/log4cpp";
179+
#else
180+
const char *logFilename = "/var/log/log4cpp/dailyrolling_abs_path_file.log";
181+
const char *logPathname = "/var/log/log4cpp";
182+
#endif
183+
184+
void setupManualEntryLog() {
185+
if (access(logPathname, F_OK) != 0) {
186+
mkdir(logPathname, 644);
187+
}
188+
189+
log4cpp::PatternLayout *ostreamLayout = new log4cpp::PatternLayout();
190+
ostreamLayout->setConversionPattern("%d: %p %c %x: %m %n");
191+
log4cpp::Appender *ostreamAppender = new log4cpp::OstreamAppender("ostreamAppender", &std::cout);
192+
ostreamAppender->setLayout(ostreamLayout);
193+
194+
log4cpp::PatternLayout *fileLayout = new log4cpp::PatternLayout();
195+
fileLayout->setConversionPattern("%d: %p %c %x: %m %n");
196+
log4cpp::Appender *fileAppender = new log4cpp::DailyRollingFileAppender("fileAppender", logFilename, maxDaysToKeep);
197+
fileAppender->setLayout(fileLayout);
198+
199+
log4cpp::Category& absolutePathCategory =
200+
log4cpp::Category::getInstance(std::string(absolutePathCategoryName));
201+
absolutePathCategory.setAdditivity(false);
202+
203+
absolutePathCategory.addAppender(ostreamAppender);
204+
absolutePathCategory.addAppender(fileAppender);
205+
absolutePathCategory.setPriority(log4cpp::Priority::DEBUG);
206+
}
207+
208+
int checkThatNoMoreThanNLogFilesPresent(const std::string _fileName, int n);
209+
210+
int makeManualEntryLog()
211+
{
212+
const int totalLinesCount = 14, linesPerDay=3, jumpPeriod=24*60*60 + 1;
213+
int i = 0, future = 0;
214+
215+
log4cpp::Category& absolutePathCategory =
216+
log4cpp::Category::getInstance(std::string(absolutePathCategoryName));
217+
218+
// 1. update system time (eg: use 'date' command on Linux) manually when test program is running here (at least 4 times)
219+
absolutePathCategory.debugStream() << "debug line " << i;
220+
while (++i <= totalLinesCount) {
221+
if (i % linesPerDay == 0) {
222+
time_t now;
223+
if (time(&now) == -1)
224+
return -1;
225+
now += jumpPeriod;
226+
future += jumpPeriod;
227+
if (stime(&now) == -1) {
228+
std::cerr << "Can not set date. Need admin privileges?" << std::endl;
229+
return -1;
230+
}
231+
}
232+
absolutePathCategory.debugStream() << "debug line " << i;
233+
}
234+
235+
time_t now;
236+
if (time(&now) == -1)
237+
return -1;
238+
now -= future;
239+
if (stime(&now) == -1) {
240+
std::cerr << "Can not set date. Need admin privileges?" << std::endl;
241+
return -1;
242+
}
243+
244+
// 2. check the number of files in /var/log/log4cpp ( <= maxDaysToKeep) (+1 to allow consequent runs of test)
245+
if (checkThatNoMoreThanNLogFilesPresent(std::string(logFilename), maxDaysToKeep + 1) == -1)
246+
return -1;
247+
248+
return 0;
249+
}
250+
251+
// Note: this test changes system time. Run it only manually
252+
int checkThatNoMoreThanNLogFilesPresent(const std::string _fileName, int n) {
253+
// iterate over files around log file and count files with same prefix
254+
const std::string::size_type last_delimiter = _fileName.rfind(PATHDELIMITER);
255+
const std::string dirname((last_delimiter == std::string::npos)? "." : _fileName.substr(0, last_delimiter));
256+
const std::string filname((last_delimiter == std::string::npos)? _fileName : _fileName.substr(last_delimiter+1, _fileName.size()-last_delimiter-1));
257+
int logFilesCount(0);
258+
#ifndef WIN32 // only available on Win32
259+
struct dirent **entries;
260+
int nentries = scandir(dirname.c_str(), &entries, 0, alphasort);
261+
if (nentries < 0)
262+
return -1;
263+
for (int i = 0; i < nentries; i++) {
264+
if (strstr(entries[i]->d_name, filname.c_str())) {
265+
++logFilesCount;
266+
}
267+
free(entries[i]);
268+
}
269+
free(entries);
270+
#else
271+
HANDLE hFind = INVALID_HANDLE_VALUE;
272+
WIN32_FIND_DATA ffd;
273+
const std::string pattern = _fileName + "*";
274+
275+
hFind = FindFirstFile(pattern.c_str(), &ffd);
276+
if (hFind != INVALID_HANDLE_VALUE) {
277+
do {
278+
if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
279+
++logFilesCount;
280+
}
281+
} while (FindNextFile(hFind, &ffd) != 0);
282+
FindClose(hFind);
283+
hFind = INVALID_HANDLE_VALUE;
284+
}
285+
#endif
286+
if (logFilesCount > n) {
287+
std::cerr << "Too many log files in the dir " << dirname << ": " << logFilesCount << std::endl;
288+
} else {
289+
std::cout << "Daily log files in the dir " << dirname << ": " << logFilesCount << std::endl;
290+
}
291+
292+
return (logFilesCount <= n) ? 0 : -1;
293+
}
294+
295+
int testDailyRollingFileAppenderChangeDateManualOnly() {
296+
setupManualEntryLog();
297+
return makeManualEntryLog();
298+
}
299+
}
300+
151301
int main()
152302
{
153303
int res = testOnlyDailyRollingFileAppender();
154304
if (!res)
155305
res = testConfigDailyRollingFileAppender();
156306

307+
// Note: this test changes system time. Run it only manually
308+
// if (!res)
309+
// res = OnlyManualTesting::testDailyRollingFileAppenderChangeDateManualOnly();
310+
157311
return res;
158312
}

0 commit comments

Comments
 (0)