summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-07-07 23:40:52 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-07-07 23:40:52 +0200
commit3c05b5816aa0fb978686b0ed16a02336e0981a0e (patch)
treea05662f3635ac9364c2bde16eea0f915190cfb1f
parentda2b049e248c1ad7efeb53685158a205335e4e36 (diff)
downloadsink-3c05b5816aa0fb978686b0ed16a02336e0981a0e.tar.gz
sink-3c05b5816aa0fb978686b0ed16a02336e0981a0e.zip
sinksh trace command including autocompletion
The sinksh command allows to easily turn tracing for certain areas on or off.
-rw-r--r--common/log.cpp69
-rw-r--r--common/log.h1
-rw-r--r--sinksh/sinksh_utils.cpp6
-rw-r--r--sinksh/syntax_modules/sink_trace.cpp44
4 files changed, 90 insertions, 30 deletions
diff --git a/common/log.cpp b/common/log.cpp
index 821df06..a3df04c 100644
--- a/common/log.cpp
+++ b/common/log.cpp
@@ -6,8 +6,11 @@
6#include <QSettings> 6#include <QSettings>
7#include <QStandardPaths> 7#include <QStandardPaths>
8#include <QSharedPointer> 8#include <QSharedPointer>
9#include <QMutex>
10#include <QMutexLocker>
9#include <iostream> 11#include <iostream>
10#include <unistd.h> 12#include <unistd.h>
13#include <memory>
11 14
12using namespace Sink::Log; 15using namespace Sink::Log;
13 16
@@ -218,9 +221,63 @@ static QByteArray getProgramName()
218 } 221 }
219} 222}
220 223
224static QSharedPointer<QSettings> debugAreasConfig()
225{
226 return QSharedPointer<QSettings>::create(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/sink/debugAreas.ini", QSettings::IniFormat);
227}
228
229class DebugAreaCollector {
230public:
231 DebugAreaCollector()
232 {
233 QMutexLocker locker(&mutex);
234 mDebugAreas = debugAreasConfig()->value("areas").value<QString>().split(';').toSet();
235 }
236
237 ~DebugAreaCollector()
238 {
239 QMutexLocker locker(&mutex);
240 mDebugAreas += debugAreasConfig()->value("areas").value<QString>().split(';').toSet();
241 debugAreasConfig()->setValue("areas", QVariant::fromValue(mDebugAreas.toList().join(';')));
242 }
243
244 void add(const QString &area)
245 {
246 QMutexLocker locker(&mutex);
247 mDebugAreas << area;
248 }
249
250 QSet<QString> debugAreas()
251 {
252 QMutexLocker locker(&mutex);
253 return mDebugAreas;
254 }
255
256 QMutex mutex;
257 QSet<QString> mDebugAreas;
258};
259
260static auto sDebugAreaCollector = std::unique_ptr<DebugAreaCollector>(new DebugAreaCollector);
261
262QSet<QString> Sink::Log::debugAreas()
263{
264 return sDebugAreaCollector->debugAreas();
265}
266
267static void collectDebugArea(const QString &debugArea)
268{
269 sDebugAreaCollector->add(debugArea);
270}
271
221static bool containsItemStartingWith(const QByteArray &pattern, const QByteArrayList &list) 272static bool containsItemStartingWith(const QByteArray &pattern, const QByteArrayList &list)
222{ 273{
223 for (const auto &item : list) { 274 for (const auto &item : list) {
275 if (item.startsWith('*')) {
276 auto stripped = item.mid(1);
277 if (pattern.contains(stripped)) {
278 return true;
279 }
280 }
224 if (pattern.startsWith(item)) { 281 if (pattern.startsWith(item)) {
225 return true; 282 return true;
226 } 283 }
@@ -248,9 +305,9 @@ QDebug Sink::Log::debugStream(DebugLevel debugLevel, int line, const char *file,
248 if (sPrimaryComponent.isEmpty()) { 305 if (sPrimaryComponent.isEmpty()) {
249 sPrimaryComponent = getProgramName(); 306 sPrimaryComponent = getProgramName();
250 } 307 }
251 QString fullDebugArea = sPrimaryComponent + "."+ QString::fromLatin1(debugComponent) + "." + QString::fromLatin1(debugArea); 308 QString fullDebugArea = sPrimaryComponent + "." + (debugComponent ? (QString::fromLatin1(debugComponent) + ".") : "") + (debugArea ? QString::fromLatin1(debugArea) : "");
252 309
253 //TODO add to autocompletion 310 collectDebugArea(fullDebugArea);
254 311
255 auto areas = debugOutputFilter(Sink::Log::Area); 312 auto areas = debugOutputFilter(Sink::Log::Area);
256 if (!areas.isEmpty()) { 313 if (!areas.isEmpty()) {
@@ -258,14 +315,6 @@ QDebug Sink::Log::debugStream(DebugLevel debugLevel, int line, const char *file,
258 return QDebug(&nullstream); 315 return QDebug(&nullstream);
259 } 316 }
260 } 317 }
261 // static QByteArray programName = getProgramName();
262 //
263 // auto filter = debugOutputFilter(Sink::Log::ApplicationName);
264 // if (!filter.isEmpty() && !filter.contains(programName)) {
265 // if (!containsItemStartingWith(programName, filter)) {
266 // return QDebug(&nullstream);
267 // }
268 // }
269 318
270 QString prefix; 319 QString prefix;
271 int prefixColorCode = ANSI_Colors::DoNothing; 320 int prefixColorCode = ANSI_Colors::DoNothing;
diff --git a/common/log.h b/common/log.h
index d801ed9..f47a3ae 100644
--- a/common/log.h
+++ b/common/log.h
@@ -15,6 +15,7 @@ enum DebugLevel
15}; 15};
16 16
17void SINK_EXPORT setPrimaryComponent(const QString &component); 17void SINK_EXPORT setPrimaryComponent(const QString &component);
18QSet<QString> SINK_EXPORT debugAreas();
18 19
19QByteArray SINK_EXPORT debugLevelName(DebugLevel debugLevel); 20QByteArray SINK_EXPORT debugLevelName(DebugLevel debugLevel);
20DebugLevel SINK_EXPORT debugLevelFromName(const QByteArray &name); 21DebugLevel SINK_EXPORT debugLevelFromName(const QByteArray &name);
diff --git a/sinksh/sinksh_utils.cpp b/sinksh/sinksh_utils.cpp
index 2a6f628..14b0aab 100644
--- a/sinksh/sinksh_utils.cpp
+++ b/sinksh/sinksh_utils.cpp
@@ -21,6 +21,7 @@
21#include "sinksh_utils.h" 21#include "sinksh_utils.h"
22 22
23#include "common/store.h" 23#include "common/store.h"
24#include "common/log.h"
24 25
25#include "utils.h" 26#include "utils.h"
26 27
@@ -115,10 +116,7 @@ QStringList resourceIds(State &state)
115 116
116QStringList debugareaCompleter(const QStringList &, const QString &fragment, State &state) 117QStringList debugareaCompleter(const QStringList &, const QString &fragment, State &state)
117{ 118{
118 QStringList list; 119 return Utils::filteredCompletions(Sink::Log::debugAreas().toList(), fragment);
119 list << "foo.bar" << "tar.war" << "bluub";
120 // return Utils::filteredCompletions(debugAreas(state), fragment);
121 return Utils::filteredCompletions(list, fragment);
122} 120}
123 121
124QStringList resourceCompleter(const QStringList &, const QString &fragment, State &state) 122QStringList resourceCompleter(const QStringList &, const QString &fragment, State &state)
diff --git a/sinksh/syntax_modules/sink_trace.cpp b/sinksh/syntax_modules/sink_trace.cpp
index e7b92de..d480254 100644
--- a/sinksh/syntax_modules/sink_trace.cpp
+++ b/sinksh/syntax_modules/sink_trace.cpp
@@ -35,34 +35,46 @@
35namespace SinkTrace 35namespace SinkTrace
36{ 36{
37 37
38bool trace(const QStringList &args, State &state) 38bool traceOff(const QStringList &args, State &state)
39{ 39{
40 // if (args.isEmpty()) { 40 Sink::Log::setDebugOutputLevel(Sink::Log::Log);
41 // state.printError(QObject::tr("Specifiy a debug area to trace.")); 41 qDebug() << "Turned trace off: " << args;
42 // return false;
43 // }
44 //
45 //
46 qDebug() << "Trace arguments: " << args;
47 Sink::Log::setDebugOutputLevel(Sink::Log::Trace);
48 // Sink::Log::setDebugOutputFilter(Sink::Log::FilterType::Area, "filter");
49
50 return true; 42 return true;
51} 43}
52 44
53bool traceOff(const QStringList &args, State &state) 45bool traceOn(const QStringList &args, State &state)
54{ 46{
55 Sink::Log::setDebugOutputLevel(Sink::Log::Log); 47 if (args.isEmpty()) {
56 qDebug() << "Turned trace off: " << args; 48 state.printError(QObject::tr("Specifiy a debug area to trace: ") + Sink::Log::debugAreas().toList().join(", "));
49 return false;
50 }
51 Sink::Log::setDebugOutputLevel(Sink::Log::Trace);
52 QByteArrayList filter;
53 for (const auto &arg : args) {
54 filter << arg.toLatin1();
55 }
56 Sink::Log::setDebugOutputFilter(Sink::Log::Area, filter);
57 return true; 57 return true;
58} 58}
59 59
60bool trace(const QStringList &args, State &state)
61{
62 return traceOn(args, state);
63}
64
65
60Syntax::List syntax() 66Syntax::List syntax()
61{ 67{
62 Syntax trace("trace", QObject::tr("Control trace debug output."), &SinkTrace::trace, Syntax::NotInteractive); 68 Syntax trace("trace", QObject::tr("Control trace debug output."), &SinkTrace::trace, Syntax::NotInteractive);
63 trace.completer = &SinkshUtils::debugareaCompleter; 69 trace.completer = &SinkshUtils::debugareaCompleter;
70
71 Syntax traceOff("off", QObject::tr("Turns off trace output."), &SinkTrace::traceOff, Syntax::NotInteractive);
72 traceOff.completer = &SinkshUtils::debugareaCompleter;
73 trace.children << traceOff;
64 74
65 trace.children << Syntax("off", QObject::tr("Turns off trace output."), &SinkTrace::traceOff, Syntax::NotInteractive); 75 Syntax traceOn("on", QObject::tr("Turns on trace output."), &SinkTrace::traceOn, Syntax::NotInteractive);
76 traceOn.completer = &SinkshUtils::debugareaCompleter;
77 trace.children << traceOn;
66 78
67 return Syntax::List() << trace; 79 return Syntax::List() << trace;
68} 80}