blob: cfb755634ede31f253715859ad3831ed63c4324a [file] [log] [blame]
liubin281ac462023-07-19 14:22:54 +08001#include <stdio.h>
2#include <sys/types.h>
3#include <sys/stat.h>
4#include <sys/socket.h>
5#include <netinet/in.h>
6#include <netdb.h>
7#include <arpa/inet.h>
8#include <fcntl.h>
9#include <time.h>
10#include <unistd.h>
11#include <errno.h>
b.liu9e8584b2024-11-06 19:21:28 +080012#include <string.h>
13#include <stdlib.h>
14#include <pthread.h>
15
liubin281ac462023-07-19 14:22:54 +080016#include "log_config.h"
b.liu9e8584b2024-11-06 19:21:28 +080017#include "mbtk_utils.h"
liubin281ac462023-07-19 14:22:54 +080018
19#define ALOG_DEV "/dev/log_radio"
xf.li43643772024-03-04 19:39:53 -080020#define LOG_CONFIG_LEN 50
liubin281ac462023-07-19 14:22:54 +080021
l.yang67782e62024-11-05 01:28:10 -080022#define RADIOLOG_BUFF_SIZE (4*1024)
23#define MAX_BUFFER_SIZE (8*1024)
24
liubin281ac462023-07-19 14:22:54 +080025typedef enum android_LogPriority {
26 ANDROID_LOG_UNKNOWN = 0,
27 ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
28 ANDROID_LOG_VERBOSE,
29 ANDROID_LOG_DEBUG,
30 ANDROID_LOG_INFO,
31 ANDROID_LOG_WARN,
32 ANDROID_LOG_ERROR,
33 ANDROID_LOG_FATAL,
34 ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
35} android_LogPriority;
36
37typedef struct AndroidLogEntry_t {
38 time_t tv_sec;
39 long tv_nsec;
40 android_LogPriority priority;
41 int32_t pid;
42 int32_t tid;
b.liu9e8584b2024-11-06 19:21:28 +080043 char * tag;
liubin281ac462023-07-19 14:22:54 +080044 size_t messageLen;
45 const char * message;
46} AndroidLogEntry;
47
xf.li43643772024-03-04 19:39:53 -080048//static const char *log_file, *log_ip, *log_port, *log_prefix, *pid_file, *hostname;
49static char log_file[LOG_CONFIG_LEN], log_ip[LOG_CONFIG_LEN], log_port[LOG_CONFIG_LEN], log_prefix[LOG_CONFIG_LEN], pid_file[LOG_CONFIG_LEN], hostname[LOG_CONFIG_LEN];
liubin281ac462023-07-19 14:22:54 +080050static int log_size = 1 * 1024 * 1024;
51
52static log_config_entry *config = NULL;
b.liu9e8584b2024-11-06 19:21:28 +080053static char tmp_log[1024] = {0};
liubin281ac462023-07-19 14:22:54 +080054
l.yangb7972c72024-10-15 22:34:51 -070055static int fd_radio = 0;
56
b.liu9e8584b2024-11-06 19:21:28 +080057int tcp_connect(char* ip, int port);
l.yang67782e62024-11-05 01:28:10 -080058
liubin281ac462023-07-19 14:22:54 +080059void hex_print(char* buf, int len)
60{
61 int i;
62
63 for (i = 0; i < len; i++) {
64 printf("%x ", buf[i]);
65 }
66}
67
68static char filterPriToChar(android_LogPriority pri)
69{
70 switch (pri) {
71 case ANDROID_LOG_VERBOSE:
72 return 'V';
73 case ANDROID_LOG_DEBUG:
74 return 'D';
75 case ANDROID_LOG_INFO:
76 return 'I';
77 case ANDROID_LOG_WARN:
78 return 'W';
79 case ANDROID_LOG_ERROR:
80 return 'E';
81 case ANDROID_LOG_FATAL:
82 return 'F';
83 case ANDROID_LOG_SILENT:
84 return 'S';
85
86 case ANDROID_LOG_DEFAULT:
87 case ANDROID_LOG_UNKNOWN:
88 default:
89 return '?';
90 }
91}
92
93static android_LogPriority filterCharToPri(char c)
94{
95 switch (c) {
96 case 'v':
97 return ANDROID_LOG_VERBOSE;
98 case 'd':
99 return ANDROID_LOG_DEBUG;
100 case 'i':
101 return ANDROID_LOG_INFO;
102 case 'w':
103 return ANDROID_LOG_WARN;
104 case 'e':
105 return ANDROID_LOG_ERROR;
106 case 'f':
107 return ANDROID_LOG_FATAL;
108 case 's':
109 return ANDROID_LOG_SILENT;
110 case '*':
111 default:
112 return ANDROID_LOG_VERBOSE;
113 }
114}
115
116int fileter_log(int pri, char *tag, struct filter_list_t *filter)
117{
118 struct filter_list_t *_filter = filter;
119
120 while(_filter)
121 {
122 int p = filterCharToPri(_filter->priority);
123 if(_filter->tag)
124 {
125 int len = strlen(_filter->tag);
126 // tag and priority
127 if(0 == memcmp(_filter->tag, tag, len) && ((pri > p) || (pri == p)))
128 return 0;
129 }else{ // have no tag
130 if(pri < p)
131 return -1;
132 else
133 return 0;
134 }
135 _filter = _filter->next;
136 }
137
138 return -1;
139}
140
141int alog_process(char* data, int len, AndroidLogEntry *entry)
142{
143 int i, n = 0;
b.liu9e8584b2024-11-06 19:21:28 +0800144// int tmp_len;
liubin281ac462023-07-19 14:22:54 +0800145
146 for (i = 0; i < len;) {
147 if (data[i] == '\0') {
148 i += 1;
149 } else {
150 switch (n) {
151 case 0: {
152 // printf("%d - %d: %x\n", i, tmp_len, data[i]);
153 i++;
154 break;
155 }
156 case 1: {
157 int* pid = (int*)&data[i];
158 entry->pid = *pid;
159 // printf("%d pid: %d\n", i, entry->pid);
160 i += 4;
161 break;
162 }
163 case 2: {
164 int* tid = (int*)&data[i];
165 entry->tid = *tid;
166 // printf("%d tid: %d\n", i, entry->tid);
167 i += 4;
168 break;
169 }
170 case 3: {
171 // printf("%d - %d: %x %x %x %x\n", i, tmp_len, data[i], data[i + 1], data[i + 2], data[i + 3]);
172 time_t* _t = (time_t*)&data[i];
173 entry->tv_sec = *_t;
174 i += 8;
175 break;
176 }
177 case 4: {
178 entry->priority = data[i];
179 entry->tag = &data[i + 1];
180 i += strlen(&data[i]);
181 break;
182 }
183 //* format: <priority:1><tag:N>\0<message:N>\0
184 case 5: {
185 entry->message = &data[i];
186 entry->messageLen = strlen(&data[i]);
187 i += entry->messageLen;
188 break;
189 }
190 default:
191 printf("process error \n");
192 break;
193 }
194 n++;
195 }
196 }
197 return 0;
198}
199
200int android_log_printLogLine(
liubin281ac462023-07-19 14:22:54 +0800201 struct file_list_t *_file_list,
202 const AndroidLogEntry *entry)
203{
204 char priChar;
205 char timeBuf[32];
l.yang67782e62024-11-05 01:28:10 -0800206 char defaultBuffer[512] = {0};
liubin281ac462023-07-19 14:22:54 +0800207 size_t totalLen;
xf.li01e39822024-10-30 16:00:32 +0800208 int index = 0;
209 int len = 0;
l.yangb7972c72024-10-15 22:34:51 -0700210 struct stat s;
b.liu9e8584b2024-11-06 19:21:28 +0800211
l.yang67782e62024-11-05 01:28:10 -0800212
213 static char buffer[MAX_BUFFER_SIZE] = {0};
214 static int buffer_index = 0;
b.liu9e8584b2024-11-06 19:21:28 +0800215
l.yangb7972c72024-10-15 22:34:51 -0700216 if(access(tmp_log, W_OK) != 0)
217 {
218 fd_radio = open(tmp_log, O_CREAT | O_WRONLY| O_APPEND, 0600);
b.liu9e8584b2024-11-06 19:21:28 +0800219 if (fd_radio < 0)
l.yangb7972c72024-10-15 22:34:51 -0700220 {
221 fprintf(stderr, "failed to open %s: %s\n", tmp_log, strerror(errno));
222 exit(-1);
liubin281ac462023-07-19 14:22:54 +0800223 }
b.liu9e8584b2024-11-06 19:21:28 +0800224
l.yangb7972c72024-10-15 22:34:51 -0700225 }
l.yang67782e62024-11-05 01:28:10 -0800226
227
l.yangb7972c72024-10-15 22:34:51 -0700228 if (log_size && (!stat(tmp_log, &s)) && (s.st_size > log_size))
229 {
230 fd_radio = get_rotate_file(fd_radio, log_file, _file_list);
b.liu9e8584b2024-11-06 19:21:28 +0800231 if (fd_radio < 0)
l.yangb7972c72024-10-15 22:34:51 -0700232 {
233 fprintf(stderr, "failed to open %s: %s\n", log_file, strerror(errno));
234 exit(-1);
235 }
b.liu9e8584b2024-11-06 19:21:28 +0800236
l.yangb7972c72024-10-15 22:34:51 -0700237 }
liubin281ac462023-07-19 14:22:54 +0800238
239 if(fileter_log(entry->priority, entry->tag, config->filter_list))
240 {
241 // printf("%s %d: fileter pri:%d tag:%s!\n", __FUNCTION__, __LINE__, entry->priority, entry->tag);
242 return -1;
243 }
244
245 priChar = filterPriToChar(entry->priority);
246 struct tm* ptm = localtime(&entry->tv_sec);
247 strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", ptm);
248
249 totalLen = snprintf(defaultBuffer, sizeof(defaultBuffer),
250 "%s %c/%s (%d): %s\n", timeBuf, priChar, entry->tag, entry->pid, entry->message);
b.liu9e8584b2024-11-06 19:21:28 +0800251
xf.li01e39822024-10-30 16:00:32 +0800252 len = strlen(defaultBuffer);
253 if(access("/etc/syslog_encrypt_flag", F_OK) == 0)
254 {
255 for(index = 0; index < len; index++)
256 {
257 defaultBuffer[index] ^= 1;
258 }
259 }
liubin281ac462023-07-19 14:22:54 +0800260
l.yang67782e62024-11-05 01:28:10 -0800261
262 if(buffer_index >= RADIOLOG_BUFF_SIZE)
263 {
264 // Flush the buffer if it's full
b.liu9e8584b2024-11-06 19:21:28 +0800265 if (write(fd_radio, buffer, buffer_index) < 0)
l.yang67782e62024-11-05 01:28:10 -0800266 {
267 perror("write error");
268 return -1;
269 }
270 buffer_index = 0; // Reset buffer index after flushing
271 }
b.liu9e8584b2024-11-06 19:21:28 +0800272
l.yang67782e62024-11-05 01:28:10 -0800273 if(totalLen < RADIOLOG_BUFF_SIZE)
274 {
b.liu9e8584b2024-11-06 19:21:28 +0800275 //copy buf to buffer
l.yang67782e62024-11-05 01:28:10 -0800276 memcpy(buffer + buffer_index, defaultBuffer, totalLen);
277 buffer_index += totalLen;
278 }
279 else
280 {
b.liu9e8584b2024-11-06 19:21:28 +0800281 mbtk_write(fd_radio, defaultBuffer, totalLen);
l.yang67782e62024-11-05 01:28:10 -0800282 }
b.liu9e8584b2024-11-06 19:21:28 +0800283
284
l.yang67782e62024-11-05 01:28:10 -0800285 return 0;
liubin281ac462023-07-19 14:22:54 +0800286}
287
288void* alog_thread(void* argv)
289{
290 int dev_fd, ret;
b.liu9e8584b2024-11-06 19:21:28 +0800291// int log_fd;
liubin281ac462023-07-19 14:22:54 +0800292 AndroidLogEntry entry;
293 char buf[512] = {0};
294 static struct file_list_t file_list;
295 config = (log_config_entry *)argv;
296
297 pthread_detach(pthread_self());
298 if (NULL == argv)
299 return NULL;
300
301 dev_fd = open(ALOG_DEV, O_RDONLY, 0600);
302 if (dev_fd < 0) {
303 fprintf(stderr, "failed to open %s: %s\n", ALOG_DEV, strerror(errno));
304 exit(-1);
305 }
306
307 memset(&file_list, 0, sizeof(struct file_list_t));
308 file_list.total = config->rotate_file_count;
xf.li43643772024-03-04 19:39:53 -0800309 //log_file = config->out_path;
310 memset(log_file, 0, sizeof(log_file));
311 memset(log_ip, 0, sizeof(log_ip));
312 memset(log_port, 0, sizeof(log_port));
313 memset(log_prefix, 0, sizeof(log_prefix));
314 memset(pid_file, 0, sizeof(pid_file));
315 memset(hostname, 0, sizeof(hostname));
316 if(config->out_path != NULL)
317 {
318 strncpy(log_file, config->out_path, LOG_CONFIG_LEN - 1);
319 }
liubin281ac462023-07-19 14:22:54 +0800320
b.liu9e8584b2024-11-06 19:21:28 +0800321 if (config->ip && config->port)
l.yangb7972c72024-10-15 22:34:51 -0700322 {
liubin281ac462023-07-19 14:22:54 +0800323 int port = atoi(config->port);
324 printf("%s %d : %s:%s\n", __FUNCTION__, __LINE__, config->ip, config->port);
b.liu9e8584b2024-11-06 19:21:28 +0800325 tcp_connect(config->ip, port);
326 }
327 else if (strlen(log_file) > 0)
l.yangb7972c72024-10-15 22:34:51 -0700328 {
329 //sprintf(tmp_log, "/tmp/log%s", strstr_tail(log_file, "/"));
b.liu9e8584b2024-11-06 19:21:28 +0800330
l.yangb7972c72024-10-15 22:34:51 -0700331 snprintf(tmp_log,sizeof(tmp_log), "%s", log_file);
liubin281ac462023-07-19 14:22:54 +0800332 // 先将文件保存到 /tmp/log/ 目录下,后面到达 rotate_file_size 后,转移到out_path
b.liu9e8584b2024-11-06 19:21:28 +0800333
334 }
335 else
l.yangb7972c72024-10-15 22:34:51 -0700336 {
b.liu9e8584b2024-11-06 19:21:28 +0800337 //log_fd = STDOUT_FILENO;
liubin281ac462023-07-19 14:22:54 +0800338 }
339 if(config->rotate_file_size)
l.yangb7972c72024-10-15 22:34:51 -0700340 {
liubin281ac462023-07-19 14:22:54 +0800341 log_size = config->rotate_file_size;
l.yangb7972c72024-10-15 22:34:51 -0700342 }
liubin281ac462023-07-19 14:22:54 +0800343 printf("android log start...\n");
b.liu9e8584b2024-11-06 19:21:28 +0800344 while (1)
l.yangb7972c72024-10-15 22:34:51 -0700345 {
liubin281ac462023-07-19 14:22:54 +0800346 ret = read(dev_fd, buf, sizeof(buf));
b.liu9e8584b2024-11-06 19:21:28 +0800347 if (ret < 0)
l.yangb7972c72024-10-15 22:34:51 -0700348 {
liubin281ac462023-07-19 14:22:54 +0800349 printf("read error\n");
350 break;
351 }
352 alog_process(buf, ret, &entry);
l.yangb7972c72024-10-15 22:34:51 -0700353 android_log_printLogLine(&file_list, &entry);
liubin281ac462023-07-19 14:22:54 +0800354 memset(buf, 0, sizeof(buf));
355 }
356 close(dev_fd);
b.liu9e8584b2024-11-06 19:21:28 +0800357
liubin281ac462023-07-19 14:22:54 +0800358 printf("%s exit \n", __FUNCTION__);
359 pthread_exit(NULL);
360 return NULL;
361}