1 /* 2 * Copyright (C) 2018, 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 #ifndef ANDROID_STATS_LOG_STATS_EVENT_LIST_H 18 #define ANDROID_STATS_LOG_STATS_EVENT_LIST_H 19 20 #include <log/log_event_list.h> 21 #include <sys/uio.h> 22 23 #ifdef __cplusplus 24 extern "C" { 25 #endif 26 void reset_log_context(android_log_context ctx); 27 int write_to_logger(android_log_context context, log_id_t id); 28 void note_log_drop(int error, int atom_tag); 29 void stats_log_close(); 30 int android_log_write_char_array(android_log_context ctx, const char* value, size_t len); 31 extern int (*write_to_statsd)(struct iovec* vec, size_t nr); 32 33 #ifdef __cplusplus 34 } 35 #endif 36 37 #ifdef __cplusplus 38 /** 39 * A copy of android_log_event_list class. 40 * 41 * android_log_event_list is going to be deprecated soon, so copy it here to 42 * avoid creating dependency on upstream code. TODO(b/78304629): Rewrite this 43 * code. 44 */ 45 class stats_event_list { 46 private: 47 android_log_context ctx; 48 int ret; 49 50 stats_event_list(const stats_event_list&) = delete; 51 void operator=(const stats_event_list&) = delete; 52 53 public: stats_event_list(int tag)54 explicit stats_event_list(int tag) : ret(0) { 55 ctx = create_android_logger(static_cast<uint32_t>(tag)); 56 } ~stats_event_list()57 ~stats_event_list() { android_log_destroy(&ctx); } 58 close()59 int close() { 60 int retval = android_log_destroy(&ctx); 61 if (retval < 0) { 62 ret = retval; 63 } 64 return retval; 65 } 66 67 /* To allow above C calls to use this class as parameter */ android_log_context()68 operator android_log_context() const { return ctx; } 69 70 /* return errors or transmit status */ status()71 int status() const { return ret; } 72 begin()73 int begin() { 74 int retval = android_log_write_list_begin(ctx); 75 if (retval < 0) { 76 ret = retval; 77 } 78 return ret; 79 } end()80 int end() { 81 int retval = android_log_write_list_end(ctx); 82 if (retval < 0) { 83 ret = retval; 84 } 85 return ret; 86 } 87 88 stats_event_list& operator<<(int32_t value) { 89 int retval = android_log_write_int32(ctx, value); 90 if (retval < 0) { 91 ret = retval; 92 } 93 return *this; 94 } 95 96 stats_event_list& operator<<(uint32_t value) { 97 int retval = android_log_write_int32(ctx, static_cast<int32_t>(value)); 98 if (retval < 0) { 99 ret = retval; 100 } 101 return *this; 102 } 103 104 stats_event_list& operator<<(bool value) { 105 int retval = android_log_write_int32(ctx, value ? 1 : 0); 106 if (retval < 0) { 107 ret = retval; 108 } 109 return *this; 110 } 111 112 stats_event_list& operator<<(int64_t value) { 113 int retval = android_log_write_int64(ctx, value); 114 if (retval < 0) { 115 ret = retval; 116 } 117 return *this; 118 } 119 120 stats_event_list& operator<<(uint64_t value) { 121 int retval = android_log_write_int64(ctx, static_cast<int64_t>(value)); 122 if (retval < 0) { 123 ret = retval; 124 } 125 return *this; 126 } 127 128 stats_event_list& operator<<(const char* value) { 129 int retval = android_log_write_string8(ctx, value); 130 if (retval < 0) { 131 ret = retval; 132 } 133 return *this; 134 } 135 136 #if defined(_USING_LIBCXX) 137 stats_event_list& operator<<(const std::string& value) { 138 int retval = android_log_write_string8_len(ctx, value.data(), value.length()); 139 if (retval < 0) { 140 ret = retval; 141 } 142 return *this; 143 } 144 #endif 145 146 stats_event_list& operator<<(float value) { 147 int retval = android_log_write_float32(ctx, value); 148 if (retval < 0) { 149 ret = retval; 150 } 151 return *this; 152 } 153 154 int write(log_id_t id = LOG_ID_EVENTS) { 155 /* facilitate -EBUSY retry */ 156 if ((ret == -EBUSY) || (ret > 0)) { 157 ret = 0; 158 } 159 int retval = write_to_logger(ctx, id); 160 /* existing errors trump transmission errors */ 161 if (!ret) { 162 ret = retval; 163 } 164 return ret; 165 } 166 167 /* 168 * Append<Type> methods removes any integer promotion 169 * confusion, and adds access to string with length. 170 * Append methods are also added for all types for 171 * convenience. 172 */ 173 AppendInt(int32_t value)174 bool AppendInt(int32_t value) { 175 int retval = android_log_write_int32(ctx, value); 176 if (retval < 0) { 177 ret = retval; 178 } 179 return ret >= 0; 180 } 181 AppendLong(int64_t value)182 bool AppendLong(int64_t value) { 183 int retval = android_log_write_int64(ctx, value); 184 if (retval < 0) { 185 ret = retval; 186 } 187 return ret >= 0; 188 } 189 AppendString(const char * value)190 bool AppendString(const char* value) { 191 int retval = android_log_write_string8(ctx, value); 192 if (retval < 0) { 193 ret = retval; 194 } 195 return ret >= 0; 196 } 197 AppendString(const char * value,size_t len)198 bool AppendString(const char* value, size_t len) { 199 int retval = android_log_write_string8_len(ctx, value, len); 200 if (retval < 0) { 201 ret = retval; 202 } 203 return ret >= 0; 204 } 205 206 #if defined(_USING_LIBCXX) AppendString(const std::string & value)207 bool AppendString(const std::string& value) { 208 int retval = android_log_write_string8_len(ctx, value.data(), value.length()); 209 if (retval < 0) { 210 ret = retval; 211 } 212 return ret; 213 } 214 Append(const std::string & value)215 bool Append(const std::string& value) { 216 int retval = android_log_write_string8_len(ctx, value.data(), value.length()); 217 if (retval < 0) { 218 ret = retval; 219 } 220 return ret; 221 } 222 #endif 223 AppendFloat(float value)224 bool AppendFloat(float value) { 225 int retval = android_log_write_float32(ctx, value); 226 if (retval < 0) { 227 ret = retval; 228 } 229 return ret >= 0; 230 } 231 232 template <typename Tvalue> Append(Tvalue value)233 bool Append(Tvalue value) { 234 *this << value; 235 return ret >= 0; 236 } 237 Append(const char * value,size_t len)238 bool Append(const char* value, size_t len) { 239 int retval = android_log_write_string8_len(ctx, value, len); 240 if (retval < 0) { 241 ret = retval; 242 } 243 return ret >= 0; 244 } 245 AppendCharArray(const char * value,size_t len)246 bool AppendCharArray(const char* value, size_t len) { 247 int retval = android_log_write_char_array(ctx, value, len); 248 if (retval < 0) { 249 ret = retval; 250 } 251 return ret >= 0; 252 } 253 }; 254 255 #endif 256 #endif // ANDROID_STATS_LOG_STATS_EVENT_LIST_H 257