Setup

With Premake

Clone the repository to the location of your choice. Create a new premake workspace and include the file c_log/premake5.lua inside your own premake file. Then link your executable project to the c_log project using this line links c_log. Finally compile the project. For a full setup of premake go to the premake github page.

Without Premake

Copy the files c_log.c, c_log.h and internal.h into your project directory and compile your project with these files.

Including to project

Once added to your project the file can be included as follows. Make sure the c_log.h file is in the include path of your project.

#include <c_log.h>

Example

The following example will create 2 loggers and show some output to demonstrate the capabilities of the library.

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

//#define CL_LOG_DISABLED
#include <c_log.h>

int main(int argc, char **argv)
{
	CL_Logger *logger = CL_LOGGER_CREATE("LOGGER", "[%T] (%N) %% %C%V\t%F, %L %M%C", 1, stdout);

	CL_Logger *logger2 = CL_LOGGER_CREATE("LOGGER2", NULL, 1, stdout);

	CL_LOG_TRACE(logger, "Hello World! %d", rand());
	CL_LOG_INFO(logger, "Hello World! %d", rand());
	CL_LOG_WARN(logger, "Hello World! %d", rand());
	CL_LOG_ERROR(logger, "Hello World! %d", rand());
	CL_LOG_FATAL(logger, "Hello World! %d", rand());

	CL_LOG_TRACE(logger2, "Hello World! %d", rand());
	CL_LOG_INFO(logger2, "Hello World! %d", rand());
	CL_LOG_WARN(logger2, "Hello World! %d", rand());
	CL_LOG_ERROR(logger2, "Hello World! %d", rand());
	CL_LOG_FATAL(logger2, "Hello World! %d", rand());

	CL_LOGGER_DESTROY(logger);
	CL_LOGGER_DESTROY(logger2);
}

Functions

This section provides in-depth information on the functions available.

CL_LOGGER_CREATE

CL_Logger *CL_LOGGER_CREATE(const char *name, const char *pattern, uint64_t output_count, ...);

Parameters

  • name -> the name of the logger which can be output when logging if it is contained in the pattern. If left NULL the logger will be named "UNNAMED".

  • pattern -> a string that will define the format of the output when logging. It can contain any character and any of the following formats:

    • %F -> the source file at which the logging was done (__FILE__ macro)
    • %L -> the line of the file at which the logging was done (__LINE__ macro)
    • %T -> the time at which the logging was done in HH:MM:SS format
    • %M -> the message that is passed to the loggin function. If %M is not present in the pattern the message will not be printed.
    • %N -> the name of the logger
    • %C -> the start and end of color. ex: %C Hello world %C ; in this case Hello world will be printed in color.
    • %V -> the name of the log level which can be TRACE, INFO, WARN, ERROR or FATAL

    If NULL is passed the pattern will be set to CL_DEFAULT_PATTERN which is defined in c_log.h. To insert a % character in the pattern write %%.

  • output_count -> the count of how many FILE * are to be passed as the next parameters.

  • ... -> the FILE *(s) to where the logger will output.

The function returns the pointer to the logger.

Usage

To output with default pattern:

CL_Logger *logger = CL_LOGGER_CREATE("TEST", NULL, 1, stdout);

To output with custom pattern:

CL_Logger *logger = CL_LOGGER_CREATE("TEST", "%C[%V]%C(%F,%L)%C%M%C", 1, stdout);

To output to stderr:

CL_Logger *logger = CL_LOGGER_CREATE("TEST", NULL, 1, stderr);

To output to a file:

FILE *file = fopen("log.txt", "w");
CL_Logger *logger = CL_LOGGER_CREATE("TEST", NULL, 1, file);

To write to multiple outputs:

FILE *file = fopen("log.txt", "w");
CL_Logger *logger = CL_LOGGER_CREATE("TEST", NULL, 2, stderr file);

CL_LOGGER_DESTROY

void CL_LOGGER_DESTROY(Logger *logger);

This function will free the data related to the logger. The passed logger cannot be used after calling this function.

Usage

CL_Logger *logger = CL_LOGGER_CREATE(&quot;TEST&quot;, NULL, 1, stdout);

// ...

CL_LOGGER_DESTROY(logger);

CL_LOG_...

void CL_LOG_TRACE(Logger *logger, const char *format, ...);
void CL_LOG_INFO(Logger *logger, const char *format, ...);
void CL_LOG_WARN(Logger *logger, const char *format, ...);
void CL_LOG_ERROR(Logger *logger, const char *format, ...);
void CL_LOG_FATAL(Logger *logger, const char *format, ...);

These functions are used to log using a specific logger. A new line is always printed at the end of the function.

Parameters

  • logger -> The logger used to print.
  • format and ... -> The message to log. These two parameters work the same as for printf in the standard library.

Usage

To print a random integer as INFO:

CL_Logger *logger = CL_LOGGER_CREATE("TEST", NULL, 1, stdout);
// ...
CL_LOG_INFO(logger, "%d", rand());
// ...
CL_LOGGER_DESTROY(logger);

CL_LOG_LVL_SET

void CL_LOGGER_LVL_SET(CL_Logger *logger, CL_LogLevel lvl);

Sets the log level at which the logger is to output.

Parameters

  • logger -> the logger to modify
  • lvl -> the log level to set

Usage

To set the level to INFO:

CL_Logger *logger = CL_LOGGER_CREATE("TEST", NULL, 1, stdout);
CL_LOGGER_LVL_SET(logger, CL_LOG_LEVEL_INFO);
// ...
CL_LOG_TRACE(logger, "will not be output")
CL_LOG_INFO(logger, "will be output");
CL_LOG_WARN(logger, "will be output");
// ...
CL_LOGGER_DESTROY(logger);

CL_LOG_LVL_GET

CL_LogLevel CL_LOGGER_LVL_GET(CL_Logger *logger);

Returns the log level of the passed logger.

Parameters

  • logger -> the logger from which the log level is retrieved.

Usage

CL_Logger *logger = CL_LOGGER_CREATE(&quot;TEST&quot;, NULL, 1, stdout);
// ...
CL_LogLevel level = CL_LOGGER_LVL_GET(logger);
// ...
CL_LOGGER_DESTROY(logger);

Log Levels

The different levels a logger can be at:

typedef enum CL_LogLevel
{
	CL_LOG_LEVEL_FATAL = 0,
	CL_LOG_LEVEL_ERROR,
	CL_LOG_LEVEL_WARN,
	CL_LOG_LEVEL_INFO,
	CL_LOG_LEVEL_TRACE
} CL_LogLevel;

Usage

No output will occur if the level of the logger is higher than the level of the function being called. For example:

CL_Logger *logger = CL_LOGGER_CREATE("TEST", NULL, 1, stdout);
CL_LOGGER_LVL_SET(logger, CL_LOG_LEVEL_WARN);
// ...
CL_LOG_INFO(logger, "will not be output");
CL_LOG_WARN(logger, "will be output");
CL_LOG_ERROR(logger, "will be output");
// ...
CL_LOGGER_DESTROY(logger);

By default the level of a logger is CL_LOG_LEVEL_TRACE.