Skip to content

Commit

Permalink
Add separate hookable tracing module (#26986)
Browse files Browse the repository at this point in the history
* Starting with some basic class declarations

* Start defining macros for building things

* implement a convenience method for scoping traces

* Restyle

* Prepare for some testing infrastructure for tracing

* Make code compile

* Implement some backend support

* Restyle

* We now have simple tracing unit tests

* More unit tests that work

* Add chip thread locking assertions

* more documentation

* Restyle

* Make spellchecker happy

* Restyle

* Minor comment fix

* Code review updates

* add numbers to scopes

* Add numeric values to instant tracing values

* Fix uniqueness for scopes

* Use std::vector and algorithm equals to make tidy happy

---------

Co-authored-by: Andrei Litvin <[email protected]>
  • Loading branch information
andy31415 and andreilitvin authored Jun 1, 2023
1 parent 860e934 commit dc8d5eb
Show file tree
Hide file tree
Showing 13 changed files with 860 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/.wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ AXXXF
AYNJV
babaf
backend
backends
backticks
backtrace
BallastConfiguration
Expand Down
1 change: 1 addition & 0 deletions src/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ if (chip_build_tests) {
"${chip_root}/src/lib/support/tests",
"${chip_root}/src/protocols/secure_channel/tests",
"${chip_root}/src/system/tests",
"${chip_root}/src/tracing/tests",
"${chip_root}/src/transport/tests",
]
}
Expand Down
42 changes: 42 additions & 0 deletions src/tracing/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright (c) 2023 Project CHIP Authors
#
# 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.

import("//build_overrides/build.gni")
import("//build_overrides/chip.gni")

declare_args() {
matter_enable_tracing_support = true
}

config("tracing_enabled") {
defines = [ "MATTER_TRACING_ENABLED" ]
}

static_library("tracing") {
sources = [
"backend.h",
"log_declares.h",
"macros.h",
"registry.cpp",
"registry.h",
"scope.h",
"scopes.h",
]

public_deps = [ "${chip_root}/src/lib/support" ]

if (matter_enable_tracing_support) {
public_configs = [ ":tracing_enabled" ]
}
}
44 changes: 44 additions & 0 deletions src/tracing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Matter tracing

This library provides a runtime-configurable tracing and logging infrastructure
for matter.

## Types of data

### Tracing

Tracing is mostly intended for following execution flow and measuring time spent
for various operations. They are:

- _scoped_ where separate begin and end events are emitted _or_

- _instant_ where a single notable event is emitted, representing a point in
time of a notable event

Tracing and instant values are set to know enumeration values at compile time,
to allow implementation of backends that require compile-time strings for their
tracing.

### Data Logging

Data logging provides the tracing module the opportunity to report input/output
data for matter data processing.

The data logging is generally limited in count and covers:

- _Messages_, specifically sent matter requests and received matter responses

- _DNSSD_ operations as they are a core component of matter, specifically
attempts to discover nodes as well as when a node is discovered or fails
discovery.

## Usage

Backends are defined by extending `chip::Tracing::Backend` in `backend.h` and
registering it via functions in `registry.h`

Actual usage is controlled using `macros.h` (and for convenience `scope.h`
provides scoped begin/end invocations).

tracing macros can be completely made a `noop` by setting
``matter_enable_tracing_support=false` when compiling.
69 changes: 69 additions & 0 deletions src/tracing/backend.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* 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/IntrusiveList.h>
#include <tracing/log_declares.h>
#include <tracing/scopes.h>

namespace chip {
namespace Tracing {

/// Represents a generic tracing back-end.
///
/// Derived from an intrusive list base as multiple
/// tracing back-ends may exist per application.
class Backend : public ::chip::IntrusiveListNodeBase<>
{
public:
virtual ~Backend() = default;

/// Begin a trace for the specified scope.
///
/// Scopes must be completed by a corresponding
/// TraceEnd call.
virtual void TraceBegin(Scope scope) = 0;

/// Tracing end assumes completing a previously
/// started scope with TraceBegin and nesting is assumed.
///
/// Expect scopes like:
/// TraceBegin(Foo)
/// TraceBegin(Bar)
/// TraceEnd(Bar)
/// TraceEnd(Foo)
///
/// The following is NOT acceptable:
/// TraceBegin(Foo)
/// TraceBegin(Bar)
/// TraceEnd(Foo)
/// TraceEnd(Bar)
virtual void TraceEnd(Scope scope) = 0;

/// Trace a zero-sized event
virtual void TraceInstant(Instant instant) = 0;

virtual void LogMessageSend(MessageSendInfo &) { TraceInstant(Instant::Log_MessageSend); }
virtual void LogMessageReceived(MessageReceiveInfo &) { TraceInstant(Instant::Log_MessageReceived); }

virtual void LogNodeLookup(NodeLookupInfo &) { TraceInstant(Instant::Log_NodeLookup); }
virtual void LogNodeDiscovered(NodeDiscoveredInfo &) { TraceInstant(Instant::Log_NodeDiscovered); }
virtual void LogNodeDiscoveryFailed(NodeDiscoveryFailedInfo &) { TraceInstant(Instant::Log_NodeDiscoveryFailed); }
};

} // namespace Tracing
} // namespace chip
32 changes: 32 additions & 0 deletions src/tracing/log_declares.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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

namespace chip {
namespace Tracing {

// These structures are forward-declared so that tracing itself has no direct dependencies
// on actual types. This allows tracing to be used anywhere lib/support could be used.

struct MessageSendInfo;
struct MessageReceiveInfo;
struct NodeLookupInfo;
struct NodeDiscoveredInfo;
struct NodeDiscoveryFailedInfo;

} // namespace Tracing
} // namespace chip
84 changes: 84 additions & 0 deletions src/tracing/macros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
*
* 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

#ifndef MATTER_TRACING_ENABLED

#define _MATTER_TRACE_DISABLE \
do \
{ \
} while (false)

#define MATTER_TRACE_BEGIN(...) _MATTER_TRACE_DISABLE(__VA_ARGS__)
#define MATTER_TRACE_END(...) _MATTER_TRACE_DISABLE(__VA_ARGS__)

#define MATTER_TRACE_INSTANT(...) _MATTER_TRACE_DISABLE(__VA_ARGS__)

#define MATTER_LOG_MESSAGE_SEND(...) _MATTER_TRACE_DISABLE(__VA_ARGS__)
#define MATTER_LOG_MESSAGE_RECEIVED(...) _MATTER_TRACE_DISABLE(__VA_ARGS__)

#define MATTER_LOG_NODE_LOOKUP(...) _MATTER_TRACE_DISABLE(__VA_ARGS__)
#define MATTER_LOG_NODE_DISCOVERED(...) _MATTER_TRACE_DISABLE(__VA_ARGS__)
#define MATTER_LOG_NODE_DISCOVERY_FAILED(...) _MATTER_TRACE_DISABLE(__VA_ARGS__)

#else // MATTER_TRACING_ENABLED

#include <tracing/log_declares.h>
#include <tracing/registry.h>
#include <tracing/scopes.h>

#define MATTER_TRACE_BEGIN(scope) ::chip::Tracing::Internal::Begin(scope)
#define MATTER_TRACE_END(scope) ::chip::Tracing::Internal::End(scope)
#define MATTER_TRACE_INSTANT(scope) ::chip::Tracing::Internal::Instant(scope)

#define MATTER_LOG_MESSAGE_SEND(...) \
do \
{ \
::chip::Tracing::MessageSendInfo _trace_data(__VA_ARGS__); \
::chip::Tracing::Internal::LogMessageSend(_trace_data); \
} while (false)

#define MATTER_LOG_MESSAGE_RECEIVED(...) \
do \
{ \
::chip::Tracing::MessageReceivedInfo _trace_data(__VA_ARGS__); \
::chip::Tracing::Internal::LogMessageReceived(_trace_data); \
} while (false)

#define MATTER_LOG_NODE_LOOKUP(...) \
do \
{ \
::chip::Tracing::NodeLookupInfo _trace_data(__VA_ARGS__); \
::chip::Tracing::Internal::LogNodeLookup(_trace_data); \
} while (false)

#define MATTER_LOG_NODE_DISCOVERED(...) \
do \
{ \
::chip::Tracing::NodeDiscoveredInfo _trace_data(__VA_ARGS__); \
::chip::Tracing::Internal::LogNodeDiscovered(_trace_data); \
} while (false)

#define MATTER_LOG_NODE_DISCOVERY_FAILED(...) \
do \
{ \
::chip::Tracing::NodeDiscoveryFailedInfo _trace_data(__VA_ARGS__); \
::chip::Tracing::Internal::LogNodeDiscoveryFailed(_trace_data); \
} while (false)

#endif
Loading

0 comments on commit dc8d5eb

Please sign in to comment.