Add data logging using the tracing module for message send/receive (#27281)
* Add message loging structures and definitions
* Run clang-format
* Fix a comment
* Restyled by clang-format
* Fix dependencies in build.gn
* Fix compile error for mac .. size_t cannot be easilu converted and we know size fits in a UInt
* Fix typo
---------
Co-authored-by: Andrei Litvin <andreilitvin@google.com>
Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/examples/common/tracing/TraceHandlers.cpp b/examples/common/tracing/TraceHandlers.cpp
index 373b00c..d595580 100644
--- a/examples/common/tracing/TraceHandlers.cpp
+++ b/examples/common/tracing/TraceHandlers.cpp
@@ -199,7 +199,7 @@
std::string jsonBody;
- uint8_t exchangeFlags = payloadHeader->GetExhangeFlags();
+ uint8_t exchangeFlags = payloadHeader->GetExchangeFlags();
jsonBody += AsFirstJsonKey("exchange_flags", std::to_string(exchangeFlags));
uint16_t exchangeId = payloadHeader->GetExchangeID();
diff --git a/src/tracing/backend.h b/src/tracing/backend.h
index bc6501d..adf6b75 100644
--- a/src/tracing/backend.h
+++ b/src/tracing/backend.h
@@ -58,7 +58,7 @@
virtual void TraceInstant(Instant instant) = 0;
virtual void LogMessageSend(MessageSendInfo &) { TraceInstant(Instant::Log_MessageSend); }
- virtual void LogMessageReceived(MessageReceiveInfo &) { TraceInstant(Instant::Log_MessageReceived); }
+ virtual void LogMessageReceived(MessageReceivedInfo &) { TraceInstant(Instant::Log_MessageReceived); }
virtual void LogNodeLookup(NodeLookupInfo &) { TraceInstant(Instant::Log_NodeLookup); }
virtual void LogNodeDiscovered(NodeDiscoveredInfo &) { TraceInstant(Instant::Log_NodeDiscovered); }
diff --git a/src/tracing/log_declares.h b/src/tracing/log_declares.h
index 8cc4e11..5e502d0 100644
--- a/src/tracing/log_declares.h
+++ b/src/tracing/log_declares.h
@@ -23,7 +23,7 @@
// on actual types. This allows tracing to be used anywhere lib/support could be used.
struct MessageSendInfo;
-struct MessageReceiveInfo;
+struct MessageReceivedInfo;
struct NodeLookupInfo;
struct NodeDiscoveredInfo;
struct NodeDiscoveryFailedInfo;
diff --git a/src/tracing/log_json/BUILD.gn b/src/tracing/log_json/BUILD.gn
index 1b8a3c8..655fda8 100644
--- a/src/tracing/log_json/BUILD.gn
+++ b/src/tracing/log_json/BUILD.gn
@@ -26,6 +26,7 @@
public_deps = [
"${chip_root}/src/lib/address_resolve",
"${chip_root}/src/tracing",
+ "${chip_root}/src/transport",
"${chip_root}/third_party/jsoncpp",
]
}
diff --git a/src/tracing/log_json/log_json_tracing.cpp b/src/tracing/log_json/log_json_tracing.cpp
index 2a89300..933009d 100644
--- a/src/tracing/log_json/log_json_tracing.cpp
+++ b/src/tracing/log_json/log_json_tracing.cpp
@@ -21,6 +21,7 @@
#include <lib/address_resolve/TracingStructs.h>
#include <lib/support/ErrorStr.h>
#include <lib/support/StringBuilder.h>
+#include <transport/TracingStructs.h>
#include <json/json.h>
@@ -219,6 +220,63 @@
ChipLogProgress(Automation, "%s", output.str().c_str());
}
+void DecodePayloadHeader(Json::Value & value, const PayloadHeader * payloadHeader)
+{
+
+ value["exchangeFlags"] = payloadHeader->GetExchangeFlags();
+ value["exchangeId"] = payloadHeader->GetExchangeID();
+ value["protocolId"] = payloadHeader->GetProtocolID().ToFullyQualifiedSpecForm();
+ value["messageType"] = payloadHeader->GetMessageType();
+ value["initiator"] = payloadHeader->IsInitiator();
+ value["needsAck"] = payloadHeader->NeedsAck();
+
+ const Optional<uint32_t> & acknowledgedMessageCounter = payloadHeader->GetAckMessageCounter();
+ if (acknowledgedMessageCounter.HasValue())
+ {
+ value["ackMessageCounter"] = acknowledgedMessageCounter.Value();
+ }
+}
+
+void DecodePacketHeader(Json::Value & value, const PacketHeader * packetHeader)
+{
+ value["msgCounter"] = packetHeader->GetMessageCounter();
+ value["sessionId"] = packetHeader->GetSessionId();
+ value["flags"] = packetHeader->GetMessageFlags();
+ value["securityFlags"] = packetHeader->GetSecurityFlags();
+
+ {
+ const Optional<NodeId> & nodeId = packetHeader->GetSourceNodeId();
+ if (nodeId.HasValue())
+ {
+ value["sourceNodeId"] = nodeId.Value();
+ }
+ }
+
+ {
+ const Optional<NodeId> & nodeId = packetHeader->GetDestinationNodeId();
+ if (nodeId.HasValue())
+ {
+ value["destinationNodeId"] = nodeId.Value();
+ }
+ }
+
+ {
+ const Optional<GroupId> & groupId = packetHeader->GetDestinationGroupId();
+ if (groupId.HasValue())
+ {
+ value["groupId"] = groupId.Value();
+ }
+ }
+}
+
+void DecodePayloadData(Json::Value & value, chip::ByteSpan payload)
+{
+ value["payloadSize"] = static_cast<Json::Value::UInt>(payload.size());
+
+ // TODO: a decode would be useful however it likely requires more decode
+ // metadata
+}
+
} // namespace
void LogJsonBackend::TraceBegin(Scope scope)
@@ -245,17 +303,54 @@
LogJsonValue(value);
}
-void LogJsonBackend::LogMessageSend(MessageSendInfo &)
+void LogJsonBackend::LogMessageSend(MessageSendInfo & info)
{
Json::Value value;
- value["TODO"] = "LogMessageSend";
+ value["event"] = "MessageSend";
+
+ switch (info.messageType)
+ {
+ case OutgoingMessageType::kGroupMessage:
+ value["messageType"] = "Group";
+ break;
+ case OutgoingMessageType::kSecureSession:
+ value["messageType"] = "Secure";
+ break;
+ case OutgoingMessageType::kUnauthenticated:
+ value["messageType"] = "Unauthenticated";
+ break;
+ }
+
+ DecodePayloadHeader(value["payloadHeader"], info.payloadHeader);
+ DecodePacketHeader(value["packetHeader"], info.packetHeader);
+ DecodePayloadData(value["payload"], info.payload);
+
LogJsonValue(value);
}
-void LogJsonBackend::LogMessageReceived(MessageReceiveInfo &)
+void LogJsonBackend::LogMessageReceived(MessageReceivedInfo & info)
{
Json::Value value;
- value["TODO"] = "LogMessageReceived";
+
+ value["event"] = "MessageReceived";
+
+ switch (info.messageType)
+ {
+ case IncomingMessageType::kGroupMessage:
+ value["messageType"] = "Group";
+ break;
+ case IncomingMessageType::kSecureUnicast:
+ value["messageType"] = "Secure";
+ break;
+ case IncomingMessageType::kUnauthenticated:
+ value["messageType"] = "Unauthenticated";
+ break;
+ }
+
+ DecodePayloadHeader(value["payloadHeader"], info.payloadHeader);
+ DecodePacketHeader(value["packetHeader"], info.packetHeader);
+ DecodePayloadData(value["payload"], info.payload);
+
LogJsonValue(value);
}
diff --git a/src/tracing/log_json/log_json_tracing.h b/src/tracing/log_json/log_json_tracing.h
index ca15c8f..ef462c9 100644
--- a/src/tracing/log_json/log_json_tracing.h
+++ b/src/tracing/log_json/log_json_tracing.h
@@ -35,7 +35,7 @@
void TraceEnd(Scope scope) override;
void TraceInstant(Instant instant) override;
void LogMessageSend(MessageSendInfo &) override;
- void LogMessageReceived(MessageReceiveInfo &) override;
+ void LogMessageReceived(MessageReceivedInfo &) override;
void LogNodeLookup(NodeLookupInfo &) override;
void LogNodeDiscovered(NodeDiscoveredInfo &) override;
void LogNodeDiscoveryFailed(NodeDiscoveryFailedInfo &) override;
diff --git a/src/tracing/registry.cpp b/src/tracing/registry.cpp
index f3497a2..bb98623 100644
--- a/src/tracing/registry.cpp
+++ b/src/tracing/registry.cpp
@@ -74,7 +74,7 @@
}
}
-void LogMessageReceived(::chip::Tracing::MessageReceiveInfo & info)
+void LogMessageReceived(::chip::Tracing::MessageReceivedInfo & info)
{
for (auto & backend : gTracingBackends)
{
diff --git a/src/tracing/registry.h b/src/tracing/registry.h
index b159614..b3a5a6a 100644
--- a/src/tracing/registry.h
+++ b/src/tracing/registry.h
@@ -64,7 +64,7 @@
void Instant(::chip::Tracing::Instant instant);
void LogMessageSend(::chip::Tracing::MessageSendInfo & info);
-void LogMessageReceived(::chip::Tracing::MessageReceiveInfo & info);
+void LogMessageReceived(::chip::Tracing::MessageReceivedInfo & info);
void LogNodeLookup(::chip::Tracing::NodeLookupInfo & info);
void LogNodeDiscovered(::chip::Tracing::NodeDiscoveredInfo & info);
void LogNodeDiscoveryFailed(::chip::Tracing::NodeDiscoveryFailedInfo & info);
diff --git a/src/transport/BUILD.gn b/src/transport/BUILD.gn
index a632f41..70168e6 100644
--- a/src/transport/BUILD.gn
+++ b/src/transport/BUILD.gn
@@ -45,6 +45,7 @@
"SessionManager.h",
"SessionMessageCounter.h",
"SessionMessageDelegate.h",
+ "TracingStructs.h",
"TransportMgr.h",
"TransportMgrBase.cpp",
"TransportMgrBase.h",
@@ -64,6 +65,7 @@
"${chip_root}/src/lib/support",
"${chip_root}/src/platform",
"${chip_root}/src/setup_payload",
+ "${chip_root}/src/tracing",
"${chip_root}/src/transport/raw",
"${nlio_root}:nlio",
]
diff --git a/src/transport/SessionManager.cpp b/src/transport/SessionManager.cpp
index 1aba11a..30494b0 100644
--- a/src/transport/SessionManager.cpp
+++ b/src/transport/SessionManager.cpp
@@ -40,9 +40,11 @@
#include <platform/CHIPDeviceLayer.h>
#include <protocols/Protocols.h>
#include <protocols/secure_channel/Constants.h>
+#include <tracing/macros.h>
#include <transport/GroupPeerMessageCounter.h>
#include <transport/GroupSession.h>
#include <transport/SecureMessageCodec.h>
+#include <transport/TracingStructs.h>
#include <transport/TransportMgr.h>
// Global object
@@ -178,6 +180,9 @@
}
// Trace before any encryption
+ MATTER_LOG_MESSAGE_SEND(chip::Tracing::OutgoingMessageType::kGroupMessage, &payloadHeader, &packetHeader,
+ chip::ByteSpan(message->Start(), message->TotalLength()));
+
CHIP_TRACE_MESSAGE_SENT(payloadHeader, packetHeader, message->Start(), message->TotalLength());
Crypto::SymmetricKeyContext * keyContext =
@@ -213,6 +218,8 @@
.SetSessionType(Header::SessionType::kUnicastSession);
// Trace before any encryption
+ MATTER_LOG_MESSAGE_SEND(chip::Tracing::OutgoingMessageType::kSecureSession, &payloadHeader, &packetHeader,
+ chip::ByteSpan(message->Start(), message->TotalLength()));
CHIP_TRACE_MESSAGE_SENT(payloadHeader, packetHeader, message->Start(), message->TotalLength());
CryptoContext::NonceStorage nonce;
@@ -244,6 +251,8 @@
}
// Trace after all headers are settled.
+ MATTER_LOG_MESSAGE_SEND(chip::Tracing::OutgoingMessageType::kUnauthenticated, &payloadHeader, &packetHeader,
+ chip::ByteSpan(message->Start(), message->TotalLength()));
CHIP_TRACE_MESSAGE_SENT(payloadHeader, packetHeader, message->Start(), message->TotalLength());
ReturnErrorOnFailure(payloadHeader.EncodeBeforeData(message));
@@ -641,12 +650,18 @@
// CHIP_ERROR_DUPLICATE_MESSAGE_RECEIVED.
unsecuredSession->GetPeerMessageCounter().CommitUnencrypted(packetHeader.GetMessageCounter());
}
-
if (mCB != nullptr)
{
+ MATTER_LOG_MESSAGE_RECEIVED(chip::Tracing::IncomingMessageType::kUnauthenticated, &payloadHeader, &packetHeader,
+ unsecuredSession, &peerAddress, chip::ByteSpan(msg->Start(), msg->TotalLength()));
+
CHIP_TRACE_MESSAGE_RECEIVED(payloadHeader, packetHeader, unsecuredSession, peerAddress, msg->Start(), msg->TotalLength());
mCB->OnMessageReceived(packetHeader, payloadHeader, session, isDuplicate, std::move(msg));
}
+ else
+ {
+ ChipLogError(Inet, "Received UNSECURED message was not processed.");
+ }
}
void SessionManager::SecureUnicastMessageDispatch(const PacketHeader & partialPacketHeader,
@@ -751,9 +766,15 @@
if (mCB != nullptr)
{
+ MATTER_LOG_MESSAGE_RECEIVED(chip::Tracing::IncomingMessageType::kSecureUnicast, &payloadHeader, &packetHeader,
+ secureSession, &peerAddress, chip::ByteSpan(msg->Start(), msg->TotalLength()));
CHIP_TRACE_MESSAGE_RECEIVED(payloadHeader, packetHeader, secureSession, peerAddress, msg->Start(), msg->TotalLength());
mCB->OnMessageReceived(packetHeader, payloadHeader, session.Value(), isDuplicate, std::move(msg));
}
+ else
+ {
+ ChipLogError(Inet, "Received SECURED message was not processed.");
+ }
}
/**
@@ -958,10 +979,18 @@
// TODO : When MCSP is done, clean up session creation logic
Transport::IncomingGroupSession groupSession(groupContext.group_id, groupContext.fabric_index,
packetHeaderCopy.GetSourceNodeId().Value());
+
+ MATTER_LOG_MESSAGE_RECEIVED(chip::Tracing::IncomingMessageType::kGroupMessage, &payloadHeader, &packetHeaderCopy,
+ &groupSession, &peerAddress, chip::ByteSpan(msg->Start(), msg->TotalLength()));
+
CHIP_TRACE_MESSAGE_RECEIVED(payloadHeader, packetHeaderCopy, &groupSession, peerAddress, msg->Start(), msg->TotalLength());
mCB->OnMessageReceived(packetHeaderCopy, payloadHeader, SessionHandle(groupSession),
SessionMessageDelegate::DuplicateMessage::No, std::move(msg));
}
+ else
+ {
+ ChipLogError(Inet, "Received GROUP message was not processed.");
+ }
}
Optional<SessionHandle> SessionManager::FindSecureSessionForNode(ScopedNodeId peerNodeId,
diff --git a/src/transport/TracingStructs.h b/src/transport/TracingStructs.h
new file mode 100644
index 0000000..5f57663
--- /dev/null
+++ b/src/transport/TracingStructs.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2023 Project CHIP Authors
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <lib/support/Span.h>
+#include <transport/Session.h>
+#include <transport/raw/MessageHeader.h>
+
+namespace chip {
+namespace Tracing {
+
+/// Concrete definitions of the message tracing info that session managers
+/// report
+
+enum class OutgoingMessageType
+{
+ kGroupMessage,
+ kSecureSession,
+ kUnauthenticated,
+};
+
+/// A message is about to be sent
+struct MessageSendInfo
+{
+ OutgoingMessageType messageType;
+ const PayloadHeader * payloadHeader;
+ const PacketHeader * packetHeader;
+ const chip::ByteSpan payload;
+};
+
+enum class IncomingMessageType
+{
+ kGroupMessage,
+ kSecureUnicast,
+ kUnauthenticated,
+};
+
+/// A message has been received
+struct MessageReceivedInfo
+{
+ const IncomingMessageType messageType;
+ const PayloadHeader * payloadHeader;
+ const PacketHeader * packetHeader;
+ const Transport::Session * session;
+ const Transport::PeerAddress * peerAddress;
+ const chip::ByteSpan payload;
+};
+
+} // namespace Tracing
+} // namespace chip
diff --git a/src/transport/raw/MessageHeader.h b/src/transport/raw/MessageHeader.h
index 4f78562..ec95731 100644
--- a/src/transport/raw/MessageHeader.h
+++ b/src/transport/raw/MessageHeader.h
@@ -511,7 +511,7 @@
uint8_t GetMessageType() const { return mMessageType; }
/** Get the raw exchange flags from this header. */
- uint8_t GetExhangeFlags() const { return mExchangeFlags.Raw(); }
+ uint8_t GetExchangeFlags() const { return mExchangeFlags.Raw(); }
/** Check whether the header has a given secure message type */
bool HasMessageType(uint8_t type) const { return mMessageType == type; }