mirror of https://github.com/nirenjan/libx52.git
				
				
				
			
		
			
				
	
	
		
			194 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			194 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
| /*
 | |
|  * Pinelog lightweight logging library
 | |
|  *
 | |
|  * Copyright (C) 2021 Nirenjan Krishnan (nirenjan@nirenjan.org)
 | |
|  *
 | |
|  * SPDX-License-Identifier: MIT
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * @file logging.h
 | |
|  * @brief Logging utility library
 | |
|  *
 | |
|  * This file contains the prototypes for the pinelog logging library
 | |
|  * used by any programs that need to log messages.
 | |
|  *
 | |
|  * @author Nirenjan Krishnan (nirenjan@nirenjan.org)
 | |
|  */
 | |
| #ifndef LOGGING_H
 | |
| #define LOGGING_H
 | |
| 
 | |
| #include <stdio.h>
 | |
| #ifndef PINELOG_TEST
 | |
| #include <stdlib.h>
 | |
| #endif
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| extern "C" {
 | |
| #endif
 | |
| 
 | |
| /**
 | |
|  * @brief Logging levels
 | |
|  *
 | |
|  * The log levels indicate the lowest severity level that will actually be
 | |
|  * logged to the logging framework.
 | |
|  */
 | |
| enum {
 | |
|     /** No messages will be logged */
 | |
|     PINELOG_LVL_NONE = -1,
 | |
| 
 | |
|     /** Only fatal messages will be logged */
 | |
|     PINELOG_LVL_FATAL,
 | |
| 
 | |
|     /** Error messages. This is the default log level */
 | |
|     PINELOG_LVL_ERROR,
 | |
| 
 | |
|     /** Warning messages */
 | |
|     PINELOG_LVL_WARNING,
 | |
| 
 | |
|     /** Informational messages */
 | |
|     PINELOG_LVL_INFO,
 | |
| 
 | |
|     /** Debug messages */
 | |
|     PINELOG_LVL_DEBUG,
 | |
| 
 | |
|     /** Trace messages */
 | |
|     PINELOG_LVL_TRACE,
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * @brief Set the default log level and output stream
 | |
|  */
 | |
| void pinelog_set_defaults(void);
 | |
| 
 | |
| /**
 | |
|  * @brief Close the output stream and terminate the logs
 | |
|  */
 | |
| void pinelog_close_output_stream(void);
 | |
| 
 | |
| #ifdef PINELOG_TEST
 | |
| /**
 | |
|  * @brief Get the pointer to the output stream. Only used in test harness.
 | |
|  *
 | |
|  * @returns FILE pointer to output stream
 | |
|  */
 | |
| FILE * pinelog_get_output_stream(void);
 | |
| #endif
 | |
| 
 | |
| /**
 | |
|  * @brief Set the output stream. Must be a FILE pointer.
 | |
|  *
 | |
|  * @param[in]   stream  Pointer to the output stream
 | |
|  *
 | |
|  * @returns 0 on success, EINVAL if the pointer is not valid.
 | |
|  */
 | |
| int pinelog_set_output_stream(FILE *stream);
 | |
| 
 | |
| /**
 | |
|  * @brief Set the output file.
 | |
|  *
 | |
|  * @param[in]   file    Filename to write to
 | |
|  *
 | |
|  * @returns 0 on success, EINVAL if the filename pointer is not valid, other
 | |
|  * error if the file could not be opened for writing.
 | |
|  */
 | |
| int pinelog_set_output_file(const char *file);
 | |
| 
 | |
| /**
 | |
|  * @brief Set the logging level
 | |
|  *
 | |
|  * @param[in]   level   Level to filter
 | |
|  *
 | |
|  * @returns 0 on success, EINVAL if the level is not valid
 | |
|  */
 | |
| int pinelog_set_level(int level);
 | |
| 
 | |
| /**
 | |
|  * @brief Get the logging level
 | |
|  *
 | |
|  * @returns the configured logging level
 | |
|  */
 | |
| int pinelog_get_level(void);
 | |
| 
 | |
| /**
 | |
|  * @brief Log a message to the logger
 | |
|  *
 | |
|  * This is the actual function that logs the message. The application should
 | |
|  * never need to call this directly, but instead, should always use the
 | |
|  * \code PINELOG_* macros.
 | |
|  *
 | |
|  * @param[in]   level   Level to log the message at
 | |
|  * @param[in]   fmt     Format string
 | |
|  *
 | |
|  * @returns None
 | |
|  */
 | |
| #if defined __has_attribute
 | |
| #   if __has_attribute(format)
 | |
|         __attribute__((format(printf, 4, 5)))
 | |
| #   endif
 | |
| #endif
 | |
| void pinelog_log_message(int level, const char *file, int line, const char *fmt, ...);
 | |
| 
 | |
| // Test harness will redefine pinelog_exit
 | |
| #ifndef PINELOG_TEST
 | |
| #define pinelog_exit exit
 | |
| #endif
 | |
| 
 | |
| // Base filename
 | |
| #if defined __has_builtin
 | |
| #   if __has_builtin(__builtin_strrchr)
 | |
| #       define PINELOG_FILE __builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__
 | |
| #   endif
 | |
| #endif
 | |
| #ifndef PINELOG_FILE
 | |
| #   define PINELOG_FILE __FILE__
 | |
| #endif
 | |
| 
 | |
| #define PINELOG_FATAL(fmt, ...) do { \
 | |
|     if (PINELOG_LVL_FATAL <= pinelog_get_level()) { \
 | |
|         pinelog_log_message(PINELOG_LVL_FATAL, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
 | |
|     } \
 | |
|     pinelog_exit(1); \
 | |
| } while (0)
 | |
| 
 | |
| #define PINELOG_ERROR(fmt, ...) do { \
 | |
|     if (PINELOG_LVL_ERROR <= pinelog_get_level()) { \
 | |
|         pinelog_log_message(PINELOG_LVL_ERROR, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
 | |
|     } \
 | |
| } while (0)
 | |
| 
 | |
| #define PINELOG_WARN(fmt, ...) do { \
 | |
|     if (PINELOG_LVL_WARNING <= pinelog_get_level()) { \
 | |
|         pinelog_log_message(PINELOG_LVL_WARNING, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
 | |
|     } \
 | |
| } while(0)
 | |
| 
 | |
| #define PINELOG_INFO(fmt, ...) do { \
 | |
|     if (PINELOG_LVL_INFO <= pinelog_get_level()) { \
 | |
|         pinelog_log_message(PINELOG_LVL_INFO, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
 | |
|     } \
 | |
| } while(0)
 | |
| 
 | |
| #define PINELOG_DEBUG(fmt, ...) do { \
 | |
|     if (PINELOG_LVL_DEBUG <= pinelog_get_level()) { \
 | |
|         pinelog_log_message(PINELOG_LVL_DEBUG, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
 | |
|     } \
 | |
| } while(0)
 | |
| 
 | |
| /* PINELOG_DISABLE_TRACE allows all traces to be compiled out */
 | |
| #ifndef PINELOG_DISABLE_TRACE
 | |
| #define PINELOG_TRACE(fmt, ...) do { \
 | |
|     if (PINELOG_LVL_TRACE <= pinelog_get_level()) { \
 | |
|         pinelog_log_message(PINELOG_LVL_TRACE, PINELOG_FILE, __LINE__, fmt, ##__VA_ARGS__); \
 | |
|     } \
 | |
| } while(0)
 | |
| #else
 | |
| #define PINELOG_TRACE(fmt, ...) do { } while(0)
 | |
| #endif
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #endif // !defined LOGGING_H
 |