RocketLogger 2.1.0
log.c
Go to the documentation of this file.
1
32#include <stdarg.h>
33#include <stdio.h>
34#include <string.h>
35#include <time.h>
36
37#include "log.h"
38
42static char log_filename[RL_LOG_PATH_LENGTH_MAX] = RL_LOG_DEFAULT_FILE;
43
47static rl_log_level_t log_verbosity = RL_LOG_VERBOSE;
48
49int rl_log_init(char const *const log_file, rl_log_level_t verbosity) {
50 // update log configuration
51 rl_log_verbosity(verbosity);
52 strncpy(log_filename, log_file, sizeof(log_filename) - 1);
53
54 // open log file (create inexistent) to check for max file size
55 FILE *log_fp = fopen(log_filename, "a");
56 if (log_fp == NULL) {
57 printf("Error: failed to open log file\n");
58 return -1;
59 }
60
61 // reset the log file if it is getting large
62 if (ftell(log_fp) > RL_LOG_FILE_SIZE_MAX) {
63 log_fp = freopen(log_filename, "w", log_fp);
64 if (log_fp == NULL) {
65 printf("Error: failed to reset log file size\n");
66 return -1;
67 }
68 }
69
70 // write header for new (empty) file, or empty line for existing file
71 if (ftell(log_fp) == 0) {
72 fprintf(log_fp, "# RocketLogger Log File\n");
73 }
74
75 // close log file
76 fclose(log_fp);
77 return 0;
78}
79
80void rl_log_verbosity(rl_log_level_t verbosity) { log_verbosity = verbosity; }
81
82int rl_log(rl_log_level_t log_level, char const *const format, ...) {
83 // do not handle ignore log level
84 if (log_level == RL_LOG_IGNORE) {
85 return 0;
86 }
87
88 // log only if log level is equal or higher than configured verbosity
89 if (log_level > log_verbosity) {
90 return 0;
91 }
92
93 // get arguments
94 va_list args;
95 va_start(args, format);
96
97 // get current time
98 time_t time_raw;
99 struct tm *time_info;
100 char time_str[24];
101
102 time(&time_raw);
103 time_info = gmtime(&time_raw);
104 strftime(time_str, sizeof(time_str), "%F %T\t", time_info);
105
106 // open log file
107 FILE *log_fp = fopen(log_filename, "a");
108 if (log_fp == NULL) {
109 printf("Error: failed to open log file\n");
110 return -1;
111 }
112
113 // write time, log level, and message to log file
114 fprintf(log_fp, "%s", time_str);
115 switch (log_level) {
116 case RL_LOG_ERROR:
117 fprintf(log_fp, "ERROR\t");
118 break;
119 case RL_LOG_WARNING:
120 fprintf(log_fp, "WARN\t");
121 break;
122 case RL_LOG_INFO:
123 fprintf(log_fp, "INFO\t");
124 break;
125 case RL_LOG_VERBOSE:
126 fprintf(log_fp, "VERB\t");
127 break;
128 default:
129 // for debugging purposes
130 fprintf(log_fp, "N/A\t");
131 printf("Error: unsupported log level with message:\n ");
132 break;
133 }
134 vfprintf(log_fp, format, args);
135 fprintf(log_fp, "\n");
136
137 // close file
138 fclose(log_fp);
139
140 // output to terminal
141 switch (log_level) {
142 case RL_LOG_ERROR:
143 printf("Error: ");
144 break;
145 case RL_LOG_WARNING:
146 printf("Warning: ");
147 break;
148 case RL_LOG_INFO:
149 printf("Info: ");
150 break;
151 case RL_LOG_VERBOSE:
152 printf("Verbose: ");
153 break;
154 default:
155 // skip handled above
156 break;
157 }
158 vprintf(format, args);
159 printf("\n");
160
161 // facilitate return
162 va_end(args);
163
164 return 0;
165}
void rl_log_verbosity(rl_log_level_t verbosity)
Definition: log.c:80
int rl_log(rl_log_level_t log_level, char const *const format,...)
Definition: log.c:82
int rl_log_init(char const *const log_file, rl_log_level_t verbosity)
Definition: log.c:49
#define RL_LOG_FILE_SIZE_MAX
Maximum log file size in bytes.
Definition: log.h:42
#define RL_LOG_DEFAULT_FILE
Default log file name.
Definition: log.h:36
#define RL_LOG_PATH_LENGTH_MAX
Maximum log file name path length.
Definition: log.h:39
enum rl_log_level rl_log_level_t
Definition: log.h:58
@ RL_LOG_ERROR
Error.
Definition: log.h:49
@ RL_LOG_WARNING
Warning.
Definition: log.h:50
@ RL_LOG_VERBOSE
Verbose.
Definition: log.h:52
@ RL_LOG_INFO
Information.
Definition: log.h:51
@ RL_LOG_IGNORE
Ignore log (only for verbosity configuration)
Definition: log.h:48