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  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, GLogLevelFlags log_level, 
00068     const gchar * message, gpointer user_data)
00069 {
00070     FILE *fh = user_data;
00071     fprintf (fh, "%*s%s\n", qof_log_num_spaces, "", message);
00072     fflush (fh);
00073 }
00074 
00075 void
00076 qof_log_init (void)
00077 {
00078     if (!fout)  /* allow qof_log_set_file */
00079     {
00080         fout = fopen ("/tmp/qof.trace", "w");
00081     }
00082 
00083     if (!fout && (filename = (gchar *) g_malloc (MAX_TRACE_FILENAME)))
00084     {
00085         snprintf (filename, MAX_TRACE_FILENAME - 1, "/tmp/qof.trace.%d",
00086             getpid ());
00087         fout = fopen (filename, "w");
00088         g_free (filename);
00089     }
00090 
00091     if (!fout)
00092         fout = stderr;
00093 
00094     g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK, fh_printer, fout);
00095 }
00096 
00097 void
00098 qof_log_set_level (QofLogModule log_module, QofLogLevel level)
00099 {
00100     gchar *level_string;
00101 
00102     if (!log_module || level == 0)
00103     {
00104         return;
00105     }
00106     level_string = g_strdup (QofLogLevelasString (level));
00107     if (!log_table)
00108     {
00109         log_table = g_hash_table_new (g_str_hash, g_str_equal);
00110     }
00111     g_hash_table_insert (log_table, (gpointer) log_module, level_string);
00112 }
00113 
00114 static void
00115 log_module_foreach (gpointer key, gpointer value, gpointer data)
00116 {
00117     g_hash_table_insert (log_table, key, data);
00118 }
00119 
00120 void
00121 qof_log_set_level_registered (QofLogLevel level)
00122 {
00123     gchar *level_string;
00124 
00125     if (!log_table || level == 0)
00126     {
00127         return;
00128     }
00129     level_string = g_strdup (QofLogLevelasString (level));
00130     g_hash_table_foreach (log_table, log_module_foreach, level_string);
00131 }
00132 
00133 void
00134 qof_log_set_file (FILE * outfile)
00135 {
00136     if (!outfile)
00137     {
00138         fout = stderr;
00139         return;
00140     }
00141     fout = outfile;
00142 }
00143 
00144 void
00145 qof_log_init_filename (const gchar * logfilename)
00146 {
00147     if (!logfilename)
00148     {
00149         fout = stderr;
00150     }
00151     else
00152     {
00153         filename = g_strdup (logfilename);
00154         fout = fopen (filename, "w");
00155     }
00156     qof_log_init ();
00157 }
00158 
00159 void
00160 qof_log_shutdown (void)
00161 {
00162     if (fout && fout != stderr)
00163     {
00164         fclose (fout);
00165     }
00166     if (filename)
00167     {
00168         g_free (filename);
00169     }
00170     if (function_buffer)
00171     {
00172         g_free (function_buffer);
00173     }
00174     g_hash_table_destroy (log_table);
00175 }
00176 
00177 const gchar *
00178 qof_log_prettify (const gchar *name)
00179 {
00180     gchar *p, *buffer;
00181     gint length;
00182 
00183     if (!name)
00184     {
00185         return "";
00186     }
00187     buffer = g_strndup (name, QOF_LOG_MAX_CHARS - 1);
00188     length = strlen (buffer);
00189     p = g_strstr_len (buffer, length, "(");
00190     if (p)
00191     {
00192         *(p + 1) = ')';
00193         *(p + 2) = 0x0;
00194     }
00195     else
00196     {
00197         strcpy (&buffer[QOF_LOG_MAX_CHARS - 4], "...()");
00198     }
00199     function_buffer = g_strdup (buffer);
00200     g_free (buffer);
00201     return function_buffer;
00202 }
00203 
00204 gboolean
00205 qof_log_check (QofLogModule log_module, QofLogLevel log_level)
00206 {
00207     gchar *log_string;
00208     /* Any positive log_level less than this will be logged. */
00209     QofLogLevel maximum; 
00210 
00211     log_string = NULL;
00212     if (log_level > QOF_LOG_TRACE)
00213         log_level = QOF_LOG_TRACE;
00214     if (!log_table || log_module == NULL || log_level < 0)
00215     {
00216         return FALSE;
00217     }
00218     log_string = (gchar *) g_hash_table_lookup (log_table, log_module);
00219     /* if log_module not found, do not log. */
00220     if (!log_string)
00221     {
00222         return FALSE;
00223     }
00224     maximum = QofLogLevelfromString (log_string);
00225     if (log_level <= maximum)
00226     {
00227         return TRUE;
00228     }
00229     return FALSE;
00230 }
00231 
00232 void
00233 qof_log_set_default (QofLogLevel log_level)
00234 {
00235     qof_log_set_level (QOF_MOD_BACKEND, log_level);
00236     qof_log_set_level (QOF_MOD_CLASS, log_level);
00237     qof_log_set_level (QOF_MOD_ENGINE, log_level);
00238     qof_log_set_level (QOF_MOD_OBJECT, log_level);
00239     qof_log_set_level (QOF_MOD_KVP, log_level);
00240     qof_log_set_level (QOF_MOD_MERGE, log_level);
00241     qof_log_set_level (QOF_MOD_QUERY, log_level);
00242     qof_log_set_level (QOF_MOD_SESSION, log_level);
00243     qof_log_set_level (QOF_MOD_CHOICE, log_level);
00244     qof_log_set_level (QOF_MOD_UTIL, log_level);
00245     qof_log_set_level (QOF_MOD_TIME, log_level);
00246     qof_log_set_level (QOF_MOD_DATE, log_level);
00247     qof_log_set_level (QOF_MOD_UNDO, log_level);
00248 }
00249 
00250 struct hash_s
00251 {
00252     QofLogCB cb;
00253     gpointer data;
00254 };
00255 
00256 static void
00257 hash_cb (gpointer key, gpointer value, gpointer data)
00258 {
00259     struct hash_s *qiter;
00260 
00261     qiter = (struct hash_s *) data;
00262     if (!qiter)
00263     {
00264         return;
00265     }
00266     (qiter->cb) (key, value, qiter->data);
00267 }
00268 
00269 void
00270 qof_log_module_foreach (QofLogCB cb, gpointer data)
00271 {
00272     struct hash_s qiter;
00273 
00274     if (!cb)
00275     {
00276         return;
00277     }
00278     qiter.cb = cb;
00279     qiter.data = data;
00280     g_hash_table_foreach (log_table, hash_cb, (gpointer) &qiter);
00281 }
00282 
00283 gint
00284 qof_log_module_count (void)
00285 {
00286     if (!log_table)
00287     {
00288         return 0;
00289     }
00290     return g_hash_table_size (log_table);
00291 }
00292 
00293 /* ************************ END OF FILE **************************** */

Generated on Fri Sep 1 15:10:40 2006 for QOF by  doxygen 1.4.7