Commit 11525fe2 authored by Lucas Russo's avatar Lucas Russo

hal/debug/*: add new logging capabilities

Now, we can log all messages directly into a file
of our choice. Also, it was added the error level and
the current timestamp for identification purposes.

This partly fixes github issue #9
parent c74a4458
debug_DIR = hal/debug
debug_OBJS = $(debug_DIR)/debug_print.o
debug_OBJS = $(debug_DIR)/debug_print.o \
$(debug_DIR)/local_print.o \
$(debug_DIR)/debug_subsys.o
debug_INCLUDE_DIRS = $(debug_DIR)
......@@ -6,7 +6,14 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <czmq.h>
#include "debug_print.h"
#include "local_print.h"
/* Our logfile */
static FILE *_debug_logfile = NULL;
void debug_print (const char *fmt, ...)
{
......@@ -17,6 +24,43 @@ void debug_print (const char *fmt, ...)
va_end (args);
}
/* Based on CZMQ s_log () function. Available in
* https://github.com/zeromq/czmq/blob/master/src/zsys.c */
static void _debug_log_write (char *dbg_lvl_str, char *msg)
{
/* Default to stdout */
if (!_debug_logfile) {
_debug_logfile = stdout;
}
time_t curtime = time (NULL);
struct tm *loctime = localtime (&curtime);
char date [20];
strftime (date, 20, "%y-%m-%d %H:%M:%S", loctime);
char log_text [1024];
snprintf (log_text, 1024, "%s: [%s] %s", dbg_lvl_str, date, msg);
fprintf (_debug_logfile, "%s", log_text);
fflush (_debug_logfile);
}
/* Based on CZMQ zsys_error () function. Available in
* https://github.com/zeromq/czmq/blob/master/src/zsys.c */
void debug_log_print (int dbg_lvl, const char *fmt, ...)
{
va_list argptr;
va_start (argptr, fmt);
char *msg = local_vprintf (fmt, argptr);
va_end (argptr);
/* Convert debug level code to string */
char *dbg_lvl_str = dbg_lvl_to_str (dbg_lvl);
_debug_log_write (dbg_lvl_str, msg);
free (msg);
free (dbg_lvl_str);
}
void debug_print_vec (const char *fmt, const char *data, int len)
{
int i;
......@@ -25,3 +69,42 @@ void debug_print_vec (const char *fmt, const char *data, int len)
printf ("\n");
}
static void _debug_set_log_file (FILE *log_file)
{
_debug_logfile = log_file;
}
void debug_set_log_file (FILE *log_file)
{
_debug_set_log_file (log_file);
}
int debug_set_log (const char *log_file_name)
{
int err = -1; /* Error */
FILE *log_file = NULL;
if (log_file_name) {
if (streq(log_file_name, "stdout")) {
log_file = stdout;
err = 1;
}
else if (streq(log_file_name, "stderr")) {
log_file = stderr;
err = 2;
}
else {
log_file = fopen (log_file_name, "w");
err = 0;
if (log_file == NULL) {
log_file = stdout;
err = 2;
}
}
}
_debug_set_log_file (log_file);
return err;
}
......@@ -10,12 +10,17 @@
#define _DEBUG_PRINT_H_
#include <stdarg.h>
#include <stdio.h>
#include "debug_subsys.h" /* This must come before "hal_opts.h" */
#include "hal_opts.h"
/************** Debug functions declarations **************/
void debug_print (const char *fmt, ...) __attribute__((format(printf,1,2)));
void debug_print_vec (const char *fmt, const char *data, int len);
void debug_log_print (int dbg_lvl, const char *fmt, ...) __attribute__((format(printf,2,3)));
/* Set the output logfile Defaults to STDOUT */
void debug_set_log_file (FILE *log_file);
int debug_set_log (const char *log_file_name);
/********************** Debug macros **********************/
......@@ -29,9 +34,12 @@ void debug_print_vec (const char *fmt, const char *data, int len);
debug_print(fmt, ## __VA_ARGS__)
#define dbg_print_vec(fmt, data, len) \
debug_print_vec(fmt, data, len)
#define dbg_log_print(dbg_lvl, fmt, ...) \
debug_log_print(dbg_lvl, fmt, ## __VA_ARGS__)
#else
#define dbg_print(fmt, ...)
#define dbg_print_vec(fmt, data, len)
#define dbg_log_print(dbg_lvl, fmt, ...)
#endif /* DBE_DBG */
......@@ -47,7 +55,8 @@ void debug_print_vec (const char *fmt, const char *data, int len);
if (((dbg) & DBG_SUBSYS_ON) && \
(((dbg) & DBG_LVL_MASK) >= \
DBG_MIN_LEVEL)) { \
dbg_print(fmt, ## __VA_ARGS__); \
dbg_log_print((dbg) & DBG_LVL_MASK, \
fmt, ## __VA_ARGS__); \
\
if ((dbg) & DBG_LVL_HALT) { \
while(1); \
......
/*
* Copyright (C) 2014 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU LGPL, version 3 or any later version.
*/
#include <czmq.h>
#include "debug_subsys.h"
char *dbg_lvl_str [DBG_LVL_NUM] = {
[0] = DBG_LVL_TRACE_STR,
[1] = DBG_LVL_INFO_STR,
[2] = DBG_LVL_WARN_STR,
[3] = DBG_LVL_ERR_STR,
[4] = DBG_LVL_FATAL_STR
};
char *dbg_lvl_to_str (int dbg_lvl)
{
/* Should be large enough for all possible debug levels */
int size = 16;
char *str = zmalloc (size);
const char *dbg_str = dbg_lvl_str [DBG_LVL_DEGEN(dbg_lvl)-1];
memcpy (str, dbg_str, strlen (dbg_str)+1);
return str;
}
......@@ -24,6 +24,7 @@
#define DBG_SUBSYS_MASK (DBG_SUBSYS_MASK_RAW << DBG_SUBSYS_SHIFT)
#define DBG_SUBSYS_GEN(val) ((val & DBG_SUBSYS_MASK_RAW) << DBG_SUBSYS_SHIFT)
#define DBG_SUBSYS_DEGEN(val) ((val & DBG_SUBSYS_MASK) >> DBG_SUBSYS_SHIFT)
/* Debug subsys raw */
#define DBG_DEV_MNGR_RAW 0x1
......@@ -58,6 +59,9 @@
/* Up to 2^3 debug levels */
#define DBG_LVL_GEN(val) ((val & DBG_LVL_MASK_RAW) << DBG_LVL_SHIFT)
#define DBG_LVL_DEGEN(val) ((val & DBG_LVL_MASK) >> DBG_LVL_SHIFT)
#define DBG_LVL_NUM 5
/* Debug levels raw */
#define DBG_LVL_TRACE_RAW 0x1
......@@ -73,6 +77,14 @@
#define DBG_LVL_ERR DBG_LVL_GEN(DBG_LVL_ERR_RAW)
#define DBG_LVL_FATAL DBG_LVL_GEN(DBG_LVL_FATAL_RAW)
#define DBG_LVL_TRACE_STR "TRACE"
#define DBG_LVL_INFO_STR "INFO"
#define DBG_LVL_WARN_STR "WARN"
#define DBG_LVL_ERR_STR "ERR"
#define DBG_LVL_FATAL_STR "FATAL"
extern char *dbg_lvl_str [DBG_LVL_NUM];
char *dbg_lvl_to_str (int dbg_lvl);
/****************** Debug halt macros ******************/
/*
......@@ -89,6 +101,7 @@
/* 1 halt signal */
#define DBG_HALT_GEN(val) ((val & DBG_HALT_MASK_RAW) << DBG_HALT_SHIFT)
#define DBG_HALT_DEGEN(val) ((val & DBG_HALT_MASK) >> DBG_HALT_SHIFT)
/* Debug halt raw */
#define DBG_LVL_HALT_RAW 0x1
......@@ -96,4 +109,5 @@
/* Debug halt mask'ed and shift'ed */
#define DBG_LVL_HALT DBG_HALT_GEN(DBG_LVL_HALT_RAW)
#endif
/*
* Copyright (C) 2014 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU LGPL, version 3 or any later version.
*/
#include <czmq.h>
char *local_vprintf (const char *format, va_list argptr)
{
return zsys_vprintf (format, argptr);
}
/*
* Copyright (C) 2014 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
* Parts taken from lwIP debug system
*
* Released according to the GNU LGPL, version 3 or any later version.
*/
#ifndef _LOCAL_PRINT_H_
#define _LOCAL_PRINT_H_
char *local_vprintf (const char *format, va_list argptr);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment