summaryrefslogtreecommitdiff
path: root/src/Debug.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/Debug.vala')
-rw-r--r--src/Debug.vala146
1 files changed, 146 insertions, 0 deletions
diff --git a/src/Debug.vala b/src/Debug.vala
new file mode 100644
index 0000000..ad626f4
--- /dev/null
+++ b/src/Debug.vala
@@ -0,0 +1,146 @@
+/* Copyright 2009-2014 Yorba Foundation
+ *
+ * This software is licensed under the GNU LGPL (version 2.1 or later).
+ * See the COPYING file in this distribution.
+ */
+
+namespace Debug {
+ private const LogLevelFlags DEFAULT_LOG_MASK =
+ LogLevelFlags.LEVEL_CRITICAL |
+ LogLevelFlags.LEVEL_WARNING |
+ LogLevelFlags.LEVEL_MESSAGE;
+
+ public const string VIEWER_PREFIX = "V";
+ public const string LIBRARY_PREFIX = "L";
+
+ // Ideally, there would be a LogLevelFlags.NONE constant to use as
+ // empty value but failing that, 0 works as well
+ private LogLevelFlags log_mask = 0;
+ private string log_app_version_prefix;
+ // log_file_stream is the canonical reference to the file stream (and owns
+ // it), while log_out and log_err are indirections that can point to
+ // log_file_stream or stdout and stderr respectively
+ private unowned FileStream log_out = null;
+ private unowned FileStream log_err = null;
+ private FileStream log_file_stream = null;
+
+ public static void init(string app_version_prefix) {
+ log_app_version_prefix = app_version_prefix;
+
+ // default to stdout/stderr if file cannot be opened or console is specified
+ log_out = stdout;
+ log_err = stderr;
+
+ string log_file_error_msg = null;
+
+ // logging to disk is currently off for viewer more; see http://trac.yorba.org/ticket/2078
+ File? log_file = (log_app_version_prefix == LIBRARY_PREFIX) ? AppDirs.get_log_file() : null;
+ if(log_file != null) {
+ File log_dir = log_file.get_parent();
+ try {
+ if (log_dir.query_exists(null) == false) {
+ if (!log_dir.make_directory_with_parents(null)) {
+ log_file_error_msg = "Unable to create data directory %s".printf(log_dir.get_path());
+ }
+ }
+ } catch (Error err) {
+ log_file_error_msg = err.message;
+ }
+ // overwrite the log file every time the application is started
+ // to ensure it doesn't grow too large; if there is a need for
+ // keeping the log, the 'w' should be replaced by 'a' and some sort
+ // of log rotation implemented
+ log_file_stream = FileStream.open(log_file.get_path(), "w");
+ if(log_file_stream != null) {
+ log_out = log_file_stream;
+ log_err = log_file_stream;
+ } else {
+ log_file_error_msg = "Unable to open or create log file %s".printf(log_file.get_path());
+ }
+ }
+
+ if (Environment.get_variable("SHOTWELL_LOG") != null) {
+ log_mask = LogLevelFlags.LEVEL_MASK;
+ } else {
+ log_mask = ((Environment.get_variable("SHOTWELL_INFO") != null) ?
+ log_mask | LogLevelFlags.LEVEL_INFO :
+ log_mask);
+ log_mask = ((Environment.get_variable("SHOTWELL_DEBUG") != null) ?
+ log_mask | LogLevelFlags.LEVEL_DEBUG :
+ log_mask);
+ log_mask = ((Environment.get_variable("SHOTWELL_MESSAGE") != null) ?
+ log_mask | LogLevelFlags.LEVEL_MESSAGE :
+ log_mask);
+ log_mask = ((Environment.get_variable("SHOTWELL_WARNING") != null) ?
+ log_mask | LogLevelFlags.LEVEL_WARNING :
+ log_mask);
+ log_mask = ((Environment.get_variable("SHOTWELL_CRITICAL") != null) ?
+ log_mask | LogLevelFlags.LEVEL_CRITICAL :
+ log_mask);
+ }
+
+ Log.set_handler(null, LogLevelFlags.LEVEL_INFO, info_handler);
+ Log.set_handler(null, LogLevelFlags.LEVEL_DEBUG, debug_handler);
+ Log.set_handler(null, LogLevelFlags.LEVEL_MESSAGE, message_handler);
+ Log.set_handler(null, LogLevelFlags.LEVEL_WARNING, warning_handler);
+ Log.set_handler(null, LogLevelFlags.LEVEL_CRITICAL, critical_handler);
+
+ if(log_mask == 0 && log_file != null) {
+ // if the log mask is still 0 and we have a log file, set the
+ // mask to the default
+ log_mask = DEFAULT_LOG_MASK;
+ }
+
+ if(log_file_error_msg != null) {
+ warning("%s", log_file_error_msg);
+ }
+ }
+
+ public static void terminate() {
+ }
+
+ private bool is_enabled(LogLevelFlags flag) {
+ return ((log_mask & flag) > 0);
+ }
+
+ private void log(FileStream stream, string prefix, string message) {
+ time_t now = time_t();
+ stream.printf("%s %d %s [%s] %s\n",
+ log_app_version_prefix,
+ Posix.getpid(),
+ Time.local(now).to_string(),
+ prefix,
+ message
+ );
+ stream.flush();
+ }
+
+ private void info_handler(string? domain, LogLevelFlags flags, string message) {
+ if (is_enabled(LogLevelFlags.LEVEL_INFO))
+ log(log_out, "INF", message);
+ }
+
+ private void debug_handler(string? domain, LogLevelFlags flags, string message) {
+ if (is_enabled(LogLevelFlags.LEVEL_DEBUG))
+ log(log_out, "DBG", message);
+ }
+
+ private void message_handler(string? domain, LogLevelFlags flags, string message) {
+ if (is_enabled(LogLevelFlags.LEVEL_MESSAGE))
+ log(log_err, "MSG", message);
+ }
+
+ private void warning_handler(string? domain, LogLevelFlags flags, string message) {
+ if (is_enabled(LogLevelFlags.LEVEL_WARNING))
+ log(log_err, "WRN", message);
+ }
+
+ private void critical_handler(string? domain, LogLevelFlags flags, string message) {
+ if (is_enabled(LogLevelFlags.LEVEL_CRITICAL)) {
+ log(log_err, "CRT", message);
+ if (log_file_stream != null)
+ log(stderr, "CRT", message); // also log to console
+ }
+ }
+}
+