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 __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)
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
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
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 }
00251
00252 struct hash_s
00253 {
00254 QofLogCB cb;
00255 gpointer data;
00256 };
00257
00258 static void
00259 hash_cb (gpointer key, gpointer value, gpointer data)
00260 {
00261 struct hash_s *qiter;
00262
00263 qiter = (struct hash_s *) data;
00264 if (!qiter)
00265 {
00266 return;
00267 }
00268 (qiter->cb) (key, value, qiter->data);
00269 }
00270
00271 void
00272 qof_log_module_foreach (QofLogCB cb, gpointer data)
00273 {
00274 struct hash_s qiter;
00275
00276 if (!cb)
00277 {
00278 return;
00279 }
00280 qiter.cb = cb;
00281 qiter.data = data;
00282 g_hash_table_foreach (log_table, hash_cb, (gpointer) &qiter);
00283 }
00284
00285 gint
00286 qof_log_module_count (void)
00287 {
00288 if (!log_table)
00289 {
00290 return 0;
00291 }
00292 return g_hash_table_size (log_table);
00293 }
00294
00295