2.23.92
[evolution.git] / e-util / e-logger.c
blob0c95520fe8272d58caf5bd7467b5cf7fda601248
1 /*
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) version 3.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with the program; if not, see <http://www.gnu.org/licenses/>
17 * Authors:
18 * Srinivasa Ragavan <sragavan@gnome.org>
20 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
32 #include <glib.h>
33 #include <glib/gi18n.h>
34 #include <glib/gstdio.h>
35 #include "e-logger.h"
36 #include "e-mktemp.h"
38 /* 5 Minutes */
39 #define TIMEOUT_INTERVAL 300000
41 #define E_LOGGER_GET_PRIVATE(obj) \
42 (G_TYPE_INSTANCE_GET_PRIVATE \
43 ((obj), E_TYPE_LOGGER, ELoggerPrivate))
45 struct _ELoggerPrivate {
46 gchar *component;
47 gchar *logfile;
48 FILE *fp;
50 guint timer;
53 enum {
54 PROP_0,
55 PROP_COMPONENT
58 static gpointer parent_class;
60 static gboolean
61 flush_logfile (ELogger *logger)
63 fflush (logger->priv->fp);
64 logger->priv->timer = 0;
66 return FALSE;
69 static void
70 logger_set_component (ELogger *logger,
71 const gchar *component)
73 gchar *temp;
75 g_return_if_fail (logger->priv->component == NULL);
77 temp = g_strdup_printf ("%s.log.XXXXXX", component);
79 logger->priv->component = g_strdup (component);
80 logger->priv->logfile = e_mktemp (temp);
81 logger->priv->fp = g_fopen (logger->priv->logfile, "w");
82 logger->priv->timer = 0;
84 g_free (temp);
87 static void
88 logger_set_property (GObject *object,
89 guint property_id,
90 const GValue *value,
91 GParamSpec *pspec)
93 switch (property_id) {
94 case PROP_COMPONENT:
95 logger_set_component (
96 E_LOGGER (object),
97 g_value_get_string (value));
98 return;
101 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
104 static void
105 logger_get_property (GObject *object,
106 guint property_id,
107 GValue *value,
108 GParamSpec *pspec)
110 switch (property_id) {
111 case PROP_COMPONENT:
112 g_value_set_string (
113 value, e_logger_get_component (
114 E_LOGGER (object)));
115 return;
118 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
121 static void
122 logger_finalize (GObject *object)
124 ELogger *logger = E_LOGGER (object);
126 if (logger->priv->timer)
127 g_source_remove (logger->priv->timer);
128 flush_logfile (logger);
129 fclose (logger->priv->fp);
131 g_free (logger->priv->component);
132 g_free (logger->priv->logfile);
134 /* Chain up to parent's finalize() method. */
135 G_OBJECT_CLASS (parent_class)->finalize (object);
138 static void
139 logger_class_init (ELoggerClass *class)
141 GObjectClass *object_class;
143 parent_class = g_type_class_peek_parent (class);
144 g_type_class_add_private (class, sizeof (ELoggerPrivate));
146 object_class = G_OBJECT_CLASS (class);
147 object_class->set_property = logger_set_property;
148 object_class->get_property = logger_get_property;
149 object_class->finalize = logger_finalize;
151 g_object_class_install_property (
152 object_class,
153 PROP_COMPONENT,
154 g_param_spec_string (
155 "component",
156 _("Component"),
157 _("Name of the component being logged"),
158 "anonymous",
159 G_PARAM_READWRITE |
160 G_PARAM_CONSTRUCT_ONLY));
163 static void
164 logger_init (ELogger *logger)
166 logger->priv = E_LOGGER_GET_PRIVATE (logger);
169 GType
170 e_logger_get_type (void)
172 static GType type = 0;
174 if (G_UNLIKELY (type == 0)) {
175 static const GTypeInfo type_info = {
176 sizeof (ELoggerClass),
177 (GBaseInitFunc) NULL,
178 (GBaseFinalizeFunc) NULL,
179 (GClassInitFunc) logger_class_init,
180 (GClassFinalizeFunc) NULL,
181 NULL, /* class_data */
182 sizeof (ELogger),
183 0, /* n_preallocs */
184 (GInstanceInitFunc) logger_init,
185 NULL /* value_table */
188 type = g_type_register_static (
189 G_TYPE_OBJECT, "ELogger", &type_info, 0);
192 return type;
195 ELogger *
196 e_logger_create (gchar *component)
198 g_return_val_if_fail (component != NULL, NULL);
200 return g_object_new (E_TYPE_LOGGER, "component", component, NULL);
203 const gchar *
204 e_logger_get_component (ELogger *logger)
206 g_return_val_if_fail (E_IS_LOGGER (logger), NULL);
208 return logger->priv->component;
211 static void
212 set_dirty (ELogger *logger)
214 if (logger->priv->timer)
215 return;
217 logger->priv->timer = g_timeout_add (
218 TIMEOUT_INTERVAL, (GSourceFunc) flush_logfile, logger);
221 void
222 e_logger_log (ELogger *logger,
223 gint level,
224 gchar *primary,
225 gchar *secondary)
227 time_t t = time (NULL);
229 g_return_if_fail (E_LOGGER (logger));
230 g_return_if_fail (primary != NULL);
231 g_return_if_fail (secondary != NULL);
233 fprintf (logger->priv->fp, "%d:%ld:%s\n", level, t, primary);
234 fprintf (logger->priv->fp, "%d:%ld:%s\n", level, t, secondary);
235 set_dirty (logger);
238 void
239 e_logger_get_logs (ELogger *logger,
240 ELogFunction func,
241 gpointer data)
243 FILE *fp;
244 gchar buf[250];
246 g_return_if_fail (E_LOGGER (logger));
247 g_return_if_fail (func != NULL);
249 /* Flush everything before we get the logs */
250 fflush (logger->priv->fp);
251 fp = g_fopen (logger->priv->logfile, "r");
253 if (!fp) {
254 fprintf (stderr, "Cannot open log file '%s' for reading! No flush yet?\n", logger->priv->logfile ? logger->priv->logfile : "[null]");
255 return;
258 while (!feof (fp)) {
259 gchar *tmp;
260 size_t len;
262 tmp = fgets (buf, sizeof (buf), fp);
263 if (!tmp)
264 break;
266 len = strlen (tmp);
267 if (len > 0 && tmp [len - 1] != '\n' && !feof (fp)) {
268 /* there are more characters on a row than 249, so read them all */
269 GString *str = g_string_sized_new (1024);
271 g_string_append (str, tmp);
273 while (!feof (fp) && len > 0 && tmp [len - 1] != '\n') {
274 tmp = fgets (buf, sizeof (buf), fp);
275 if (!tmp)
276 break;
278 len = strlen (tmp);
279 g_string_append (str, tmp);
282 func (str->str, data);
284 g_string_free (str, TRUE);
285 } else
286 func (tmp, data);
289 fclose (fp);