1.logger.h
#pragma once
#include "defines.h"
#define LOG_WARN_ENABLED 1
#define LOG_INFO_ENABLED 1
#define LOG_DEBUG_ENABLED 1
#define LOG_TRACE_ENABLED 1
//Disabled debug and trace for logging for release builds
#if KRELEASE == 1
#define LOG_DEBUG_ENABLED 0
#define LOG_TRACE_ENABLED 0
#endif
typedef enum log_level
{
LOG_LEVEL_FATAL = 0,
LOG_LEVEL_ERROR = 1,
LOG_LEVEL_WARN = 2,
LOG_LEVEL_INFO = 3,
LOG_LEVEL_DEBUG = 4,
LOG_LEVEL_TRACE = 5
}log_level;
b8 initialize_logging(u64* memory_requirement,void* state);
void shutdown_logging();
KAPI void log_output(log_level level,const char* message,...);
//logs a fatal-level message
#define KFATAL(message,...) log_output(LOG_LEVEL_FATAL,message,##__VA_ARGS__);
#ifndef KERROR
#define KERROR(message,...) log_output(LOG_LEVEL_ERROR,message,##__VA_ARGS__);
#endif
#if LOG_WARN_ENABLED == 1
//LOG WARNING ENABLEDS
#define KWARN(message,...) log_output(LOG_LEVEL_WARN,message,##__VA_ARGS__);
#else
//Does Log_wARN_ENABLED NOT EUQALS 1
#define KWARN(message,...)
#endif
#if LOG_INFO_EANBLED == 0
//LOG INFO ENABLEDS
#define KINFO(message, ...) log_output(LOG_LEVEL_INFO,message,##__VA_ARGS__);
#else
#define KINFO(message, ...)
#endif
#if LOG_DEBUG_EANBLED == 0
//Debug
#define KDEBUG(message, ...) log_output(LOG_LEVEL_DEBUG,message,##__VA_ARGS__);
#else
#define KDEBUG(message, ...)
#endif
#if LOG_TRACE_EANBLED == 0
//Debug
#define KTRACE(message, ...) log_output(LOG_LEVEL_TRACE,message,##__VA_ARGS__);
#else
#define KTRACE(message, ...)
#endif
2.logger.c
#include "platform/platform.h"
#include "core/kstring.h"
#include "platform/filesystem.h"
#include "core/kmemory.h"
#include "core/kstring.h"
//TODO:temporary
#include "logger.h"
#include "stdio.h"
#include "string.h"
#include <stdarg.h>
#include "asserts.h"
typedef struct logger_system_state
{
file_handle log_file_handle;
}logger_system_state;
static logger_system_state* state_ptr;
void append_to_log_file(const char* message)
{
if(state_ptr && state_ptr->log_file_handle.is_valid)
{
u64 length = string_length(message);
u64 written = 0;
/*if(!filesystem_write(&state_ptr->log_file_handle, length, message, &written))
{
platform_console_write_error("ERROR writing to console.log.",LOG_LEVEL_ERROR);
}
*/
}
}
b8 initialize_logging(u64* memory_requirement,void* state)
{
*memory_requirement = sizeof(logger_system_state);
if(state == 0)
{
return true;
}
state_ptr = state;
//state_ptr->intialized = true;
if(!filesystem_open("console.log",FILE_MODE_WRITE,false,&state_ptr->log_file_handle))
{
platform_console_write_error("ERROR: Unable to open console.log for writing.",LOG_LEVEL_ERROR);
return false;
}
/*
KFATAL("A test message: %f",3.14f);
KERROR("A test message: %f",3.14f);
KWARN("A test message: %f",3.14f);
KINFO("A test message: %f",3.14f);
KDEBUG("A test message: %f",3.14f);
KTRACE("A test message: %f",3.14f);
*/
//TODO: create log file
return true;
}
void shutdown_logging()
{
state_ptr = 0;
//TODO:clean all log
}
void log_output(log_level level,const char* message,...)
{
/*
const char* level_strings[6]={"[FATAL]:","[ERROR]:","[WARN]:","[INFO]:","[DEBUG]:","[TRACE]:"};
b8 is_error = level < 2;
//Technically imposes a 32k character limit on a single log entry.but...
char out_message[32000];
memset(out_message,0,sizeof(out_message));
//Format original message
__builtin_va_list arg_ptr;
va_start(arg_ptr,message);
vsnprintf(out_message,32000,message,arg_ptr);
va_end(arg_ptr);
const i32 msg_length = 32000;
char out_message2[msg_length];
sprintf(out_message2,"%s%s\n", level_strings[level], out_message);
//TODO:platform-specific output
printf("%s",out_message2);
//platform specific output
if(is_error){
platform_console_write_error(out_message,level);
}else{
platform_console_write(out_message,level);
}
*/
const char* level_strings[6] = {"[FATAL]: ","[ERROR]: ","[WARN]: ","[INFO]: ","[DEBUG]: ","[TRACE]: "};
b8 is_error = level <2;
char out_message[32000];
kzero_memory(out_message,sizeof(out_message));
__builtin_va_list arg_ptr;
va_start(arg_ptr,message);
string_format_v(out_message,message,arg_ptr);
va_end(arg_ptr);
string_format(out_message,"%s%s\n",level_strings[level],out_message);
if(is_error)
{
platform_console_write_error(out_message,level);
}else
{
platform_console_write(out_message,level);
}
append_to_log_file(out_message);
}
void report_assertion_failure(const char* expression,const char* message,const char* file,i32 line)
{
log_output(LOG_LEVEL_FATAL,"Assertion failure: %s,message:%s,in file: %s,line:%d\n",expression,message,file,line);
}