Skip to content

Commit

Permalink
Allow json tracing to go to files instead of just logs (#27628)
Browse files Browse the repository at this point in the history
* Rename log_json to just json

* Add file output option for json tracing

* make the output look like a json array when outputing to file

* Restyle

* Fix support of "json:log"

* Fix support of "json:log"

* Rename open/close to openfile/closefile to avoid override errors

* Restyle

* StartsWith should be available now globally as it is always used

* Forward declare json to make arm cross compile pass

* Restyle

* Add json_tracing exceptions for includes checks
  • Loading branch information
andy31415 authored and pull[bot] committed Jan 9, 2024
1 parent c07f497 commit 2567361
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 67 deletions.
2 changes: 1 addition & 1 deletion examples/common/tracing/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ source_set("commandline") {
deps = [
"${chip_root}/src/lib/support",
"${chip_root}/src/tracing",
"${chip_root}/src/tracing/log_json",
"${chip_root}/src/tracing/json",
]

public_deps = [ ":tracing_features" ]
Expand Down
25 changes: 18 additions & 7 deletions examples/common/tracing/TracingCommandLineArgument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#include <lib/support/StringSplitter.h>
#include <lib/support/logging/CHIPLogging.h>
#include <tracing/log_json/log_json_tracing.h>
#include <tracing/json/json_tracing.h>
#include <tracing/registry.h>

#if ENABLE_PERFETTO_TRACING
Expand All @@ -34,7 +34,6 @@ namespace chip {
namespace CommandLineApp {

namespace {
#if ENABLE_PERFETTO_TRACING

bool StartsWith(CharSpan argument, const char * prefix)
{
Expand All @@ -48,8 +47,6 @@ bool StartsWith(CharSpan argument, const char * prefix)
return argument.data_equal(CharSpan(prefix, prefix_len));
}

#endif

} // namespace

void TracingSetup::EnableTracingFor(const char * cliArg)
Expand All @@ -59,9 +56,23 @@ void TracingSetup::EnableTracingFor(const char * cliArg)

while (splitter.Next(value))
{
if (value.data_equal(CharSpan::fromCharString("log")))
if (StartsWith(value, "json:"))
{
chip::Tracing::Register(mLogJsonBackend);
std::string fileName(value.data() + 5, value.size() - 5);

if (fileName != "log")
{
CHIP_ERROR err = mJsonBackend.OpenFile(fileName.c_str());
if (err != CHIP_NO_ERROR)
{
ChipLogError(AppServer, "Failed to open json trace output: %" CHIP_ERROR_FORMAT, err.Format());
}
}
else
{
mJsonBackend.CloseFile(); // just in case, ensure no file output
}
chip::Tracing::Register(mJsonBackend);
}
#if ENABLE_PERFETTO_TRACING
else if (value.data_equal(CharSpan::fromCharString("perfetto")))
Expand Down Expand Up @@ -101,7 +112,7 @@ void TracingSetup::StopTracing()

#endif

chip::Tracing::Unregister(mLogJsonBackend);
chip::Tracing::Unregister(mJsonBackend);
}

} // namespace CommandLineApp
Expand Down
10 changes: 5 additions & 5 deletions examples/common/tracing/TracingCommandLineArgument.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#include "tracing/enabled_features.h"

#include <tracing/log_json/log_json_tracing.h>
#include <tracing/json/json_tracing.h>

#if ENABLE_PERFETTO_TRACING
#include <tracing/perfetto/file_output.h> // nogncheck
Expand All @@ -29,9 +29,9 @@
/// A string with supported command line tracing targets
/// to be pretty-printed in help strings if needed
#if ENABLE_PERFETTO_TRACING
#define SUPPORTED_COMMAND_LINE_TRACING_TARGETS "log, perfetto, perfetto:<path>"
#define SUPPORTED_COMMAND_LINE_TRACING_TARGETS "json:log, json:<path> perfetto, perfetto:<path>"
#else
#define SUPPORTED_COMMAND_LINE_TRACING_TARGETS "log"
#define SUPPORTED_COMMAND_LINE_TRACING_TARGETS "json:log, json:<path>"
#endif

namespace chip {
Expand All @@ -44,7 +44,7 @@ class TracingSetup
~TracingSetup() { StopTracing(); }

/// Enable tracing based on the given command line argument
/// like "log" or "log,perfetto" or similar
/// like "json:log" or "json:/tmp/foo.txt,perfetto" or similar
///
/// Single arguments as well as comma separated ones are accepted.
///
Expand All @@ -57,7 +57,7 @@ class TracingSetup
void StopTracing();

private:
::chip::Tracing::LogJson::LogJsonBackend mLogJsonBackend;
::chip::Tracing::Json::JsonBackend mJsonBackend;

#if ENABLE_PERFETTO_TRACING
chip::Tracing::Perfetto::FileTraceOutput mPerfettoFileOutput;
Expand Down
2 changes: 1 addition & 1 deletion examples/tv-casting-app/tv-casting-common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ chip_data_model("tv-casting-common") {
"${chip_root}/src/app/tests/suites/commands/interaction_model",
"${chip_root}/src/lib/support/jsontlv",
"${chip_root}/src/tracing",
"${chip_root}/src/tracing/log_json",
"${chip_root}/src/tracing/json",
"${chip_root}/third_party/inipp",
"${chip_root}/third_party/jsoncpp",
]
Expand Down
3 changes: 2 additions & 1 deletion scripts/tools/check_includes_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,5 +156,6 @@
'src/controller/ExamplePersistentStorage.cpp': {'fstream'},

# Library meant for non-embedded
'src/tracing/log_json/log_json_tracing.cpp': {'string', 'sstream'}
'src/tracing/json/json_tracing.cpp': {'string', 'sstream'},
'src/tracing/json/json_tracing.h': {'fstream'}
}
6 changes: 3 additions & 3 deletions src/tracing/log_json/BUILD.gn → src/tracing/json/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import("//build_overrides/chip.gni")

# As this uses std::string, this library is NOT for use
# for embedded devices.
static_library("log_json") {
static_library("json") {
sources = [
"log_json_tracing.cpp",
"log_json_tracing.h",
"json_tracing.cpp",
"json_tracing.h",
]

public_deps = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* limitations under the License.
*/

#include <tracing/log_json/log_json_tracing.h>
#include <tracing/json/json_tracing.h>

#include <lib/address_resolve/TracingStructs.h>
#include <lib/support/ErrorStr.h>
Expand All @@ -25,31 +25,20 @@

#include <json/json.h>

#include <errno.h>

#include <sstream>
#include <string>

namespace chip {
namespace Tracing {
namespace LogJson {
namespace Json {

namespace {

using chip::StringBuilder;

/// Writes the given value to chip log
void LogJsonValue(Json::Value const & value)
{
Json::StreamWriterBuilder builder;

std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
std::stringstream output;

writer->write(value, &output);

ChipLogProgress(Automation, "%s", output.str().c_str());
}

void DecodePayloadHeader(Json::Value & value, const PayloadHeader * payloadHeader)
void DecodePayloadHeader(::Json::Value & value, const PayloadHeader * payloadHeader)
{

value["exchangeFlags"] = payloadHeader->GetExchangeFlags();
Expand All @@ -66,7 +55,7 @@ void DecodePayloadHeader(Json::Value & value, const PayloadHeader * payloadHeade
}
}

void DecodePacketHeader(Json::Value & value, const PacketHeader * packetHeader)
void DecodePacketHeader(::Json::Value & value, const PacketHeader * packetHeader)
{
value["msgCounter"] = packetHeader->GetMessageCounter();
value["sessionId"] = packetHeader->GetSessionId();
Expand Down Expand Up @@ -98,46 +87,52 @@ void DecodePacketHeader(Json::Value & value, const PacketHeader * packetHeader)
}
}

void DecodePayloadData(Json::Value & value, chip::ByteSpan payload)
void DecodePayloadData(::Json::Value & value, chip::ByteSpan payload)
{
value["payloadSize"] = static_cast<Json::Value::UInt>(payload.size());
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(const char * label, const char * group)
JsonBackend::~JsonBackend()
{
CloseFile();
}

void JsonBackend::TraceBegin(const char * label, const char * group)
{
Json::Value value;
::Json::Value value;

value["event"] = "TraceBegin";
value["label"] = label;
value["group"] = group;
LogJsonValue(value);
OutputValue(value);
}

void LogJsonBackend::TraceEnd(const char * label, const char * group)
void JsonBackend::TraceEnd(const char * label, const char * group)
{
Json::Value value;
::Json::Value value;
value["event"] = "TraceEnd";
value["label"] = label;
value["group"] = group;
LogJsonValue(value);
OutputValue(value);
}

void LogJsonBackend::TraceInstant(const char * label, const char * group)
void JsonBackend::TraceInstant(const char * label, const char * group)
{
Json::Value value;
::Json::Value value;
value["event"] = "TraceInstant";
value["label"] = label;
value["group"] = group;
LogJsonValue(value);
OutputValue(value);
}

void LogJsonBackend::LogMessageSend(MessageSendInfo & info)
void JsonBackend::LogMessageSend(MessageSendInfo & info)
{
Json::Value value;
::Json::Value value;
value["event"] = "MessageSend";

switch (info.messageType)
Expand All @@ -157,12 +152,12 @@ void LogJsonBackend::LogMessageSend(MessageSendInfo & info)
DecodePacketHeader(value["packetHeader"], info.packetHeader);
DecodePayloadData(value["payload"], info.payload);

LogJsonValue(value);
OutputValue(value);
}

void LogJsonBackend::LogMessageReceived(MessageReceivedInfo & info)
void JsonBackend::LogMessageReceived(MessageReceivedInfo & info)
{
Json::Value value;
::Json::Value value;

value["event"] = "MessageReceived";

Expand All @@ -183,25 +178,25 @@ void LogJsonBackend::LogMessageReceived(MessageReceivedInfo & info)
DecodePacketHeader(value["packetHeader"], info.packetHeader);
DecodePayloadData(value["payload"], info.payload);

LogJsonValue(value);
OutputValue(value);
}

void LogJsonBackend::LogNodeLookup(NodeLookupInfo & info)
void JsonBackend::LogNodeLookup(NodeLookupInfo & info)
{
Json::Value value;
::Json::Value value;

value["event"] = "LogNodeLookup";
value["node_id"] = info.request->GetPeerId().GetNodeId();
value["compressed_fabric_id"] = info.request->GetPeerId().GetCompressedFabricId();
value["min_lookup_time_ms"] = info.request->GetMinLookupTime().count();
value["max_lookup_time_ms"] = info.request->GetMaxLookupTime().count();

LogJsonValue(value);
OutputValue(value);
}

void LogJsonBackend::LogNodeDiscovered(NodeDiscoveredInfo & info)
void JsonBackend::LogNodeDiscovered(NodeDiscoveredInfo & info)
{
Json::Value value;
::Json::Value value;
value["event"] = "LogNodeDiscovered";

value["node_id"] = info.peerId->GetNodeId();
Expand All @@ -221,7 +216,7 @@ void LogJsonBackend::LogNodeDiscovered(NodeDiscoveredInfo & info)
}

{
Json::Value result;
::Json::Value result;

char address_buff[chip::Transport::PeerAddress::kMaxToStringSize];

Expand All @@ -236,21 +231,76 @@ void LogJsonBackend::LogNodeDiscovered(NodeDiscoveredInfo & info)
value["result"] = result;
}

LogJsonValue(value);
OutputValue(value);
}

void LogJsonBackend::LogNodeDiscoveryFailed(NodeDiscoveryFailedInfo & info)
void JsonBackend::LogNodeDiscoveryFailed(NodeDiscoveryFailedInfo & info)
{
Json::Value value;
::Json::Value value;

value["event"] = "LogNodeDiscoveryFailed";
value["node_id"] = info.peerId->GetNodeId();
value["compressed_fabric_id"] = info.peerId->GetCompressedFabricId();
value["error"] = chip::ErrorStr(info.error);

LogJsonValue(value);
OutputValue(value);
}

void JsonBackend::CloseFile()
{
if (!mOutputFile.is_open())
{
return;
}

mOutputFile << "]\n";

mOutputFile.close();
}

CHIP_ERROR JsonBackend::OpenFile(const char * path)
{
CloseFile();
mOutputFile.open(path, std::ios_base::out);

if (!mOutputFile)
{
return CHIP_ERROR_POSIX(errno);
}

mOutputFile << "[\n";
mFirstRecord = true;

return CHIP_NO_ERROR;
}

void JsonBackend::OutputValue(::Json::Value & value)
{
::Json::StreamWriterBuilder builder;
std::unique_ptr<::Json::StreamWriter> writer(builder.newStreamWriter());

if (mOutputFile.is_open())
{
if (!mFirstRecord)
{
mOutputFile << ",\n";
}
else
{
mFirstRecord = false;
}
value["time_ms"] = chip::System::SystemClock().GetMonotonicTimestamp().count();
writer->write(value, &mOutputFile);
mOutputFile.flush();
}
else
{
std::stringstream output;
writer->write(value, &output);
ChipLogProgress(Automation, "%s", output.str().c_str());
}
}

} // namespace LogJson
} // namespace Json
} // namespace Tracing
} // namespace chip
Loading

0 comments on commit 2567361

Please sign in to comment.