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