• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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