mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-30 00:00:11 +01:00

The write / DAC direction has been tested with two output signals, see etc/comedi.conf for reference. For now, the buffer size may not be (considerably) smaller than 32kB, Comedi stops working for unknown reasons. To compensate for the latency (always approx. one buffer size) if only small sample rates are required, configure the path for upsampling (sample-and-hold via rate parameter) at the same rate as the out direction of the comedi node.
196 lines
5.6 KiB
C
196 lines
5.6 KiB
C
/** Logging and debugging routines
|
|
*
|
|
* @file
|
|
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
|
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
|
* @license GNU General Public License (version 3)
|
|
*
|
|
* VILLASnode
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*********************************************************************************/
|
|
|
|
#pragma once
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <stdarg.h>
|
|
#include <time.h>
|
|
#include <sys/ioctl.h>
|
|
|
|
#include "advio.h"
|
|
#include "common.h"
|
|
#include "log_config.h"
|
|
|
|
#ifdef __GNUC__
|
|
#define INDENT int __attribute__ ((__cleanup__(log_outdent), unused)) _old_indent = log_indent(1);
|
|
#define NOINDENT int __attribute__ ((__cleanup__(log_outdent), unused)) _old_indent = log_noindent();
|
|
#else
|
|
#define INDENT ;
|
|
#define NOINDENT ;
|
|
#endif
|
|
|
|
/* The log level which is passed as first argument to print() */
|
|
#define LOG_LVL_DEBUG CLR_GRY("Debug")
|
|
#define LOG_LVL_INFO CLR_WHT("Info ")
|
|
#define LOG_LVL_WARN CLR_YEL("Warn ")
|
|
#define LOG_LVL_ERROR CLR_RED("Error")
|
|
#define LOG_LVL_STATS CLR_MAG("Stats")
|
|
|
|
/** Debug facilities.
|
|
*
|
|
* To be or-ed with the debug level
|
|
*/
|
|
enum log_facilities {
|
|
LOG_POOL = (1L << 8),
|
|
LOG_QUEUE = (1L << 9),
|
|
LOG_CONFIG = (1L << 10),
|
|
LOG_HOOK = (1L << 11),
|
|
LOG_PATH = (1L << 12),
|
|
LOG_NODE = (1L << 13),
|
|
LOG_MEM = (1L << 14),
|
|
LOG_WEB = (1L << 15),
|
|
LOG_API = (1L << 16),
|
|
LOG_LOG = (1L << 17),
|
|
LOG_VFIO = (1L << 18),
|
|
LOG_PCI = (1L << 19),
|
|
LOG_XIL = (1L << 20),
|
|
LOG_TC = (1L << 21),
|
|
LOG_IF = (1L << 22),
|
|
LOG_ADVIO = (1L << 23),
|
|
|
|
/* Node-types */
|
|
LOG_SOCKET = (1L << 24),
|
|
LOG_FILE = (1L << 25),
|
|
LOG_FPGA = (1L << 26),
|
|
LOG_NGSI = (1L << 27),
|
|
LOG_WEBSOCKET = (1L << 28),
|
|
LOG_OPAL = (1L << 30),
|
|
LOG_COMEDI = (1L << 31),
|
|
|
|
/* Classes */
|
|
LOG_NODES = LOG_NODE | LOG_SOCKET | LOG_FILE | LOG_FPGA | LOG_NGSI | LOG_WEBSOCKET | LOG_OPAL,
|
|
LOG_KERNEL = LOG_VFIO | LOG_PCI | LOG_TC | LOG_IF,
|
|
LOG_ALL = ~0xFF
|
|
};
|
|
|
|
struct log {
|
|
enum state state;
|
|
|
|
struct timespec epoch; /**< A global clock used to prefix the log messages. */
|
|
|
|
struct winsize window; /**< Size of the terminal window. */
|
|
int width; /**< The real usable log output width which fits into one line. */
|
|
|
|
/** Debug level used by the debug() macro.
|
|
* It defaults to V (defined by the Makefile) and can be
|
|
* overwritten by the 'debug' setting in the configuration file. */
|
|
int level;
|
|
long facilities; /**< Debug facilities used by the debug() macro. */
|
|
const char *path; /**< Path of the log file. */
|
|
char *prefix; /**< Prefix each line with this string. */
|
|
int syslog; /**< Whether or not to log to syslogd. */
|
|
|
|
FILE *file; /**< Send all log output to this file / stdout / stderr. */
|
|
};
|
|
|
|
/** The global log instance. */
|
|
struct log *global_log;
|
|
struct log default_log;
|
|
|
|
/** Initialize log object */
|
|
int log_init(struct log *l, int level, long faciltities);
|
|
|
|
int log_open(struct log *l);
|
|
|
|
int log_close(struct log *l);
|
|
|
|
/** Destroy log object */
|
|
int log_destroy(struct log *l);
|
|
|
|
/** Change log indention for current thread.
|
|
*
|
|
* The argument level can be negative!
|
|
*/
|
|
int log_indent(int levels);
|
|
|
|
/** Disable log indention of current thread. */
|
|
int log_noindent();
|
|
|
|
/** A helper function the restore the previous log indention level.
|
|
*
|
|
* This function is usually called by a __cleanup__ handler (GCC C Extension).
|
|
* See INDENT macro.
|
|
*/
|
|
void log_outdent(int *);
|
|
|
|
/** Set logging facilities based on expression.
|
|
*
|
|
* Currently we support two types of expressions:
|
|
* 1. A comma seperated list of logging facilities
|
|
* 2. A comma seperated list of logging facilities which is prefixes with an exclamation mark '!'
|
|
*
|
|
* The first case enables only faciltities which are in the list.
|
|
* The second case enables all faciltities with exception of those which are in the list.
|
|
*
|
|
* @param expression The expression
|
|
* @return The new facilties mask (see enum log_faciltities)
|
|
*/
|
|
int log_set_facility_expression(struct log *l, const char *expression);
|
|
|
|
/** Logs variadic messages to stdout.
|
|
*
|
|
* @param lvl The log level
|
|
* @param fmt The format string (printf alike)
|
|
*/
|
|
void log_print(struct log *l, const char *lvl, const char *fmt, ...)
|
|
__attribute__ ((format(printf, 3, 4)));
|
|
|
|
/** Logs variadic messages to stdout.
|
|
*
|
|
* @param lvl The log level
|
|
* @param fmt The format string (printf alike)
|
|
* @param va The variadic argument list (see stdarg.h)
|
|
*/
|
|
void log_vprint(struct log *l, const char *lvl, const char *fmt, va_list va);
|
|
|
|
/** Printf alike debug message with level. */
|
|
void debug(long lvl, const char *fmt, ...)
|
|
__attribute__ ((format(printf, 2, 3)));
|
|
|
|
/** Printf alike info message. */
|
|
void info(const char *fmt, ...)
|
|
__attribute__ ((format(printf, 1, 2)));
|
|
|
|
/** Printf alike warning message. */
|
|
void warn(const char *fmt, ...)
|
|
__attribute__ ((format(printf, 1, 2)));
|
|
|
|
/** Printf alike statistics message. */
|
|
void stats(const char *fmt, ...)
|
|
__attribute__ ((format(printf, 1, 2)));
|
|
|
|
/** Print error and exit. */
|
|
void error(const char *fmt, ...)
|
|
__attribute__ ((format(printf, 1, 2)));
|
|
|
|
/** Print error and strerror(errno). */
|
|
void serror(const char *fmt, ...)
|
|
__attribute__ ((format(printf, 1, 2)));
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|