SELKIELogger  1.0.0
logging.c
1 /*
2  * Copyright (C) 2023 Swansea University
3  *
4  * This file is part of the SELKIELogger suite of tools.
5  *
6  * SELKIELogger is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation, either version 3 of the License, or (at your option)
9  * any later version.
10  *
11  * SELKIELogger is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this SELKIELogger product.
18  * If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include <errno.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <time.h>
25 
26 #include "logging.h"
27 
47 void log_error(const program_state *s, const char *format, ...) {
48  va_list args;
49  char *label;
50  if (s->shutdown) {
51  label = "[Shutdown]";
52  } else if (!s->started) {
53  label = "[Startup]";
54  } else {
55  label = "[Running]";
56  }
57  fprintf(stderr, "%-10s Error: ", label);
58  va_start(args, format);
59  vfprintf(stderr, format, args);
60  va_end(args);
61  fprintf(stderr, "\n");
62 
63  if (s->log) {
64  fprintf(s->log, "%s Error: ", label);
65  va_start(args, format);
66  vfprintf(s->log, format, args);
67  va_end(args);
68  fprintf(s->log, "\n");
69  }
70 }
71 
86 void log_warning(const program_state *s, const char *format, ...) {
87  va_list args;
88  char *label;
89  if (s->shutdown) {
90  label = "[Shutdown]";
91  } else if (!s->started) {
92  label = "[Startup]";
93  } else {
94  label = "[Running]";
95  }
96  fprintf(stderr, "%-10s Warning: ", label);
97  va_start(args, format);
98  vfprintf(stderr, format, args);
99  va_end(args);
100  fprintf(stderr, "\n");
101 
102  if (s->log) {
103  fprintf(s->log, "%s Error: ", label);
104  va_start(args, format);
105  vfprintf(s->log, format, args);
106  va_end(args);
107  fprintf(s->log, "\n");
108  }
109 }
110 
125 void log_info(const program_state *s, const int level, const char *format, ...) {
126  va_list args;
127  char *label;
128  if (s->shutdown) {
129  label = "[Shutdown]";
130  } else if (!s->started) {
131  label = "[Startup]";
132  } else {
133  label = "[Running]";
134  }
135 
136  if (s->verbose >= level) {
137  fprintf(stdout, "%-10s Info:%d: ", label, level);
138  va_start(args, format);
139  vfprintf(stdout, format, args);
140  va_end(args);
141  fprintf(stdout, "\n");
142  }
143 
144  if (s->log && (s->logverbose >= level)) {
145  fprintf(s->log, "%s Info:%d: ", label, level);
146  va_start(args, format);
147  vfprintf(s->log, format, args);
148  va_end(args);
149  fprintf(s->log, "\n");
150  }
151 }
152 
169 FILE *openSerialNumberedFile(const char *prefix, const char *extension, char **name) {
170  time_t now = time(NULL);
171  struct tm *tm = localtime(&now);
172  char *fileName = NULL;
173  char date[9];
174  strftime(date, 9, "%Y%m%d", tm);
175 
176  int i = 0;
177  FILE *file = NULL;
178  while (i <= 0xFF) {
179  errno = 0;
180  if (asprintf(&fileName, "%s%s%02x.%s", prefix, date, i, extension) == -1) { return NULL; }
181  errno = 0;
182  file = fopen(fileName, "w+x"); // w+x = rw + create. Fail if exists
183  if (file) {
184  if (name) {
185  char *fStem = strndup(fileName, strlen(fileName) - strlen(extension) - 1);
186  (*name) = fStem;
187  }
188  free(fileName);
189  return file;
190  }
191  if (errno != EEXIST) {
192  free(fileName);
193  return NULL;
194  }
195  i++;
196  free(fileName);
197  fileName = NULL;
198  }
199 
200  return NULL;
201 }
202 
208  if (s->log) { fclose(s->log); }
209  s->log = NULL;
210 }
void destroy_program_state(program_state *s)
Cleanly destroy program state.
Definition: logging.c:207
FILE * openSerialNumberedFile(const char *prefix, const char *extension, char **name)
Open dated, serial numbered file with given prefix and extension.
Definition: logging.c:169
void log_info(const program_state *s, const int level, const char *format,...)
Output formatted information message at a given level.
Definition: logging.c:125
void log_warning(const program_state *s, const char *format,...)
Output formatted warning message.
Definition: logging.c:86
void log_error(const program_state *s, const char *format,...)
Output formatted error message.
Definition: logging.c:47
Program state and logging information.
Definition: logging.h:40
int logverbose
Current log verbosity (file output)
Definition: logging.h:45
int verbose
Current log verbosity (console output)
Definition: logging.h:43
bool started
Indicates startup completed.
Definition: logging.h:41
FILE * log
Log file.
Definition: logging.h:44
bool shutdown
Indicates shutdown begun.
Definition: logging.h:42