blob: fcce2ff3b36e9336482e66820dee98a13dde187d [file] [log] [blame]
Yao Chencaf339d2017-10-06 16:01:10 -07001/*
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
Yao Chencaf339d2017-10-06 16:01:10 -070017#include "stats_util.h"
Yao Chen729093d2017-10-16 10:33:26 -070018#include <log/log_event_list.h>
Yao Chencaf339d2017-10-06 16:01:10 -070019
20namespace android {
21namespace os {
22namespace statsd {
23
24static inline uint32_t get4LE(const char* src) {
25 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
26}
27
28int getTagId(log_msg msg) {
29 return get4LE(msg.msg());
30}
31
32EventMetricData parse(log_msg msg) {
33 // dump all statsd logs to dropbox for now.
34 // TODO: Add filtering, aggregation, etc.
35 EventMetricData eventMetricData;
36
37 // set tag.
38 int tag = getTagId(msg);
39 // TODO: Replace the following line when we can serialize on the fly.
40 // eventMetricData.set_tag(tag);
41
42 // set timestamp of the event.
43 eventMetricData.set_timestamp_nanos(msg.entry_v1.sec * NS_PER_SEC + msg.entry_v1.nsec);
44
45 // start iterating k,v pairs.
46 android_log_context context =
47 create_android_log_parser(const_cast<log_msg*>(&msg)->msg() + sizeof(uint32_t),
48 const_cast<log_msg*>(&msg)->len() - sizeof(uint32_t));
49 android_log_list_element elem;
50
51 if (context) {
52 memset(&elem, 0, sizeof(elem));
53 size_t index = 0;
54 int32_t key = -1;
55
56 do {
57 elem = android_log_read_next(context);
58 switch ((int)elem.type) {
59 case EVENT_TYPE_INT:
60 if (index % 2 == 0) {
61 key = elem.data.int32;
62 } else {
63 // TODO: Fix the following lines when we can serialize on the fly.
64 /*
65 int32_t val = elem.data.int32;
66 KeyValuePair* keyValuePair = eventMetricData.add_key_value_pair();
67 keyValuePair->set_key(key);
68 keyValuePair->set_value_int(val);
69 */
70 }
71 index++;
72 break;
73 case EVENT_TYPE_FLOAT:
74 if (index % 2 == 1) {
75 // TODO: Fix the following lines when we can serialize on the fly.
76 /*
77 float val = elem.data.float32;
78 KeyValuePair* keyValuePair = eventMetricData.add_key_value_pair();
79 keyValuePair->set_key(key);
80 keyValuePair->set_value_float(val);
81 */
82 }
83 index++;
84 break;
85 case EVENT_TYPE_STRING:
86 if (index % 2 == 1) {
87 // TODO: Fix the following lines when we can serialize on the fly.
88 /*
89 char* val = elem.data.string;
90 KeyValuePair* keyValuePair = eventMetricData.add_key_value_pair();
91 keyValuePair->set_key(key);
92 keyValuePair->set_value_str(val);
93 */
94 }
95 index++;
96 break;
97 case EVENT_TYPE_LONG:
98 if (index % 2 == 1) {
99 // TODO: Fix the following lines when we can serialize on the fly.
100 /*
101 int64_t val = elem.data.int64;
102 KeyValuePair* keyValuePair = eventMetricData.add_key_value_pair();
103 keyValuePair->set_key(key);
104 keyValuePair->set_value_int(val);
105 */
106 }
107 index++;
108 break;
109 case EVENT_TYPE_LIST:
110 break;
111 case EVENT_TYPE_LIST_STOP:
112 break;
113 case EVENT_TYPE_UNKNOWN:
114 break;
115 default:
116 elem.complete = true;
117 break;
118 }
119
120 if (elem.complete) {
121 break;
122 }
123 } while ((elem.type != EVENT_TYPE_UNKNOWN) && !elem.complete);
124
125 android_log_destroy(&context);
126 }
127
128 return eventMetricData;
129}
130
Yao Chen729093d2017-10-16 10:33:26 -0700131// There is no existing hash function for the dimension key ("repeated KeyValuePair").
132// Temporarily use a string concatenation as the hashable key.
133// TODO: Find a better hash function for std::vector<KeyValuePair>.
134HashableDimensionKey getHashableKey(std::vector<KeyValuePair> keys) {
135 std::string flattened;
136 for (const KeyValuePair& pair : keys) {
137 flattened += std::to_string(pair.key());
138 flattened += ":";
139 switch (pair.value_case()) {
140 case KeyValuePair::ValueCase::kValueStr:
141 flattened += pair.value_str();
142 break;
143 case KeyValuePair::ValueCase::kValueInt:
144 flattened += std::to_string(pair.value_int());
145 break;
146 case KeyValuePair::ValueCase::kValueBool:
147 flattened += std::to_string(pair.value_bool());
148 break;
149 case KeyValuePair::ValueCase::kValueFloat:
150 flattened += std::to_string(pair.value_float());
151 break;
152 default:
153 break;
154 }
155 flattened += "|";
156 }
157 return flattened;
158}
159
Yao Chencaf339d2017-10-06 16:01:10 -0700160} // namespace statsd
161} // namespace os
162} // namespace android