qoflog.c

00001 /* **************************************************************************
00002  *            qoflog.c
00003  *
00004  *  Mon Nov 21 14:41:59 2005
00005  *  Author: Rob Clark (rclark@cs.hmc.edu)
00006  *  Copyright (C) 1997-2003 Linas Vepstas <linas@linas.org>
00007  *  Copyright  2005-2008  Neil Williams
00008  *  linux@codehelp.co.uk
00009  *************************************************************************** */
00010 /*
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License
00022  *  along with this program; if not, write to the Free Software
00023  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00024  *  02110-1301,  USA
00025  */
00026 
00027 #include "config.h"
00028 
00029 #include <glib.h>
00030 #include <unistd.h>
00031 #include "qof.h"
00032 
00033 #define QOF_LOG_MAX_CHARS 50
00034 #define QOF_LOG_INDENT_WIDTH 4
00035 
00036 static FILE *fout = NULL;
00037 static gchar *filename = NULL;
00038 static gchar *function_buffer = NULL;
00039 static const gint MAX_TRACE_FILENAME = 100;
00040 static GHashTable *log_table = NULL;
00041 static gint qof_log_num_spaces = 0;
00042 
00043 /* uses the enum_as_string macro.
00044 Lookups are done on the string. */
00045 AS_STRING_FUNC (QofLogLevel, LOG_LEVEL_LIST)
00046 FROM_STRING_FUNC (QofLogLevel, LOG_LEVEL_LIST)
00047 
00048 void qof_log_add_indent (void)
00049 {
00050     qof_log_num_spaces += QOF_LOG_INDENT_WIDTH;
00051 }
00052 
00053 gint
00054 qof_log_get_indent (void)
00055 {
00056     return qof_log_num_spaces;
00057 }
00058 
00059 void
00060 qof_log_drop_indent (void)
00061 {
00062     qof_log_num_spaces = (qof_log_num_spaces < QOF_LOG_INDENT_WIDTH) ?
00063         0 : qof_log_num_spaces - QOF_LOG_INDENT_WIDTH;
00064 }
00065 
00066 static void
00067 fh_printer (const gchar * log_domain __attribute__ ((unused)), 
00068     GLogLevelFlags log_level __attribute__ ((unused)), 
00069     const gchar * message, gpointer user_data)
00070 {
00071     FILE *fh = user_data;
00072     fprintf (fh, "%*s%s\n", qof_log_num_spaces, "", message);
00073     fflush (fh);
00074 }
00075 
00076 void
00077 qof_log_init (void)
00078 {
00079     if (!fout)  /* allow qof_log_set_file */
00080     {
00081         fout = fopen ("/tmp/qof.trace", "w");
00082     }
00083 
00084     if (!fout && (filename = (gchar *) g_malloc (MAX_TRACE_FILENAME)))
00085     {
00086         snprintf (filename, MAX_TRACE_FILENAME - 1, "/tmp/qof.trace.%d",
00087             getpid ());
00088         fout = fopen (filename, "w");
00089         g_free (filename);
00090     }
00091 
00092     if (!fout)
00093         fout = stderr;
00094 
00095     g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK, fh_printer, fout);
00096 }
00097 
00098 void
00099 qof_log_set_level (QofLogModule log_module, QofLogLevel level)
00100 {
00101     gchar *level_string;
00102 
00103     if (!log_module || level == 0)
00104     {
00105         return;
00106     }
00107     level_string = g_strdup (QofLogLevelasString (level));
00108     if (!log_table)
00109     {
00110         log_table = g_hash_table_new (g_str_hash, g_str_equal);
00111     }
00112     g_hash_table_insert (log_table, (gpointer) log_module, level_string);
00113 }
00114 
00115 static void
00116 log_module_foreach (gpointer key, 
00117     gpointer value __attribute__ ((unused)), gpointer data)
00118 {
00119     g_hash_table_insert (log_table, key, data);
00120 }
00121 
00122 void
00123 qof_log_set_level_registered (QofLogLevel level)
00124 {
00125     gchar *level_string;
00126 
00127     if (!log_table || level == 0)
00128     {
00129         return;
00130     }
00131     level_string = g_strdup (QofLogLevelasString (level));
00132     g_hash_table_foreach (log_table, log_module_foreach, level_string);
00133 }
00134 
00135 void
00136 qof_log_set_file (FILE * outfile)
00137 {
00138     if (!outfile)
00139     {
00140         fout = stderr;
00141         return;
00142     }
00143     fout = outfile;
00144 }
00145 
00146 void
00147 qof_log_init_filename (const gchar * logfilename)
00148 {
00149     if (!logfilename)
00150     {
00151         fout = stderr;
00152     }
00153     else
00154     {
00155         filename = g_strdup (logfilename);
00156         fout = fopen (filename, "w");
00157     }
00158     qof_log_init ();
00159 }
00160 
00161 void
00162 qof_log_shutdown (void)
00163 {
00164     if (fout && fout != stderr)
00165     {
00166         fclose (fout);
00167     }
00168     if (filename)
00169     {
00170         g_free (filename);
00171     }
00172     if (function_buffer)
00173     {
00174         g_free (function_buffer);
00175     }
00176     g_hash_table_destroy (log_table);
00177 }
00178 
00179 const gchar *
00180 qof_log_prettify (const gchar *name)
00181 {
00182     gchar *p, *buffer;
00183     gint length;
00184 
00185     if (!name)
00186     {
00187         return "";
00188     }
00189     buffer = g_strndup (name, QOF_LOG_MAX_CHARS - 1);
00190     length = strlen (buffer);
00191     p = g_strstr_len (buffer, length, "(");
00192     if (p)
00193     {
00194         *(p + 1) = ')';
00195         *(p + 2) = 0x0;
00196     }
00197     else
00198     {
00199         strcpy (&buffer[QOF_LOG_MAX_CHARS - 4], "...()");
00200     }
00201     function_buffer = g_strdup (buffer);
00202     g_free (buffer);
00203     return function_buffer;
00204 }
00205 
00206 gboolean
00207 qof_log_check (QofLogModule log_module, QofLogLevel log_level)
00208 {
00209     gchar *log_string;
00210     /* Any positive log_level less than this will be logged. */
00211     QofLogLevel maximum; 
00212 
00213     log_string = NULL;
00214     if (log_level > QOF_LOG_TRACE)
00215         log_level = QOF_LOG_TRACE;
00216     if (!log_table || log_module == NULL)
00217     {
00218         return FALSE;
00219     }
00220     log_string = (gchar *) g_hash_table_lookup (log_table, log_module);
00221     /* if log_module not found, do not log. */
00222     if (!log_string)
00223     {
00224         return FALSE;
00225     }
00226     maximum = QofLogLevelfromString (log_string);
00227     if (log_level <= maximum)
00228     {
00229         return TRUE;
00230     }
00231     return FALSE;
00232 }
00233 
00234 void
00235 qof_log_set_default (QofLogLevel log_level)
00236 {
00237     qof_log_set_level (QOF_MOD_BACKEND, log_level);
00238     qof_log_set_level (QOF_MOD_CLASS, log_level);
00239     qof_log_set_level (QOF_MOD_ENGINE, log_level);
00240     qof_log_set_level (QOF_MOD_OBJECT, log_level);
00241     qof_log_set_level (QOF_MOD_KVP, log_level);
00242     qof_log_set_level (QOF_MOD_MERGE, log_level);
00243     qof_log_set_level (QOF_MOD_QUERY, log_level);
00244     qof_log_set_level (QOF_MOD_SESSION, log_level);
00245     qof_log_set_level (QOF_MOD_CHOICE, log_level);
00246     qof_log_set_level (QOF_MOD_UTIL, log_level);
00247     qof_log_set_level (QOF_MOD_TIME, log_level);
00248     qof_log_set_level (QOF_MOD_DATE, log_level);
00249     qof_log_set_level (QOF_MOD_UNDO, log_level);
00250     qof_log_set_level (QOF_MOD_ERROR, log_level);
00251     qof_log_set_level (QOF_MOD_QSF, log_level);
00252     qof_log_set_level (QOF_MOD_SQLITE, log_level);
00253     qof_log_set_level (QOF_MOD_GDA, log_level);
00254 }
00255 
00256 struct hash_s
00257 {
00258     QofLogCB cb;
00259     gpointer data;
00260 };
00261 
00262 static void
00263 hash_cb (gpointer key, gpointer value, gpointer data)
00264 {
00265     struct hash_s *qiter;
00266 
00267     qiter = (struct hash_s *) data;
00268     if (!qiter)
00269     {
00270         return;
00271     }
00272     (qiter->cb) (key, value, qiter->data);
00273 }
00274 
00275 void
00276 qof_log_module_foreach (QofLogCB cb, gpointer data)
00277 {
00278     struct hash_s qiter;
00279 
00280     if (!cb)
00281     {
00282         return;
00283     }
00284     qiter.cb = cb;
00285     qiter.data = data;
00286     g_hash_table_foreach (log_table, hash_cb, (gpointer) &qiter);
00287 }
00288 
00289 gint
00290 qof_log_module_count (void)
00291 {
00292     if (!log_table)
00293     {
00294         return 0;
00295     }
00296     return g_hash_table_size (log_table);
00297 }
00298 
00299 /* ************************ END OF FILE **************************** */

Generated on Thu Jan 31 22:50:26 2008 for QOF by  doxygen 1.5.4