rjw | 1f88458 | 2022-01-06 17:20:42 +0800 | [diff] [blame^] | 1 | diff --git a/system/core/liblog/logger_write.c b/system/core/liblog/logger_write.c |
| 2 | index b802ed7..3061862 100644 |
| 3 | --- a/system/core/liblog/logger_write.c |
| 4 | +++ b/system/core/liblog/logger_write.c |
| 5 | @@ -31,6 +31,14 @@ |
| 6 | #include <private/android_filesystem_config.h> |
| 7 | #include <private/android_logger.h> |
| 8 | |
| 9 | +#define __REDIRECT_TO_SYSLOGD__ |
| 10 | + |
| 11 | +#if defined(__REDIRECT_TO_SYSLOGD__) |
| 12 | +#include <syslog.h> |
| 13 | +#include <sys/syscall.h> |
| 14 | +#include <unistd.h> |
| 15 | +#endif |
| 16 | + |
| 17 | #include "config_write.h" |
| 18 | #include "log_portability.h" |
| 19 | #include "logger.h" |
| 20 | @@ -186,8 +194,187 @@ static inline uint32_t get4LE(const uint8_t* src) |
| 21 | return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); |
| 22 | } |
| 23 | |
| 24 | +#if defined(__REDIRECT_TO_SYSLOGD__) |
| 25 | +static int filterPriAndSysPri (android_LogPriority pri, int *sys_pri) |
| 26 | +{ |
| 27 | + switch (pri) { |
| 28 | + case ANDROID_LOG_DEBUG: |
| 29 | + *sys_pri = LOG_DEBUG; |
| 30 | + return 3; |
| 31 | + case ANDROID_LOG_INFO: |
| 32 | + *sys_pri = LOG_INFO; |
| 33 | + return 4; |
| 34 | + case ANDROID_LOG_WARN: |
| 35 | + *sys_pri = LOG_WARNING; |
| 36 | + return 5; |
| 37 | + case ANDROID_LOG_ERROR: |
| 38 | + *sys_pri = LOG_ERR; |
| 39 | + return 6; |
| 40 | + case ANDROID_LOG_FATAL: |
| 41 | + *sys_pri = LOG_CRIT; |
| 42 | + return 7; |
| 43 | + case ANDROID_LOG_SILENT: |
| 44 | + *sys_pri = LOG_EMERG; |
| 45 | + return 8; |
| 46 | + |
| 47 | + case ANDROID_LOG_DEFAULT: |
| 48 | + case ANDROID_LOG_UNKNOWN: |
| 49 | + default: |
| 50 | + *sys_pri = LOG_INFO; |
| 51 | + return 1; |
| 52 | + } |
| 53 | +} |
| 54 | + |
| 55 | +static char *filterLogId(log_id_t log_id) |
| 56 | +{ |
| 57 | + switch (log_id) { |
| 58 | + case LOG_ID_MAIN: |
| 59 | + return "MAIN"; |
| 60 | + case LOG_ID_RADIO : |
| 61 | + return "RADIO"; |
| 62 | + case LOG_ID_EVENTS: |
| 63 | + return "EVENT"; |
| 64 | + case LOG_ID_SYSTEM: |
| 65 | + return "SYSTEM"; |
| 66 | + default: |
| 67 | + return "UNKOWN"; |
| 68 | + } |
| 69 | +} |
| 70 | + |
| 71 | +/* |
| 72 | + * Extract an 8-byte value from a byte stream. |
| 73 | + */ |
| 74 | +static inline uint64_t get8LE(const uint8_t* src) |
| 75 | +{ |
| 76 | + uint32_t low, high; |
| 77 | + |
| 78 | + low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); |
| 79 | + high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24); |
| 80 | + return ((long long) high << 32) | (long long) low; |
| 81 | +} |
| 82 | + |
| 83 | +static char filterEvtType(char type, char *buf, void *payload, ssize_t len) |
| 84 | +{ |
| 85 | + switch(type) { |
| 86 | + case EVENT_TYPE_INT: |
| 87 | + sprintf(buf, "%d", get4LE(payload)); |
| 88 | + return 'I'; |
| 89 | + case EVENT_TYPE_LONG: |
| 90 | + sprintf(buf, "%lld", get8LE(payload)); |
| 91 | + return 'L'; |
| 92 | + case EVENT_TYPE_STRING: |
| 93 | + snprintf(buf, len, "%s", payload); |
| 94 | + buf[len] = '\0'; |
| 95 | + return 'S'; |
| 96 | + default: /* not support */ |
| 97 | + sprintf(buf, "?"); |
| 98 | + return '?'; |
| 99 | + } |
| 100 | +} |
| 101 | +#endif |
| 102 | + |
| 103 | + |
| 104 | static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr) |
| 105 | { |
| 106 | +#if defined(__REDIRECT_TO_SYSLOGD__) |
| 107 | + int ret; |
| 108 | + size_t totalLen = 0, defaultLen = 512, prefixLen; |
| 109 | + int write_allocate = 0; |
| 110 | + int sys_pri = LOG_INFO; |
| 111 | + char *writeBuf = NULL; |
| 112 | + char defaultBuf[512]; |
| 113 | + char prefixBuf[128]; |
| 114 | + char *idChar; |
| 115 | + int priChar; |
| 116 | + |
| 117 | + // for main, system, radio |
| 118 | + ssize_t msg_len = 0; |
| 119 | + int priority = ANDROID_LOG_INFO; |
| 120 | + char *tag, *msg; |
| 121 | + |
| 122 | + // for event |
| 123 | + int32_t etag; |
| 124 | + char type; |
| 125 | + void *payload; |
| 126 | + |
| 127 | + // ------------------------------------------------------------------ |
| 128 | + // get log id |
| 129 | + idChar = filterLogId(log_id); |
| 130 | + |
| 131 | +#if 0 //disable event logid |
| 132 | + if(log_id == LOG_ID_EVENTS) { /* event type */ |
| 133 | + if(nr == 2) { // __android_log_bwrite |
| 134 | + etag = *((int32_t *)vec[0].iov_base); |
| 135 | + type = EVENT_TYPE_INT; |
| 136 | + payload = (void *)vec[1].iov_base; |
| 137 | + msg_len = vec[1].iov_len; |
| 138 | + } else { // __android_log_btwrite |
| 139 | + etag = *((int32_t *)vec[0].iov_base); |
| 140 | + type = *((char *)vec[1].iov_base); |
| 141 | + |
| 142 | + if(!strcmp(&type, "")) |
| 143 | + type = EVENT_TYPE_STRING; |
| 144 | + |
| 145 | + payload = (void *)vec[2].iov_base; |
| 146 | + msg_len = vec[2].iov_len; |
| 147 | + } |
| 148 | + |
| 149 | + // get type char |
| 150 | + priChar = filterEvtType(type, prefixBuf, payload, msg_len); |
| 151 | + |
| 152 | + // format prefix (brief format) |
| 153 | + snprintf(defaultBuf, sizeof(defaultBuf), |
| 154 | + "<%c>/%c/%d(%5d): %s\n", |
| 155 | + idChar, priChar, etag, getpid(), prefixBuf); |
| 156 | + // log to syslog |
| 157 | + syslog(sys_pri, "%s", defaultBuf); |
| 158 | + ret = strlen(defaultBuf); |
| 159 | + } |
| 160 | + else |
| 161 | +#endif |
| 162 | + { /* radio, system, main */ |
| 163 | + // get messages and tag from io vector |
| 164 | + msg_len = vec[2].iov_len; |
| 165 | + priority = *((int *)vec[0].iov_base); |
| 166 | + tag = (char *)vec[1].iov_base; |
| 167 | + msg = (char *)vec[2].iov_base; |
| 168 | + |
| 169 | + /* disable Android VERBOSE log */ |
| 170 | + if (priority == ANDROID_LOG_VERBOSE) { |
| 171 | + return -EINVAL; |
| 172 | + } |
| 173 | + |
| 174 | + // get priority and logid char |
| 175 | + priChar = filterPriAndSysPri(priority, &sys_pri); |
| 176 | + |
| 177 | + // format prefix (brief format) |
| 178 | + prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), |
| 179 | + "(%5d, %5d),[%s],[%d],[Tag]%s[TAG]: ", getpid(), syscall(SYS_gettid), idChar, priChar, tag); |
| 180 | + |
| 181 | + // compute size |
| 182 | + totalLen = prefixLen + msg_len + 1 + 1; |
| 183 | + if(totalLen <= defaultLen) { |
| 184 | + writeBuf = defaultBuf; |
| 185 | + } else { |
| 186 | + write_allocate = 1; |
| 187 | + writeBuf = (char *)malloc(totalLen); |
| 188 | + if(writeBuf == NULL) |
| 189 | + return 0; |
| 190 | + } |
| 191 | + |
| 192 | + // combine final string |
| 193 | + writeBuf[0] = '\0'; |
| 194 | + strncat(writeBuf, prefixBuf, prefixLen); |
| 195 | + strncat(writeBuf, msg, msg_len); |
| 196 | + strcat(writeBuf, "\n"); |
| 197 | + |
| 198 | + // log to syslog |
| 199 | + syslog(sys_pri, "%s", writeBuf); |
| 200 | + ret = strlen(writeBuf); |
| 201 | + |
| 202 | + if(write_allocate) free(writeBuf); |
| 203 | + } |
| 204 | +#else |
| 205 | struct android_log_transport_write *node; |
| 206 | int ret; |
| 207 | struct timespec ts; |
| 208 | @@ -316,6 +503,7 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr) |
| 209 | (void)(*node->write)(log_id, &ts, vec, nr); |
| 210 | } |
| 211 | } |
| 212 | +#endif |
| 213 | |
| 214 | return ret; |
| 215 | } |
| 216 | @@ -327,6 +515,27 @@ static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr) |
| 217 | if (write_to_log == __write_to_log_init) { |
| 218 | int ret; |
| 219 | |
| 220 | +#if defined(__REDIRECT_TO_SYSLOGD__) |
| 221 | + // open syslogd |
| 222 | + if (access("/etc/configs/syslog_split", F_OK) == 0) { |
| 223 | + switch (log_id) { |
| 224 | + case LOG_ID_MAIN: |
| 225 | + openlog("ALOG", 0, LOG_LOCAL0); |
| 226 | + break; |
| 227 | + case LOG_ID_SYSTEM: |
| 228 | + openlog("SLOG", 0, LOG_LOCAL1); |
| 229 | + break; |
| 230 | + case LOG_ID_RADIO: |
| 231 | + openlog("RLOG", 0, LOG_LOCAL2); |
| 232 | + break; |
| 233 | + default: |
| 234 | + openlog("ALOG", 0, LOG_LOCAL0); |
| 235 | + break; |
| 236 | + } |
| 237 | + } else { |
| 238 | + openlog("ALOG", 0, LOG_USER); |
| 239 | + } |
| 240 | +#else |
| 241 | ret = __write_to_log_initialize(); |
| 242 | if (ret < 0) { |
| 243 | __android_log_unlock(); |
| 244 | @@ -335,7 +544,7 @@ static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr) |
| 245 | } |
| 246 | return ret; |
| 247 | } |
| 248 | - |
| 249 | +#endif |
| 250 | write_to_log = __write_to_log_daemon; |
| 251 | } |
| 252 | |