diff options
Diffstat (limited to 'src/shared/dlt_common.c')
-rw-r--r-- | src/shared/dlt_common.c | 156 |
1 files changed, 146 insertions, 10 deletions
diff --git a/src/shared/dlt_common.c b/src/shared/dlt_common.c index 97766f7..cbbe99a 100644 --- a/src/shared/dlt_common.c +++ b/src/shared/dlt_common.c @@ -31,6 +31,7 @@ #include <time.h> /* for localtime_r(), strftime() */ #include <limits.h> /* for NAME_MAX */ #include <inttypes.h> /* for PRI formatting macro */ +#include <libgen.h> /* dirname */ #include <stdarg.h> #include <err.h> @@ -41,6 +42,7 @@ #include "dlt_user_shared.h" #include "dlt_common.h" #include "dlt_common_cfg.h" +#include "dlt_multiple_files.h" #include "dlt_version.h" @@ -84,6 +86,17 @@ static bool print_with_attributes = false; int logging_mode = DLT_LOG_TO_STDERR; FILE *logging_handle = NULL; +//use ohandle as an indicator that multiple files logging is active +MultipleFilesRingBuffer multiple_files_ring_buffer = { + .directory={0}, + .filename={0}, + .fileSize=0, + .maxSize=0, + .filenameTimestampBased=false, + .filenameBase={0}, + .filenameExt={0}, + .ohandle=-1}; + char *message_type[] = { "log", "app_trace", "nw_trace", "control", "", "", "", "" }; char *log_info[] = { "", "fatal", "error", "warn", "info", "debug", "verbose", "", "", "", "", "", "", "", "", "" }; char *trace_type[] = { "", "variable", "func_in", "func_out", "state", "vfb", "", "", "", "", "", "", "", "", "", "" }; @@ -1816,34 +1829,114 @@ void dlt_print_with_attributes(bool state) DltReturnValue dlt_log_init(int mode) { + return dlt_log_init_multiple_logfiles_support((DltLoggingMode)mode, false, 0, 0); +} + +DltReturnValue dlt_log_init_multiple_logfiles_support(const DltLoggingMode mode, const bool enable_multiple_logfiles, + const int logging_file_size, const int logging_files_max_size) +{ if ((mode < DLT_LOG_TO_CONSOLE) || (mode > DLT_LOG_DROPPED)) { - dlt_user_printf("Wrong parameter for mode: %d\n", mode); + dlt_vlog(LOG_WARNING, "Wrong parameter for mode: %d\n", mode); return DLT_RETURN_WRONG_PARAMETER; } logging_mode = mode; - if (logging_mode == DLT_LOG_TO_FILE) { - /* internal logging to file */ - logging_handle = fopen(logging_filename, "a"); + if (logging_mode != DLT_LOG_TO_FILE) { + return DLT_RETURN_OK; + } - if (logging_handle == NULL) { - dlt_user_printf("Internal log file %s cannot be opened!\n", logging_filename); - return DLT_RETURN_ERROR; + if (enable_multiple_logfiles) { + dlt_user_printf("configure dlt logging using file limits\n"); + int result = dlt_log_init_multiple_logfiles(logging_file_size, logging_files_max_size); + if (result == DLT_RETURN_OK) { + return DLT_RETURN_OK; } + dlt_user_printf("dlt logging for limits fails with error code=%d, use logging without limits as fallback\n", result); + return dlt_log_init_single_logfile(); + } else { + dlt_user_printf("configure dlt logging without file limits\n"); + return dlt_log_init_single_logfile(); } +} +DltReturnValue dlt_log_init_single_logfile() +{ + /* internal logging to file */ + errno = 0; + logging_handle = fopen(logging_filename, "a"); + + if (logging_handle == NULL) { + dlt_user_printf("Internal log file %s cannot be opened, error: %s\n", logging_filename, strerror(errno)); + return DLT_RETURN_ERROR; + } return DLT_RETURN_OK; } +DltReturnValue dlt_log_init_multiple_logfiles(const int logging_file_size, const int logging_files_max_size) +{ + char path_logging_filename[PATH_MAX + 1]; + strncpy(path_logging_filename, logging_filename, PATH_MAX); + path_logging_filename[PATH_MAX] = 0; + + const char *directory = dirname(path_logging_filename); + if (directory[0]) { + char basename_logging_filename[NAME_MAX + 1]; + strncpy(basename_logging_filename, logging_filename, NAME_MAX); + basename_logging_filename[NAME_MAX] = 0; + + const char *file_name = basename(basename_logging_filename); + char filename_base[NAME_MAX]; + if (!dlt_extract_base_name_without_ext(file_name, filename_base, sizeof(filename_base))) return DLT_RETURN_ERROR; + + const char *filename_ext = get_filename_ext(file_name); + if (!filename_ext) return DLT_RETURN_ERROR; + + DltReturnValue result = multiple_files_buffer_init( + &multiple_files_ring_buffer, + directory, + logging_file_size, + logging_files_max_size, + false, + true, + filename_base, + filename_ext); + + return result; + } + + return DLT_RETURN_ERROR; +} + void dlt_log_free(void) { - if (logging_mode == DLT_LOG_TO_FILE && logging_handle) + if (logging_mode == DLT_LOG_TO_FILE) { + if (dlt_is_log_in_multiple_files_active()) { + dlt_log_free_multiple_logfiles(); + } else { + dlt_log_free_single_logfile(); + } + } +} + +void dlt_log_free_single_logfile() +{ + if (logging_handle) fclose(logging_handle); } +void dlt_log_free_multiple_logfiles() +{ + if (DLT_RETURN_ERROR == multiple_files_buffer_free(&multiple_files_ring_buffer)) return; + + // reset indicator of multiple files usage + multiple_files_ring_buffer.ohandle = -1; +} + int dlt_user_printf(const char *format, ...) { + if (format == NULL) return -1; + va_list args; va_start(args, format); @@ -1922,9 +2015,13 @@ DltReturnValue dlt_log(int prio, char *s) #endif break; case DLT_LOG_TO_FILE: - /* log to file */ - if (logging_handle) { + + if (dlt_is_log_in_multiple_files_active()) { + dlt_log_multiple_files_write(sFormatString, (unsigned int)sTimeSpec.tv_sec, + (unsigned int)(sTimeSpec.tv_nsec / 1000), getpid(), asSeverity[prio], s); + } + else if (logging_handle) { fprintf(logging_handle, sFormatString, (unsigned int)sTimeSpec.tv_sec, (unsigned int)(sTimeSpec.tv_nsec / 1000), getpid(), asSeverity[prio], s); fflush(logging_handle); @@ -4308,3 +4405,42 @@ int dlt_execute_command(char *filename, char *command, ...) free(args); return ret; } + +char *get_filename_ext(const char *filename) +{ + if (filename == NULL) { + fprintf(stderr, "ERROR: %s: invalid arguments\n", __FUNCTION__); + return NULL; + } + + char *dot = strrchr(filename, '.'); + return (!dot || dot == filename) ? NULL : dot; +} + +bool dlt_extract_base_name_without_ext(const char* const abs_file_name, char* base_name, long base_name_len) { + if (abs_file_name == NULL || base_name == NULL) return false; + + const char* last_separator = strrchr(abs_file_name, '.'); + if (!last_separator) return false; + long length = last_separator - abs_file_name; + length = length > base_name_len ? base_name_len : length; + + strncpy(base_name, abs_file_name, length); + base_name[length] = '\0'; + return true; +} + +void dlt_log_multiple_files_write(const char* format, ...) +{ + char output_string[2048] = { 0 }; + va_list args; + va_start (args, format); + vsnprintf(output_string, 2047, format, args); + va_end (args); + multiple_files_buffer_write(&multiple_files_ring_buffer, (unsigned char*)output_string, strlen(output_string)); +} + +bool dlt_is_log_in_multiple_files_active() +{ + return multiple_files_ring_buffer.ohandle > -1; +} |