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