mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@11964 57a11ea4-9604-0410-9ed3-97b8803252fd
275 lines
10 KiB
C
275 lines
10 KiB
C
/********************************************************************\
|
|
* gnc-trace.h -- QOF error logging and tracing facility *
|
|
* Copyright (C) 1998-2003 Linas Vepstas <linas@linas.org> *
|
|
* Copyright (c) 2005 Neil Williams <linux@codehelp.co.uk> *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU General Public License as *
|
|
* published by the Free Software Foundation; either version 2 of *
|
|
* the License, or (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License*
|
|
* along with this program; if not, contact: *
|
|
* *
|
|
* Free Software Foundation Voice: +1-617-542-5942 *
|
|
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
|
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
|
* *
|
|
* Author: Linas Vepstas (linas@linas.org) *
|
|
\********************************************************************/
|
|
|
|
/** @addtogroup Trace
|
|
@{ */
|
|
|
|
/** @file gnc-trace.h
|
|
* @brief QOF error logging and tracing facility
|
|
* @author Neil Williams <linux@codehelp.co.uk>
|
|
*/
|
|
|
|
#ifndef GNC_TRACE_H
|
|
#define GNC_TRACE_H
|
|
|
|
#include <glib.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include "qof.h"
|
|
#include "gnc-engine-util.h"
|
|
|
|
#define QOF_MOD_ENGINE "qof-engine"
|
|
|
|
#define LOG_LEVEL_LIST(_) \
|
|
_(GNC_LOG_FATAL, = 0) \
|
|
_(GNC_LOG_ERROR, = 1) \
|
|
_(GNC_LOG_WARNING, = 2) \
|
|
_(GNC_LOG_INFO, = 3) \
|
|
_(GNC_LOG_DEBUG, = 4) \
|
|
_(GNC_LOG_DETAIL, = 5) \
|
|
_(GNC_LOG_TRACE, = 6)
|
|
|
|
DEFINE_ENUM (gncLogLevel, LOG_LEVEL_LIST)
|
|
|
|
/** Convert gncLogLevel to a string.
|
|
|
|
The macro correlates the enum value and an
|
|
exact copy as a string, removing the need to
|
|
keep two separate lists in sync.
|
|
*/
|
|
AS_STRING_DEC(gncLogLevel, LOG_LEVEL_LIST)
|
|
|
|
/** Convert the log_string to a gncLogLevel
|
|
|
|
Only for use as a partner to ::gncLogLevelasString
|
|
*/
|
|
FROM_STRING_DEC(gncLogLevel, LOG_LEVEL_LIST)
|
|
|
|
#define GNC_TRACE_INDENT_WIDTH 4
|
|
|
|
/** Initialize the error logging subsystem
|
|
|
|
\note Applications should call gnc_set_logfile
|
|
to set the output, otherwise the
|
|
default of \a /tmp/qof.trace will be used.
|
|
|
|
As an alternative, use qof_log_init_filename
|
|
which sets the filename and initialises the
|
|
logging subsystem in one operation.
|
|
*/
|
|
void gnc_log_init (void);
|
|
|
|
/** Set the logging level of the given log_module. */
|
|
void gnc_set_log_level(QofLogModule module, gncLogLevel level);
|
|
|
|
/** Set the logging level for all known log_modules.
|
|
|
|
\note Unless a log_module has been registered using
|
|
gnc_set_log_level, it will be unaffected by this change.
|
|
|
|
*/
|
|
void gnc_set_log_level_global(gncLogLevel level);
|
|
|
|
/** Specify an alternate log output, to pipe or file. By default,
|
|
* all logging goes to /tmp/qof.trace
|
|
|
|
Needs to be called \b before gnc_log_init()
|
|
*/
|
|
void gnc_set_logfile (FILE *outfile);
|
|
|
|
/** Specify a filename for log output.
|
|
|
|
Calls gnc_log_init() for you.
|
|
*/
|
|
void qof_log_init_filename (const gchar* logfilename);
|
|
|
|
/** Be nice, close the logfile is possible. */
|
|
void qof_log_shutdown (void);
|
|
|
|
/** gnc_log_prettify() cleans up subroutine names. AIX/xlC has the habit
|
|
* of printing signatures not names; clean this up. On other operating
|
|
* systems, truncate name to 30 chars. Note this routine is not thread
|
|
* safe. Note we wouldn't need this routine if AIX did something more
|
|
* reasonable. Hope thread safety doesn't poke us in eye. */
|
|
const char * gnc_log_prettify (const char *name);
|
|
|
|
/** Do not log log_modules that have not been enabled.
|
|
|
|
Whether to log cannot be decided inline because a hashtable is
|
|
now used. This is the price of extending logging to non-Gnucash
|
|
log_modules.
|
|
|
|
*/
|
|
gboolean gnc_should_log(QofLogModule log_module, gncLogLevel log_level);
|
|
|
|
/** Set the default QOF log_modules to the log level. */
|
|
void qof_log_set_default(gncLogLevel log_level);
|
|
|
|
typedef void (*QofLogCB) (QofLogModule log_module, gncLogLevel* log_level, gpointer user_data);
|
|
|
|
/** Iterate over each known log_module
|
|
|
|
Only log_modules with log_levels set will
|
|
be available.
|
|
*/
|
|
void qof_log_module_foreach(QofLogCB cb, gpointer data);
|
|
|
|
/** Number of log_modules registered*/
|
|
gint qof_log_module_count(void);
|
|
|
|
#define FUNK gnc_log_prettify(__FUNCTION__)
|
|
|
|
/** Log error/waring/info messages to stderr or to other pipe.
|
|
* This logging infrastructure is meant for validating the
|
|
* correctness of the execution of the code. 'Info' level
|
|
* messages help trace program flow. 'Error' messages are
|
|
* meant to indicate internal data inconsistencies.
|
|
*
|
|
* Messages can be logged to stdout, stderr, or to any desired
|
|
* FILE * file handle. Use fdopen() to get a file handle from a
|
|
* file descriptor. Use gnc_set_logfile to set the logging file
|
|
* handle.
|
|
*/
|
|
|
|
/** Log an fatal error */
|
|
#define FATAL(format, args...) do { \
|
|
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, \
|
|
"Fatal Error: %s(): " format, FUNK , ## args); \
|
|
} while (0)
|
|
|
|
/** Log an serious error */
|
|
#define PERR(format, args...) do { \
|
|
if (gnc_should_log (log_module, GNC_LOG_ERROR)) {\
|
|
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, \
|
|
"Error: %s(): " format, FUNK , ## args); \
|
|
} \
|
|
} while (0)
|
|
|
|
/** Log an warning */
|
|
#define PWARN(format, args...) do { \
|
|
if (gnc_should_log (log_module, GNC_LOG_WARNING)) { \
|
|
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, \
|
|
"Warning: %s(): " format, FUNK , ## args); \
|
|
} \
|
|
} while (0)
|
|
|
|
/** Print an informational note */
|
|
#define PINFO(format, args...) do { \
|
|
if (gnc_should_log (log_module, GNC_LOG_INFO)) { \
|
|
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, \
|
|
"Info: %s(): " format, \
|
|
FUNK , ## args); \
|
|
} \
|
|
} while (0)
|
|
|
|
/** Print an debugging message */
|
|
#define DEBUG(format, args...) do { \
|
|
if (gnc_should_log (log_module, GNC_LOG_DEBUG)) {\
|
|
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
|
|
"Debug: %s(): " format, \
|
|
FUNK , ## args); \
|
|
} \
|
|
} while (0)
|
|
|
|
/** Print an function entry debugging message */
|
|
#define ENTER(format, args...) do { \
|
|
extern gint gnc_trace_num_spaces; \
|
|
if (gnc_should_log (log_module, GNC_LOG_DEBUG)) {\
|
|
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
|
|
"Enter in %s: %s()" format, __FILE__, \
|
|
FUNK , ## args); \
|
|
gnc_trace_num_spaces += GNC_TRACE_INDENT_WIDTH;\
|
|
} \
|
|
} while (0)
|
|
|
|
/** Print an function exit debugging message */
|
|
#define LEAVE(format, args...) do { \
|
|
extern gint gnc_trace_num_spaces; \
|
|
if (gnc_should_log (log_module, GNC_LOG_DEBUG)) {\
|
|
gnc_trace_num_spaces -= GNC_TRACE_INDENT_WIDTH;\
|
|
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
|
|
"Leave: %s()" format, \
|
|
FUNK , ## args); \
|
|
} \
|
|
} while (0)
|
|
|
|
/** Print an function trace debugging message */
|
|
#define TRACE(format, args...) do { \
|
|
if (gnc_should_log (log_module, GNC_LOG_TRACE)) {\
|
|
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
|
|
"Trace: %s(): " format, FUNK , ## args); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define DEBUGCMD(x) do { \
|
|
if (gnc_should_log (log_module, GNC_LOG_DEBUG)) { \
|
|
(x); \
|
|
} \
|
|
} while (0)
|
|
|
|
/* -------------------------------------------------------- */
|
|
/** Infrastructure to make timing measurements for critical peices
|
|
* of code. Used for only for performance tuning & debugging.
|
|
*/
|
|
|
|
void gnc_start_clock (int clockno, QofLogModule log_module, gncLogLevel log_level,
|
|
const char *function_name, const char *format, ...);
|
|
|
|
void gnc_report_clock (int clockno,
|
|
QofLogModule log_module,
|
|
gncLogLevel log_level,
|
|
const char *function_name,
|
|
const char *format, ...);
|
|
|
|
void gnc_report_clock_total (int clockno,
|
|
QofLogModule log_module,
|
|
gncLogLevel log_level,
|
|
const char *function_name,
|
|
const char *format, ...);
|
|
|
|
/** start a particular timer */
|
|
#define START_CLOCK(clockno,format, args...) do { \
|
|
if (gnc_should_log (log_module, GNC_LOG_INFO)) \
|
|
gnc_start_clock (clockno, log_module, GNC_LOG_INFO, \
|
|
__FUNCTION__, format , ## args); \
|
|
} while (0)
|
|
|
|
/** report elapsed time since last report on a particular timer */
|
|
#define REPORT_CLOCK(clockno,format, args...) do { \
|
|
if (gnc_should_log (log_module, GNC_LOG_INFO)) \
|
|
gnc_report_clock (clockno, log_module, GNC_LOG_INFO, \
|
|
__FUNCTION__, format , ## args); \
|
|
} while (0)
|
|
|
|
/** report total elapsed time since timer started */
|
|
#define REPORT_CLOCK_TOTAL(clockno,format, args...) do { \
|
|
if (gnc_should_log (log_module, GNC_LOG_INFO)) \
|
|
gnc_report_clock_total (clockno, log_module, GNC_LOG_INFO, \
|
|
__FUNCTION__, format , ## args); \
|
|
} while (0)
|
|
|
|
#endif /* GNC_TRACE_H */
|
|
/* @} */
|