00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00044
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)
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
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
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