Add new options, e.g. --from and --to, that specify a range of dates. Only log messages between those dates shall be printed by the command. --- src/dtm/tools/osaflog.cc | 155 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 144 insertions(+), 11 deletions(-)
diff --git a/src/dtm/tools/osaflog.cc b/src/dtm/tools/osaflog.cc index c93401c7e..f34cf5f4d 100644 --- a/src/dtm/tools/osaflog.cc +++ b/src/dtm/tools/osaflog.cc @@ -21,6 +21,7 @@ #include <sys/stat.h> #include <sys/un.h> #include <unistd.h> +#include <time.h> #include <cerrno> #include <cstddef> #include <cstdint> @@ -62,7 +63,13 @@ uint64_t GetInode(int fd); bool PrettyPrint(FILE* stream); bool PrettyPrint(const char* line, size_t size); int ExtractTrace(const std::string& core_file, const std::string& trace_file); +time_t ConvertToDateTime(const char* date_time, const char* format); +bool IsValidRange(time_t from, time_t to, time_t current); +bool IsValidDateTime(const char* input); char buf[65 * 1024]; +time_t from_date; +time_t to_date; +size_t date_time_len; } // namespace @@ -76,6 +83,8 @@ int main(int argc, char** argv) { {"all", no_argument, nullptr, 'a'}, {"extract-trace", required_argument, 0, 'e'}, {"max-idle", required_argument, 0, 'i'}, + {"from", required_argument, 0, 'x'}, + {"to", required_argument, 0, 'y'}, {0, 0, 0, 0}}; uint64_t max_file_size = 0; @@ -108,7 +117,7 @@ int main(int argc, char** argv) { exit(EXIT_FAILURE); } - while ((option = getopt_long(argc, argv, "m:b:p:f:e:i:ra", + while ((option = getopt_long(argc, argv, "m:b:p:f:e:i:ra:x:y:", long_options, &long_index)) != -1) { switch (option) { case 'p': @@ -170,6 +179,56 @@ int main(int argc, char** argv) { } thread_trace = true; break; + case 'x': + if (optarg == nullptr) { + fprintf(stderr, "date time is not specified in arguments\n"); + exit(EXIT_FAILURE); + } + if (!IsValidDateTime(optarg)) { + fprintf(stderr, "invalid format. Should be " + "\"yyyy-mm-dd hh:mm:ss\" or \"yyyy-mm-dd\"\n"); + exit(EXIT_FAILURE); + } + if (date_time_len && date_time_len != strlen(optarg)) { + fprintf(stderr, "--from and --to is not same format\n"); + exit(EXIT_FAILURE); + } + from_date = + ConvertToDateTime(optarg, strlen(optarg) == strlen("yyyy-mm-dd") + ? "%Y-%m-%d" + : "%Y-%m-%d %H:%M:%S"); + if (date_time_len && !IsValidRange(from_date, 0, to_date)) { + fprintf(stderr, "date time in arguments --from must be " + "less than or equal to --to\n"); + exit(EXIT_FAILURE); + } + date_time_len = strlen(optarg); + break; + case 'y': + if (optarg == nullptr) { + fprintf(stderr, "date time is not specified in arguments\n"); + exit(EXIT_FAILURE); + } + if (!IsValidDateTime(optarg)) { + fprintf(stderr, "invalid format. Should be " + "\"yyyy-mm-dd hh:mm:ss\" or \"yyyy-mm-dd\"\n"); + exit(EXIT_FAILURE); + } + if (date_time_len && date_time_len != strlen(optarg)) { + fprintf(stderr, "--from and --to is not same format\n"); + exit(EXIT_FAILURE); + } + to_date = + ConvertToDateTime(optarg, strlen(optarg) == strlen("yyyy-mm-dd") + ? "%Y-%m-%d" + : "%Y-%m-%d %H:%M:%S"); + if (date_time_len && !IsValidRange(from_date, 0, to_date)) { + fprintf(stderr, "date time in arguments --from must be " + "less than or equal to --to\n"); + exit(EXIT_FAILURE); + } + date_time_len = strlen(optarg); + break; default: PrintUsage(argv[0]); exit(EXIT_FAILURE); } @@ -187,7 +246,11 @@ int main(int argc, char** argv) { (argc == optind && rotate_set && !rotate_all)) { PrintUsage(argv[0]); exit(EXIT_FAILURE); - } + } + if (argc == optind && date_time_len) { + fprintf(stderr, "LOGSTREAM is not specified\n"); + exit(EXIT_FAILURE); + } if (flush_set == true) { flush_result = Flush(); } @@ -235,36 +298,50 @@ void PrintUsage(const char* program_name) { "\n" "Options:\n" "\n" - "--flush Flush all buffered messages in the log\n" + "-f or --flush Flush all buffered messages in the log\n" " server to disk even when no LOGSTREAM\n" " is specified.\n" - "--print print the messages stored on disk for the\n" + "-p or --print print the messages stored on disk for the\n" " specified LOGSTREAM(s). This option is the\n" " default when no option is specified.\n" - "--delete Delete the specified LOGSTREAM(s) by\n" + "-d or --delete Delete the specified LOGSTREAM(s) by\n" " removing allocated resources in the log\n" " server. Does not delete log files from disk.\n" - "--rotate Rotate the specified LOGSTREAM(s).\n" - "--all Rotate all LOGSTREAM(s).\n" + "-r or --rotate Rotate the specified LOGSTREAM(s).\n" + "-a or --all Rotate all LOGSTREAM(s).\n" " This option only works with '--rotate'.\n" - "--max-file-size=SIZE Set the maximum size of the log file to\n" + "-m SIZE or --max-file-size=SIZE\n" + " Set the maximum size of the log file to\n" " SIZE bytes. The log file will be rotated\n" " when it exceeds this size. Suffixes k, M and\n" " G can be used for kilo-, mega- and\n" " gigabytes.\n" - "--max-backups=NUM Set the maximum number of backup files to\n" + "-b NUM or --max-backups=NUM\n" + " Set the maximum number of backup files to\n" " retain during log rotation to NUM.\n" + "-e <corefile> <tracefile> or\n" "--extract-trace <corefile> <tracefile>\n" " If a process produces a core dump file has\n" " THREAD_TRACE_BUFFER enabled, this option\n" " reads the <corefile> to extract the trace\n" " strings in all threads and writes them to\n" " the <tracefile> file.\n" - "--max-idle=NUM Set the maximum number of idle time to NUM\n" + "-i NUM or --max-idle=NUM\n" + " Set the maximum number of idle time to NUM\n" " minutes. If a stream has not been used for\n" " the given time, the stream will be closed.\n" " Given zero (default) to max-idle to disable\n" - " this functionality.\n", + " this functionality.\n" + "-x DATE_TIME or --from=DATE_TIME\n" + " Specify log message is printed greater\n" + " than or equal to DATE_TIME\n" + "-y DATE_TIME or --to=DATE_TIME\n" + " Specify log message is printed less than\n" + " or equal to DATE_TIME\n" + " unique format when using '--from' '--to'\n" + " DATE_TIME = \"yyyy-mm-dd hh:mm:ss\" or\n" + " \"yyyy-mm-dd\"\n" + " Range of dates only works with '--print'\n", program_name); } @@ -476,6 +553,15 @@ bool PrettyPrint(const char* line, size_t size) { pretty_date[10] = ' '; pretty_date[19] = '.'; pretty_date[23] = '\0'; + const char* format = + date_time_len == strlen("yyyy-mm-dd") ? "%Y-%m-%d" : "%Y-%m-%d %H:%M:%S"; + char pretty_date_cpy[33]; + memcpy(pretty_date_cpy, pretty_date, date_time_len); + pretty_date_cpy[date_time_len] = '\0'; + time_t current = ConvertToDateTime(pretty_date_cpy, format); + if ((from_date || to_date) && !IsValidRange(from_date, to_date, current)) { + return true; + } printf("%s %s", pretty_date, msg_field); return true; } @@ -536,4 +622,51 @@ int ExtractTrace(const std::string& core_file, log_writer.Flush(); return EXIT_SUCCESS; } + +time_t ConvertToDateTime(const char* date_time, const char* format) { + struct tm timeDate; + if (strptime(date_time, format, &timeDate) == NULL) { + return 0; + } + if (strlen(date_time) == strlen("yyyy-mm-dd")) { + timeDate.tm_hour = 0; + timeDate.tm_min = 0; + timeDate.tm_sec = 0; + } + timeDate.tm_isdst = -1; + time_t time_p = mktime(&timeDate); + if (time_p == -1) { + return 0; + } + return time_p; +} + +bool IsValidRange(time_t from, time_t to, time_t current) { + // return true when all unavailable + if ((from == 0 && to == 0) || current == 0) return true; + // validate when having input `to` and `current` + if (from == 0 && to != 0) return difftime(to, current) >= 0; + // validate when having input `from` and `current` + if (from != 0 && to == 0) return difftime(current, from) >= 0; + // validate when all args available + return difftime(current, from) >= 0 && difftime(to, current) >= 0; +} + +bool IsValidDateTime(const char* input) { + bool ret = false; + const char* valid_format[] = {"%Y-%m-%d %H:%M:%S", "%Y-%m-%d"}; + size_t date_length = strlen("yyyy-mm-dd"); + size_t date_time_length = date_length + strlen("hh:mm:ss") + 1; + size_t input_length = strlen(input); + if (input_length == date_time_length) { + if (ConvertToDateTime(input, valid_format[0]) != -1) { + ret = true; + } + } else if (input_length == date_length) { + if (ConvertToDateTime(input, valid_format[1]) != -1) { + ret = true; + } + } + return ret; +} } // namespace -- 2.25.1 _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel