[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
gEDA-user: [PATCH] Write logs to $HOME/.gEDA/logs/.
Here is a suggested patch. Portability is still dubious, but I've done
my best to make sure that we create new logfiles in a secure manner.
The format of the log filenames is intended so as to make it easy for a
user to find the most recent log file when troubleshooting.
I'd appreciate comments as to whether this will work (or even compile)
on Windows!
Peter
--
Peter Brett
Electronic Systems Engineer
Integral Informatics Ltd
From cabf7399d5f7d24559f8c36571e8bdf65fc673fa Mon Sep 17 00:00:00 2001
From: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date: Fri, 16 Jan 2009 22:20:29 +0000
Subject: [PATCH] Write logs to $HOME/.gEDA/logs/.
Rewrite s_log_init() to put log files in a centralised location. A
user application (e.g. gnetlist) provides a prefix, and log file is
opened at:
$HOME/.gEDA/logs/<prefix>-<YYYYmmdd>-<serial>.log
The serial is found by the following procedure:
1. Read through the directory to find the highest existing <serial>.
2. Starting with that number, repeatedly attempt to open()
incrementing files with O_CREAT|O_EXCL flags to guarantee that a
new file is created.
3. If after LOG_OPEN_ATTEMPTS = 5 attempts a unique filename hasn't
been found, fail.
---
gattrib/src/gattrib.c | 6 +--
gnetlist/src/gnetlist.c | 4 +-
gschem/src/gschem.c | 5 +--
gsymcheck/src/gsymcheck.c | 4 +-
libgeda/src/s_log.c | 103 +++++++++++++++++++++++++++++++++++++++-----
utils/gschlas/gschlas.c | 4 +-
6 files changed, 96 insertions(+), 30 deletions(-)
diff --git a/gattrib/src/gattrib.c b/gattrib/src/gattrib.c
index e5f6818..778d0db 100644
--- a/gattrib/src/gattrib.c
+++ b/gattrib/src/gattrib.c
@@ -142,11 +142,7 @@ void gattrib_main(void *closure, int argc, char *argv[])
/* ---------- create log file right away ---------- */
/* ---------- even if logging is enabled ---------- */
- cwd = g_get_current_dir();
- logfile = g_build_filename (cwd, "gattrib.log", NULL);
- s_log_init (logfile);
- g_free (logfile);
- g_free (cwd);
+ s_log_init ("gattrib");
s_log_message
("gEDA/gattrib version %s%s.%s\n", PREPEND_VERSION_STRING,
diff --git a/gnetlist/src/gnetlist.c b/gnetlist/src/gnetlist.c
index 1f73dbb..ee7b8d4 100644
--- a/gnetlist/src/gnetlist.c
+++ b/gnetlist/src/gnetlist.c
@@ -143,9 +143,7 @@ void main_prog(void *closure, int argc, char *argv[])
/* create log file right away */
/* even if logging is enabled */
- logfile = g_build_filename (cwd, "gnetlist.log", NULL);
- s_log_init (logfile);
- g_free (logfile);
+ s_log_init ("gnetlist");
s_log_message("gEDA/gnetlist version %s%s.%s\n", PREPEND_VERSION_STRING,
DOTTED_VERSION, DATE_VERSION);
diff --git a/gschem/src/gschem.c b/gschem/src/gschem.c
index 1c3122a..af4511e 100644
--- a/gschem/src/gschem.c
+++ b/gschem/src/gschem.c
@@ -178,11 +178,8 @@ void main_prog(void *closure, int argc, char *argv[])
load_newer_backup_func = x_fileselect_load_backup;
select_func = o_select_object;
- /*! \todo Probably the file name shuold be defined elsewhere */
/* create log file right away even if logging is enabled */
- filename = g_build_filename (cwd, "gschem.log", NULL);
- s_log_init (filename);
- g_free (filename);
+ s_log_init ("gschem");
s_log_message(
_("gEDA/gschem version %s%s.%s\n"), PREPEND_VERSION_STRING,
diff --git a/gsymcheck/src/gsymcheck.c b/gsymcheck/src/gsymcheck.c
index 04b1ae3..21f1c3a 100644
--- a/gsymcheck/src/gsymcheck.c
+++ b/gsymcheck/src/gsymcheck.c
@@ -63,10 +63,8 @@ main_prog(void *closure, int argc, char *argv[])
/* create log file right away */
/* even if logging is enabled */
- logfile = g_build_filename (cwd, "gsymcheck.log", NULL);
x_log_update_func = s_log_update;
- s_log_init (logfile);
- g_free (logfile);
+ s_log_init ("gsymcheck");
logging_dest=STDOUT_TTY;
if (!quiet_mode)
diff --git a/libgeda/src/s_log.c b/libgeda/src/s_log.c
index fcc087c..8d1ea52 100644
--- a/libgeda/src/s_log.c
+++ b/libgeda/src/s_log.c
@@ -42,6 +42,8 @@
#include "libgeda_priv.h"
+#include <time.h>
+
#ifdef HAVE_LIBDMALLOC
#include <dmalloc.h>
#endif
@@ -57,6 +59,8 @@ int do_logging = TRUE;
#define PRINT_LOG_LEVELS (CATCH_LOG_LEVELS ^ \
(G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE))
+#define LOG_OPEN_ATTEMPTS 5
+
static void s_log_handler (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *message,
@@ -73,27 +77,102 @@ static guint log_handler_id;
*
* \param [in] filename Character string with file name to log to.
*/
-void s_log_init (const gchar *filename)
+void s_log_init (const gchar *prefix)
{
+ /* FIXME we assume that the prefix is in the filesystem encoding. */
+
+ gchar *full_prefix = NULL;
+ size_t full_prefix_len = 0;
+ time_t nowt;
+ struct tm *nowtm;
+ gchar *dir_path = NULL;
+ gchar *filename = NULL;
+ int s, i;
+ int last_exist_logn = 0;
+ GDir *logdir = NULL;
+
+ if (logfile_fd != -1) {
+ g_critical ("s_log_init: Log already initialised.\n");
+ return;
+ }
if (do_logging == FALSE) {
- logfile_fd = -1;
return;
}
- /* create log file */
- logfile_fd = open (filename, O_RDWR|O_CREAT|O_TRUNC, 0600);
- if (logfile_fd == -1) {
- fprintf(stderr, "Could not open log file: %s\n", filename);
- fprintf(stderr, "Errno was: %d\n", errno);
+ time (&nowt);
+ nowtm = gmtime (&nowt);
+
+ /* create "real" prefix -- this has the form "<prefix>-<date>-" */
+ full_prefix = g_strdup_printf ("%s-%04i%02i%02i-", prefix,
+ nowtm->tm_year + 1900, nowtm->tm_mon + 1,
+ nowtm->tm_mday);
+ full_prefix_len = strlen (full_prefix);
+
+ /* Find/create the directory where we're going to put the logs.
+ * FIXME should this be configured somehow?
+ *
+ * Then run through it finding the "biggest" existing filename with
+ * a matching prefix & date. */
+ dir_path = g_build_filename (g_getenv ("HOME"),
+ ".gEDA", "logs", NULL);
+ /* Try to create the directory. */
+ s = g_mkdir_with_parents (dir_path, 0777/*octal*/);
+ if (s != 0) {
+ /* FIXME should we report this somehow? */
+ fprintf (stderr, "Could not create log directory %s: %s\n",
+ dir_path, strerror (errno));
+ g_free (dir_path);
+ g_free (full_prefix);
return;
}
- /* install the log handler */
- log_handler_id = g_log_set_handler (NULL,
- CATCH_LOG_LEVELS,
- s_log_handler,
- NULL);
+ logdir = g_dir_open (dir_path, 0, NULL);
+ while (TRUE) {
+ const gchar *file = g_dir_read_name (logdir);
+ int n;
+ if (file == NULL) break;
+ if (strncmp (full_prefix, file, full_prefix_len)) continue;
+
+ s = sscanf (file + full_prefix_len, "%i", &n);
+ if (s != 1) continue;
+
+ if (n > last_exist_logn) last_exist_logn = n;
+ }
+
+ /* Now try and create a new file. When we fail, increment the number. */
+ i = 0;
+ while (logfile_fd == -1 && (LOG_OPEN_ATTEMPTS > i++)) {
+ filename = g_strdup_printf ("%s%s%s%i.log", dir_path,
+ G_DIR_SEPARATOR_S, full_prefix,
+ ++last_exist_logn);
+ printf ("%s\n", filename);
+ logfile_fd = open (filename, O_RDWR|O_CREAT|O_EXCL, 0600);
+
+ if (logfile_fd == -1 && (errno != EEXIST)) break;
+ }
+
+ if (logfile_fd != -1) {
+
+ /* install the log handler */
+ log_handler_id = g_log_set_handler (NULL,
+ CATCH_LOG_LEVELS,
+ s_log_handler,
+ NULL);
+
+ } else {
+ /* FIXME convert dir_path to UTF-8 */
+ if (errno == EEXIST) {
+ fprintf (stderr, "Could not create unique log filename in %s\n",
+ dir_path);
+ } else {
+ fprintf (stderr, "Could not create log file in %s: %s\n",
+ dir_path, strerror (errno));
+ }
+ }
+ g_free (filename);
+ g_free (dir_path);
+ g_free (full_prefix);
}
/*! \brief Terminates the logging of messages.
diff --git a/utils/gschlas/gschlas.c b/utils/gschlas/gschlas.c
index a30de63..c98c0aa 100644
--- a/utils/gschlas/gschlas.c
+++ b/utils/gschlas/gschlas.c
@@ -68,9 +68,7 @@ main_prog(void *closure, int argc, char *argv[])
/* create log file right away */
/* even if logging is enabled */
- logfile = g_build_filename (cwd, "gschlas.log", NULL);
- s_log_init (logfile);
- g_free (logfile);
+ s_log_init ("gschlas");
logging_dest=STDOUT_TTY;
if (!quiet_mode)
--
1.6.0.6
_______________________________________________
geda-user mailing list
geda-user@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-user