From 5d43fadcc3ef3f8a3b6bcaea501bf445d49403cc Mon Sep 17 00:00:00 2001 From: Kalila L Date: Sun, 7 Feb 2021 02:02:55 -0500 Subject: [PATCH 1/7] Initial audit logging, for review. --- .../src/entities/EntityServer.cpp | 5 ++ assignment-client/src/entities/EntityServer.h | 2 +- .../resources/describe-settings.json | 8 +++ .../entities/src/EntitiesAuditLogging.cpp | 14 ++++ libraries/entities/src/EntitiesAuditLogging.h | 19 +++++ libraries/entities/src/EntityTree.cpp | 72 ++++++++++++++++++- libraries/entities/src/EntityTree.h | 8 +++ 7 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 libraries/entities/src/EntitiesAuditLogging.cpp create mode 100644 libraries/entities/src/EntitiesAuditLogging.h diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index e68f95bda05..f756dd3b285 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -310,6 +310,10 @@ void EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectio bool wantEditLogging = false; readOptionBool(QString("wantEditLogging"), settingsSectionObject, wantEditLogging); qDebug("wantEditLogging=%s", debug::valueOf(wantEditLogging)); + + bool wantAuditEditLogging = false; + readOptionBool(QString("wantAuditEditLogging"), settingsSectionObject, wantAuditEditLogging); + qDebug("wantAuditEditLogging=%s", debug::valueOf(wantAuditEditLogging)); bool wantTerseEditLogging = false; readOptionBool(QString("wantTerseEditLogging"), settingsSectionObject, wantTerseEditLogging); @@ -337,6 +341,7 @@ void EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectio startDynamicDomainVerification(); tree->setWantEditLogging(wantEditLogging); + tree->setWantAuditEditLogging(wantAuditEditLogging); tree->setWantTerseEditLogging(wantTerseEditLogging); QString entityScriptSourceWhitelist; diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index 9bb3a237e06..7c0b451a451 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -45,7 +45,7 @@ class EntityServer : public OctreeServer, public NewlyCreatedEntityHook { virtual PacketType getMyEditNackType() const override { return PacketType::EntityEditNack; } virtual QString getMyDomainSettingsKey() const override { return QString("entity_server_settings"); } - // subclass may implement these method + // subclass may implement these methods virtual void beforeRun() override; virtual bool hasSpecialPacketsToSend(const SharedNodePointer& node) override; virtual int sendSpecialPackets(const SharedNodePointer& node, OctreeQueryNode* queryNode, int& packetsSent) override; diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index bb7acf344c3..b69de473ce2 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -1616,6 +1616,14 @@ "default": false, "advanced": true }, + { + "name": "wantAuditEditLogging", + "type": "checkbox", + "label": "Audit Edit Logging", + "help": "Log edits with audit information.", + "default": true, + "advanced": true + }, { "name": "verboseDebug", "type": "checkbox", diff --git a/libraries/entities/src/EntitiesAuditLogging.cpp b/libraries/entities/src/EntitiesAuditLogging.cpp new file mode 100644 index 00000000000..a07f3e42771 --- /dev/null +++ b/libraries/entities/src/EntitiesAuditLogging.cpp @@ -0,0 +1,14 @@ +// +// EntitiesAuditLogging.cpp +// libraries/entities/src +// +// Created by Kalila L on Feb 5 2021. +// Copyright 2021 Vircadia contributors. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "EntitiesAuditLogging.h" + +Q_LOGGING_CATEGORY(entities_audit, "vircadia.entities.audit") diff --git a/libraries/entities/src/EntitiesAuditLogging.h b/libraries/entities/src/EntitiesAuditLogging.h new file mode 100644 index 00000000000..3381e0b3e07 --- /dev/null +++ b/libraries/entities/src/EntitiesAuditLogging.h @@ -0,0 +1,19 @@ +// +// EntitiesAuditLogging.h +// libraries/entities/src +// +// Created by Kalila L on Feb 5 2021. +// Copyright 2021 Vircadia contributors. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef vircadia_EntitiesAuditLogging_h +#define vircadia_EntitiesAuditLogging_h + +#include + +Q_DECLARE_LOGGING_CATEGORY(entities_audit) + +#endif // vircadia_EntitiesAuditLogging_h diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 24b6f7ccd40..ccefbf605f1 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -37,6 +37,7 @@ #include "UpdateEntityOperator.h" #include "QVariantGLM.h" #include "EntitiesLogging.h" +#include "EntitiesAuditLogging.h" #include "RecurseOctreeToMapOperator.h" #include "RecurseOctreeToJSONOperator.h" #include "LogHandler.h" @@ -1795,6 +1796,36 @@ void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const } } +QJsonObject auditLogAddBuffer; +QJsonObject auditLogEditBuffer; +QTimer* auditLogProcessorTimer; +int AUDIT_LOG_OUTPUT_INTERVAL = 5000; + +void EntityTree::processAuditLogBuffers() { + if (!auditLogAddBuffer.isEmpty()) { + QJsonObject objectToOutput; + objectToOutput.insert("add", auditLogAddBuffer); + qCDebug(entities_audit) << objectToOutput; + auditLogAddBuffer = QJsonObject(); + } + if (!auditLogEditBuffer.isEmpty()) { + QJsonObject objectToOutput; + objectToOutput.insert("edit", auditLogEditBuffer); + qCDebug(entities_audit) << objectToOutput; + auditLogEditBuffer = QJsonObject(); + } +} + +void EntityTree::startAuditLogProcessor() { + auditLogProcessorTimer = new QTimer(this); + connect(auditLogProcessorTimer, &QTimer::timeout, this, &EntityTree::processAuditLogBuffers); + auditLogProcessorTimer->start(AUDIT_LOG_OUTPUT_INTERVAL); +} + +void EntityTree::stopAuditLogProcessor() { + auditLogProcessorTimer->stop(); +} + // NOTE: Caller must lock the tree before calling this. int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode) { @@ -1802,6 +1833,9 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c qCWarning(entities) << "EntityTree::processEditPacketData() should only be called on a server tree."; return 0; } + if (wantAuditEditLogging() && !auditLogProcessorTimer) { + EntityTree::startAuditLogProcessor(); + } int processedBytes = 0; bool isAdd = false; @@ -1828,6 +1862,9 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c quint64 startCreate = 0, endCreate = 0; quint64 startFilter = 0, endFilter = 0; quint64 startLogging = 0, endLogging = 0; + quint64 startProcessing = 0, endProcessing = 0; + + startProcessing = usecTimestampNow(); bool suppressDisallowedClientScript = false; bool suppressDisallowedServerScript = false; @@ -2003,6 +2040,22 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c qCDebug(entities) << "User [" << senderNode->getUUID() << "] editing entity. ID:" << entityItemID; qCDebug(entities) << " properties:" << properties; } + /*if (wantAuditEditLogging()) {*/ + if (true) { + HifiSockAddr senderSocket = senderNode->getPublicSocket(); + + QJsonValue findExisting = auditLogEditBuffer.take(senderSocket.toString()); + if (!findExisting.isUndefined()) { + QJsonObject existingObject = findExisting.toObject(); + if (!existingObject.contains(entityItemID.toString())) { + existingObject.insert(entityItemID.toString(), ""); + } + auditLogEditBuffer.insert(senderSocket.toString(), existingObject); + } else { + QJsonObject newEntry{ { entityItemID.toString(), "" } }; + auditLogEditBuffer.insert(senderSocket.toString(), newEntry); + } + } if (wantTerseEditLogging()) { QList changedProperties = properties.listChangedProperties(); fixupTerseEditLogging(properties, changedProperties); @@ -2082,6 +2135,22 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c << newEntity->getEntityItemID(); qCDebug(entities) << " properties:" << properties; } + /*if (wantAuditEditLogging()) {*/ + if (true) { + HifiSockAddr senderSocket = senderNode->getPublicSocket(); + + QJsonValue findExisting = auditLogAddBuffer.take(senderSocket.toString()); + if (!findExisting.isUndefined()) { + QJsonObject existingObject = findExisting.toObject(); + if (!existingObject.contains(entityItemID.toString())) { + existingObject.insert(entityItemID.toString(), ""); + } + auditLogAddBuffer.insert(senderSocket.toString(), existingObject); + } else { + QJsonObject newEntry{ { entityItemID.toString(), "" } }; + auditLogAddBuffer.insert(senderSocket.toString(), newEntry); + } + } if (wantTerseEditLogging()) { QList changedProperties = properties.listChangedProperties(); fixupTerseEditLogging(properties, changedProperties); @@ -2105,6 +2174,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c } } + endProcessing = usecTimestampNow(); _totalDecodeTime += endDecode - startDecode; _totalLookupTime += endLookup - startLookup; @@ -2112,7 +2182,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c _totalCreateTime += endCreate - startCreate; _totalLoggingTime += endLogging - startLogging; _totalFilterTime += endFilter - startFilter; - + qDebug() << "totalProcessingTime" << (startProcessing - endProcessing); break; } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 66e761f7a04..e2c47a96f3a 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -190,6 +190,9 @@ class EntityTree : public Octree, public SpatialParentTree { bool wantEditLogging() const { return _wantEditLogging; } void setWantEditLogging(bool value) { _wantEditLogging = value; } + + bool wantAuditEditLogging() const { return _wantAuditEditLogging; } + void setWantAuditEditLogging(bool value) { _wantAuditEditLogging = value; } bool wantTerseEditLogging() const { return _wantTerseEditLogging; } void setWantTerseEditLogging(bool value) { _wantTerseEditLogging = value; } @@ -339,6 +342,7 @@ class EntityTree : public Octree, public SpatialParentTree { EntitySimulationPointer _simulation; bool _wantEditLogging = false; + bool _wantAuditEditLogging = true; bool _wantTerseEditLogging = false; @@ -389,6 +393,10 @@ class EntityTree : public Octree, public SpatialParentTree { void sendChallengeOwnershipRequestPacket(const QByteArray& id, const QByteArray& text, const QByteArray& nodeToChallenge, const SharedNodePointer& senderNode); void validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode); + void EntityTree::processAuditLogBuffers(); + void EntityTree::startAuditLogProcessor(); + void EntityTree::stopAuditLogProcessor(); + std::shared_ptr _myAvatar{ nullptr }; static std::function _getEntityObjectOperator; From 2fd3fb20edffc95cf504a662e60f84f1919da217 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Mon, 8 Feb 2021 05:14:36 -0500 Subject: [PATCH 2/7] Add interval default + setting, counter for edits, name for adds. --- .../src/entities/EntityServer.cpp | 11 ++++++-- .../resources/describe-settings.json | 10 ++++++- libraries/entities/src/EntityTree.cpp | 28 +++++++++---------- libraries/entities/src/EntityTree.h | 6 ++++ 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index f756dd3b285..59a8a66d4fd 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -315,12 +315,19 @@ void EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectio readOptionBool(QString("wantAuditEditLogging"), settingsSectionObject, wantAuditEditLogging); qDebug("wantAuditEditLogging=%s", debug::valueOf(wantAuditEditLogging)); + EntityTreePointer tree = std::static_pointer_cast(_tree); + + int auditEditLoggingInterval; + if (readOptionInt("auditEditLoggingInterval", settingsSectionObject, auditEditLoggingInterval)) { + tree->setAuditEditLoggingInterval(auditEditLoggingInterval); + } else { + tree->setAuditEditLoggingInterval(EntityTree::DEFAULT_AUDIT_EDIT_INTERVAL); + } + bool wantTerseEditLogging = false; readOptionBool(QString("wantTerseEditLogging"), settingsSectionObject, wantTerseEditLogging); qDebug("wantTerseEditLogging=%s", debug::valueOf(wantTerseEditLogging)); - EntityTreePointer tree = std::static_pointer_cast(_tree); - int maxTmpEntityLifetime; if (readOptionInt("maxTmpLifetime", settingsSectionObject, maxTmpEntityLifetime)) { tree->setEntityMaxTmpLifetime(maxTmpEntityLifetime); diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index b69de473ce2..fefd0df37fa 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -1621,7 +1621,15 @@ "type": "checkbox", "label": "Audit Edit Logging", "help": "Log edits with audit information.", - "default": true, + "default": false, + "advanced": true + }, + { + "name": "auditEditLoggingInterval", + "label": "Audit Entity Edit Logging Interval", + "help": "Milliseconds between the outputting and clearing of audit logs for entity edits/adds.", + "placeholder": "10000", + "default": "10000", "advanced": true }, { diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index ccefbf605f1..f3067241304 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -46,6 +46,7 @@ static const quint64 DELETED_ENTITIES_EXTRA_USECS_TO_CONSIDER = USECS_PER_MSEC * 50; const float EntityTree::DEFAULT_MAX_TMP_ENTITY_LIFETIME = 60 * 60; // 1 hour +const float EntityTree::DEFAULT_AUDIT_EDIT_INTERVAL = 10000; // 10 seconds static const QString DOMAIN_UNLIMITED = "domainUnlimited"; EntityTree::EntityTree(bool shouldReaverage) : @@ -1799,7 +1800,6 @@ void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const QJsonObject auditLogAddBuffer; QJsonObject auditLogEditBuffer; QTimer* auditLogProcessorTimer; -int AUDIT_LOG_OUTPUT_INTERVAL = 5000; void EntityTree::processAuditLogBuffers() { if (!auditLogAddBuffer.isEmpty()) { @@ -1819,7 +1819,7 @@ void EntityTree::processAuditLogBuffers() { void EntityTree::startAuditLogProcessor() { auditLogProcessorTimer = new QTimer(this); connect(auditLogProcessorTimer, &QTimer::timeout, this, &EntityTree::processAuditLogBuffers); - auditLogProcessorTimer->start(AUDIT_LOG_OUTPUT_INTERVAL); + auditLogProcessorTimer->start(auditEditLoggingInterval()); } void EntityTree::stopAuditLogProcessor() { @@ -1862,9 +1862,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c quint64 startCreate = 0, endCreate = 0; quint64 startFilter = 0, endFilter = 0; quint64 startLogging = 0, endLogging = 0; - quint64 startProcessing = 0, endProcessing = 0; - startProcessing = usecTimestampNow(); bool suppressDisallowedClientScript = false; bool suppressDisallowedServerScript = false; @@ -2040,19 +2038,20 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c qCDebug(entities) << "User [" << senderNode->getUUID() << "] editing entity. ID:" << entityItemID; qCDebug(entities) << " properties:" << properties; } - /*if (wantAuditEditLogging()) {*/ - if (true) { + if (wantAuditEditLogging()) { HifiSockAddr senderSocket = senderNode->getPublicSocket(); QJsonValue findExisting = auditLogEditBuffer.take(senderSocket.toString()); if (!findExisting.isUndefined()) { QJsonObject existingObject = findExisting.toObject(); if (!existingObject.contains(entityItemID.toString())) { - existingObject.insert(entityItemID.toString(), ""); + existingObject.insert(entityItemID.toString(), 1); + } else { + existingObject[entityItemID.toString()] = existingObject[entityItemID.toString()].toInt() + 1; } auditLogEditBuffer.insert(senderSocket.toString(), existingObject); } else { - QJsonObject newEntry{ { entityItemID.toString(), "" } }; + QJsonObject newEntry{ { entityItemID.toString(), 1 } }; auditLogEditBuffer.insert(senderSocket.toString(), newEntry); } } @@ -2135,19 +2134,20 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c << newEntity->getEntityItemID(); qCDebug(entities) << " properties:" << properties; } - /*if (wantAuditEditLogging()) {*/ - if (true) { + if (wantAuditEditLogging()) { HifiSockAddr senderSocket = senderNode->getPublicSocket(); QJsonValue findExisting = auditLogAddBuffer.take(senderSocket.toString()); if (!findExisting.isUndefined()) { QJsonObject existingObject = findExisting.toObject(); if (!existingObject.contains(entityItemID.toString())) { - existingObject.insert(entityItemID.toString(), ""); + existingObject.insert(entityItemID.toString(), EntityTypes::getEntityTypeName(properties.getType())); } auditLogAddBuffer.insert(senderSocket.toString(), existingObject); } else { - QJsonObject newEntry{ { entityItemID.toString(), "" } }; + QJsonObject newEntry{ { + entityItemID.toString(), EntityTypes::getEntityTypeName(properties.getType()) + } }; auditLogAddBuffer.insert(senderSocket.toString(), newEntry); } } @@ -2174,15 +2174,13 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c } } - endProcessing = usecTimestampNow(); - _totalDecodeTime += endDecode - startDecode; _totalLookupTime += endLookup - startLookup; _totalUpdateTime += endUpdate - startUpdate; _totalCreateTime += endCreate - startCreate; _totalLoggingTime += endLogging - startLogging; _totalFilterTime += endFilter - startFilter; - qDebug() << "totalProcessingTime" << (startProcessing - endProcessing); + break; } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index e2c47a96f3a..cf407f10eef 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -193,6 +193,9 @@ class EntityTree : public Octree, public SpatialParentTree { bool wantAuditEditLogging() const { return _wantAuditEditLogging; } void setWantAuditEditLogging(bool value) { _wantAuditEditLogging = value; } + + float auditEditLoggingInterval() const { return _auditEditLoggingInterval; } + void setAuditEditLoggingInterval(float value) { _auditEditLoggingInterval = value; } bool wantTerseEditLogging() const { return _wantTerseEditLogging; } void setWantTerseEditLogging(bool value) { _wantTerseEditLogging = value; } @@ -253,6 +256,8 @@ class EntityTree : public Octree, public SpatialParentTree { void notifyNewCollisionSoundURL(const QString& newCollisionSoundURL, const EntityItemID& entityID); static const float DEFAULT_MAX_TMP_ENTITY_LIFETIME; + + static const float DEFAULT_AUDIT_EDIT_INTERVAL; QByteArray computeNonce(const EntityItemID& entityID, const QString ownerKey); bool verifyNonce(const EntityItemID& entityID, const QString& nonce); @@ -343,6 +348,7 @@ class EntityTree : public Octree, public SpatialParentTree { bool _wantEditLogging = false; bool _wantAuditEditLogging = true; + float _auditEditLoggingInterval { DEFAULT_AUDIT_EDIT_INTERVAL }; bool _wantTerseEditLogging = false; From 47079106b7849ecf1388d41b86e99f07d7ff3bb2 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Mon, 8 Feb 2021 06:27:04 -0500 Subject: [PATCH 3/7] Fix builds due to definition. --- libraries/entities/src/EntityTree.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index cf407f10eef..ad85e44953f 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -399,9 +399,9 @@ class EntityTree : public Octree, public SpatialParentTree { void sendChallengeOwnershipRequestPacket(const QByteArray& id, const QByteArray& text, const QByteArray& nodeToChallenge, const SharedNodePointer& senderNode); void validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode); - void EntityTree::processAuditLogBuffers(); - void EntityTree::startAuditLogProcessor(); - void EntityTree::stopAuditLogProcessor(); + void processAuditLogBuffers(); + void startAuditLogProcessor(); + void stopAuditLogProcessor(); std::shared_ptr _myAvatar{ nullptr }; From 998616fdc14aded3a5f69f670b0ee6890922bf62 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Wed, 10 Feb 2021 20:03:08 -0500 Subject: [PATCH 4/7] Put entity audit logging stuff into its own class. --- .../entities/src/EntitiesAuditLogging.cpp | 72 ++++++++++++++++++- libraries/entities/src/EntitiesAuditLogging.h | 18 ++++- libraries/entities/src/EntitiesLogging.h | 2 +- libraries/entities/src/EntityTree.cpp | 69 +++--------------- libraries/entities/src/EntityTree.h | 12 ++-- 5 files changed, 104 insertions(+), 69 deletions(-) diff --git a/libraries/entities/src/EntitiesAuditLogging.cpp b/libraries/entities/src/EntitiesAuditLogging.cpp index a07f3e42771..f52af6f51cf 100644 --- a/libraries/entities/src/EntitiesAuditLogging.cpp +++ b/libraries/entities/src/EntitiesAuditLogging.cpp @@ -11,4 +11,74 @@ #include "EntitiesAuditLogging.h" -Q_LOGGING_CATEGORY(entities_audit, "vircadia.entities.audit") +#include +#include + +Q_LOGGING_CATEGORY(entities_audit, "vircadia.entities.audit"); + +QJsonObject auditLogAddBuffer; +QJsonObject auditLogEditBuffer; +QTimer* auditLogProcessorTimer; + +void EntitiesAuditLogging::processAuditLogBuffers() { + if (!auditLogAddBuffer.isEmpty()) { + QJsonObject objectToOutput; + objectToOutput.insert("add", auditLogAddBuffer); + qCDebug(entities_audit) << objectToOutput; + auditLogAddBuffer = QJsonObject(); + } + if (!auditLogEditBuffer.isEmpty()) { + QJsonObject objectToOutput; + objectToOutput.insert("edit", auditLogEditBuffer); + qCDebug(entities_audit) << objectToOutput; + auditLogEditBuffer = QJsonObject(); + } +} + +void EntitiesAuditLogging::startAuditLogProcessor() { + auditLogProcessorTimer = new QTimer(this); + connect(auditLogProcessorTimer, &QTimer::timeout, this, &EntitiesAuditLogging::processAuditLogBuffers); + auditLogProcessorTimer->start(_auditEditLoggingInterval); +} + +void EntitiesAuditLogging::stopAuditLogProcessor() { + auditLogProcessorTimer->stop(); +} + +bool EntitiesAuditLogging::isProcessorRunning() { + if (!auditLogProcessorTimer) { + return false; + } else { + return true; + } +} + +void EntitiesAuditLogging::processAddEntityPacket(const QString& sender, const QString& entityID, const QString& entityType) { + QJsonValue findExisting = auditLogAddBuffer.take(sender); + if (!findExisting.isUndefined()) { + QJsonObject existingObject = findExisting.toObject(); + if (!existingObject.contains(entityID)) { + existingObject.insert(entityID, entityType); + } + auditLogAddBuffer.insert(sender, existingObject); + } else { + QJsonObject newEntry{ { entityID, entityType } }; + auditLogAddBuffer.insert(sender, newEntry); + } +} + +void EntitiesAuditLogging::processEditEntityPacket(const QString& sender, const QString& entityID) { + QJsonValue findExisting = auditLogEditBuffer.take(sender); + if (!findExisting.isUndefined()) { + QJsonObject existingObject = findExisting.toObject(); + if (!existingObject.contains(entityID)) { + existingObject.insert(entityID, 1); + } else { + existingObject[entityID] = existingObject[entityID].toInt() + 1; + } + auditLogEditBuffer.insert(sender, existingObject); + } else { + QJsonObject newEntry{ { entityID, 1 } }; + auditLogEditBuffer.insert(sender, newEntry); + } +} \ No newline at end of file diff --git a/libraries/entities/src/EntitiesAuditLogging.h b/libraries/entities/src/EntitiesAuditLogging.h index 3381e0b3e07..3cc7cd5679a 100644 --- a/libraries/entities/src/EntitiesAuditLogging.h +++ b/libraries/entities/src/EntitiesAuditLogging.h @@ -14,6 +14,22 @@ #include -Q_DECLARE_LOGGING_CATEGORY(entities_audit) +Q_DECLARE_LOGGING_CATEGORY(entities_audit); + +class EntitiesAuditLogging : public QObject { + Q_OBJECT +public: + bool isProcessorRunning(); + void startAuditLogProcessor(); + void stopAuditLogProcessor(); + void setAuditEditLoggingInterval(float interval) { _auditEditLoggingInterval = interval; }; + void processAddEntityPacket(const QString& sender, const QString& entityID, const QString& entityType); + void processEditEntityPacket(const QString& sender, const QString& entityID); + +private: + void processAuditLogBuffers(); + + float _auditEditLoggingInterval; +}; #endif // vircadia_EntitiesAuditLogging_h diff --git a/libraries/entities/src/EntitiesLogging.h b/libraries/entities/src/EntitiesLogging.h index 393c7f0e9ff..12f753e96a7 100644 --- a/libraries/entities/src/EntitiesLogging.h +++ b/libraries/entities/src/EntitiesLogging.h @@ -14,6 +14,6 @@ #include -Q_DECLARE_LOGGING_CATEGORY(entities) +Q_DECLARE_LOGGING_CATEGORY(entities); #endif // hifi_EntitiesLogging_h diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index f3067241304..b7087ad9266 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1797,33 +1797,8 @@ void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const } } -QJsonObject auditLogAddBuffer; -QJsonObject auditLogEditBuffer; -QTimer* auditLogProcessorTimer; - -void EntityTree::processAuditLogBuffers() { - if (!auditLogAddBuffer.isEmpty()) { - QJsonObject objectToOutput; - objectToOutput.insert("add", auditLogAddBuffer); - qCDebug(entities_audit) << objectToOutput; - auditLogAddBuffer = QJsonObject(); - } - if (!auditLogEditBuffer.isEmpty()) { - QJsonObject objectToOutput; - objectToOutput.insert("edit", auditLogEditBuffer); - qCDebug(entities_audit) << objectToOutput; - auditLogEditBuffer = QJsonObject(); - } -} - -void EntityTree::startAuditLogProcessor() { - auditLogProcessorTimer = new QTimer(this); - connect(auditLogProcessorTimer, &QTimer::timeout, this, &EntityTree::processAuditLogBuffers); - auditLogProcessorTimer->start(auditEditLoggingInterval()); -} - -void EntityTree::stopAuditLogProcessor() { - auditLogProcessorTimer->stop(); +void EntityTree::setAuditEditLoggingInterval(float interval) { + entitiesAuditLogProcessor.setAuditEditLoggingInterval(interval); } // NOTE: Caller must lock the tree before calling this. @@ -1833,8 +1808,9 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c qCWarning(entities) << "EntityTree::processEditPacketData() should only be called on a server tree."; return 0; } - if (wantAuditEditLogging() && !auditLogProcessorTimer) { - EntityTree::startAuditLogProcessor(); + + if (wantAuditEditLogging() && !entitiesAuditLogProcessor.isProcessorRunning()) { + entitiesAuditLogProcessor.startAuditLogProcessor(); } int processedBytes = 0; @@ -2039,21 +2015,8 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c qCDebug(entities) << " properties:" << properties; } if (wantAuditEditLogging()) { - HifiSockAddr senderSocket = senderNode->getPublicSocket(); - - QJsonValue findExisting = auditLogEditBuffer.take(senderSocket.toString()); - if (!findExisting.isUndefined()) { - QJsonObject existingObject = findExisting.toObject(); - if (!existingObject.contains(entityItemID.toString())) { - existingObject.insert(entityItemID.toString(), 1); - } else { - existingObject[entityItemID.toString()] = existingObject[entityItemID.toString()].toInt() + 1; - } - auditLogEditBuffer.insert(senderSocket.toString(), existingObject); - } else { - QJsonObject newEntry{ { entityItemID.toString(), 1 } }; - auditLogEditBuffer.insert(senderSocket.toString(), newEntry); - } + entitiesAuditLogProcessor.processEditEntityPacket(senderNode->getPublicSocket().toString(), + entityItemID.toString()); } if (wantTerseEditLogging()) { QList changedProperties = properties.listChangedProperties(); @@ -2135,21 +2098,9 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c qCDebug(entities) << " properties:" << properties; } if (wantAuditEditLogging()) { - HifiSockAddr senderSocket = senderNode->getPublicSocket(); - - QJsonValue findExisting = auditLogAddBuffer.take(senderSocket.toString()); - if (!findExisting.isUndefined()) { - QJsonObject existingObject = findExisting.toObject(); - if (!existingObject.contains(entityItemID.toString())) { - existingObject.insert(entityItemID.toString(), EntityTypes::getEntityTypeName(properties.getType())); - } - auditLogAddBuffer.insert(senderSocket.toString(), existingObject); - } else { - QJsonObject newEntry{ { - entityItemID.toString(), EntityTypes::getEntityTypeName(properties.getType()) - } }; - auditLogAddBuffer.insert(senderSocket.toString(), newEntry); - } + entitiesAuditLogProcessor.processAddEntityPacket(senderNode->getPublicSocket().toString(), + entityItemID.toString(), + EntityTypes::getEntityTypeName(properties.getType())); } if (wantTerseEditLogging()) { QList changedProperties = properties.listChangedProperties(); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index ad85e44953f..96569ae55dd 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -20,6 +20,7 @@ #include "AddEntityOperator.h" #include "EntityTreeElement.h" +#include "EntitiesAuditLogging.h" #include "DeleteEntityOperator.h" #include "MovingEntitiesOperator.h" @@ -193,9 +194,8 @@ class EntityTree : public Octree, public SpatialParentTree { bool wantAuditEditLogging() const { return _wantAuditEditLogging; } void setWantAuditEditLogging(bool value) { _wantAuditEditLogging = value; } - - float auditEditLoggingInterval() const { return _auditEditLoggingInterval; } - void setAuditEditLoggingInterval(float value) { _auditEditLoggingInterval = value; } + + void setAuditEditLoggingInterval(float value); bool wantTerseEditLogging() const { return _wantTerseEditLogging; } void setWantTerseEditLogging(bool value) { _wantTerseEditLogging = value; } @@ -399,10 +399,6 @@ class EntityTree : public Octree, public SpatialParentTree { void sendChallengeOwnershipRequestPacket(const QByteArray& id, const QByteArray& text, const QByteArray& nodeToChallenge, const SharedNodePointer& senderNode); void validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode); - void processAuditLogBuffers(); - void startAuditLogProcessor(); - void stopAuditLogProcessor(); - std::shared_ptr _myAvatar{ nullptr }; static std::function _getEntityObjectOperator; @@ -415,6 +411,8 @@ class EntityTree : public Octree, public SpatialParentTree { bool _serverlessDomain { false }; + EntitiesAuditLogging entitiesAuditLogProcessor; + std::map _namedPaths; // Return an AACube containing object and all its entity descendants From 45a629d3952dbc3227ea81f185a94119638d12d2 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Thu, 11 Feb 2021 01:39:09 -0500 Subject: [PATCH 5/7] Latest state. --- libraries/entities/src/EntitiesAuditLogging.cpp | 16 +++++----------- libraries/entities/src/EntitiesAuditLogging.h | 5 +++++ libraries/entities/src/EntityTree.cpp | 3 +++ libraries/entities/src/EntityTree.h | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/libraries/entities/src/EntitiesAuditLogging.cpp b/libraries/entities/src/EntitiesAuditLogging.cpp index f52af6f51cf..a4511a50aee 100644 --- a/libraries/entities/src/EntitiesAuditLogging.cpp +++ b/libraries/entities/src/EntitiesAuditLogging.cpp @@ -16,11 +16,8 @@ Q_LOGGING_CATEGORY(entities_audit, "vircadia.entities.audit"); -QJsonObject auditLogAddBuffer; -QJsonObject auditLogEditBuffer; -QTimer* auditLogProcessorTimer; - void EntitiesAuditLogging::processAuditLogBuffers() { + qDebug() << "PROCESSING..."; if (!auditLogAddBuffer.isEmpty()) { QJsonObject objectToOutput; objectToOutput.insert("add", auditLogAddBuffer); @@ -36,21 +33,18 @@ void EntitiesAuditLogging::processAuditLogBuffers() { } void EntitiesAuditLogging::startAuditLogProcessor() { - auditLogProcessorTimer = new QTimer(this); + auditLogProcessorTimer = new QTimer(); connect(auditLogProcessorTimer, &QTimer::timeout, this, &EntitiesAuditLogging::processAuditLogBuffers); auditLogProcessorTimer->start(_auditEditLoggingInterval); } void EntitiesAuditLogging::stopAuditLogProcessor() { - auditLogProcessorTimer->stop(); + delete auditLogProcessorTimer; + auditLogProcessorTimer = NULL; } bool EntitiesAuditLogging::isProcessorRunning() { - if (!auditLogProcessorTimer) { - return false; - } else { - return true; - } + return auditLogProcessorTimer; } void EntitiesAuditLogging::processAddEntityPacket(const QString& sender, const QString& entityID, const QString& entityType) { diff --git a/libraries/entities/src/EntitiesAuditLogging.h b/libraries/entities/src/EntitiesAuditLogging.h index 3cc7cd5679a..5157b0ec850 100644 --- a/libraries/entities/src/EntitiesAuditLogging.h +++ b/libraries/entities/src/EntitiesAuditLogging.h @@ -13,6 +13,8 @@ #define vircadia_EntitiesAuditLogging_h #include +#include +#include Q_DECLARE_LOGGING_CATEGORY(entities_audit); @@ -29,6 +31,9 @@ class EntitiesAuditLogging : public QObject { private: void processAuditLogBuffers(); + QJsonObject auditLogAddBuffer; + QJsonObject auditLogEditBuffer; + QTimer* auditLogProcessorTimer; float _auditEditLoggingInterval; }; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index b7087ad9266..39fecb16ec5 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -67,6 +67,7 @@ EntityTree::~EntityTree() { // TODO: EntityTreeElement::_tree should be raw back pointer. // AND: EntityItem::_element should be a raw back pointer. //eraseAllOctreeElements(false); // KEEP THIS + entitiesAuditLogProcessor.stopAuditLogProcessor(); } void EntityTree::setEntityScriptSourceWhitelist(const QString& entityScriptSourceWhitelist) { @@ -1813,6 +1814,8 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c entitiesAuditLogProcessor.startAuditLogProcessor(); } + qDebug() << "PROCESSING" << wantAuditEditLogging() << " - " << entitiesAuditLogProcessor.isProcessorRunning(); + int processedBytes = 0; bool isAdd = false; bool isClone = false; diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 96569ae55dd..7cf56568b45 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -347,7 +347,7 @@ class EntityTree : public Octree, public SpatialParentTree { EntitySimulationPointer _simulation; bool _wantEditLogging = false; - bool _wantAuditEditLogging = true; + bool _wantAuditEditLogging { false }; float _auditEditLoggingInterval { DEFAULT_AUDIT_EDIT_INTERVAL }; bool _wantTerseEditLogging = false; From 4692b7ecb69aa43a5ba02c907b7b98af35c69ebd Mon Sep 17 00:00:00 2001 From: Kalila L Date: Fri, 19 Mar 2021 06:24:43 -0400 Subject: [PATCH 6/7] Further state. --- .../entities/src/EntitiesAuditLogging.cpp | 24 +++++++++++++------ libraries/entities/src/EntitiesAuditLogging.h | 4 +++- libraries/entities/src/EntityTree.cpp | 2 +- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/libraries/entities/src/EntitiesAuditLogging.cpp b/libraries/entities/src/EntitiesAuditLogging.cpp index a4511a50aee..6419420c8c3 100644 --- a/libraries/entities/src/EntitiesAuditLogging.cpp +++ b/libraries/entities/src/EntitiesAuditLogging.cpp @@ -16,8 +16,11 @@ Q_LOGGING_CATEGORY(entities_audit, "vircadia.entities.audit"); +EntitiesAuditLogging::~EntitiesAuditLogging() { + EntitiesAuditLogging::stopAuditLogProcessor(); +} + void EntitiesAuditLogging::processAuditLogBuffers() { - qDebug() << "PROCESSING..."; if (!auditLogAddBuffer.isEmpty()) { QJsonObject objectToOutput; objectToOutput.insert("add", auditLogAddBuffer); @@ -33,18 +36,25 @@ void EntitiesAuditLogging::processAuditLogBuffers() { } void EntitiesAuditLogging::startAuditLogProcessor() { - auditLogProcessorTimer = new QTimer(); - connect(auditLogProcessorTimer, &QTimer::timeout, this, &EntitiesAuditLogging::processAuditLogBuffers); - auditLogProcessorTimer->start(_auditEditLoggingInterval); + _auditLogProcessorTimer = new QTimer(); + connect(_auditLogProcessorTimer, &QTimer::timeout, this, &EntitiesAuditLogging::processAuditLogBuffers); + _auditLogProcessorTimer->start(_auditEditLoggingInterval); } void EntitiesAuditLogging::stopAuditLogProcessor() { - delete auditLogProcessorTimer; - auditLogProcessorTimer = NULL; + if (_auditLogProcessorTimer) { + _auditLogProcessorTimer->stop(); + _auditLogProcessorTimer->deleteLater(); + _auditLogProcessorTimer = nullptr; + } } bool EntitiesAuditLogging::isProcessorRunning() { - return auditLogProcessorTimer; + if (_auditLogProcessorTimer != NULL && _auditLogProcessorTimer && _auditLogProcessorTimer->isActive()) { + return true; + } else { + return false; + } } void EntitiesAuditLogging::processAddEntityPacket(const QString& sender, const QString& entityID, const QString& entityType) { diff --git a/libraries/entities/src/EntitiesAuditLogging.h b/libraries/entities/src/EntitiesAuditLogging.h index 5157b0ec850..d4ce8e13e07 100644 --- a/libraries/entities/src/EntitiesAuditLogging.h +++ b/libraries/entities/src/EntitiesAuditLogging.h @@ -21,6 +21,8 @@ Q_DECLARE_LOGGING_CATEGORY(entities_audit); class EntitiesAuditLogging : public QObject { Q_OBJECT public: + virtual ~EntitiesAuditLogging(); + bool isProcessorRunning(); void startAuditLogProcessor(); void stopAuditLogProcessor(); @@ -33,7 +35,7 @@ class EntitiesAuditLogging : public QObject { QJsonObject auditLogAddBuffer; QJsonObject auditLogEditBuffer; - QTimer* auditLogProcessorTimer; + QTimer* _auditLogProcessorTimer; float _auditEditLoggingInterval; }; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 39fecb16ec5..03ad011121d 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -67,7 +67,7 @@ EntityTree::~EntityTree() { // TODO: EntityTreeElement::_tree should be raw back pointer. // AND: EntityItem::_element should be a raw back pointer. //eraseAllOctreeElements(false); // KEEP THIS - entitiesAuditLogProcessor.stopAuditLogProcessor(); + qCDebug(entities) << "Killing entityTree..."; } void EntityTree::setEntityScriptSourceWhitelist(const QString& entityScriptSourceWhitelist) { From d2a319b59b06144f295823386568cf2e5f7d6afa Mon Sep 17 00:00:00 2001 From: Kalila L Date: Fri, 19 Mar 2021 07:09:04 -0400 Subject: [PATCH 7/7] Fixed crashing, I think... --- libraries/entities/src/EntitiesAuditLogging.cpp | 2 +- libraries/entities/src/EntitiesAuditLogging.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntitiesAuditLogging.cpp b/libraries/entities/src/EntitiesAuditLogging.cpp index 6419420c8c3..d3ae2f72adc 100644 --- a/libraries/entities/src/EntitiesAuditLogging.cpp +++ b/libraries/entities/src/EntitiesAuditLogging.cpp @@ -50,7 +50,7 @@ void EntitiesAuditLogging::stopAuditLogProcessor() { } bool EntitiesAuditLogging::isProcessorRunning() { - if (_auditLogProcessorTimer != NULL && _auditLogProcessorTimer && _auditLogProcessorTimer->isActive()) { + if (_auditLogProcessorTimer && _auditLogProcessorTimer != NULL && _auditLogProcessorTimer->isActive()) { return true; } else { return false; diff --git a/libraries/entities/src/EntitiesAuditLogging.h b/libraries/entities/src/EntitiesAuditLogging.h index d4ce8e13e07..126af281e07 100644 --- a/libraries/entities/src/EntitiesAuditLogging.h +++ b/libraries/entities/src/EntitiesAuditLogging.h @@ -35,7 +35,7 @@ class EntitiesAuditLogging : public QObject { QJsonObject auditLogAddBuffer; QJsonObject auditLogEditBuffer; - QTimer* _auditLogProcessorTimer; + QTimer* _auditLogProcessorTimer { nullptr }; float _auditEditLoggingInterval; };