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 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