Line data Source code
1 : /**
2 : *
3 : * Copyright (c) 2021 Project CHIP Authors
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 :
18 : #pragma once
19 :
20 : #include <access/SubjectDescriptor.h>
21 : #include <app/ConcreteEventPath.h>
22 : #include <app/EventPathParams.h>
23 : #include <app/data-model/FabricScoped.h>
24 : #include <app/util/basic-types.h>
25 : #include <lib/core/CHIPCore.h>
26 : #include <lib/core/Optional.h>
27 : #include <lib/core/TLV.h>
28 : #include <lib/support/LinkedList.h>
29 : #include <system/SystemPacketBuffer.h>
30 :
31 : inline constexpr size_t kNumPriorityLevel = 3;
32 : namespace chip {
33 : namespace app {
34 :
35 : /**
36 : * @brief
37 : * The Priority of the log entry.
38 : *
39 : * @details
40 : * Priority is used as a way to filter events before they are
41 : * actually emitted into the log. After the event is in the log, we
42 : * make no further provisions to expunge it from the log.
43 : * The priority level serves to prioritize event storage. If an
44 : * event of high priority is added to a full buffer, events are
45 : * dropped in order of priority (and age) to accommodate it. As such,
46 : * priority levels only have relative value. If a system is
47 : * using only one priority level, events are dropped only in order
48 : * of age, like a ring buffer.
49 : */
50 :
51 : enum class PriorityLevel : uint8_t
52 : {
53 :
54 : First = 0,
55 : /**
56 : * Debug priority denotes log entries of interest to the
57 : * developers of the system and is used primarily in the
58 : * development phase. Debug priority logs are
59 : * not accounted for in the bandwidth or power budgets of the
60 : * constrained devices; as a result, they must be used only over
61 : * a limited time span in production systems.
62 : */
63 :
64 : Debug = First,
65 : /**
66 : * Info priority denotes log entries that provide extra insight
67 : * and diagnostics into the running system. Info logging level may
68 : * be used over an extended period of time in a production system,
69 : * or may be used as the default log level in a field trial. On
70 : * the constrained devices, the entries logged with Info level must
71 : * be accounted for in the bandwidth and memory budget, but not in
72 : * the power budget.
73 : */
74 : Info = 1,
75 :
76 : /**
77 : * Critical priority denotes events whose loss would
78 : * directly impact customer-facing features. Applications may use
79 : * loss of Production Critical events to indicate system failure.
80 : * On constrained devices, entries logged with Critical
81 : * priority must be accounted for in the power and memory budget,
82 : * as it is expected that they are always logged and offloaded
83 : * from the device.
84 : */
85 : Critical = 2,
86 : Last = Critical,
87 : Invalid = Last + 1,
88 :
89 : };
90 :
91 : static_assert(sizeof(std::underlying_type_t<PriorityLevel>) <= sizeof(unsigned),
92 : "Logging that converts PriorityLevel to unsigned will be lossy");
93 :
94 : /**
95 : * @brief
96 : * The struct that provides an application set System or Epoch timestamp.
97 : */
98 : struct Timestamp
99 : {
100 : enum class Type : uint8_t
101 : {
102 : kSystem = 0,
103 : kEpoch
104 : };
105 7925 : constexpr Timestamp() = default;
106 5015 : Timestamp(Type aType, uint64_t aValue) : mType(aType), mValue(aValue) {}
107 : Timestamp(System::Clock::Timestamp aValue) : mType(Type::kSystem), mValue(aValue.count()) {}
108 5003 : static Timestamp Epoch(System::Clock::Timestamp aValue)
109 : {
110 5003 : Timestamp timestamp(Type::kEpoch, aValue.count());
111 5003 : return timestamp;
112 : }
113 12 : static Timestamp System(System::Clock::Timestamp aValue)
114 : {
115 12 : Timestamp timestamp(Type::kSystem, aValue.count());
116 12 : return timestamp;
117 : }
118 :
119 1330 : bool IsSystem() const { return mType == Type::kSystem; }
120 0 : bool IsEpoch() const { return mType == Type::kEpoch; }
121 :
122 : Type mType = Type::kSystem;
123 : uint64_t mValue = 0;
124 : };
125 :
126 : /**
127 : * The structure that provides options for the different event fields.
128 : */
129 : class EventOptions
130 : {
131 : public:
132 1727 : EventOptions() = default;
133 :
134 : template <typename EVENT_TYPE>
135 4 : EventOptions(EndpointId endpointId, const EVENT_TYPE & eventData) :
136 4 : mPath(endpointId, eventData.GetClusterId(), eventData.GetEventId()), mPriority(eventData.GetPriorityLevel())
137 : {
138 4 : constexpr bool isFabricScoped = DataModel::IsFabricScoped<EVENT_TYPE>::value;
139 : if constexpr (isFabricScoped)
140 : {
141 2 : mFabricIndex = eventData.GetFabricIndex();
142 : }
143 4 : }
144 :
145 : ConcreteEventPath mPath;
146 : PriorityLevel mPriority = PriorityLevel::Invalid;
147 : // kUndefinedFabricIndex 0 means not fabric associated at all
148 : FabricIndex mFabricIndex = kUndefinedFabricIndex;
149 : };
150 :
151 : /**
152 : * @brief
153 : * Structure for copying event lists on output.
154 : */
155 : struct EventLoadOutContext
156 : {
157 2223 : EventLoadOutContext(TLV::TLVWriter & aWriter, PriorityLevel aPriority, EventNumber aStartingEventNumber) :
158 2223 : mWriter(aWriter), mPriority(aPriority), mStartingEventNumber(aStartingEventNumber), mCurrentEventNumber(0), mFirst(true)
159 2223 : {}
160 :
161 : TLV::TLVWriter & mWriter;
162 : PriorityLevel mPriority = PriorityLevel::Invalid;
163 : EventNumber mStartingEventNumber = 0;
164 : Timestamp mPreviousTime;
165 : Timestamp mCurrentTime;
166 : EventNumber mCurrentEventNumber = 0;
167 : size_t mEventCount = 0;
168 : const SingleLinkedListNode<EventPathParams> * mpInterestedEventPaths = nullptr;
169 : bool mFirst = true;
170 : Access::SubjectDescriptor mSubjectDescriptor;
171 : };
172 : } // namespace app
173 : } // namespace chip
|