Logging
DQCsim provides a centralized logging interface for plugins. This ensures that log messages are processed in a consistent way among different plugins. It also makes sure that messages don't print "through" each other, as they would when stdout/stderr were used directly (these are not thread-safe).
The logging interface is only available from within threads that are hosting a plugin (or the main thread of a plugin process) and the thread which started the simulation.
Log levels
Every message has a severity level associated with it. These severities should be interpreted as follows:
trace
is intended for reporting debugging information useful for debugging the internals of the originating plugin, but not necessarily for debugging the plugins around it. Such messages would normally only be generated by debug builds, to prevent them from impacting performance under normal circumstances.debug
is intended for reporting debugging information which may also be useful when debugging the plugins around it, such as the arguments with which a public API function was called.info
is intended for reporting information that was not explicitly requested by the user, such as a plugin starting up or shutting down.note
is intended for reporting information that was explicitly requested by the user/API caller, such as the result of an API function requested through the command line, or an explicitly captured stdout/stderr stream. It may also be used for reporting events that the user may not be expecting, but are not exceptional enough to warrent issuing a warning.warn
is intended for reporting that a third party did something unexpected, but that an attempt will be made to work around the problem, such as a failed connection attempt that we're going to retry.error
is intended for reporting or propagating a non-fatal error, such as a third party requesting usage of an unimplemented function.fatal
is intended for reporting fatal errors, such as a third party reporting an error for something that we really needed.
Sending log messages
The preferred way for C programs to submit log messages is through the
following macros. These automatically add information such as line number and
source filename through the C preprocessor. They also fall back to writing to
stderr
if logging fails for some reason. Their interface is just like
printf
, but the final newline is implicit.
dqcs_log_trace()
Convenience macro for calling dqcs_log_format()
with trace loglevel and
automatically determined function name, filename, and line number.
Convenience macro for calling dqcs_log_format()
with trace loglevel and
automatically determined function name, filename, and line number.
#define dqcs_log_trace(fmt, ...) \
dqcs_log_format( \
_DQCSIM_LOGLEVEL_PREFIX_ DQCS_LOG_TRACE, \
_DQCSIM_LANGUAGE_, \
__FILE__, \
__LINE__, \
fmt, \
##__VA_ARGS__ \
)
dqcs_log_debug()
Convenience macro for calling dqcs_log_format()
with debug loglevel and
automatically determined function name, filename, and line number.
Convenience macro for calling dqcs_log_format()
with debug loglevel and
automatically determined function name, filename, and line number.
#define dqcs_log_debug(fmt, ...) \
dqcs_log_format( \
_DQCSIM_LOGLEVEL_PREFIX_ DQCS_LOG_DEBUG, \
_DQCSIM_LANGUAGE_, \
__FILE__, \
__LINE__, \
fmt, \
##__VA_ARGS__ \
)
dqcs_log_info()
Convenience macro for calling dqcs_log_format()
with info loglevel and
automatically determined function name, filename, and line number.
Convenience macro for calling dqcs_log_format()
with info loglevel and
automatically determined function name, filename, and line number.
#define dqcs_log_info(fmt, ...) \
dqcs_log_format( \
_DQCSIM_LOGLEVEL_PREFIX_ DQCS_LOG_INFO, \
_DQCSIM_LANGUAGE_, \
__FILE__, \
__LINE__, \
fmt, \
##__VA_ARGS__ \
)
dqcs_log_note()
Convenience macro for calling dqcs_log_format()
with note loglevel and
automatically determined function name, filename, and line number.
Convenience macro for calling dqcs_log_format()
with note loglevel and
automatically determined function name, filename, and line number.
#define dqcs_log_note(fmt, ...) \
dqcs_log_format( \
_DQCSIM_LOGLEVEL_PREFIX_ DQCS_LOG_NOTE, \
_DQCSIM_LANGUAGE_, \
__FILE__, \
__LINE__, \
fmt, \
##__VA_ARGS__ \
)
dqcs_log_warn()
Convenience macro for calling dqcs_log_format()
with warn loglevel and
automatically determined function name, filename, and line number.
Convenience macro for calling dqcs_log_format()
with warn loglevel and
automatically determined function name, filename, and line number.
#define dqcs_log_warn(fmt, ...) \
dqcs_log_format( \
_DQCSIM_LOGLEVEL_PREFIX_ DQCS_LOG_WARN, \
_DQCSIM_LANGUAGE_, \
__FILE__, \
__LINE__, \
fmt, \
##__VA_ARGS__ \
)
dqcs_log_error()
Convenience macro for calling dqcs_log_format()
with error loglevel and
automatically determined function name, filename, and line number.
Convenience macro for calling dqcs_log_format()
with error loglevel and
automatically determined function name, filename, and line number.
#define dqcs_log_error(fmt, ...) \
dqcs_log_format( \
_DQCSIM_LOGLEVEL_PREFIX_ DQCS_LOG_ERROR, \
_DQCSIM_LANGUAGE_, \
__FILE__, \
__LINE__, \
fmt, \
##__VA_ARGS__ \
)
dqcs_log_fatal()
Convenience macro for calling dqcs_log_format()
with fatal loglevel and
automatically determined function name, filename, and line number.
Convenience macro for calling dqcs_log_format()
with fatal loglevel and
automatically determined function name, filename, and line number.
#define dqcs_log_fatal(fmt, ...) \
dqcs_log_format( \
_DQCSIM_LOGLEVEL_PREFIX_ DQCS_LOG_FATAL, \
_DQCSIM_LANGUAGE_, \
__FILE__, \
__LINE__, \
fmt, \
##__VA_ARGS__ \
)
To get more control over the metadata or to set the loglevel programmatically, you can use the following function.
dqcs_log_format()
Sends a log message using the current logger using printf-like formatting.
Sends a log message using the current logger using printf-like formatting.
static void dqcs_log_format(
dqcs_loglevel_t level,
const char *module,
const char *file,
uint32_t line,
const char *fmt,
...
)
This function is identical to dqcs_log_raw()
, except instead of a single
string it takes a printf-like format string and varargs to compose the
message.
The above macros and functions ultimately call dqcs_log_raw()
. This function
does not fall back to stderr
if logging fails, and does not support
printf
-style format strings. The latter may be useful for interfacing with
languages that don't support calling variadic functions.
dqcs_log_raw()
Primitive API for sending a log message using the current logger.
Primitive API for sending a log message using the current logger.
dqcs_return_t dqcs_log_raw(
dqcs_loglevel_t level,
const char *module,
const char *file,
uint32_t line_nr,
const char *message
)
Returns DQCS_SUCCESS
if logging was successful, or DQCS_FAILURE
if no
logger is available in the current thread or one of the arguments could not
be converted. Loggers are available in the simulation host thread and in
threads running plugins.
Formatting and fallback to stderr
As an alternative to this function, you can also use dqcs_log_format()
.
This function differs from dqcs_log_raw()
in two ways:
- Instead of the
message
string, a printf-style format string and associated varargs are passed to construct the message. - When logging fails, this function falls back to writing to
stderr
instead of returning the errors.
Macros
From C and C++, these functions are normally not called directly. Instead, the following macros are used:
dqcs_log_trace("trace message!");
dqcs_log_debug("debug message!");
dqcs_log_info("info message!");
dqcs_log_note("notice!");
dqcs_log_warn("warning!");
dqcs_log_error("error!");
dqcs_log_fatal("fatal error!");
These macros automatically set file
to the C source filename and line
to the line number. module
is hardcoded to "C" or "CPP" depending on
source file language. They use dqcs_log_format()
, so they also support
printf-style formatting. For instance:
dqcs_note("answer to %s: %d", "ultimate question", 42);
stdout and stderr
By default, DQCsim will capture the stdout and stderr streams of the plugin processes it launches. Each received line will simply be turned into a log message. This is particularly useful for logging problems related to connecting to DQCsim.