blob: 596d623debe56c14e48571b1382df19504d9cc08 [file] [log] [blame]
Joe Onoratoc4dfae52017-10-17 23:38:21 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
Yao Chen8a8d16c2018-02-08 14:50:40 -080019#include "FieldValue.h"
Joe Onoratoc4dfae52017-10-17 23:38:21 -070020
Howard Roa46b6582018-09-18 16:45:02 -070021#include <android/frameworks/stats/1.0/types.h>
Chenjie Yu12e5e672018-09-14 15:54:59 -070022#include <android/os/StatsLogEventWrapper.h>
Yao Chen5110bed2017-10-23 12:50:02 -070023#include <android/util/ProtoOutputStream.h>
Joe Onoratoc4dfae52017-10-17 23:38:21 -070024#include <log/log_read.h>
Yao Chen80235402017-11-13 20:42:25 -080025#include <private/android_logger.h>
Tej Singha02bfab2019-10-01 19:03:24 -070026#include <stats_event_list.h>
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -080027#include <stats_event.h>
Yao Chen5110bed2017-10-23 12:50:02 -070028#include <utils/Errors.h>
Joe Onoratoc4dfae52017-10-17 23:38:21 -070029
30#include <string>
31#include <vector>
32
Howard Roa46b6582018-09-18 16:45:02 -070033using namespace android::frameworks::stats::V1_0;
34
Joe Onoratoc4dfae52017-10-17 23:38:21 -070035namespace android {
36namespace os {
37namespace statsd {
38
Yao Chen9c1debe2018-02-19 14:39:19 -080039struct AttributionNodeInternal {
40 void set_uid(int32_t id) {
41 mUid = id;
42 }
43
44 void set_tag(const std::string& value) {
45 mTag = value;
46 }
47
48 int32_t uid() const {
49 return mUid;
50 }
51
52 const std::string& tag() const {
53 return mTag;
54 }
55
56 int32_t mUid;
57 std::string mTag;
58};
Chenjie Yu97dbb202019-02-13 16:42:04 -080059
60struct InstallTrainInfo {
61 int64_t trainVersionCode;
Muhammad Qureshif4ca8242019-03-01 09:20:15 -080062 std::string trainName;
63 int32_t status;
Jeff Hamiltonfa2f91c2019-03-22 00:25:02 -040064 std::vector<int64_t> experimentIds;
Chenjie Yu97dbb202019-02-13 16:42:04 -080065};
Jeff Hamiltonfa2f91c2019-03-22 00:25:02 -040066
Joe Onoratoc4dfae52017-10-17 23:38:21 -070067/**
68 * Wrapper for the log_msg structure.
69 */
70class LogEvent {
71public:
72 /**
Ruchir Rastogi1736ba42019-11-04 14:37:13 -080073 * Read a LogEvent from the socket
Joe Onoratoc4dfae52017-10-17 23:38:21 -070074 */
Ruchir Rastogi1736ba42019-11-04 14:37:13 -080075 explicit LogEvent(uint8_t* msg, uint32_t len, uint32_t uid);
Joe Onoratoc4dfae52017-10-17 23:38:21 -070076
Chenjie Yud7e3a222018-11-28 21:29:44 +000077 /**
Tej Singh89817632019-12-09 16:58:08 -080078 * Temp constructor to use for pulled atoms until we flip the socket schema.
79 */
80 explicit LogEvent(uint8_t* msg, uint32_t len, uint32_t uid, bool useNewSchema);
81
82 /**
Chenjie Yud7e3a222018-11-28 21:29:44 +000083 * Creates LogEvent from StatsLogEventWrapper.
84 */
85 static void createLogEvents(const StatsLogEventWrapper& statsLogEventWrapper,
86 std::vector<std::shared_ptr<LogEvent>>& logEvents);
87
88 /**
89 * Construct one LogEvent from a StatsLogEventWrapper with the i-th work chain. -1 if no chain.
90 */
91 explicit LogEvent(const StatsLogEventWrapper& statsLogEventWrapper, int workChainIndex);
Chenjie Yu12e5e672018-09-14 15:54:59 -070092
Joe Onoratoc4dfae52017-10-17 23:38:21 -070093 /**
Yao Chen80235402017-11-13 20:42:25 -080094 * Constructs a LogEvent with synthetic data for testing. Must call init() before reading.
Joe Onoratoc4dfae52017-10-17 23:38:21 -070095 */
Yangster-mac330af582018-02-08 15:24:38 -080096 explicit LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs);
97
98 // For testing. The timestamp is used as both elapsed real time and logd timestamp.
99 explicit LogEvent(int32_t tagId, int64_t timestampNs);
David Chen1481fe12017-10-16 13:16:34 -0700100
Howard Ro1a2a3992018-10-22 22:51:57 -0700101 // For testing. The timestamp is used as both elapsed real time and logd timestamp.
102 explicit LogEvent(int32_t tagId, int64_t timestampNs, int32_t uid);
103
Yangster-mac48b3d622018-08-18 12:38:11 -0700104 /**
105 * Constructs a KeyValuePairsAtom LogEvent from value maps.
106 */
107 explicit LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
108 int32_t uid,
Howard Ro4078dd42018-09-27 17:41:08 -0700109 const std::map<int32_t, int32_t>& int_map,
110 const std::map<int32_t, int64_t>& long_map,
Yangster-mac48b3d622018-08-18 12:38:11 -0700111 const std::map<int32_t, std::string>& string_map,
112 const std::map<int32_t, float>& float_map);
113
Chenjie Yu6b1667c2019-01-18 10:09:33 -0800114 // Constructs a BinaryPushStateChanged LogEvent from API call.
115 explicit LogEvent(const std::string& trainName, int64_t trainVersionCode, bool requiresStaging,
116 bool rollbackEnabled, bool requiresLowLatencyMonitor, int32_t state,
117 const std::vector<uint8_t>& experimentIds, int32_t userId);
118
Howard Roa46b6582018-09-18 16:45:02 -0700119 explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
Maggie White58174da2019-01-18 15:23:35 -0800120 const VendorAtom& vendorAtom);
121
Chenjie Yu97dbb202019-02-13 16:42:04 -0800122 explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
123 const InstallTrainInfo& installTrainInfo);
124
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700125 ~LogEvent();
126
127 /**
128 * Get the timestamp associated with this event.
129 */
Yangster-mac330af582018-02-08 15:24:38 -0800130 inline int64_t GetLogdTimestampNs() const { return mLogdTimestampNs; }
131 inline int64_t GetElapsedTimestampNs() const { return mElapsedTimestampNs; }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700132
133 /**
134 * Get the tag for this event.
135 */
Yangster-mac68985802018-01-21 10:05:09 -0800136 inline int GetTagId() const { return mTagId; }
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700137
Yangster-mac68985802018-01-21 10:05:09 -0800138 inline uint32_t GetUid() const {
Yao Chend10f7b12017-12-18 12:53:50 -0800139 return mLogUid;
140 }
141
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700142 /**
143 * Get the nth value, starting at 1.
144 *
145 * Returns BAD_INDEX if the index is larger than the number of elements.
146 * Returns BAD_TYPE if the index is available but the data is the wrong type.
147 */
148 int64_t GetLong(size_t key, status_t* err) const;
Chenjie Yu80f91122018-01-31 20:24:50 -0800149 int GetInt(size_t key, status_t* err) const;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700150 const char* GetString(size_t key, status_t* err) const;
151 bool GetBool(size_t key, status_t* err) const;
152 float GetFloat(size_t key, status_t* err) const;
153
154 /**
Yao Chen80235402017-11-13 20:42:25 -0800155 * Write test data to the LogEvent. This can only be used when the LogEvent is constructed
156 * using LogEvent(tagId, timestampNs). You need to call init() before you can read from it.
157 */
158 bool write(uint32_t value);
159 bool write(int32_t value);
160 bool write(uint64_t value);
161 bool write(int64_t value);
Yao Chen9c1debe2018-02-19 14:39:19 -0800162 bool write(const std::string& value);
Yao Chen80235402017-11-13 20:42:25 -0800163 bool write(float value);
Yao Chen9c1debe2018-02-19 14:39:19 -0800164 bool write(const std::vector<AttributionNodeInternal>& nodes);
165 bool write(const AttributionNodeInternal& node);
Tej Singha02bfab2019-10-01 19:03:24 -0700166 bool writeBytes(const std::string& value);
Howard Ro1a2a3992018-10-22 22:51:57 -0700167 bool writeKeyValuePairs(int32_t uid,
168 const std::map<int32_t, int32_t>& int_map,
Howard Ro4078dd42018-09-27 17:41:08 -0700169 const std::map<int32_t, int64_t>& long_map,
Yangster-mace124e422018-08-16 10:30:28 -0700170 const std::map<int32_t, std::string>& string_map,
171 const std::map<int32_t, float>& float_map);
Yao Chen80235402017-11-13 20:42:25 -0800172
173 /**
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700174 * Return a string representation of this event.
175 */
Yao Chen9c1debe2018-02-19 14:39:19 -0800176 std::string ToString() const;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700177
178 /**
Yao Chen5110bed2017-10-23 12:50:02 -0700179 * Write this object to a ProtoOutputStream.
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700180 */
Yao Chen5110bed2017-10-23 12:50:02 -0700181 void ToProto(android::util::ProtoOutputStream& out) const;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700182
David Chen1481fe12017-10-16 13:16:34 -0700183 /**
David Chen1481fe12017-10-16 13:16:34 -0700184 * Used with the constructor where tag is passed in. Converts the log_event_list to read mode
185 * and prepares the list for reading.
186 */
187 void init();
188
Chenjie Yua7259ab2017-12-10 08:31:05 -0800189 /**
Yangster-mac330af582018-02-08 15:24:38 -0800190 * Set elapsed timestamp if the original timestamp is missing.
Chenjie Yua7259ab2017-12-10 08:31:05 -0800191 */
Yangster-mac330af582018-02-08 15:24:38 -0800192 void setElapsedTimestampNs(int64_t timestampNs) {
193 mElapsedTimestampNs = timestampNs;
194 }
195
196 /**
197 * Set the timestamp if the original logd timestamp is missing.
198 */
199 void setLogdWallClockTimestampNs(int64_t timestampNs) {
200 mLogdTimestampNs = timestampNs;
201 }
Chenjie Yua7259ab2017-12-10 08:31:05 -0800202
Yangster-mac20877162017-12-22 17:19:39 -0800203 inline int size() const {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800204 return mValues.size();
Chenjie Yud9dfda72017-12-11 17:41:20 -0800205 }
206
Yao Chen8a8d16c2018-02-08 14:50:40 -0800207 const std::vector<FieldValue>& getValues() const {
208 return mValues;
209 }
Yangster-macd40053e2018-01-09 16:29:22 -0800210
Yao Chen8a8d16c2018-02-08 14:50:40 -0800211 std::vector<FieldValue>* getMutableValues() {
212 return &mValues;
213 }
Yangster-mac20877162017-12-22 17:19:39 -0800214
Ruchir Rastogi1736ba42019-11-04 14:37:13 -0800215 bool isValid() {
216 return mValid;
217 }
218
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800219 inline LogEvent makeCopy() {
220 return LogEvent(*this);
221 }
222
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700223private:
224 /**
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800225 * Only use this if copy is absolutely needed.
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700226 */
Chih-Hung Hsieh3227aab2018-12-20 13:42:28 -0800227 LogEvent(const LogEvent&);
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700228
Ruchir Rastogi1736ba42019-11-04 14:37:13 -0800229
230 /**
231 * Parsing function for new encoding scheme.
232 */
233 void initNew();
234
235 void parseInt32(int32_t* pos, int32_t depth, bool* last);
236 void parseInt64(int32_t* pos, int32_t depth, bool* last);
237 void parseString(int32_t* pos, int32_t depth, bool* last);
238 void parseFloat(int32_t* pos, int32_t depth, bool* last);
239 void parseBool(int32_t* pos, int32_t depth, bool* last);
240 void parseByteArray(int32_t* pos, int32_t depth, bool* last);
241 void parseKeyValuePairs(int32_t* pos, int32_t depth, bool* last);
242 void parseAttributionChain(int32_t* pos, int32_t depth, bool* last);
243
244 /**
245 * mBuf is a pointer to the current location in the buffer being parsed.
246 * Because the buffer lives on the StatsSocketListener stack, this pointer
247 * is only valid during the LogEvent constructor. It will be set to null at
248 * the end of initNew.
249 */
250 uint8_t* mBuf;
251
252 uint32_t mRemainingLen; // number of valid bytes left in the buffer being parsed
253 bool mValid = true; // stores whether the event we received from the socket is valid
254
255 /**
256 * Side-effects:
257 * If there is enough space in buffer to read value of type T
258 * - move mBuf past the value that was just read
259 * - decrement mRemainingLen by size of T
260 * Else
261 * - set mValid to false
262 */
263 template <class T>
264 T readNextValue() {
265 T value;
266 if (mRemainingLen < sizeof(T)) {
267 mValid = false;
268 value = 0; // all primitive types can successfully cast 0
269 } else {
270 value = *((T*)mBuf);
271 mBuf += sizeof(T);
272 mRemainingLen -= sizeof(T);
273 }
274 return value;
275 }
276
277 template <class T>
278 void addToValues(int32_t* pos, int32_t depth, T& value, bool* last) {
279 Field f = Field(mTagId, pos, depth);
280 // do not decorate last position at depth 0
281 for (int i = 1; i < depth; i++) {
282 if (last[i]) f.decorateLastPos(i);
283 }
284
285 Value v = Value(value);
286 mValues.push_back(FieldValue(f, v));
287 }
288
289 uint8_t getTypeId(uint8_t typeInfo);
290 uint8_t getNumAnnotations(uint8_t typeInfo);
291
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700292 /**
293 * Parses a log_msg into a LogEvent object.
294 */
Yao Chen80235402017-11-13 20:42:25 -0800295 void init(android_log_context context);
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700296
Yao Chen8a8d16c2018-02-08 14:50:40 -0800297 // The items are naturally sorted in DFS order as we read them. this allows us to do fast
298 // matching.
299 std::vector<FieldValue> mValues;
Yao Chen80235402017-11-13 20:42:25 -0800300
Yangster-mac20877162017-12-22 17:19:39 -0800301 // This field is used when statsD wants to create log event object and write fields to it. After
302 // calling init() function, this object would be destroyed to save memory usage.
303 // When the log event is created from log msg, this field is never initiated.
Yao Chen48d75182018-01-23 09:40:48 -0800304 android_log_context mContext = NULL;
Yao Chen93fe3a32017-11-02 13:52:59 -0700305
Yangster-mac330af582018-02-08 15:24:38 -0800306 // The timestamp set by the logd.
307 int64_t mLogdTimestampNs;
308
309 // The elapsed timestamp set by statsd log writer.
310 int64_t mElapsedTimestampNs;
Yao Chen93fe3a32017-11-02 13:52:59 -0700311
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700312 int mTagId;
Yao Chend10f7b12017-12-18 12:53:50 -0800313
314 uint32_t mLogUid;
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700315};
316
Jeff Hamiltonfa2f91c2019-03-22 00:25:02 -0400317void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::vector<uint8_t>* protoOut);
318
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700319} // namespace statsd
320} // namespace os
321} // namespace android
322