blob: bac8222ab563f0d0dc4f4cf4d7f99d9efe01a79d [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001diff --git a/system/core/liblog/logger_write.c b/system/core/liblog/logger_write.c
2index 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