1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "FieldValue.h"
#include <android/frameworks/stats/1.0/types.h>
#include <android/os/StatsLogEventWrapper.h>
#include <android/util/ProtoOutputStream.h>
#include <log/log_event_list.h>
#include <log/log_read.h>
#include <private/android_logger.h>
#include <utils/Errors.h>
#include <string>
#include <vector>
using namespace android::frameworks::stats::V1_0;
namespace android {
namespace os {
namespace statsd {
struct AttributionNodeInternal {
void set_uid(int32_t id) {
mUid = id;
}
void set_tag(const std::string& value) {
mTag = value;
}
int32_t uid() const {
return mUid;
}
const std::string& tag() const {
return mTag;
}
int32_t mUid;
std::string mTag;
};
/**
* Wrapper for the log_msg structure.
*/
class LogEvent {
public:
/**
* Read a LogEvent from a log_msg.
*/
explicit LogEvent(log_msg& msg);
explicit LogEvent(const StatsLogEventWrapper& statsLogEventWrapper);
/**
* Constructs a LogEvent with synthetic data for testing. Must call init() before reading.
*/
explicit LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs);
// For testing. The timestamp is used as both elapsed real time and logd timestamp.
explicit LogEvent(int32_t tagId, int64_t timestampNs);
// For testing. The timestamp is used as both elapsed real time and logd timestamp.
explicit LogEvent(int32_t tagId, int64_t timestampNs, int32_t uid);
/**
* Constructs a KeyValuePairsAtom LogEvent from value maps.
*/
explicit LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
int32_t uid,
const std::map<int32_t, int32_t>& int_map,
const std::map<int32_t, int64_t>& long_map,
const std::map<int32_t, std::string>& string_map,
const std::map<int32_t, float>& float_map);
explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
const SpeakerImpedance& speakerImpedance);
explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
const HardwareFailed& hardwareFailed);
explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
const PhysicalDropDetected& physicalDropDetected);
explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
const ChargeCycles& chargeCycles);
explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs);
explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
const SlowIo& slowIo);
explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
const BatteryCausedShutdown& batteryCausedShutdown);
~LogEvent();
/**
* Get the timestamp associated with this event.
*/
inline int64_t GetLogdTimestampNs() const { return mLogdTimestampNs; }
inline int64_t GetElapsedTimestampNs() const { return mElapsedTimestampNs; }
/**
* Get the tag for this event.
*/
inline int GetTagId() const { return mTagId; }
inline uint32_t GetUid() const {
return mLogUid;
}
/**
* Get the nth value, starting at 1.
*
* Returns BAD_INDEX if the index is larger than the number of elements.
* Returns BAD_TYPE if the index is available but the data is the wrong type.
*/
int64_t GetLong(size_t key, status_t* err) const;
int GetInt(size_t key, status_t* err) const;
const char* GetString(size_t key, status_t* err) const;
bool GetBool(size_t key, status_t* err) const;
float GetFloat(size_t key, status_t* err) const;
/**
* Write test data to the LogEvent. This can only be used when the LogEvent is constructed
* using LogEvent(tagId, timestampNs). You need to call init() before you can read from it.
*/
bool write(uint32_t value);
bool write(int32_t value);
bool write(uint64_t value);
bool write(int64_t value);
bool write(const std::string& value);
bool write(float value);
bool write(const std::vector<AttributionNodeInternal>& nodes);
bool write(const AttributionNodeInternal& node);
bool writeKeyValuePairs(int32_t uid,
const std::map<int32_t, int32_t>& int_map,
const std::map<int32_t, int64_t>& long_map,
const std::map<int32_t, std::string>& string_map,
const std::map<int32_t, float>& float_map);
/**
* Return a string representation of this event.
*/
std::string ToString() const;
/**
* Write this object to a ProtoOutputStream.
*/
void ToProto(android::util::ProtoOutputStream& out) const;
/**
* Used with the constructor where tag is passed in. Converts the log_event_list to read mode
* and prepares the list for reading.
*/
void init();
/**
* Set elapsed timestamp if the original timestamp is missing.
*/
void setElapsedTimestampNs(int64_t timestampNs) {
mElapsedTimestampNs = timestampNs;
}
/**
* Set the timestamp if the original logd timestamp is missing.
*/
void setLogdWallClockTimestampNs(int64_t timestampNs) {
mLogdTimestampNs = timestampNs;
}
inline int size() const {
return mValues.size();
}
const std::vector<FieldValue>& getValues() const {
return mValues;
}
std::vector<FieldValue>* getMutableValues() {
return &mValues;
}
private:
/**
* Don't copy, it's slower. If we really need this we can add it but let's try to
* avoid it.
*/
explicit LogEvent(const LogEvent&);
/**
* Parses a log_msg into a LogEvent object.
*/
void init(android_log_context context);
// The items are naturally sorted in DFS order as we read them. this allows us to do fast
// matching.
std::vector<FieldValue> mValues;
// This field is used when statsD wants to create log event object and write fields to it. After
// calling init() function, this object would be destroyed to save memory usage.
// When the log event is created from log msg, this field is never initiated.
android_log_context mContext = NULL;
// The timestamp set by the logd.
int64_t mLogdTimestampNs;
// The elapsed timestamp set by statsd log writer.
int64_t mElapsedTimestampNs;
int mTagId;
uint32_t mLogUid;
};
} // namespace statsd
} // namespace os
} // namespace android
|