- Add new logging system, supports logging to stdout/stderr and optionally logfile and system log (syslog on unix, windows event log on win32)
This commit is contained in:
parent
3b0cc0e0dc
commit
d22da7e24e
|
@ -0,0 +1,73 @@
|
|||
/* GKrellM
|
||||
| Copyright (C) 1999-2008 Bill Wilson
|
||||
|
|
||||
| Author: Bill Wilson billw@gkrellm.net
|
||||
| Latest versions might be found at: http://gkrellm.net
|
||||
|
|
||||
|
|
||||
| GKrellM is free software: you can redistribute it and/or modify it
|
||||
| under the terms of the GNU General Public License as published by
|
||||
| the Free Software Foundation, either version 3 of the License, or
|
||||
| (at your option) any later version.
|
||||
|
|
||||
| GKrellM is distributed in the hope that it will be useful, but WITHOUT
|
||||
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
| or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
| License for more details.
|
||||
|
|
||||
| You should have received a copy of the GNU General Public License
|
||||
| along with this program. If not, see http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
#ifndef GK_LOG_P_H
|
||||
#define GK_LOG_P_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
typedef void (*GkrellmLogFunc) (GLogLevelFlags log_level, const gchar *message);
|
||||
typedef gboolean (*GkrellmLogInitFunc) (void);
|
||||
typedef gboolean (*GkrellmLogCleanupFunc) (void);
|
||||
|
||||
/**
|
||||
* Installs a log handler and adds default logging behaviour.
|
||||
*
|
||||
* All GLib log functions and macros (i..e g_log(), g_debug(), g_warning() etc)
|
||||
* are handled by our log handler from now on
|
||||
**/
|
||||
void gkrellm_log_init(void);
|
||||
|
||||
/**
|
||||
* Removes our log handler reverting to default GLib log behaviour.
|
||||
**/
|
||||
void gkrellm_log_cleanup(void);
|
||||
|
||||
/**
|
||||
* Registers another log function.
|
||||
*
|
||||
* Calls function @p init if it's not NULL and registers function @p log if
|
||||
* the (optional) call to @p init was successful.
|
||||
*
|
||||
* @note This is mainly used by gkrellmd to register an additional
|
||||
* syslog handler.
|
||||
**/
|
||||
gboolean gkrellm_log_register(
|
||||
GkrellmLogFunc log,
|
||||
GkrellmLogInitFunc init,
|
||||
GkrellmLogCleanupFunc cleanup);
|
||||
|
||||
/**
|
||||
* Unregisters a log function
|
||||
*
|
||||
* Also calls the GkrellmLogCleanupFunc passed together with @p log
|
||||
* in gkrellm_log_register().
|
||||
**/
|
||||
gboolean gkrellm_log_unregister(GkrellmLogFunc log);
|
||||
|
||||
/**
|
||||
* Enables or disables logging into a file
|
||||
*
|
||||
* @param filename path to logfile or NULL to disable logging into a file
|
||||
**/
|
||||
void gkrellm_log_set_filename(const gchar* filename);
|
||||
|
||||
#endif //GK_LOG_P_H
|
|
@ -0,0 +1,291 @@
|
|||
/* GKrellM
|
||||
| Copyright (C) 1999-2008 Bill Wilson
|
||||
|
|
||||
| Author: Stefan Gehn stefan.gkrellm@srcbox.net
|
||||
| Latest versions might be found at: http://gkrellm.net
|
||||
|
|
||||
|
|
||||
| GKrellM is free software: you can redistribute it and/or modify it
|
||||
| under the terms of the GNU General Public License as published by
|
||||
| the Free Software Foundation, either version 3 of the License, or
|
||||
| (at your option) any later version.
|
||||
|
|
||||
| GKrellM is distributed in the hope that it will be useful, but WITHOUT
|
||||
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
| or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
| License for more details.
|
||||
|
|
||||
| You should have received a copy of the GNU General Public License
|
||||
| along with this program. If not, see http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
/*
|
||||
Wanted logic:
|
||||
|
||||
- g_print for user-visible messages, --version and --help fall into this category.
|
||||
g_print usage should be kept at a minimum because
|
||||
gkrellm is a gui-app, while gkrellmd is a daemon. Neither of them is suited
|
||||
for terminal-interaction.
|
||||
|
||||
- gkrellm_debug(DEBUG_FOO, "msg"); for all debug messages.
|
||||
|
||||
- g_warning("msg") for all failed function calls etc.
|
||||
|
||||
Output should go to:
|
||||
- g_print : gui-window or stdout where applicable
|
||||
- gkrellm_debug : gui-window or logfile if set
|
||||
- gkrellm_warning: gui-window or logfile if set
|
||||
*/
|
||||
|
||||
|
||||
#include "log.h"
|
||||
#include "log-private.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#if !defined(WIN32)
|
||||
#include <syslog.h>
|
||||
#endif // !WIN32
|
||||
|
||||
// Include gkrellm headers to access _GK struct inside gkrellm_debug()
|
||||
#if defined(GKRELLM_SERVER)
|
||||
#include "../server/gkrellmd.h"
|
||||
#include "../server/gkrellmd-private.h"
|
||||
#else
|
||||
#include "../src/gkrellm.h"
|
||||
#include "../src/gkrellm-private.h"
|
||||
#endif
|
||||
|
||||
typedef struct _GkrellmLogFacility
|
||||
{
|
||||
GkrellmLogFunc log;
|
||||
GkrellmLogCleanupFunc cleanup;
|
||||
} GkrellmLogFacility;
|
||||
|
||||
static GPtrArray *s_log_facility_ptr_array = NULL;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Logging into a logfile
|
||||
|
||||
/**
|
||||
* Handle to a logfile.
|
||||
* Set by gkrellm_log_set_filename() and used by gkrellm_log_to_file()
|
||||
**/
|
||||
static FILE *s_gkrellm_logfile = NULL;
|
||||
|
||||
static gboolean
|
||||
gkrellm_log_file_cleanup()
|
||||
{
|
||||
if (s_gkrellm_logfile)
|
||||
fclose(s_gkrellm_logfile);
|
||||
s_gkrellm_logfile = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gkrellm_log_file_log(GLogLevelFlags log_level, const gchar *message)
|
||||
{
|
||||
time_t raw_time;
|
||||
char *local_time_str;
|
||||
|
||||
if (!s_gkrellm_logfile)
|
||||
return;
|
||||
|
||||
// Prepend log message with current date/time
|
||||
time(&raw_time);
|
||||
local_time_str = ctime(&raw_time);
|
||||
local_time_str[24] = ' '; // overwrite newline with space
|
||||
fputs(local_time_str, s_gkrellm_logfile);
|
||||
|
||||
fputs(message, s_gkrellm_logfile);
|
||||
fflush(s_gkrellm_logfile);
|
||||
}
|
||||
|
||||
void
|
||||
gkrellm_log_set_filename(const gchar* filename)
|
||||
{
|
||||
// Remove from logging chain if we already had been registered before
|
||||
// This also cleans up an open logfile.
|
||||
gkrellm_log_unregister(gkrellm_log_file_log);
|
||||
|
||||
if (filename && filename[0] != '\0')
|
||||
{
|
||||
// Open the file to log into
|
||||
s_gkrellm_logfile = fopen(filename, "at");
|
||||
// Add our callbacks to logging chain
|
||||
if (s_gkrellm_logfile)
|
||||
{
|
||||
gkrellm_log_register(gkrellm_log_file_log, NULL,
|
||||
gkrellm_log_file_cleanup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
//! Logs onto stdout/stderr
|
||||
static void
|
||||
gkrellm_log_to_terminal(GLogLevelFlags log_level, const gchar *message)
|
||||
{
|
||||
// warning, error or critical go to stderr
|
||||
if (log_level & G_LOG_LEVEL_WARNING
|
||||
|| log_level & G_LOG_LEVEL_CRITICAL
|
||||
|| log_level & G_LOG_LEVEL_ERROR)
|
||||
{
|
||||
fputs(message, stderr);
|
||||
return;
|
||||
}
|
||||
#if defined(WIN32)
|
||||
// debug on windows gets special treatment
|
||||
if (log_level & G_LOG_LEVEL_DEBUG)
|
||||
OutputDebugStringA(message);
|
||||
#endif
|
||||
// Everything also ends up on stdout
|
||||
// (may be invisible on most desktop-systems, especially on windows!)
|
||||
fputs(message, stdout);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
//! Handler that receives all the log-messages first
|
||||
static void
|
||||
gkrellm_log_handler(const gchar *log_domain, GLogLevelFlags log_level,
|
||||
const gchar *message, gpointer user_data)
|
||||
{
|
||||
gchar *localized_message;
|
||||
gint i;
|
||||
GkrellmLogFacility *f;
|
||||
|
||||
localized_message = g_locale_from_utf8(message, -1, NULL, NULL, NULL);
|
||||
if (localized_message == NULL)
|
||||
{
|
||||
for (i = 0; i < s_log_facility_ptr_array->len; i++)
|
||||
{
|
||||
f = (g_ptr_array_index(s_log_facility_ptr_array, i));
|
||||
f->log(log_level, message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < s_log_facility_ptr_array->len; i++)
|
||||
{
|
||||
f = (g_ptr_array_index(s_log_facility_ptr_array, i));
|
||||
f->log(log_level, localized_message);
|
||||
}
|
||||
|
||||
g_free(localized_message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Non-Static functions that can be used in gkrellm
|
||||
|
||||
void
|
||||
gkrellm_log_init()
|
||||
{
|
||||
if (s_log_facility_ptr_array)
|
||||
return; // already initialized
|
||||
s_log_facility_ptr_array = g_ptr_array_new();
|
||||
g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL
|
||||
| G_LOG_FLAG_RECURSION, gkrellm_log_handler, NULL);
|
||||
gkrellm_log_register(gkrellm_log_to_terminal, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gkrellm_log_cleanup()
|
||||
{
|
||||
gint i;
|
||||
GkrellmLogFacility *f;
|
||||
|
||||
if (!s_log_facility_ptr_array)
|
||||
return; // gkrellm_log_init() not called yet
|
||||
|
||||
// Call cleanup on all log-facilities and free our internal struct
|
||||
for (i = 0; i < s_log_facility_ptr_array->len; i++)
|
||||
{
|
||||
f = (g_ptr_array_index(s_log_facility_ptr_array, i));
|
||||
if (f->cleanup != NULL)
|
||||
f->cleanup();
|
||||
g_free(f);
|
||||
}
|
||||
g_ptr_array_free(s_log_facility_ptr_array, TRUE);
|
||||
s_log_facility_ptr_array = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gkrellm_log_register(
|
||||
GkrellmLogFunc log,
|
||||
GkrellmLogInitFunc init,
|
||||
GkrellmLogCleanupFunc cleanup)
|
||||
{
|
||||
GkrellmLogFacility *f;
|
||||
gint i;
|
||||
|
||||
if (!s_log_facility_ptr_array)
|
||||
return FALSE; // gkrellm_log_init() not called yet
|
||||
|
||||
// Check if log callback is already regisrered
|
||||
for (i = 0; i < s_log_facility_ptr_array->len; i++)
|
||||
{
|
||||
f = (g_ptr_array_index(s_log_facility_ptr_array, i));
|
||||
if (f->log == log)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (init != NULL && init() == FALSE)
|
||||
return FALSE;
|
||||
|
||||
// remember logging function and cleanup function in a struct
|
||||
f = g_new0(GkrellmLogFacility, 1);
|
||||
f->log = log;
|
||||
f->cleanup = cleanup;
|
||||
|
||||
// add struct to list of log facilities
|
||||
g_ptr_array_add(s_log_facility_ptr_array, (gpointer)f);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gkrellm_log_unregister(GkrellmLogFunc log)
|
||||
{
|
||||
gint i;
|
||||
GkrellmLogFacility *f;
|
||||
|
||||
if (!s_log_facility_ptr_array)
|
||||
return FALSE; // gkrellm_log_init() not called yet
|
||||
|
||||
for (i = 0; i < s_log_facility_ptr_array->len; i++)
|
||||
{
|
||||
f = (g_ptr_array_index(s_log_facility_ptr_array, i));
|
||||
if (f->log == log)
|
||||
{
|
||||
if (f->cleanup != NULL)
|
||||
f->cleanup();
|
||||
g_ptr_array_remove_index(s_log_facility_ptr_array, i);
|
||||
g_free(f);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Public functions that can be used in gkrellm and plugins
|
||||
|
||||
void
|
||||
gkrellm_debug(guint debug_level, const gchar *format, ...)
|
||||
{
|
||||
if (_GK.debug_level & debug_level)
|
||||
{
|
||||
va_list varargs;
|
||||
va_start(varargs, format);
|
||||
|
||||
g_logv(NULL, G_LOG_LEVEL_DEBUG, format, varargs);
|
||||
|
||||
va_end(varargs);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/* GKrellM
|
||||
* Copyright (C) 1999-2008 Bill Wilson
|
||||
*
|
||||
* @author Bill Wilson <billw@gkrellm.net>
|
||||
*
|
||||
| Latest versions might be found at: http://gkrellm.net
|
||||
|
|
||||
|
|
||||
| GKrellM is free software: you can redistribute it and/or modify it
|
||||
| under the terms of the GNU General Public License as published by
|
||||
| the Free Software Foundation, either version 3 of the License, or
|
||||
| (at your option) any later version.
|
||||
|
|
||||
| GKrellM is distributed in the hope that it will be useful, but WITHOUT
|
||||
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
| or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
| License for more details.
|
||||
|
|
||||
| You should have received a copy of the GNU General Public License
|
||||
| along with this program. If not, see http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
#ifndef GK_LOG_H
|
||||
#define GK_LOG_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/**
|
||||
* @brief Prints our and/or logs a debug message.
|
||||
*
|
||||
* If a logfile was set @see gkrellm_log_set_filename() the message will
|
||||
* be logged into the logfile as well.
|
||||
**/
|
||||
void gkrellm_debug(guint debug_level, const gchar *format, ...);
|
||||
|
||||
#endif //GK_LOG_H
|
Loading…
Reference in New Issue