blob: 3f13ab6307f2704ff406e29523e5caa69ac39a27 [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>
12#include "log_config.h"
13
14#define ALOG_DEV "/dev/log_radio"
xf.li43643772024-03-04 19:39:53 -080015#define LOG_CONFIG_LEN 50
liubin281ac462023-07-19 14:22:54 +080016
17typedef enum android_LogPriority {
18 ANDROID_LOG_UNKNOWN = 0,
19 ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
20 ANDROID_LOG_VERBOSE,
21 ANDROID_LOG_DEBUG,
22 ANDROID_LOG_INFO,
23 ANDROID_LOG_WARN,
24 ANDROID_LOG_ERROR,
25 ANDROID_LOG_FATAL,
26 ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
27} android_LogPriority;
28
29typedef struct AndroidLogEntry_t {
30 time_t tv_sec;
31 long tv_nsec;
32 android_LogPriority priority;
33 int32_t pid;
34 int32_t tid;
35 const char * tag;
36 size_t messageLen;
37 const char * message;
38} AndroidLogEntry;
39
xf.li43643772024-03-04 19:39:53 -080040//static const char *log_file, *log_ip, *log_port, *log_prefix, *pid_file, *hostname;
41static 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 +080042static int log_size = 1 * 1024 * 1024;
43
44static log_config_entry *config = NULL;
45static char tmp_log[48] = {0};
46
l.yangb7972c72024-10-15 22:34:51 -070047static int fd_radio = 0;
48
liubin281ac462023-07-19 14:22:54 +080049void hex_print(char* buf, int len)
50{
51 int i;
52
53 for (i = 0; i < len; i++) {
54 printf("%x ", buf[i]);
55 }
56}
57
58static char filterPriToChar(android_LogPriority pri)
59{
60 switch (pri) {
61 case ANDROID_LOG_VERBOSE:
62 return 'V';
63 case ANDROID_LOG_DEBUG:
64 return 'D';
65 case ANDROID_LOG_INFO:
66 return 'I';
67 case ANDROID_LOG_WARN:
68 return 'W';
69 case ANDROID_LOG_ERROR:
70 return 'E';
71 case ANDROID_LOG_FATAL:
72 return 'F';
73 case ANDROID_LOG_SILENT:
74 return 'S';
75
76 case ANDROID_LOG_DEFAULT:
77 case ANDROID_LOG_UNKNOWN:
78 default:
79 return '?';
80 }
81}
82
83static android_LogPriority filterCharToPri(char c)
84{
85 switch (c) {
86 case 'v':
87 return ANDROID_LOG_VERBOSE;
88 case 'd':
89 return ANDROID_LOG_DEBUG;
90 case 'i':
91 return ANDROID_LOG_INFO;
92 case 'w':
93 return ANDROID_LOG_WARN;
94 case 'e':
95 return ANDROID_LOG_ERROR;
96 case 'f':
97 return ANDROID_LOG_FATAL;
98 case 's':
99 return ANDROID_LOG_SILENT;
100 case '*':
101 default:
102 return ANDROID_LOG_VERBOSE;
103 }
104}
105
106int fileter_log(int pri, char *tag, struct filter_list_t *filter)
107{
108 struct filter_list_t *_filter = filter;
109
110 while(_filter)
111 {
112 int p = filterCharToPri(_filter->priority);
113 if(_filter->tag)
114 {
115 int len = strlen(_filter->tag);
116 // tag and priority
117 if(0 == memcmp(_filter->tag, tag, len) && ((pri > p) || (pri == p)))
118 return 0;
119 }else{ // have no tag
120 if(pri < p)
121 return -1;
122 else
123 return 0;
124 }
125 _filter = _filter->next;
126 }
127
128 return -1;
129}
130
131int alog_process(char* data, int len, AndroidLogEntry *entry)
132{
133 int i, n = 0;
134 int tmp_len;
135
136 for (i = 0; i < len;) {
137 if (data[i] == '\0') {
138 i += 1;
139 } else {
140 switch (n) {
141 case 0: {
142 // printf("%d - %d: %x\n", i, tmp_len, data[i]);
143 i++;
144 break;
145 }
146 case 1: {
147 int* pid = (int*)&data[i];
148 entry->pid = *pid;
149 // printf("%d pid: %d\n", i, entry->pid);
150 i += 4;
151 break;
152 }
153 case 2: {
154 int* tid = (int*)&data[i];
155 entry->tid = *tid;
156 // printf("%d tid: %d\n", i, entry->tid);
157 i += 4;
158 break;
159 }
160 case 3: {
161 // printf("%d - %d: %x %x %x %x\n", i, tmp_len, data[i], data[i + 1], data[i + 2], data[i + 3]);
162 time_t* _t = (time_t*)&data[i];
163 entry->tv_sec = *_t;
164 i += 8;
165 break;
166 }
167 case 4: {
168 entry->priority = data[i];
169 entry->tag = &data[i + 1];
170 i += strlen(&data[i]);
171 break;
172 }
173 //* format: <priority:1><tag:N>\0<message:N>\0
174 case 5: {
175 entry->message = &data[i];
176 entry->messageLen = strlen(&data[i]);
177 i += entry->messageLen;
178 break;
179 }
180 default:
181 printf("process error \n");
182 break;
183 }
184 n++;
185 }
186 }
187 return 0;
188}
189
190int android_log_printLogLine(
liubin281ac462023-07-19 14:22:54 +0800191 struct file_list_t *_file_list,
192 const AndroidLogEntry *entry)
193{
194 char priChar;
195 char timeBuf[32];
196 char defaultBuffer[512];
197 size_t totalLen;
l.yangb7972c72024-10-15 22:34:51 -0700198
199 struct stat s;
liubin281ac462023-07-19 14:22:54 +0800200 char * ret = NULL;
l.yangb7972c72024-10-15 22:34:51 -0700201
202 if(access(tmp_log, W_OK) != 0)
203 {
204 fd_radio = open(tmp_log, O_CREAT | O_WRONLY| O_APPEND, 0600);
205 if (fd_radio < 0)
206 {
207 fprintf(stderr, "failed to open %s: %s\n", tmp_log, strerror(errno));
208 exit(-1);
liubin281ac462023-07-19 14:22:54 +0800209 }
l.yangb7972c72024-10-15 22:34:51 -0700210
211 }
212
213 if (log_size && (!stat(tmp_log, &s)) && (s.st_size > log_size))
214 {
215 fd_radio = get_rotate_file(fd_radio, log_file, _file_list);
216 if (fd_radio < 0)
217 {
218 fprintf(stderr, "failed to open %s: %s\n", log_file, strerror(errno));
219 exit(-1);
220 }
221 }
liubin281ac462023-07-19 14:22:54 +0800222
223 if(fileter_log(entry->priority, entry->tag, config->filter_list))
224 {
225 // printf("%s %d: fileter pri:%d tag:%s!\n", __FUNCTION__, __LINE__, entry->priority, entry->tag);
226 return -1;
227 }
228
229 priChar = filterPriToChar(entry->priority);
230 struct tm* ptm = localtime(&entry->tv_sec);
231 strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", ptm);
232
233 totalLen = snprintf(defaultBuffer, sizeof(defaultBuffer),
234 "%s %c/%s (%d): %s\n", timeBuf, priChar, entry->tag, entry->pid, entry->message);
235
l.yangb7972c72024-10-15 22:34:51 -0700236 ret = write(fd_radio, defaultBuffer, totalLen);
liubin281ac462023-07-19 14:22:54 +0800237
238 return ret;
239}
240
241void* alog_thread(void* argv)
242{
243 int dev_fd, ret;
244 int log_fd;
245 AndroidLogEntry entry;
246 char buf[512] = {0};
247 static struct file_list_t file_list;
248 config = (log_config_entry *)argv;
249
250 pthread_detach(pthread_self());
251 if (NULL == argv)
252 return NULL;
253
254 dev_fd = open(ALOG_DEV, O_RDONLY, 0600);
255 if (dev_fd < 0) {
256 fprintf(stderr, "failed to open %s: %s\n", ALOG_DEV, strerror(errno));
257 exit(-1);
258 }
259
260 memset(&file_list, 0, sizeof(struct file_list_t));
261 file_list.total = config->rotate_file_count;
xf.li43643772024-03-04 19:39:53 -0800262 //log_file = config->out_path;
263 memset(log_file, 0, sizeof(log_file));
264 memset(log_ip, 0, sizeof(log_ip));
265 memset(log_port, 0, sizeof(log_port));
266 memset(log_prefix, 0, sizeof(log_prefix));
267 memset(pid_file, 0, sizeof(pid_file));
268 memset(hostname, 0, sizeof(hostname));
269 if(config->out_path != NULL)
270 {
271 strncpy(log_file, config->out_path, LOG_CONFIG_LEN - 1);
272 }
liubin281ac462023-07-19 14:22:54 +0800273
l.yangb7972c72024-10-15 22:34:51 -0700274 if (config->ip && config->port)
275 {
liubin281ac462023-07-19 14:22:54 +0800276 int port = atoi(config->port);
277 printf("%s %d : %s:%s\n", __FUNCTION__, __LINE__, config->ip, config->port);
278 log_fd = tcp_connect(config->ip, port);
l.yangb7972c72024-10-15 22:34:51 -0700279 }
280 else if (strlen(log_file) > 0)
281 {
282 //sprintf(tmp_log, "/tmp/log%s", strstr_tail(log_file, "/"));
283
284 snprintf(tmp_log,sizeof(tmp_log), "%s", log_file);
liubin281ac462023-07-19 14:22:54 +0800285 // 先将文件保存到 /tmp/log/ 目录下,后面到达 rotate_file_size 后,转移到out_path
l.yangb7972c72024-10-15 22:34:51 -0700286
287 }
288 else
289 {
liubin281ac462023-07-19 14:22:54 +0800290 log_fd = STDOUT_FILENO;
291 }
292 if(config->rotate_file_size)
l.yangb7972c72024-10-15 22:34:51 -0700293 {
liubin281ac462023-07-19 14:22:54 +0800294 log_size = config->rotate_file_size;
l.yangb7972c72024-10-15 22:34:51 -0700295 }
liubin281ac462023-07-19 14:22:54 +0800296 printf("android log start...\n");
l.yangb7972c72024-10-15 22:34:51 -0700297 while (1)
298 {
liubin281ac462023-07-19 14:22:54 +0800299 ret = read(dev_fd, buf, sizeof(buf));
l.yangb7972c72024-10-15 22:34:51 -0700300 if (ret < 0)
301 {
liubin281ac462023-07-19 14:22:54 +0800302 printf("read error\n");
303 break;
304 }
305 alog_process(buf, ret, &entry);
l.yangb7972c72024-10-15 22:34:51 -0700306 android_log_printLogLine(&file_list, &entry);
liubin281ac462023-07-19 14:22:54 +0800307 memset(buf, 0, sizeof(buf));
308 }
309 close(dev_fd);
l.yangb7972c72024-10-15 22:34:51 -0700310
liubin281ac462023-07-19 14:22:54 +0800311 printf("%s exit \n", __FUNCTION__);
312 pthread_exit(NULL);
313 return NULL;
314}