Adds date and time specifier for the log file name.

This commit is contained in:
Andrea Mazzoleni 2014-02-16 10:03:02 +01:00
parent f6c2ae14de
commit cb0a280ddc
9 changed files with 154 additions and 31 deletions

View file

@ -19,6 +19,8 @@ SnapRAID HISTORY
* In "fix", if a previous fixing attempt was made resulting in a
.unrecoverable file, uses this file as starting point for the
new attempt.
* In the log file name allow the use of the '>>', %D, %T modifiers
to select append mode, and to insert the date and time in the name.
* New source code organization. The RAID engine is now
an external component usable also in other projects.

View file

@ -101,7 +101,7 @@ man_MANS = snapraid.1
clean-local:
rm -f valgrind.log callgrind.log cachegrind.log
rm -rf test
rm -f test.log output.log
rm -f test*.log output.log
rm -f *.gcda *.gcno *.gcov
rm -rf cov
rm -f lcov.info
@ -144,12 +144,16 @@ check-local:
$(TESTENV) ./snapraid$(EXEEXT) --test-skip-device -c $(CONF) status
echo --- Run the speed test
$(TESTENV) ./snapraid$(EXEEXT) --test-skip-device -T
echo --- As empty, sync and check forcing murmur3
echo --- Some commands with empty array
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -v -c $(CONF) diff
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -v -c $(CONF) dup
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -v -c $(CONF) list > output.log
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) --test-force-murmur3 sync
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status -l ">&1"
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status -l ">&2"
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status -l ">>test.log"
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status -l test-%D-%T.log
if HAVE_SYMLINK
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(PAR1) pool
endif

View file

@ -820,6 +820,10 @@ and you\(cqll get only a summary at the end of the operations.
When checking and fixing this allows to keep separated
the possible huge list of errors from the human readable
output.
If the specified FILE path start with \(cq>>\(cq the file is opened
in append mode. Inside the path, occurrences of %D and %T are
replaced with the date and time in the format YYYYMMDD and
HHMMSS.
.TP
.B \-s, \-\-start BLKSTART
Starts the processing from the specified

View file

@ -86,6 +86,105 @@ void memory(void)
printf("Using %u MiB of memory.\n", (unsigned)(malloc_counter() / 1024 / 1024));
}
void log_open(const char* log)
{
char path[PATH_MAX];
const char* mode;
char text_T[32];
char text_D[32];
time_t t;
struct tm* tm;
/* if no log file is specified, don't output */
if (log == 0) {
#ifdef _WIN32
log = "NUL";
#else
log = "/dev/null";
#endif
}
t = time(0);
tm = localtime(&t);
if (tm) {
strftime(text_T, sizeof(text_T), "%H%M%S", tm);
strftime(text_D, sizeof(text_T), "%Y%m%d", tm);
} else {
strcpy(text_T, "invalid");
strcpy(text_D, "invalid");
}
/* file mode */
mode = "wt";
if (*log == '>') {
++log;
if (*log == '>') {
mode = "at";
++log;
}
if (log[0] == '&' && log[1] == '1') {
stdlog = stdout;
return;
}
if (log[0] == '&' && log[1] == '2') {
stdlog = stderr;
return;
}
}
/* process the path */
for(*path=0;*log!=0;) {
switch (*log) {
case '%' :
++log;
switch (*log) {
case '%' :
pathcatc(path, sizeof(path), '%');
break;
case 'T' :
pathcat(path, sizeof(path), text_T);
break;
case 'D' :
pathcat(path, sizeof(path), text_D);
break;
default:
/* LCOV_EXCL_START */
fprintf(stderr, "Invalid type specifier '%c' in the log file.\n", *log);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
break;
default:
pathcatc(path, sizeof(path), *log);
break;
}
++log;
}
stdlog = fopen(path, mode);
if (!stdlog) {
/* LCOV_EXCL_START */
fprintf(stderr, "Error opening the log file '%s'. %s.\n", path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
}
void log_close(const char* log)
{
if (stdlog != stdout && stdlog != stderr) {
if (fclose(stdlog) != 0) {
/* LCOV_EXCL_START */
fprintf(stderr, "Error closing the log file '%s'. %s.\n", log, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
}
}
#define OPT_TEST_SKIP_SELF 256
#define OPT_TEST_KILL_AFTER_SYNC 257
#define OPT_TEST_EXPECT_UNRECOVERABLE 258
@ -584,27 +683,8 @@ int main(int argc, char* argv[])
}
}
/* if no log file is specified, don't output */
if (log == 0) {
#ifdef _WIN32
log = "NUL";
#else
log = "/dev/null";
#endif
}
if (strcmp(log, "1") == 0) {
stdlog = stdout;
} else if (strcmp(log, "2") == 0) {
stdlog = stderr;
} else {
stdlog = fopen(log, "wt");
if (!stdlog) {
/* LCOV_EXCL_START */
fprintf(stderr, "Error opening the log file '%s'. %s.\n", log, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
}
/* open the log file */
log_open(log);
if (!opt.skip_self)
selftest();
@ -786,14 +866,7 @@ int main(int argc, char* argv[])
}
/* close log file */
if (stdlog != stdout && stdlog != stderr) {
if (fclose(stdlog) != 0) {
/* LCOV_EXCL_START */
fprintf(stderr, "Error closing the log file '%s'. %s.\n", log, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
}
log_close(log);
#if HAVE_LOCKFILE
if (!opt.skip_lock) {

View file

@ -586,6 +586,10 @@ Options
When checking and fixing this allows to keep separated
the possible huge list of errors from the human readable
output.
If the specified path starts with '>>' the file is opened
in append mode. Occurrences of %D and %T in the name are
replaced with the date and time in the format YYYYMMDD and
HHMMSS.
-s, --start BLKSTART
Starts the processing from the specified

View file

@ -631,6 +631,10 @@ SnapRAID provides the following options:
When checking and fixing this allows to keep separated
the possible huge list of errors from the human readable
output.
If the specified path starts with '>>' the file is opened
in append mode. Occurrences of %D and %T in the name are
replaced with the date and time in the format YYYYMMDD and
HHMMSS.
-s, --start BLKSTART
Starts the processing from the specified

11
state.c
View file

@ -347,6 +347,8 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
unsigned line;
tommy_node* i;
unsigned l;
time_t t;
struct tm* tm;
/* copy the options */
state->opt = *opt;
@ -357,7 +359,16 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
state->command = command;
t = time(0);
tm = localtime(&t);
fprintf(stdlog, "version:%s\n", PACKAGE_VERSION);
fprintf(stdlog, "unixtime:%"PRIi64"\n", (int64_t)t);
if (tm) {
char datetime[64];
strftime(datetime, sizeof(datetime), "%F %T", tm);
fprintf(stdlog, "time:%s\n", datetime);
}
fprintf(stdlog, "conf:%s\n", path);
fflush(stdlog);

15
util.c
View file

@ -1267,6 +1267,21 @@ void pathcat(char* dst, size_t size, const char* src)
memcpy(dst + dst_len, src, src_len + 1);
}
void pathcatc(char* dst, size_t size, char c)
{
size_t dst_len = strlen(dst);
if (dst_len + 2 > size) {
/* LCOV_EXCL_START */
fprintf(stderr, "Path too long\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
dst[dst_len] = c;
dst[dst_len + 1] = 0;
}
void pathimport(char* dst, size_t size, const char* src)
{
pathcpy(dst, size, src);

6
util.h
View file

@ -403,6 +403,12 @@ void pathcpy(char* dst, size_t size, const char* src);
*/
void pathcat(char* dst, size_t size, const char* src);
/**
* Concatenates a path limiting the size.
* Aborts if too long.
*/
void pathcatc(char* dst, size_t size, char c);
/**
* Imports a path limiting the size.
* In Windows all the backslash are converted to the C standard of forward slash.