[rkward/frameworks] /: Rotate a limited number of debug log files, instead of creating an indefinite number.

Thomas Friedrichsmeier null at kde.org
Tue May 23 10:07:15 UTC 2017


Git commit 2f056db597e558702ae25459e70deee71f41c881 by Thomas Friedrichsmeier.
Committed on 23/05/2017 at 10:06.
Pushed by tfry into branch 'frameworks'.

Rotate a limited number of debug log files, instead of creating an indefinite number.

M  +1    -0    ChangeLog
M  +1    -1    doc/rkward/man-rkward.1.docbook
M  +13   -7    rkward/debug.h
M  +14   -22   rkward/main.cpp
M  +1    -1    rkward/misc/xmlhelper.cpp
M  +2    -2    rkward/rbackend/rinterface.cpp
M  +2    -2    rkward/rbackend/rkfrontendtransmitter.cpp
M  +7    -11   rkward/rbackend/rkrbackendprotocol_backend.cpp
M  +27   -1    rkward/rbackend/rkrbackendprotocol_shared.cpp
M  +1    -1    rkward/rbackend/rksessionvars.cpp
M  +8    -10   rkward/settings/rksettingsmoduledebug.cpp
M  +2    -5    rkward/settings/rksettingsmoduledebug.h

https://commits.kde.org/rkward/2f056db597e558702ae25459e70deee71f41c881

diff --git a/ChangeLog b/ChangeLog
index dd0b2ac0..5f8a4835 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+- Limit the number of debug log-files to keep (at most three, each, for frontend and backend)
 - Remove Windows-only UI for setInternet2()-option (no longer available in R, with setInternet2(TRUE) the default since R 3.2.2)
 - Remove startup wrapper script (moving the still-needed functionality into the main executable)
     TODO: This is still mostly EXPERIMENTAL, and only vaguely tested on Linux so far. It should help resolve a number of long standing quirks, though, such as command windows (on Windows), icons,
diff --git a/doc/rkward/man-rkward.1.docbook b/doc/rkward/man-rkward.1.docbook
index 6a5729ff..7f0eab81 100644
--- a/doc/rkward/man-rkward.1.docbook
+++ b/doc/rkward/man-rkward.1.docbook
@@ -67,7 +67,7 @@
 </varlistentry>
 <varlistentry>
 <term><option>--debug-output</option> <replaceable>where</replaceable></term>
-<listitem><para>Where to send debug output. Default is to store it in a file in the temporary directory. Specifying "terminal" will write debug output to stderr, instead (useful for debugging, sometimes). Not that debug output from the backend process is always stored in a file.</para></listitem>
+<listitem><para>Where to send debug output. Default is to store it in a file in the temporary directory. Specifying "terminal" will write debug output to stderr, instead (useful for debugging startup problems). Note that debug output from the backend process is always stored in a file.</para></listitem>
 </varlistentry>
 <varlistentry>
 <term><option>--debug-flags</option> <replaceable>flags</replaceable></term>
diff --git a/rkward/debug.h b/rkward/debug.h
index a39cd6dd..ffe64528 100644
--- a/rkward/debug.h
+++ b/rkward/debug.h
@@ -2,7 +2,7 @@
                           debug  -  description
                              -------------------
     begin                : Sun Aug 8 2004
-    copyright            : (C) 2004, 2006 by Thomas Friedrichsmeier
+    copyright            : (C) 2004, 2006, 2017 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -17,10 +17,7 @@
 
 #define RKWARD_DEBUG
 
-extern int RK_Debug_Level;
-extern int RK_Debug_Flags;
-extern int RK_Debug_CommandStep;
-extern void RKDebug (int flags, int level, const char *fmt, ...);
+void RKDebug (int flags, int level, const char *fmt, ...);
 
 // Debug-levels
 #define DL_TRACE 0
@@ -48,8 +45,8 @@ extern void RKDebug (int flags, int level, const char *fmt, ...);
 
 #ifdef RKWARD_DEBUG
 // Debug functions 
-#	define RK_DO(expr,flags,level) if ((flags & RK_Debug_Flags) && (level >= RK_Debug_Level)) { expr; }
-#	define RK_DEBUG(flags,level,...) { if ((flags & RK_Debug_Flags) && (level >= RK_Debug_Level)) RKDebug (flags,level,__VA_ARGS__); }
+#	define RK_DO(expr,flags,level) if ((flags & RK_Debug::RK_Debug_Flags) && (level >= RK_Debug::RK_Debug_Level)) { expr; }
+#	define RK_DEBUG(flags,level,...) { if ((flags & RK_Debug::RK_Debug_Flags) && (level >= RK_Debug::RK_Debug_Level)) RKDebug (flags,level,__VA_ARGS__); }
 #	define RK_ASSERT(x) if (!(x)) RK_DEBUG (DEBUG_ALL, DL_FATAL, "Assert '%s' failed at %s - function %s line %d", #x, __FILE__, __FUNCTION__, __LINE__);
 #	ifndef RKWARD_NO_TRACE
 #		define RK_TRACE(flags) RK_DEBUG (flags, DL_TRACE, "Trace: %s - function %s line %d", __FILE__, __FUNCTION__, __LINE__);
@@ -62,3 +59,12 @@ extern void RKDebug (int flags, int level, const char *fmt, ...);
 #	define RK_ASSERT(x)
 #	define RK_TRACE(flags)
 #endif
+
+class QFile;
+namespace RK_Debug {
+	extern int RK_Debug_Level;
+	extern int RK_Debug_Flags;
+	extern int RK_Debug_CommandStep;
+	bool setupLogFile (const QString &basename);
+	extern QFile* debug_file;
+};
diff --git a/rkward/main.cpp b/rkward/main.cpp
index 5179cc4a..33f83517 100644
--- a/rkward/main.cpp
+++ b/rkward/main.cpp
@@ -111,10 +111,7 @@ QString findExeAtPath (const QString appname, const QString &path) {
 	return QString ();
 }
 
-int RK_Debug_Level = 0;
-int RK_Debug_Flags = DEBUG_ALL;
 bool RK_Debug_Terminal = false;
-int RK_Debug_CommandStep = 0;
 QMutex RK_Debug_Mutex;
 
 void RKDebugMessageOutput (QtMsgType type, const QMessageLogContext &ctx, const QString &msg) {
@@ -133,12 +130,12 @@ void RKDebugMessageOutput (QtMsgType type, const QMessageLogContext &ctx, const
 		fprintf (stderr, "\n");
 	} else {
 #ifdef QT_MESSAGELOGCONTEXT
-		RKSettingsModuleDebug::debug_file->write (ctx.file);
-		RKSettingsModuleDebug::debug_file->write (ctx.function);
+		RK_Debug::debug_file->write (ctx.file);
+		RK_Debug::debug_file->write (ctx.function);
 #endif
-		RKSettingsModuleDebug::debug_file->write (qPrintable (msg));
-		RKSettingsModuleDebug::debug_file->write ("\n");
-		RKSettingsModuleDebug::debug_file->flush ();
+		RK_Debug::debug_file->write (qPrintable (msg));
+		RK_Debug::debug_file->write ("\n");
+		RK_Debug::debug_file->flush ();
 	}
 	RK_Debug_Mutex.unlock ();
 }
@@ -219,15 +216,16 @@ int main (int argc, char *argv[]) {
 	aboutData.processCommandLine (&parser);
 
 	// Set up debugging
-	RK_Debug_Level = DL_FATAL - QString (parser.value ("debug-level")).toInt ();
-	RK_Debug_Flags = QString (parser.value ("debug-flags")).toInt ();
+	RK_Debug::RK_Debug_Level = DL_FATAL - QString (parser.value ("debug-level")).toInt ();
+	RK_Debug::RK_Debug_Flags = QString (parser.value ("debug-flags")).toInt ();
 	RK_Debug_Terminal = QString (parser.value ("debug-output")) == "terminal";
-	RKSettingsModuleDebug::debug_file = new QTemporaryFile (QDir::tempPath () + "/rkward.frontend");
-	RKSettingsModuleDebug::debug_file->setAutoRemove (RK_Debug_Terminal);
-	if (RKSettingsModuleDebug::debug_file->open ()) {
-		RK_DEBUG (APP, DL_INFO, "Full debug output is at %s", qPrintable (RKSettingsModuleDebug::debug_file->fileName ()));
-		qInstallMessageHandler (RKDebugMessageOutput);
+	if (RK_Debug::setupLogFile (QDir::tempPath () + "/rkward.frontend")) {
+		RK_DEBUG (APP, DL_INFO, "Full debug output is at %s", qPrintable (RK_Debug::debug_file->fileName ()));
+	} else {
+		RK_Debug_Terminal = true;
+		RK_DEBUG (APP, DL_INFO, "Failed to open debug file %s", qPrintable (RK_Debug::debug_file->fileName ()));
 	}
+	qInstallMessageHandler (RKDebugMessageOutput);
 
 	// handle positional (file) arguments, first
 	QStringList url_args = parser.positionalArguments ();
@@ -344,17 +342,11 @@ int main (int argc, char *argv[]) {
 		new RKWardMainWindow ();
 	}
 
-/* KF5 TODO: Still needed?
-	// Usually, KDE always adds the current directory to the list of prefixes.
-	// However, since RKWard 0.5.6, the main binary is in KDE's libexec dir, which defies this mechanism. Therefore, RKWARD_ENSURE_PREFIX is set from the wrapper script.
-	QByteArray add_path = qgetenv ("RKWARD_ENSURE_PREFIX");
-	if (!add_path.isEmpty ()) KGlobal::dirs ()->addPrefix (QString::fromLocal8Bit (add_path)); */
-
 	// do it!
 	int status = app.exec ();
 
 	qInstallMessageHandler (0);
-	RKSettingsModuleDebug::debug_file->close ();
+	RK_Debug::debug_file->close ();
 
 	return status;
 }
diff --git a/rkward/misc/xmlhelper.cpp b/rkward/misc/xmlhelper.cpp
index 44d6ea7e..28b98d9e 100644
--- a/rkward/misc/xmlhelper.cpp
+++ b/rkward/misc/xmlhelper.cpp
@@ -387,7 +387,7 @@ void XMLHelper::displayError (const QDomNode *in_node, const QString &message, i
 
 	if (message_level < debug_level) message_level = debug_level;
 
-	if ((RK_Debug_Flags & XML) && (message_level >= RK_Debug_Level)) {
+	if ((RK_Debug::RK_Debug_Flags & XML) && (message_level >= RK_Debug::RK_Debug_Level)) {
 		QString backtrace = i18n ("XML-parsing '%1' ", filename);
 		// create a "backtrace"
 		QStringList list;
diff --git a/rkward/rbackend/rinterface.cpp b/rkward/rbackend/rinterface.cpp
index 37c812c9..f21078c9 100644
--- a/rkward/rbackend/rinterface.cpp
+++ b/rkward/rbackend/rinterface.cpp
@@ -249,10 +249,10 @@ void RInterface::doNextCommand (RCommand *command) {
 	}
 	// importantly, this point is not reached for the fake startup command
 
-	if (RK_Debug_CommandStep) {
+	if (RK_Debug::RK_Debug_CommandStep) {
 		QTime t;
 		t.start ();
-		while (t.elapsed () < RK_Debug_CommandStep) {}
+		while (t.elapsed () < RK_Debug::RK_Debug_CommandStep) {}
 	}
 
 	flushOutput (true);
diff --git a/rkward/rbackend/rkfrontendtransmitter.cpp b/rkward/rbackend/rkfrontendtransmitter.cpp
index 1f735a9f..99b64fb1 100644
--- a/rkward/rbackend/rkfrontendtransmitter.cpp
+++ b/rkward/rbackend/rkfrontendtransmitter.cpp
@@ -94,7 +94,7 @@ void RKFrontendTransmitter::run () {
 	backend->setEnvironment (env);
 
 	QStringList args;
-	args.append ("--debug-level=" + QString::number (RK_Debug_Level));
+	args.append ("--debug-level=" + QString::number (RK_Debug::RK_Debug_Level));
 	// NOTE: QProcess quotes its arguments, *but* properly passing all spaces and quotes through the R CMD wrapper, seems near(?) impossible on Windows. Instead, we use percent encoding, internally.
 	args.append ("--server-name=" + server->fullServerName ().toUtf8 ().toPercentEncoding ());
 	args.append ("--rkd-server-name=" + rkd_transmitter->serverName ().toUtf8 ().toPercentEncoding ());
@@ -118,7 +118,7 @@ void RKFrontendTransmitter::run () {
 	if (!debugger.isEmpty ()) {
 		args = debugger.split (' ') + args;
 	}
-	if (DL_DEBUG >= RK_Debug_Level) {
+	if (DL_DEBUG >= RK_Debug::RK_Debug_Level) {
 		qDebug ("%s", qPrintable (args.join ("\n")));
 		qDebug ("%s", qPrintable (qgetenv ("R_BINARY")));
 	}
diff --git a/rkward/rbackend/rkrbackendprotocol_backend.cpp b/rkward/rbackend/rkrbackendprotocol_backend.cpp
index 84a87884..61d59ada 100644
--- a/rkward/rbackend/rkrbackendprotocol_backend.cpp
+++ b/rkward/rbackend/rkrbackendprotocol_backend.cpp
@@ -36,19 +36,16 @@
 #include <QUrl>
 
 	void RK_setupGettext (const char*);
-	int RK_Debug_Level = 2;
-	int RK_Debug_Flags = DEBUG_ALL;
 	QMutex RK_Debug_Mutex;
-	QTemporaryFile* RK_Debug_File;
 
 	void RKDebugMessageOutput (QtMsgType type, const QMessageLogContext &, const QString &msg) {
 		RK_Debug_Mutex.lock ();
 		if (type == QtFatalMsg) {
 			fprintf (stderr, "%s\n", qPrintable (msg));
 		}
-		RK_Debug_File->write (qPrintable (msg));
-		RK_Debug_File->write ("\n");
-		RK_Debug_File->flush ();
+		RK_Debug::debug_file->write (qPrintable (msg));
+		RK_Debug::debug_file->write ("\n");
+		RK_Debug::debug_file->flush ();
 		RK_Debug_Mutex.unlock ();
 	}
 
@@ -73,16 +70,15 @@
 		setvbuf (stdout, NULL, _IONBF, 0);
 		setvbuf (stderr, NULL, _IONBF, 0);
 
-		RK_Debug_File = new QTemporaryFile (QDir::tempPath () + "/rkward.rbackend");
-		RK_Debug_File->setAutoRemove (false);
-		if (RK_Debug_File->open ()) qInstallMessageHandler (RKDebugMessageOutput);
+		RK_Debug::RK_Debug_Flags = RBACKEND;
+		if (RK_Debug::setupLogFile (QDir::tempPath () + "/rkward.rbackend")) qInstallMessageHandler (RKDebugMessageOutput);
 
 		QString servername, rkd_server_name;
 		QString data_dir, locale_dir;
 		QStringList args = app.arguments ();
 		for (int i = 1; i < args.count (); ++i) {
 			if (args[i].startsWith ("--debug-level")) {
-				RK_Debug_Level = args[i].section ('=', 1).toInt ();
+				RK_Debug::RK_Debug_Level = args[i].section ('=', 1).toInt ();
 			} else if (args[i].startsWith ("--server-name")) {
 				servername = QUrl::fromPercentEncoding (args[i].section ('=', 1).toUtf8 ());
 			} else if (args[i].startsWith ("--data-dir")) {
@@ -156,5 +152,5 @@ void RKRBackendProtocolBackend::msleep (int delay) {
 }
 
 QString RKRBackendProtocolBackend::backendDebugFile () {
-	return RK_Debug_File->fileName ();
+	return RK_Debug::debug_file->fileName ();
 }
diff --git a/rkward/rbackend/rkrbackendprotocol_shared.cpp b/rkward/rbackend/rkrbackendprotocol_shared.cpp
index bef62f67..5048373d 100644
--- a/rkward/rbackend/rkrbackendprotocol_shared.cpp
+++ b/rkward/rbackend/rkrbackendprotocol_shared.cpp
@@ -2,7 +2,7 @@
                           rkrbackendprotocol  -  description
                              -------------------
     begin                : Thu Nov 04 2010
-    copyright            : (C) 2010, 2011, 2013 by Thomas Friedrichsmeier
+    copyright            : (C) 2010, 2011, 2013, 2017 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -167,3 +167,29 @@ QString RKRSharedFunctionality::quote (const QString &string) {
 
 	return ret;
 }
+
+#include <QFile>
+/* These definitions don't really belong into this file, but, importantly, they need to be compiled for both frontend and backend. */
+namespace RK_Debug {
+	int RK_Debug_Level = 0;
+	int RK_Debug_Flags = DEBUG_ALL;
+	int RK_Debug_CommandStep = 0;
+	QFile *debug_file = 0;
+
+	bool setupLogFile (const QString &basename) {
+		QStringList all_debug_files (basename);
+		all_debug_files << basename + ".0" << basename + ".1";
+		for (int i = all_debug_files.size () -1; i >= 0; --i) {
+			QFile oldfile (all_debug_files[i]);
+			if (oldfile.exists ()) {
+				if (i < all_debug_files.size () -1) {
+					oldfile.rename (all_debug_files[i+1]);
+				} else {
+					oldfile.remove ();
+				}
+			}
+		}
+		debug_file = new QFile (basename);
+		return (debug_file->open (QIODevice::WriteOnly | QIODevice::Truncate));
+	}
+};
diff --git a/rkward/rbackend/rksessionvars.cpp b/rkward/rbackend/rksessionvars.cpp
index e64eb101..2aab714a 100644
--- a/rkward/rbackend/rksessionvars.cpp
+++ b/rkward/rbackend/rksessionvars.cpp
@@ -135,7 +135,7 @@ QStringList RKSessionVars::frontendSessionInfo () {
 	lines.append ("Backend version (as known to the frontend): " + r_version_string);
 	lines.append (QString());
 	lines.append ("Debug message file (this may contain relevant diagnostic output in case of trouble):");
-	lines.append (RKSettingsModuleDebug::debug_file->fileName ());
+	lines.append (RK_Debug::debug_file->fileName ());
 	return lines;
 }
 
diff --git a/rkward/settings/rksettingsmoduledebug.cpp b/rkward/settings/rksettingsmoduledebug.cpp
index 09095ae4..fc6acd30 100644
--- a/rkward/settings/rksettingsmoduledebug.cpp
+++ b/rkward/settings/rksettingsmoduledebug.cpp
@@ -32,8 +32,6 @@
 #include "../rkglobals.h"
 #include "../debug.h"
 
-QTemporaryFile* RKSettingsModuleDebug::debug_file = 0;
-
 RKSettingsModuleDebug::RKSettingsModuleDebug (RKSettings *gui, QWidget *parent) : RKSettingsModule (gui, parent) {
 	RK_TRACE (SETTINGS);
 
@@ -47,7 +45,7 @@ RKSettingsModuleDebug::RKSettingsModuleDebug (RKSettings *gui, QWidget *parent)
 
 	label = new QLabel (i18n ("Debug level"), this);
 	debug_level_box = new RKSpinBox (this);
-	debug_level_box->setIntMode (DL_TRACE, DL_FATAL, DL_FATAL - RK_Debug_Level);
+	debug_level_box->setIntMode (DL_TRACE, DL_FATAL, DL_FATAL - RK_Debug::RK_Debug_Level);
 	connect (debug_level_box, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &RKSettingsModuleDebug::settingChanged);
 	main_vbox->addWidget (label);
 	main_vbox->addWidget (debug_level_box);
@@ -75,7 +73,7 @@ RKSettingsModuleDebug::RKSettingsModuleDebug (RKSettings *gui, QWidget *parent)
 	QList<QAbstractButton*> buttons = debug_flags_group->buttons ();
 	for (QList<QAbstractButton*>::const_iterator it = buttons.constBegin (); it != buttons.constEnd (); ++it) {
 		box_layout->addWidget (*it);
-		(*it)->setChecked (RK_Debug_Flags & debug_flags_group->id (*it));
+		(*it)->setChecked (RK_Debug::RK_Debug_Flags & debug_flags_group->id (*it));
 	}
 	connect (debug_flags_group, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this, &RKSettingsModuleDebug::settingChanged);
 	main_vbox->addWidget (group);
@@ -83,15 +81,15 @@ RKSettingsModuleDebug::RKSettingsModuleDebug (RKSettings *gui, QWidget *parent)
 
 	label = new QLabel (i18n ("Command timeout"), this);
 	command_timeout_box = new RKSpinBox (this);
-	command_timeout_box->setIntMode (0, 10000, RK_Debug_CommandStep);
+	command_timeout_box->setIntMode (0, 10000, RK_Debug::RK_Debug_CommandStep);
 	connect (command_timeout_box, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &RKSettingsModuleDebug::settingChanged);
 	main_vbox->addWidget (label);
 	main_vbox->addWidget (command_timeout_box);
 
 	main_vbox->addStretch ();
 
-	if (debug_file) {
-		label = new QLabel (i18n ("<i>Note:</i> Debug output is written to %1", debug_file->fileName ()));
+	if (RK_Debug::debug_file) {
+		label = new QLabel (i18n ("<i>Note:</i> Debug output is written to %1", RK_Debug::debug_file->fileName ()));
 		main_vbox->addWidget (label);
 		main_vbox->addStretch ();
 	}
@@ -114,14 +112,14 @@ QString RKSettingsModuleDebug::caption () {
 void RKSettingsModuleDebug::applyChanges () {
 	RK_TRACE (SETTINGS);
 
-	RK_Debug_Level = DL_FATAL - debug_level_box->intValue ();
-	RK_Debug_CommandStep = command_timeout_box->intValue ();
+	RK_Debug::RK_Debug_Level = DL_FATAL - debug_level_box->intValue ();
+	RK_Debug::RK_Debug_CommandStep = command_timeout_box->intValue ();
 	int flags = 0;
 	QList<QAbstractButton*> buttons = debug_flags_group->buttons ();
 	for (QList<QAbstractButton*>::const_iterator it = buttons.constBegin (); it != buttons.constEnd (); ++it) {
 		if ((*it)->isChecked ()) flags |= debug_flags_group->id (*it);
 	}
-	RK_Debug_Flags = flags;
+	RK_Debug::RK_Debug_Flags = flags;
 }
 
 void RKSettingsModuleDebug::save (KConfig *config) {
diff --git a/rkward/settings/rksettingsmoduledebug.h b/rkward/settings/rksettingsmoduledebug.h
index 9c2ade31..92a3d6aa 100644
--- a/rkward/settings/rksettingsmoduledebug.h
+++ b/rkward/settings/rksettingsmoduledebug.h
@@ -2,7 +2,7 @@
                           rksettingsmoduledebug -  description
                              -------------------
     begin                : Tue Oct 23 2007
-    copyright            : (C) 2007, 2009 by Thomas Friedrichsmeier
+    copyright            : (C) 2007, 2009, 2017 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -21,7 +21,7 @@
 
 class RKSpinBox;
 class QButtonGroup;
-class QTemporaryFile;
+class QFile;
 
 /**
 configuration for the Command Editor windows
@@ -46,9 +46,6 @@ public:
 	// static members are declared in debug.h and defined in main.cpp
 public slots:
 	void settingChanged (int);
-public:
-	// public for internal reason, only! Do not mess with this!
-	static QTemporaryFile* debug_file;
 private:
 	RKSpinBox* command_timeout_box;
 	RKSpinBox* debug_level_box;



More information about the rkward-tracker mailing list