summaryrefslogtreecommitdiff
path: root/services/logging.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/logging.cpp')
-rw-r--r--services/logging.cpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/services/logging.cpp b/services/logging.cpp
new file mode 100644
index 0000000..5c35dae
--- /dev/null
+++ b/services/logging.cpp
@@ -0,0 +1,153 @@
+/*
+ This file is part of Icecream.
+
+ Copyright (c) 2004 Stephan Kulow <coolo@suse.de>
+
+ This program 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 2 of the License, or
+ (at your option) any later version.
+
+ This program 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+#include <iostream>
+#include "logging.h"
+#include <fstream>
+#include <signal.h>
+#ifdef __linux__
+#include <dlfcn.h>
+#endif
+
+using namespace std;
+
+int debug_level = 0;
+ostream *logfile_trace = 0;
+ostream *logfile_info = 0;
+ostream *logfile_warning = 0;
+ostream *logfile_error = 0;
+string logfile_prefix;
+
+static ofstream logfile_null( "/dev/null" );
+static ofstream logfile_file;
+static string logfile_filename;
+
+void reset_debug( int );
+
+void setup_debug(int level, const string &filename, const string& prefix)
+{
+ string fname = filename;
+ debug_level = level;
+ logfile_prefix = prefix;
+ logfile_filename = filename;
+
+ if ( logfile_file.is_open() )
+ logfile_file.close();
+ ostream *output = 0;
+ if ( filename.length() ) {
+ logfile_file.clear();
+ logfile_file.open( filename.c_str(), fstream::out | fstream::app );
+#ifdef __linux__
+ if (fname[0] != '/') {
+ char buf[256];
+ if (getcwd(buf, sizeof(buf))) {
+ fname.insert(0, "/");
+ fname.insert(0, buf);
+ }
+ }
+ setenv("SEGFAULT_OUTPUT_NAME", fname.c_str(), false);
+#endif
+ output = &logfile_file;
+ } else
+ output = &cerr;
+
+#ifdef __linux__
+ (void) dlopen("libSegFault.so", RTLD_NOW | RTLD_LOCAL);
+#endif
+
+ if ( debug_level & Debug )
+ logfile_trace = output;
+ else
+ logfile_trace = &logfile_null;
+
+ if ( debug_level & Info )
+ logfile_info = output;
+ else
+ logfile_info = &logfile_null;
+
+ if ( debug_level & Warning )
+ logfile_warning = output;
+ else
+ logfile_warning = &logfile_null;
+
+ if ( debug_level & Error )
+ logfile_error = output;
+ else
+ logfile_error = &logfile_null;
+
+ signal( SIGHUP, reset_debug );
+}
+
+void reset_debug( int )
+{
+ setup_debug(debug_level, logfile_filename);
+}
+
+void close_debug()
+{
+ if (logfile_null.is_open())
+ logfile_null.close();
+ if (logfile_file.is_open())
+ logfile_file.close();
+
+ logfile_trace = logfile_info = logfile_warning = logfile_error = 0;
+}
+
+/* Flushes all ostreams used for debug messages. You need to call
+ this before forking. */
+void flush_debug()
+{
+ if (logfile_null.is_open())
+ logfile_null.flush();
+ if (logfile_file.is_open())
+ logfile_file.flush();
+}
+
+#ifdef HAVE_BACKTRACE
+#include <execinfo.h>
+#endif
+
+string get_backtrace() {
+ string s;
+
+#ifdef HAVE_BACKTRACE
+ void* trace[256];
+ int n = backtrace(trace, 256);
+ if (!n)
+ return s;
+ char** strings = backtrace_symbols (trace, n);
+
+ s = "[\n";
+
+ for (int i = 0; i < n; ++i) {
+ s += ": ";
+ s += strings[i];
+ s += "\n";
+ }
+ s += "]\n";
+ if (strings)
+ free (strings);
+#endif
+
+ return s;
+}
+
+unsigned log_block::nesting;