diff --git a/server/jsonrpc/jsontypes.cpp b/server/jsonrpc/jsontypes.cpp index 22354845..11f05a86 100644 --- a/server/jsonrpc/jsontypes.cpp +++ b/server/jsonrpc/jsontypes.cpp @@ -754,12 +754,21 @@ StateDescriptor JsonTypes::unpackStateDescriptor(const QVariantMap &stateDescrip LogFilter JsonTypes::unpackLogFilter(const QVariantMap &logFilterMap) { LogFilter filter; - if (logFilterMap.contains("startTime")) { - filter.setStartDate(QDateTime::fromMSecsSinceEpoch(logFilterMap.value("startTime").toInt())); - } - if (logFilterMap.contains("endTime")) { - filter.setEndDate(QDateTime::fromMSecsSinceEpoch(logFilterMap.value("endTime").toInt())); + if (logFilterMap.contains("timeFilters")) { + QVariantList timeFilters = logFilterMap.value("timeFilters").toList(); + foreach (const QVariant &timeFilter, timeFilters) { + QVariantMap timeFilterMap = timeFilter.toMap(); + QDateTime startDate; QDateTime endDate; + if (timeFilterMap.contains("startDate")) { + startDate = QDateTime::fromTime_t(timeFilterMap.value("startDate").toInt()); + } + if (timeFilterMap.contains("endDate")) { + endDate = QDateTime::fromTime_t(timeFilterMap.value("endDate").toInt()); + } + filter.addTimeFilter(startDate, endDate); + } } + if (logFilterMap.contains("loggingSources")) { QVariantList loggingSources = logFilterMap.value("loggingSources").toList(); foreach (const QVariant &source, loggingSources) { diff --git a/server/jsonrpc/logginghandler.cpp b/server/jsonrpc/logginghandler.cpp index b3a0c11d..acb7446b 100644 --- a/server/jsonrpc/logginghandler.cpp +++ b/server/jsonrpc/logginghandler.cpp @@ -35,15 +35,18 @@ LoggingHandler::LoggingHandler(QObject *parent) : // Notifications params.clear(); returns.clear(); - setDescription("LogEntryAdded", "Emitted whenever an entry is appended to the logging system."); + setDescription("LogEntryAdded", "Emitted whenever an entry is appended to the logging system. " + "The filters can be combinend."); params.insert("logEntry", JsonTypes::logEntryRef()); setParams("LogEntryAdded", params); params.clear(); returns.clear(); setDescription("GetLogEntries", "Get the LogEntries matching the given filter."); - params.insert("o:startTime", JsonTypes::basicTypeToString(JsonTypes::Int)); - params.insert("o:endTime", JsonTypes::basicTypeToString(JsonTypes::Int)); + QVariantMap timeFilter; + timeFilter.insert("o:startDate", JsonTypes::basicTypeToString(JsonTypes::Int)); + timeFilter.insert("o:endDate", JsonTypes::basicTypeToString(JsonTypes::Int)); + params.insert("o:timeFilters", QVariantList() << timeFilter); params.insert("o:loggingSources", QVariantList() << JsonTypes::loggingSourceRef()); params.insert("o:loggingLevels", QVariantList() << JsonTypes::loggingLevelRef()); params.insert("o:eventTypes", QVariantList() << JsonTypes::loggingEventTypeRef()); @@ -73,7 +76,7 @@ void LoggingHandler::logEntryAdded(const LogEntry &logEntry) JsonReply* LoggingHandler::GetLogEntries(const QVariantMap ¶ms) const { - qCDebug(dcJsonRpc) << "asked for log entries" << params; + qCDebug(dcJsonRpc) << "Asked for log entries" << params; LogFilter filter = JsonTypes::unpackLogFilter(params); diff --git a/server/logging/logengine.cpp b/server/logging/logengine.cpp index 0639b897..067451bb 100644 --- a/server/logging/logengine.cpp +++ b/server/logging/logengine.cpp @@ -29,7 +29,7 @@ #include #include -#define DB_SCHEMA_VERSION 1 +#define DB_SCHEMA_VERSION 2 namespace guhserver { @@ -43,7 +43,6 @@ LogEngine::LogEngine(QObject *parent): qCWarning(dcLogEngine) << "Database not valid:" << m_db.lastError().driverText() << m_db.lastError().databaseText(); return; } - if (!m_db.open()) { qCWarning(dcLogEngine) << "Error opening log database:" << m_db.lastError().driverText() << m_db.lastError().databaseText(); return; @@ -69,7 +68,7 @@ QList LogEngine::logEntries(const LogFilter &filter) const while (query.next()) { LogEntry entry( - QDateTime::fromMSecsSinceEpoch(query.value("timestamp").toLongLong()), + QDateTime::fromTime_t(query.value("timestamp").toLongLong()), (Logging::LoggingLevel)query.value("loggingLevel").toInt(), (Logging::LoggingSource)query.value("sourceType").toInt(), query.value("errorCode").toInt()); @@ -150,7 +149,7 @@ void LogEngine::logRuleActiveChanged(const Rule &rule) void LogEngine::appendLogEntry(const LogEntry &entry) { QString queryString = QString("INSERT INTO entries (timestamp, loggingEventType, loggingLevel, sourceType, typeId, deviceId, value, active, errorCode) values ('%1', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9');") - .arg(entry.timestamp().toMSecsSinceEpoch()) + .arg(entry.timestamp().toTime_t()) .arg(entry.eventType()) .arg(entry.level()) .arg(entry.source()) @@ -186,7 +185,7 @@ void LogEngine::initDB() if (version != DB_SCHEMA_VERSION) { qCWarning(dcLogEngine) << "Log schema version not matching! Schema upgrade not implemented yet. Logging might fail."; } else { - qCDebug(dcLogEngine) << "Log database schema version matches"; + qCDebug(dcLogEngine) << "Log database schema version" << DB_SCHEMA_VERSION << "matches"; } } else { qCWarning(dcLogEngine) << "Broken log database. Version not found in metadata table."; @@ -194,7 +193,7 @@ void LogEngine::initDB() if (!m_db.tables().contains("sourceTypes")) { query.exec("CREATE TABLE sourceTypes (id int, name varchar(20), PRIMARY KEY(id));"); - qCDebug(dcLogEngine) << query.lastError().databaseText(); + //qCDebug(dcLogEngine) << query.lastError().databaseText(); QMetaEnum logTypes = Logging::staticMetaObject.enumerator(Logging::staticMetaObject.indexOfEnumerator("LoggingSource")); Q_ASSERT_X(logTypes.isValid(), "LogEngine", "Logging has no enum LoggingSource"); for (int i = 0; i < logTypes.keyCount(); i++) { @@ -204,7 +203,7 @@ void LogEngine::initDB() if (!m_db.tables().contains("loggingEventTypes")) { query.exec("CREATE TABLE loggingEventTypes (id int, name varchar(20), PRIMARY KEY(id));"); - qCDebug(dcLogEngine) << query.lastError().databaseText(); + //qCDebug(dcLogEngine) << query.lastError().databaseText(); QMetaEnum logTypes = Logging::staticMetaObject.enumerator(Logging::staticMetaObject.indexOfEnumerator("LoggingEventType")); Q_ASSERT_X(logTypes.isValid(), "LogEngine", "Logging has no enum LoggingEventType"); for (int i = 0; i < logTypes.keyCount(); i++) { diff --git a/server/logging/logentry.cpp b/server/logging/logentry.cpp index e199b1da..da70a551 100644 --- a/server/logging/logentry.cpp +++ b/server/logging/logentry.cpp @@ -159,6 +159,7 @@ int LogEntry::errorCode() const QDebug operator<<(QDebug dbg, const LogEntry &entry) { dbg.nospace() << "LogEntry (count:" << entry.timestamp().toString() << endl; + dbg.nospace() << " time stamp: " << entry.timestamp().toTime_t() << endl; dbg.nospace() << " DeviceId: " << entry.deviceId().toString() << endl; dbg.nospace() << " type id: " << entry.typeId().toString() << endl; dbg.nospace() << " source: " << entry.sourceString() << endl; diff --git a/server/logging/logfilter.cpp b/server/logging/logfilter.cpp index 6f28e8e8..a98fbed2 100644 --- a/server/logging/logfilter.cpp +++ b/server/logging/logfilter.cpp @@ -19,6 +19,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "logfilter.h" +#include "loggingcategories.h" namespace guhserver { @@ -69,24 +70,16 @@ QString LogFilter::queryString() const return query; } -void LogFilter::setStartDate(const QDateTime &startDate) +void LogFilter::addTimeFilter(const QDateTime &startDate, const QDateTime &endDate) { - m_startDate = startDate; + QPair timeFilter(startDate, endDate); + if (!m_timeFilters.contains(timeFilter)) + m_timeFilters.append(timeFilter); } -QDateTime LogFilter::startDate() const +QList > LogFilter::timeFilters() const { - return m_startDate; -} - -void LogFilter::setEndDate(const QDateTime &endDate) -{ - m_endDate = endDate; -} - -QDateTime LogFilter::endDate() const -{ - return m_endDate; + return m_timeFilters; } void LogFilter::addLoggingSource(const Logging::LoggingSource &source) @@ -157,8 +150,7 @@ QList LogFilter::values() const bool LogFilter::isEmpty() const { - return m_endDate.isNull() && - m_startDate.isNull() && + return m_timeFilters.isEmpty() && m_sources.isEmpty() && m_levels.isEmpty() && m_eventTypes.isEmpty() && @@ -170,22 +162,50 @@ bool LogFilter::isEmpty() const QString LogFilter::createDateString() const { QString query; - if (m_startDate.isValid() && !m_endDate.isValid()) { + if (!m_timeFilters.isEmpty()) { + if (m_timeFilters.count() == 1) { + QPair timeFilter = m_timeFilters.first(); + query.append(createTimeFilterString(timeFilter)); + } else { + query.append("( "); + QPair timeFilter; + foreach (timeFilter, m_timeFilters) { + query.append(createTimeFilterString(timeFilter)); + if (timeFilter != m_timeFilters.last()) + query.append("OR "); + } + query.append(") "); + } + } + return query; +} + +QString LogFilter::createTimeFilterString(QPair timeFilter) const +{ + QString query; + QDateTime startDate = timeFilter.first; + QDateTime endDate = timeFilter.second; + + qCDebug(dcLogEngine) << "create timefiler for" << startDate.toString() << endDate.toString(); + + query.append("( "); + if (startDate.isValid() && !endDate.isValid()) { // only start date is valid query.append(QString("timestamp BETWEEN '%1' AND '%2' ") - .arg(m_startDate.toMSecsSinceEpoch()) - .arg(QDateTime::currentDateTime().toMSecsSinceEpoch())); - } else if (!m_startDate.isValid() && m_endDate.isValid()) { + .arg(startDate.toTime_t()) + .arg(QDateTime::currentDateTime().toTime_t())); + } else if (!startDate.isValid() && endDate.isValid()) { // only end date is valid query.append(QString("timestamp NOT BETWEEN '%1' AND '%2' ") - .arg(m_endDate.toMSecsSinceEpoch()) - .arg(QDateTime::currentDateTime().toMSecsSinceEpoch())); - } else if (m_startDate.isValid() && m_endDate.isValid()) { + .arg(endDate.toTime_t()) + .arg(QDateTime::currentDateTime().toTime_t())); + } else if (startDate.isValid() && endDate.isValid()) { // both dates are valid query.append(QString("timestamp BETWEEN '%1' AND '%2' ") - .arg(m_startDate.toMSecsSinceEpoch()) - .arg(m_endDate.toMSecsSinceEpoch())); + .arg(startDate.toTime_t()) + .arg(endDate.toTime_t())); } + query.append(") "); return query; } diff --git a/server/logging/logfilter.h b/server/logging/logfilter.h index a9b3e99b..a947d9c4 100644 --- a/server/logging/logfilter.h +++ b/server/logging/logfilter.h @@ -22,6 +22,7 @@ #ifndef LOGFILTER_H #define LOGFILTER_H +#include #include #include "logging.h" @@ -36,11 +37,9 @@ public: QString queryString() const; - void setStartDate(const QDateTime &startDate); - QDateTime startDate() const; - void setEndDate(const QDateTime &endDate); - QDateTime endDate() const; + void addTimeFilter(const QDateTime &startDate = QDateTime(), const QDateTime &endDate = QDateTime()); + QList > timeFilters() const; void addLoggingSource(const Logging::LoggingSource &source) ; QList loggingSources() const; @@ -66,9 +65,7 @@ public: bool isEmpty() const; private: - QDateTime m_startDate; - QDateTime m_endDate; - + QList > m_timeFilters; QList m_sources; QList m_levels; QList m_eventTypes; @@ -77,6 +74,7 @@ private: QList m_values; QString createDateString() const; + QString createTimeFilterString(QPair timeFilter) const; QString createSourcesString() const; QString createLevelsString() const; QString createEventTypesString() const; diff --git a/tests/auto/api.json b/tests/auto/api.json index 781fdb94..af2dd1aa 100644 --- a/tests/auto/api.json +++ b/tests/auto/api.json @@ -278,6 +278,30 @@ "Logging.GetLogEntries": { "description": "Get the LogEntries matching the given filter.", "params": { + "o:deviceIds": [ + "Uuid" + ], + "o:eventTypes": [ + "$ref:LoggingEventType" + ], + "o:loggingLevels": [ + "$ref:LoggingLevel" + ], + "o:loggingSources": [ + "$ref:LoggingSource" + ], + "o:timeFilters": [ + { + "o:endDate": "Int", + "o:startDate": "Int" + } + ], + "o:typeIds": [ + "Uuid" + ], + "o:values": [ + "Variant" + ] }, "returns": { "loggingError": "$ref:LoggingError", @@ -434,7 +458,7 @@ } }, "Logging.LogEntryAdded": { - "description": "Emitted whenever an entry is appended to the logging system.", + "description": "Emitted whenever an entry is appended to the logging system. The filters can be combinend.", "params": { "logEntry": "$ref:LogEntry" } @@ -603,7 +627,8 @@ }, "LoggingError": [ "LoggingErrorNoError", - "LoggingErrorLogEntryNotFound" + "LoggingErrorLogEntryNotFound", + "LoggingErrorInvalidFilterParameter" ], "LoggingEventType": [ "LoggingEventTypeTrigger",