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/util/ProtoOutputStream.h> 22 #include <log/log_event_list.h> 23 #include <log/log_read.h> 24 #include <private/android_logger.h> 25 #include <utils/Errors.h> 26 27 #include <string> 28 #include <vector> 29 30 namespace android { 31 namespace os { 32 namespace statsd { 33 34 struct AttributionNodeInternal { set_uidAttributionNodeInternal35 void set_uid(int32_t id) { 36 mUid = id; 37 } 38 set_tagAttributionNodeInternal39 void set_tag(const std::string& value) { 40 mTag = value; 41 } 42 uidAttributionNodeInternal43 int32_t uid() const { 44 return mUid; 45 } 46 tagAttributionNodeInternal47 const std::string& tag() const { 48 return mTag; 49 } 50 51 int32_t mUid; 52 std::string mTag; 53 }; 54 /** 55 * Wrapper for the log_msg structure. 56 */ 57 class LogEvent { 58 public: 59 /** 60 * Read a LogEvent from a log_msg. 61 */ 62 explicit LogEvent(log_msg& msg); 63 64 /** 65 * Constructs a LogEvent with synthetic data for testing. Must call init() before reading. 66 */ 67 explicit LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs); 68 69 // For testing. The timestamp is used as both elapsed real time and logd timestamp. 70 explicit LogEvent(int32_t tagId, int64_t timestampNs); 71 72 ~LogEvent(); 73 74 /** 75 * Get the timestamp associated with this event. 76 */ GetLogdTimestampNs()77 inline int64_t GetLogdTimestampNs() const { return mLogdTimestampNs; } GetElapsedTimestampNs()78 inline int64_t GetElapsedTimestampNs() const { return mElapsedTimestampNs; } 79 80 /** 81 * Get the tag for this event. 82 */ GetTagId()83 inline int GetTagId() const { return mTagId; } 84 GetUid()85 inline uint32_t GetUid() const { 86 return mLogUid; 87 } 88 89 /** 90 * Get the nth value, starting at 1. 91 * 92 * Returns BAD_INDEX if the index is larger than the number of elements. 93 * Returns BAD_TYPE if the index is available but the data is the wrong type. 94 */ 95 int64_t GetLong(size_t key, status_t* err) const; 96 int GetInt(size_t key, status_t* err) const; 97 const char* GetString(size_t key, status_t* err) const; 98 bool GetBool(size_t key, status_t* err) const; 99 float GetFloat(size_t key, status_t* err) const; 100 101 /** 102 * Write test data to the LogEvent. This can only be used when the LogEvent is constructed 103 * using LogEvent(tagId, timestampNs). You need to call init() before you can read from it. 104 */ 105 bool write(uint32_t value); 106 bool write(int32_t value); 107 bool write(uint64_t value); 108 bool write(int64_t value); 109 bool write(const std::string& value); 110 bool write(float value); 111 bool write(const std::vector<AttributionNodeInternal>& nodes); 112 bool write(const AttributionNodeInternal& node); 113 114 /** 115 * Return a string representation of this event. 116 */ 117 std::string ToString() const; 118 119 /** 120 * Write this object to a ProtoOutputStream. 121 */ 122 void ToProto(android::util::ProtoOutputStream& out) const; 123 124 /** 125 * Used with the constructor where tag is passed in. Converts the log_event_list to read mode 126 * and prepares the list for reading. 127 */ 128 void init(); 129 130 /** 131 * Set elapsed timestamp if the original timestamp is missing. 132 */ setElapsedTimestampNs(int64_t timestampNs)133 void setElapsedTimestampNs(int64_t timestampNs) { 134 mElapsedTimestampNs = timestampNs; 135 } 136 137 /** 138 * Set the timestamp if the original logd timestamp is missing. 139 */ setLogdWallClockTimestampNs(int64_t timestampNs)140 void setLogdWallClockTimestampNs(int64_t timestampNs) { 141 mLogdTimestampNs = timestampNs; 142 } 143 size()144 inline int size() const { 145 return mValues.size(); 146 } 147 getValues()148 const std::vector<FieldValue>& getValues() const { 149 return mValues; 150 } 151 getMutableValues()152 std::vector<FieldValue>* getMutableValues() { 153 return &mValues; 154 } 155 156 private: 157 /** 158 * Don't copy, it's slower. If we really need this we can add it but let's try to 159 * avoid it. 160 */ 161 explicit LogEvent(const LogEvent&); 162 163 /** 164 * Parses a log_msg into a LogEvent object. 165 */ 166 void init(android_log_context context); 167 168 // The items are naturally sorted in DFS order as we read them. this allows us to do fast 169 // matching. 170 std::vector<FieldValue> mValues; 171 172 // This field is used when statsD wants to create log event object and write fields to it. After 173 // calling init() function, this object would be destroyed to save memory usage. 174 // When the log event is created from log msg, this field is never initiated. 175 android_log_context mContext = NULL; 176 177 // The timestamp set by the logd. 178 int64_t mLogdTimestampNs; 179 180 // The elapsed timestamp set by statsd log writer. 181 int64_t mElapsedTimestampNs; 182 183 int mTagId; 184 185 uint32_t mLogUid; 186 }; 187 188 } // namespace statsd 189 } // namespace os 190 } // namespace android 191 192