#pragma once /*! \defgroup logging Osmocom logging framework * @{ */ /*! \file logging.h */ #include #include #include #include #include #include /*! \brief Maximum number of logging contexts */ #define LOG_MAX_CTX 8 /*! \brief Maximum number of logging filters */ #define LOG_MAX_FILTERS 8 #define DEBUG #ifdef DEBUG /*! \brief Log a debug message through the Osmocom logging framework * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL) * \param[in] fmt format string * \param[in] args variable argument list */ #define DEBUGP(ss, fmt, args...) LOGP(ss, LOGL_DEBUG, fmt, ##args) #define DEBUGPC(ss, fmt, args...) LOGPC(ss, LOGL_DEBUG, fmt, ##args) #else #define DEBUGP(xss, fmt, args...) #define DEBUGPC(ss, fmt, args...) #endif void osmo_vlogp(int subsys, int level, const char *file, int line, int cont, const char *format, va_list ap); void logp(int subsys, const char *file, int line, int cont, const char *format, ...) OSMO_DEPRECATED("Use DEBUGP* macros instead"); /*! \brief Log a new message through the Osmocom logging framework * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL) * \param[in] level logging level (e.g. \ref LOGL_NOTICE) * \param[in] fmt format string * \param[in] args variable argument list */ #define LOGP(ss, level, fmt, args...) \ LOGPSRC(ss, level, NULL, 0, fmt, ## args) /*! \brief Continue a log message through the Osmocom logging framework * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL) * \param[in] level logging level (e.g. \ref LOGL_NOTICE) * \param[in] fmt format string * \param[in] args variable argument list */ #define LOGPC(ss, level, fmt, args...) \ do { \ if (log_check_level(ss, level)) \ logp2(ss, level, __BASE_FILE__, __LINE__, 1, fmt, ##args); \ } while(0) /*! \brief Log through the Osmocom logging framework with explicit source. * If caller_file is passed as NULL, __BASE_FILE__ and __LINE__ are used * instead of caller_file and caller_line (so that this macro here defines * both cases in the same place, and to catch cases where callers fail to pass * a non-null filename string). * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL) * \param[in] level logging level (e.g. \ref LOGL_NOTICE) * \param[in] caller_file caller's source file string (e.g. __BASE_FILE__) * \param[in] caller_line caller's source line nr (e.g. __LINE__) * \param[in] fmt format string * \param[in] args variable argument list */ #define LOGPSRC(ss, level, caller_file, caller_line, fmt, args...) \ do { \ if (log_check_level(ss, level)) {\ if (caller_file) \ logp2(ss, level, caller_file, caller_line, 0, fmt, ##args); \ else \ logp2(ss, level, __BASE_FILE__, __LINE__, 0, fmt, ##args); \ }\ } while(0) /*! \brief different log levels */ #define LOGL_DEBUG 1 /*!< \brief debugging information */ #define LOGL_INFO 3 /*!< \brief general information */ #define LOGL_NOTICE 5 /*!< \brief abnormal/unexpected condition */ #define LOGL_ERROR 7 /*!< \brief error condition, requires user action */ #define LOGL_FATAL 8 /*!< \brief fatal, program aborted */ /* logging levels defined by the library itself */ #define DLGLOBAL -1 /*!< global logging */ #define DLLAPD -2 /*!< LAPD implementation */ #define DLINP -3 /*!< (A-bis) Input sub-system */ #define DLMUX -4 /*!< Osmocom Multiplex (Osmux) */ #define DLMI -5 /*!< ISDN-layer below input sub-system */ #define DLMIB -6 /*!< ISDN layer B-channel */ #define DLSMS -7 /*!< SMS sub-system */ #define DLCTRL -8 /*!< Control Interface */ #define DLGTP -9 /*!< GTP (GPRS Tunneling Protocol */ #define DLSTATS -10 /*!< Statistics */ #define DLGSUP -11 /*!< Generic Subscriber Update Protocol */ #define DLOAP -12 /*!< Osmocom Authentication Protocol */ #define OSMO_NUM_DLIB 12 /*!< Number of logging sub-systems in libraries */ /*! Configuration of singgle log category / sub-system */ struct log_category { uint8_t loglevel; /*!< configured log-level */ uint8_t enabled; /*!< is logging enabled? */ }; /*! \brief Information regarding one logging category */ struct log_info_cat { const char *name; /*!< name of category */ const char *color; /*!< color string for cateyory */ const char *description; /*!< description text */ uint8_t loglevel; /*!< currently selected log-level */ uint8_t enabled; /*!< is this category enabled or not */ }; /*! \brief Log context information, passed to filter */ struct log_context { void *ctx[LOG_MAX_CTX+1]; }; /*! \brief Indexes to indicate the object currently acted upon. * Array indexes for the global \a log_context array. */ enum logging_ctx_items { LOGGING_CTX_GB_NSVC, LOGGING_CTX_GB_BVC, LOGGING_CTX_BSC_SUBSCR, LOGGING_CTX_VLR_SUBSCR, _LOGGING_CTX_COUNT }; /*! \brief Indexes to indicate objects that should be logged. * Array indexes to log_target->filter_data and bit indexes for * log_target->filter_map. */ enum logging_filters { LOGGING_FILTER_ALL, LOGGING_FILTER_GB_NSVC, LOGGING_FILTER_GB_BVC, LOGGING_FILTER_BSC_SUBSCR, LOGGING_FILTER_VLR_SUBSCR, _LOGGING_FILTER_COUNT }; /*! \brief Compatibility with older libosmocore versions */ #define LOG_FILTER_ALL (1<