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