Tracer is the general logging system for the MonetDB stack, modelled after other well-known logging schemes (e.g: Python). It provides a number of logging levels and options to increase or reduce the verbosity either of individual parts of the code or of the codebase as a whole. It allows users to focus on logging messages related to certain steps of execution, in order to aid debugging. The behaviour of Tracer can be controlled at runtime using a SQL API designed for that purpose.
Tracer supports the following logging levels with the following order: CRITICAL
> ERROR
> WARNING
> INFO
> DEBUG
.
MonetDB is built upon three different layers SQL, MAL and GDK. Each layer consists of certain components. For instance, SQL layer involves âSQL MVCâ, âSQL optimizerâ and many more. However, not all the components need to belong to a single layer. There are components that target the whole stack, such as memory allocation, I/O and threads or MonetDB modules like lidar, fits and bam, that fall under a more general category. Tracer introduces the concept of âcomponent loggingâ where each component can be in a different logging level. The list of the available components is the following:
ACCELERATOR
ALGO
ALLOC
BAT_
CHECK_
DELTA
HEAP
IO_
PAR
PERF
TEM
THRD
GEOM
FITS
SHP
SQL_PARSER
SQL_TRANS
SQL_REWRITER
SQL_EXECUTION
SQL_STORE
MAL_WLC
MAL_REMOTE
MAL_MAPI
MAL_SERVER
MAL_OPTIMIZER
GDK
Tracer provides a way for 1) manipulating massively the logging level of the components depending on the layer they belong to and 2) setting all the components to a certain level of verbosity. In the following list you can find the available layers that Tracer supports:
SQL_ALL
Sets SQL layerMAL_ALL
Sets MAL layerGDK_ALL
Sets GDK layerMDB_ALL
Sets all the components (MonetDB codebase)Tracer introduces the concept of adapters in MonetDB stack. Simply, an adapter determines where the logging messages will be output. MonetDB, for now, supports only one adapter, but more will come in the future. Below you can find the supported adapters along with a brief explanation.
BASIC: Writes all the logging messages produced to the log file âmdbtrace.logâ. The file is created by default in the DB path directory, however, as itâs mentioned later on you have the option to specify the desired path on startup.
Moreover any produced logging messages with level greater than or
equal to WARNING
(i.e. WARNING
, ERROR
, and CRITICAL
) will
always be written in the standard error of the mserver5
process. This means that when the database is started using monetdbd
these messages will appear in merovingian.log
(see the monetdbd manpage).
For long running production deployments this duplication can produce a lot of wasted disk space, especially if log rotation is not used. In order to avoid that situation if the user has not specified any initialization parameters for Tracer, it will only output these messages in standard error. Specifically this means that if no logging level changes for any of the components and no output file have been specified âmdbtrace.logâ will be empty.
Tracer is compatible with the logrotate
utility.
Sending a SIGHUP to âmserver5â will cause Tracer to reopen âmdbtrace.logâ if the BASIC adapter is used.
Using directly mserver5
: In order to use a different file than the default âmdbtrace.logâ in the DB path to store the produced traces, you can simply start mserver5 with the option â--dbtrace=â.
Using merovingian (monetdbd
): In order to use a different file than the default âmdbtrace.logâ DB path in order to store the produced traces, you can use monetdb
program and set the variable âdbtraceâ. For instance: âmonetdb set dbtrace /tmp/mydb_trace.log mydbâ.
Tracer comes with a number of SQL procedures which can be called at the user level to control the tracing. Using the mclient program, you can simply execute CALL logging.*(...);
in order to interact with the logging system.
logging.flush()
Tracer uses a buffer under the hood where it stores all the logs until reaching 64KB. After that point, a flush buffer operation is performed automatically. However, in case your messages remain in the buffer because e.g: you have too few logging messages, you can always perform this call in order to flush the buffer explicitly. The log messages are getting outputted to the active adapter at that moment.
logging.setcomplevel(str comp, str level)
Sets the log level for a specific component.
logging.resetcomplevel(str comp)
Resets the log level for a specific component back to the default (ERROR).
logging.setlayerlevel(str layer, str level)
Sets the log level for a specific layer
logging.resetlayerlevel(str layer)
Resets the log level for a specific layer back to the default (ERROR).
logging.setflushlevel(str level)
Sets the flush level. A flush level determines the importance of a certain logging level. When an important message comes to the logger which has the same logging level as the flush level, Tracer will be triggered to flush the buffer. Tracer by default will always decide to flush CRITICAL and ERROR messages no matter the flush level is set.
logging.resetflushlevel()
Resets the flush level back to the default (INFO).
logging.setadapter(str adapter)
Sets the adapter that Tracer is going to use in order to output the logging messages.
logging.resetadapter()
Resets the adapter back to the default (BASIC).
SELECT * FROM logging.compinfo;
Executing this query will retrieve all the available components along with their id and the logging level that has been set.
If you are a MonetDB developer/enthusiast and you would like to contribute in the logging system of MonetDB by either introducing new layers, components or logging levels, then 'gdk/gdk_tracer.h' and 'gdk/gdk_tracer.c' are the files you are looking for!