Files
Eric F d398a6ced2 Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1)
- OpenOCPP extracted (firmware OCPP 1.6J/2.0.1)
- ShapeShifter library installed (pip install -e)
- ShapeShifter specification extracted
- EVerest extracted

TODO updated with progress
2026-06-08 00:38:27 -04:00

132 lines
4.5 KiB
C++

// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2022-2023 chargebyte GmbH
// Copyright (C) 2022-2023 Contributors to EVerest
#include "log.hpp"
#include <everest/logging.hpp> // for logging
#include <stdarg.h> // for va_list, va_{start,end}()
#include <stdio.h> // for v*printf()
#include <stdlib.h> // for atoi()
#include <string.h> // for strlen()
#include <sys/time.h> // for gettimeofday()
#include <time.h> // for strftime()
dloglevel_t minloglevel_current = DLOG_LEVEL_INFO;
static const char* debug_level_logstring_map[DLOG_LEVEL_NUMLEVELS] = {
// tailing space, no need to add it later when printing
// try to keep the strings almost same length, looks better
"[(LOG)] ", "[ERROR] ", "[WARN] ", "[INFO] ", "[DEBUG] ", "[TRACE] "};
const char* debug_level_mqtt_string_map[DLOG_LEVEL_NUMLEVELS] = {"always", "error", "warning",
"info", "debug", "trace"};
// FIXME: inline?
void dlog_func(const dloglevel_t loglevel, const char* filename, const int linenumber, const char* functionname,
const char* format, ...) {
// fast exit
if (loglevel > minloglevel_current) {
return;
}
char* format_copy = NULL;
FILE* outstream = stderr; // change output target here, if desired
struct timeval debug_tval;
struct tm tm;
char log_datetimestamp[16]; // length due to format [00:00:00.000], rounded up to fit 32-bit alignment
gettimeofday(&debug_tval, NULL); // ignore return value
size_t offset =
strftime(log_datetimestamp, sizeof(log_datetimestamp), "[%H:%M:%S", gmtime_r(&debug_tval.tv_sec, &tm));
if (offset < 1) {
// in our use of strftime(), this is an error
return;
}
snprintf(log_datetimestamp + offset, sizeof(log_datetimestamp) - offset, ".%03ld] ", debug_tval.tv_usec / 1000);
va_list args;
va_start(args, format);
// print the user given part
// strip possible newline character from user-given string
// FIXME: could be skipped
if (format) {
size_t formatlen = std::string(format).size();
format_copy = static_cast<char*>(calloc(1, formatlen + 1)); // additional byte for terminating \0
memcpy(format_copy, format, formatlen);
if ((formatlen >= 1) && (format_copy[formatlen - 1] == '\n')) {
format_copy[formatlen - 1] = '\0';
}
}
char output[256];
if (format_copy != NULL) {
vsnprintf(output, sizeof(output), format_copy, args);
}
// force EOL
fputs("\n", outstream);
fflush(outstream);
va_end(args);
if (format_copy) {
free(format_copy);
}
switch (loglevel) {
case DLOG_LEVEL_ERROR:
EVLOG_error << output;
break;
case DLOG_LEVEL_WARNING:
EVLOG_warning << output;
break;
case DLOG_LEVEL_INFO:
EVLOG_info << output;
break;
case DLOG_LEVEL_DEBUG:
EVLOG_debug << output;
break;
case DLOG_LEVEL_TRACE:
EVLOG_verbose << output;
break;
default:
EVLOG_critical << "Unknown log level";
break;
}
}
void dlog_level_inc(void) {
dloglevel_t minloglevel_new = (dloglevel_t)((int)minloglevel_current + 1);
if (minloglevel_new == DLOG_LEVEL_NUMLEVELS) {
// wrap to bottom, but not DLOG_LEVEL_ALWAYS
minloglevel_new = DLOG_LEVEL_ERROR;
}
dlog_level_set(minloglevel_new);
}
void dlog_level_set(const dloglevel_t loglevel) {
// no sanity checks currently
const dloglevel_t minloglevel_old = minloglevel_current;
dloglevel_t newloglevel = loglevel;
if (newloglevel >= DLOG_LEVEL_NUMLEVELS) {
// set something illegally high
newloglevel = (dloglevel_t)(int)(DLOG_LEVEL_NUMLEVELS - 1);
}
if (newloglevel <= DLOG_LEVEL_ALWAYS) {
// set something illegally low
newloglevel = (dloglevel_t)(int)(DLOG_LEVEL_ALWAYS + 1);
}
if (newloglevel != minloglevel_current) {
minloglevel_current = newloglevel;
dlog(DLOG_LEVEL_ALWAYS, "switched log level from %d (\"%s\") to %d (\"%s\")", minloglevel_old,
debug_level_logstring_map[minloglevel_old], newloglevel, debug_level_logstring_map[newloglevel]);
}
}
dloglevel_t dlog_level_get(void) {
return minloglevel_current;
}
static const char* dlog_level_get_string(const dloglevel_t loglevel) {
if ((loglevel < 1) || loglevel >= DLOG_LEVEL_NUMLEVELS) {
return "invalid_level";
}
return debug_level_mqtt_string_map[loglevel];
}