You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
263 lines
7.1 KiB
263 lines
7.1 KiB
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* Copyright 1997 - July 2008 CWI, August 2008 - 2022 MonetDB B.V.
|
|
*/
|
|
|
|
/* // TODO: Complete it when documentation is accepted
|
|
*
|
|
* Tracer is the general logging system for the MonetDB stack modelled
|
|
* after the 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 code parts or of the codebase as a
|
|
* whole. It allows users to focus on logging messages related to
|
|
* certain steps of execution, which can be proved handy when it comes
|
|
* to debugging. The behavior of Tracer can be controlled at runtime
|
|
* using the SQL API described later on. Certain calls require an "id"
|
|
* to operate which can be found on the list of each section below.
|
|
*
|
|
* Internally, the logger uses a buffer to capture log messages before
|
|
* they are forwarded to the specific adapter.
|
|
*
|
|
* - Sets the minimum flush level that an event will trigger the
|
|
* logger to flush the buffer
|
|
* - Produces messages to the output stream. It is also used as a
|
|
* fallback mechanism in case GDKtracer fails to log for whatever
|
|
* reason.
|
|
* - Struct buffer with allocated space etc.
|
|
* - Flush buffer sends the messages to the selected adapter
|
|
* - Write about the log structure (e.g: MT_thread_get_name + datetime
|
|
* + blah blah)
|
|
*/
|
|
|
|
#ifndef _GDK_TRACER_H_
|
|
#define _GDK_TRACER_H_
|
|
|
|
#define GENERATE_ENUM(ENUM) ENUM,
|
|
|
|
|
|
// ADAPTERS
|
|
#define FOREACH_ADPTR(ADPTR) \
|
|
ADPTR( BASIC ) \
|
|
ADPTR( PROFILER ) \
|
|
ADPTR( MBEDDED ) \
|
|
\
|
|
ADPTR( ADAPTERS_COUNT )
|
|
|
|
typedef enum {
|
|
FOREACH_ADPTR(GENERATE_ENUM)
|
|
} adapter_t;
|
|
|
|
|
|
|
|
// LOG LEVELS
|
|
#define FOREACH_LEVEL(LEVEL) \
|
|
LEVEL( M_CRITICAL ) \
|
|
LEVEL( M_ERROR ) \
|
|
LEVEL( M_WARNING ) \
|
|
LEVEL( M_INFO ) \
|
|
LEVEL( M_DEBUG ) \
|
|
\
|
|
LEVEL( LOG_LEVELS_COUNT )
|
|
|
|
typedef enum {
|
|
FOREACH_LEVEL(GENERATE_ENUM)
|
|
} log_level_t;
|
|
|
|
|
|
// LAYERS
|
|
#define FOREACH_LAYER(LAYER) \
|
|
LAYER( MDB_ALL ) \
|
|
LAYER( SQL_ALL ) \
|
|
LAYER( MAL_ALL ) \
|
|
LAYER( GDK_ALL ) \
|
|
\
|
|
LAYER( LAYERS_COUNT )
|
|
|
|
typedef enum {
|
|
FOREACH_LAYER(GENERATE_ENUM)
|
|
} layer_t;
|
|
|
|
|
|
|
|
|
|
/*
|
|
*
|
|
* NOTE: Adding/Removing components will affect the test tracer00.mal
|
|
* See the test file for more details.
|
|
*
|
|
*/
|
|
// COMPONENTS
|
|
#define FOREACH_COMP(COMP) \
|
|
COMP( ACCELERATOR ) \
|
|
COMP( ALGO ) \
|
|
COMP( ALLOC ) \
|
|
COMP( BAT_ ) \
|
|
COMP( CHECK_ ) \
|
|
COMP( DELTA ) \
|
|
COMP( HEAP ) \
|
|
COMP( IO_ ) \
|
|
COMP( PAR ) \
|
|
COMP( PERF ) \
|
|
COMP( TEM ) \
|
|
COMP( THRD ) \
|
|
\
|
|
COMP( GEOM ) \
|
|
COMP( FITS ) \
|
|
COMP( SHP ) \
|
|
\
|
|
COMP( SQL_PARSER ) \
|
|
COMP( SQL_TRANS ) \
|
|
COMP( SQL_REWRITER ) \
|
|
COMP( SQL_EXECUTION ) \
|
|
COMP( SQL_STORE ) \
|
|
\
|
|
COMP( MAL_WLC ) \
|
|
COMP( MAL_REMOTE ) \
|
|
COMP( MAL_MAPI ) \
|
|
COMP( MAL_SERVER ) \
|
|
\
|
|
COMP( MAL_OPTIMIZER ) \
|
|
\
|
|
COMP( GDK ) \
|
|
\
|
|
COMP( COMPONENTS_COUNT )
|
|
|
|
typedef enum {
|
|
FOREACH_COMP(GENERATE_ENUM)
|
|
} component_t;
|
|
|
|
|
|
|
|
/*
|
|
* Logging macros
|
|
*/
|
|
gdk_export log_level_t lvl_per_component[];
|
|
|
|
// If the LOG_LEVEL of the message is one of the following: CRITICAL,
|
|
// ERROR or WARNING it is logged no matter the component. In any other
|
|
// case the component is taken into account
|
|
#define GDK_TRACER_TEST(LOG_LEVEL, COMP) \
|
|
(LOG_LEVEL <= M_WARNING || \
|
|
lvl_per_component[COMP] >= LOG_LEVEL)
|
|
|
|
|
|
#define GDK_TRACER_LOG_BODY(LOG_LEVEL, COMP, MSG, ...) \
|
|
GDKtracer_log(__FILE__, __func__, __LINE__, \
|
|
LOG_LEVEL, COMP, NULL, MSG, ##__VA_ARGS__)
|
|
|
|
#ifdef __COVERITY__
|
|
/* hide this for static code analysis: too many false positives */
|
|
#define GDK_TRACER_LOG(LOG_LEVEL, COMP, MSG, ...) ((void) 0)
|
|
#else
|
|
#define GDK_TRACER_LOG(LOG_LEVEL, COMP, MSG, ...) \
|
|
do { \
|
|
if (GDK_TRACER_TEST(LOG_LEVEL, COMP)) { \
|
|
GDK_TRACER_LOG_BODY(LOG_LEVEL, COMP, MSG, \
|
|
## __VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
#endif
|
|
|
|
|
|
#define TRC_CRITICAL(COMP, MSG, ...) \
|
|
GDK_TRACER_LOG_BODY(M_CRITICAL, COMP, MSG, ## __VA_ARGS__)
|
|
|
|
#define TRC_ERROR(COMP, MSG, ...) \
|
|
GDK_TRACER_LOG_BODY(M_ERROR, COMP, MSG, ## __VA_ARGS__)
|
|
|
|
#define TRC_WARNING(COMP, MSG, ...) \
|
|
GDK_TRACER_LOG_BODY(M_WARNING, COMP, MSG, ## __VA_ARGS__)
|
|
|
|
#define TRC_INFO(COMP, MSG, ...) \
|
|
GDK_TRACER_LOG(M_INFO, COMP, MSG, ## __VA_ARGS__)
|
|
|
|
#define TRC_DEBUG(COMP, MSG, ...) \
|
|
GDK_TRACER_LOG(M_DEBUG, COMP, MSG, ## __VA_ARGS__)
|
|
|
|
|
|
|
|
// Conditional logging - Example usage
|
|
// NOTE: When using the macro with *_IF always use the macro with
|
|
// *_ENDIF for logging. Avoiding to do that will result into checking
|
|
// the LOG_LEVEL of the the COMPONENT 2 times. Also NEVER use the
|
|
// *_ENDIF macro without before performing a check with *_IF
|
|
// macro. Such an action will have as a consequence logging everything
|
|
// without taking into account the LOG_LEVEL of the COMPONENT.
|
|
/*
|
|
TRC_CRITICAL_IF(SQL_STORE)
|
|
{
|
|
TRC_CRITICAL_ENDIF(SQL_STORE, "Test\n")
|
|
}
|
|
*/
|
|
#define TRC_CRITICAL_IF(COMP) \
|
|
/* if (GDK_TRACER_TEST(M_CRITICAL, COMP)) */
|
|
|
|
#define TRC_ERROR_IF(COMP) \
|
|
/* if (GDK_TRACER_TEST(M_ERROR, COMP)) */
|
|
|
|
#define TRC_WARNING_IF(COMP) \
|
|
/* if (GDK_TRACER_TEST(M_WARNING, COMP)) */
|
|
|
|
#define TRC_INFO_IF(COMP) \
|
|
if (GDK_TRACER_TEST(M_INFO, COMP))
|
|
|
|
#define TRC_DEBUG_IF(COMP) \
|
|
if (GDK_TRACER_TEST(M_DEBUG, COMP))
|
|
|
|
|
|
#define TRC_CRITICAL_ENDIF(COMP, MSG, ...) \
|
|
GDK_TRACER_LOG_BODY(M_CRITICAL, COMP, MSG, ## __VA_ARGS__)
|
|
|
|
#define TRC_ERROR_ENDIF(COMP, MSG, ...) \
|
|
GDK_TRACER_LOG_BODY(M_ERROR, COMP, MSG, ## __VA_ARGS__)
|
|
|
|
#define TRC_WARNING_ENDIF(COMP, MSG, ...) \
|
|
GDK_TRACER_LOG_BODY(M_WARNING, COMP, MSG, ## __VA_ARGS__)
|
|
|
|
#define TRC_INFO_ENDIF(COMP, MSG, ...) \
|
|
GDK_TRACER_LOG_BODY(M_INFO, COMP, MSG, ## __VA_ARGS__)
|
|
|
|
#define TRC_DEBUG_ENDIF(COMP, MSG, ...) \
|
|
GDK_TRACER_LOG_BODY(M_DEBUG, COMP, MSG, ## __VA_ARGS__)
|
|
|
|
|
|
|
|
/*
|
|
* GDKtracer API
|
|
* For the allowed log_levels, components and layers see the
|
|
* LOG_LEVEL, COMPONENT and LAYER enum respectively.
|
|
*/
|
|
// Used for logrotate
|
|
gdk_export void GDKtracer_reinit_basic(int sig);
|
|
|
|
gdk_export gdk_return GDKtracer_set_tracefile(const char *tracefile);
|
|
|
|
gdk_export gdk_return GDKtracer_stop(void);
|
|
|
|
gdk_export gdk_return GDKtracer_set_component_level(const char *comp, const char *lvl);
|
|
gdk_export const char *GDKtracer_get_component_level(const char *comp);
|
|
gdk_export gdk_return GDKtracer_reset_component_level(const char *comp);
|
|
|
|
gdk_export gdk_return GDKtracer_set_layer_level(const char *layer, const char *lvl);
|
|
gdk_export gdk_return GDKtracer_reset_layer_level(const char *layer);
|
|
|
|
gdk_export gdk_return GDKtracer_set_flush_level(const char *lvl);
|
|
gdk_export gdk_return GDKtracer_reset_flush_level(void);
|
|
|
|
gdk_export gdk_return GDKtracer_set_adapter(const char *adapter);
|
|
gdk_export gdk_return GDKtracer_reset_adapter(void);
|
|
|
|
gdk_export void GDKtracer_log(const char *file, const char *func,
|
|
int lineno, log_level_t lvl,
|
|
component_t comp,
|
|
const char *syserr,
|
|
_In_z_ _Printf_format_string_ const char *format, ...)
|
|
__attribute__((__format__(__printf__, 7, 8)));
|
|
|
|
gdk_export gdk_return GDKtracer_flush_buffer(void);
|
|
|
|
#endif /* _GDK_TRACER_H_ */
|