1 /*************************************************************************
3 * Copyright 2020 highstreet technologies GmbH and others
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 ***************************************************************************/
20 #include "log_utils.h"
28 #include <sys/types.h>
30 #include <sys/types.h>
35 #include <core/framework.h>
37 static int instances = 0;
38 static FILE* logfile = 0;
40 static char *extract_format(const char *format);
42 void log_init(const char *logfilename) {
43 assert(instances == 0);
46 logfile = fopen(logfilename, "w");
51 void log__message(char const * const fname, uint32_t location, int verbose_level, const char *format, ...) {
55 char *verbose_file = 0;
56 int free_verbose_file = 0;
58 char *verbose_screen = 0;
59 int free_verbose_screen = 0;
61 if(verbose_level < 0) {
62 //when verbose negative, treat as add (no filename, line, time, etc)
63 verbose_level = -verbose_level;
64 verbose_file = (char *)format;
65 verbose_screen = (char *)format;
68 //extract just the filename, no path
69 const char *filename = fname + strlen(fname) - 1;
70 while((filename != fname) && (*filename != '/')) {
73 if(*filename == '/') {
77 time_t t = time(NULL);
78 struct tm tm = *localtime(&t);
80 asprintf(&verbose_file, "[%d-%02d-%02d|%02d:%02d:%02d|%s:%u] %s", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, filename, location, format);
81 if(verbose_file == 0) {
82 verbose_file = (char *)format;
85 free_verbose_file = 1;
88 if(verbose_level != 0) {
89 asprintf(&verbose_screen, "[%d-%02d-%02d|%02d:%02d:%02d] %s", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, format);
92 verbose_screen = strdup(verbose_file);
95 if(verbose_screen == 0) {
96 verbose_screen = (char *)format;
99 free_verbose_screen = 1;
103 //log to file in an uncolored format (simple format)
104 va_start(arg, format);
105 char *simple_format = extract_format(verbose_file);
106 vfprintf(logfile, simple_format, arg);
108 if(simple_format != verbose_file) {
114 if(free_verbose_file) {
118 if(verbose_level <= framework_arguments.verbosity_level) {
120 if(verbose_level == 0) {
121 fprintf(stderr, LOG_COLOR_BOLD_RED);
122 va_start(arg, format);
123 vfprintf(stderr, verbose_screen, arg);
125 fprintf(stderr, LOG_COLOR_RESET);
127 fprintf(stdout, LOG_COLOR_BOLD_RED);
130 va_start(arg, format);
131 vfprintf(stdout, verbose_screen, arg);
134 if(verbose_level == 0) {
135 fprintf(stdout, LOG_COLOR_RESET);
139 if(free_verbose_screen) {
140 free(verbose_screen);
144 void log_close(void) {
149 static char *extract_format(const char *format) {
152 int l = strlen(format);
153 char *ret = (char *)malloc(sizeof(char) * (l + 1));
155 fprintf(stderr, LOG_COLOR_BOLD_RED"bad malloc in log system\n"LOG_COLOR_RESET);
156 return (char *)format;
161 bool in_escape = false;
166 if(format[s] == 27) {
172 if(format[s] == 'm') {
180 ret[d++] = format[s];
191 void log_redirect_stderr(const char *stderrfilename) {
192 remove(stderrfilename);
193 int stderr_fd = open(stderrfilename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
194 dup2(stderr_fd, STDERR_FILENO);