1 /* 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 19 #include "FieldValue.h" 20 21 #include <android/os/StatsLogEventWrapper.h> 22 #include <android/util/ProtoOutputStream.h> 23 #include <log/log_read.h> 24 #include <private/android_logger.h> 25 26 #include <string> 27 #include <vector> 28 29 namespace android { 30 namespace os { 31 namespace statsd { 32 33 struct AttributionNodeInternal { set_uidAttributionNodeInternal34 void set_uid(int32_t id) { 35 mUid = id; 36 } 37 set_tagAttributionNodeInternal38 void set_tag(const std::string& value) { 39 mTag = value; 40 } 41 uidAttributionNodeInternal42 int32_t uid() const { 43 return mUid; 44 } 45 tagAttributionNodeInternal46 const std::string& tag() const { 47 return mTag; 48 } 49 50 int32_t mUid; 51 std::string mTag; 52 }; 53 54 struct InstallTrainInfo { 55 int64_t trainVersionCode; 56 std::string trainName; 57 int32_t status; 58 std::vector<int64_t> experimentIds; 59 }; 60 61 /** 62 * Wrapper for the log_msg structure. 63 */ 64 class LogEvent { 65 public: 66 /** 67 * Read a LogEvent from a log_msg. 68 */ 69 explicit LogEvent(log_msg& msg); 70 71 /** 72 * Creates LogEvent from StatsLogEventWrapper. 73 */ 74 static void createLogEvents(const StatsLogEventWrapper& statsLogEventWrapper, 75 std::vector<std::shared_ptr<LogEvent>>& logEvents); 76 77 /** 78 * Construct one LogEvent from a StatsLogEventWrapper with the i-th work chain. -1 if no chain. 79 */ 80 explicit LogEvent(const StatsLogEventWrapper& statsLogEventWrapper, int workChainIndex); 81 82 /** 83 * Constructs a LogEvent with synthetic data for testing. Must call init() before reading. 84 */ 85 explicit LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs); 86 87 // For testing. The timestamp is used as both elapsed real time and logd timestamp. 88 explicit LogEvent(int32_t tagId, int64_t timestampNs); 89 90 // For testing. The timestamp is used as both elapsed real time and logd timestamp. 91 explicit LogEvent(int32_t tagId, int64_t timestampNs, int32_t uid); 92 93 /** 94 * Constructs a KeyValuePairsAtom LogEvent from value maps. 95 */ 96 explicit LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs, 97 int32_t uid, 98 const std::map<int32_t, int32_t>& int_map, 99 const std::map<int32_t, int64_t>& long_map, 100 const std::map<int32_t, std::string>& string_map, 101 const std::map<int32_t, float>& float_map); 102 103 // Constructs a BinaryPushStateChanged LogEvent from API call. 104 explicit LogEvent(const std::string& trainName, int64_t trainVersionCode, bool requiresStaging, 105 bool rollbackEnabled, bool requiresLowLatencyMonitor, int32_t state, 106 const std::vector<uint8_t>& experimentIds, int32_t userId); 107 108 explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs, 109 const InstallTrainInfo& installTrainInfo); 110 111 ~LogEvent(); 112 113 /** 114 * Get the timestamp associated with this event. 115 */ GetLogdTimestampNs()116 inline int64_t GetLogdTimestampNs() const { return mLogdTimestampNs; } GetElapsedTimestampNs()117 inline int64_t GetElapsedTimestampNs() const { return mElapsedTimestampNs; } 118 119 /** 120 * Get the tag for this event. 121 */ GetTagId()122 inline int GetTagId() const { return mTagId; } 123 GetUid()124 inline uint32_t GetUid() const { 125 return mLogUid; 126 } 127 128 /** 129 * Get the nth value, starting at 1. 130 * 131 * Returns BAD_INDEX if the index is larger than the number of elements. 132 * Returns BAD_TYPE if the index is available but the data is the wrong type. 133 */ 134 int64_t GetLong(size_t key, status_t* err) const; 135 int GetInt(size_t key, status_t* err) const; 136 const char* GetString(size_t key, status_t* err) const; 137 bool GetBool(size_t key, status_t* err) const; 138 float GetFloat(size_t key, status_t* err) const; 139 140 /** 141 * Write test data to the LogEvent. This can only be used when the LogEvent is constructed 142 * using LogEvent(tagId, timestampNs). You need to call init() before you can read from it. 143 */ 144 bool write(uint32_t value); 145 bool write(int32_t value); 146 bool write(uint64_t value); 147 bool write(int64_t value); 148 bool write(const std::string& value); 149 bool write(float value); 150 bool write(const std::vector<AttributionNodeInternal>& nodes); 151 bool write(const AttributionNodeInternal& node); 152 bool writeKeyValuePairs(int32_t uid, 153 const std::map<int32_t, int32_t>& int_map, 154 const std::map<int32_t, int64_t>& long_map, 155 const std::map<int32_t, std::string>& string_map, 156 const std::map<int32_t, float>& float_map); 157 158 /** 159 * Return a string representation of this event. 160 */ 161 std::string ToString() const; 162 163 /** 164 * Write this object to a ProtoOutputStream. 165 */ 166 void ToProto(android::util::ProtoOutputStream& out) const; 167 168 /** 169 * Used with the constructor where tag is passed in. Converts the log_event_list to read mode 170 * and prepares the list for reading. 171 */ 172 void init(); 173 174 /** 175 * Set elapsed timestamp if the original timestamp is missing. 176 */ setElapsedTimestampNs(int64_t timestampNs)177 void setElapsedTimestampNs(int64_t timestampNs) { 178 mElapsedTimestampNs = timestampNs; 179 } 180 181 /** 182 * Set the timestamp if the original logd timestamp is missing. 183 */ setLogdWallClockTimestampNs(int64_t timestampNs)184 void setLogdWallClockTimestampNs(int64_t timestampNs) { 185 mLogdTimestampNs = timestampNs; 186 } 187 size()188 inline int size() const { 189 return mValues.size(); 190 } 191 getValues()192 const std::vector<FieldValue>& getValues() const { 193 return mValues; 194 } 195 getMutableValues()196 std::vector<FieldValue>* getMutableValues() { 197 return &mValues; 198 } 199 makeCopy()200 inline LogEvent makeCopy() { 201 return LogEvent(*this); 202 } 203 204 private: 205 /** 206 * Only use this if copy is absolutely needed. 207 */ 208 LogEvent(const LogEvent&); 209 210 /** 211 * Parses a log_msg into a LogEvent object. 212 */ 213 void init(android_log_context context); 214 215 // The items are naturally sorted in DFS order as we read them. this allows us to do fast 216 // matching. 217 std::vector<FieldValue> mValues; 218 219 // This field is used when statsD wants to create log event object and write fields to it. After 220 // calling init() function, this object would be destroyed to save memory usage. 221 // When the log event is created from log msg, this field is never initiated. 222 android_log_context mContext = NULL; 223 224 // The timestamp set by the logd. 225 int64_t mLogdTimestampNs; 226 227 // The elapsed timestamp set by statsd log writer. 228 int64_t mElapsedTimestampNs; 229 230 int mTagId; 231 232 uint32_t mLogUid; 233 }; 234 235 void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::vector<uint8_t>* protoOut); 236 237 } // namespace statsd 238 } // namespace os 239 } // namespace android 240