diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-07-07 23:40:52 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-07-07 23:40:52 +0200 |
commit | 3c05b5816aa0fb978686b0ed16a02336e0981a0e (patch) | |
tree | a05662f3635ac9364c2bde16eea0f915190cfb1f | |
parent | da2b049e248c1ad7efeb53685158a205335e4e36 (diff) | |
download | sink-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.cpp | 69 | ||||
-rw-r--r-- | common/log.h | 1 | ||||
-rw-r--r-- | sinksh/sinksh_utils.cpp | 6 | ||||
-rw-r--r-- | sinksh/syntax_modules/sink_trace.cpp | 44 |
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 | ||
12 | using namespace Sink::Log; | 15 | using namespace Sink::Log; |
13 | 16 | ||
@@ -218,9 +221,63 @@ static QByteArray getProgramName() | |||
218 | } | 221 | } |
219 | } | 222 | } |
220 | 223 | ||
224 | static QSharedPointer<QSettings> debugAreasConfig() | ||
225 | { | ||
226 | return QSharedPointer<QSettings>::create(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/sink/debugAreas.ini", QSettings::IniFormat); | ||
227 | } | ||
228 | |||
229 | class DebugAreaCollector { | ||
230 | public: | ||
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 | |||
260 | static auto sDebugAreaCollector = std::unique_ptr<DebugAreaCollector>(new DebugAreaCollector); | ||
261 | |||
262 | QSet<QString> Sink::Log::debugAreas() | ||
263 | { | ||
264 | return sDebugAreaCollector->debugAreas(); | ||
265 | } | ||
266 | |||
267 | static void collectDebugArea(const QString &debugArea) | ||
268 | { | ||
269 | sDebugAreaCollector->add(debugArea); | ||
270 | } | ||
271 | |||
221 | static bool containsItemStartingWith(const QByteArray &pattern, const QByteArrayList &list) | 272 | static 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 | ||
17 | void SINK_EXPORT setPrimaryComponent(const QString &component); | 17 | void SINK_EXPORT setPrimaryComponent(const QString &component); |
18 | QSet<QString> SINK_EXPORT debugAreas(); | ||
18 | 19 | ||
19 | QByteArray SINK_EXPORT debugLevelName(DebugLevel debugLevel); | 20 | QByteArray SINK_EXPORT debugLevelName(DebugLevel debugLevel); |
20 | DebugLevel SINK_EXPORT debugLevelFromName(const QByteArray &name); | 21 | DebugLevel 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 | ||
116 | QStringList debugareaCompleter(const QStringList &, const QString &fragment, State &state) | 117 | QStringList 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 | ||
124 | QStringList resourceCompleter(const QStringList &, const QString &fragment, State &state) | 122 | QStringList 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 @@ | |||
35 | namespace SinkTrace | 35 | namespace SinkTrace |
36 | { | 36 | { |
37 | 37 | ||
38 | bool trace(const QStringList &args, State &state) | 38 | bool 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 | ||
53 | bool traceOff(const QStringList &args, State &state) | 45 | bool 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 | ||
60 | bool trace(const QStringList &args, State &state) | ||
61 | { | ||
62 | return traceOn(args, state); | ||
63 | } | ||
64 | |||
65 | |||
60 | Syntax::List syntax() | 66 | Syntax::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 | } |