1 /*
2 * Copyright (C) 2015-2019 Alibaba Group Holding Limited
3 */
4
5 #include "ulog/ulog.h"
6 #include "ulog_api.h"
7
8 #include <string.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <stdarg.h>
12 #include "aos/kernel.h"
13 #if ULOG_POP_CLOUD_ENABLE
14 #include "uagent_type.h"
15 #endif
16 bool aos_ulog_init = false;
17
18 extern void (*aos_cust_output_func)(const char *fmt, ...);
19 #if AOS_COMP_CLI
20
21 #include "aos/cli.h"
22
update_net_cli(const char cmd,const char * param)23 __attribute__((weak)) void update_net_cli(const char cmd, const char *param)
24 {
25 /* Will be overwrite in session_udp, as this implement take effect only the UDP feature support,
26 I don't like so many compile switcher in the code which result reader is not so comfortable,
27 so weak attribute used here.
28 */
29 }
30
fs_control_cli(const char cmd,const char * param)31 __attribute__((weak)) void fs_control_cli(const char cmd, const char *param)
32 {
33 /* Will be overwrite in session_fs */
34 }
35
on_show_ulog_file()36 __attribute__((weak)) void on_show_ulog_file()
37 {
38 /* Will be overwrite in session_fs */
39 }
40
41 #if ULOG_CONFIG_ASYNC
cmd_cli_ulog(char * pwbuf,int blen,int argc,char * argv[])42 static void cmd_cli_ulog(char *pwbuf, int blen, int argc, char *argv[])
43 {
44 bool exit_loop = false;
45 uint8_t session = 0xFF;
46 uint8_t level = 0xFF;
47 uint8_t i;
48
49 if (argc == 2) {
50 const char* option = argv[1];
51 switch (option[0]) {
52 case 'f':
53 on_show_ulog_file();
54 break;
55 case 'x': {
56 #if ULOG_CONFIG_POP_FS
57 char *buf = (char*)aos_malloc(512);
58 if (NULL != buf) {
59 aos_cli_printf("get ulog list %d\n", aos_get_ulog_list(buf, 512));
60 puts(buf);
61 aos_free(buf);
62 }
63 #else
64 aos_cli_printf("pop log to fs is off");
65 #endif /* ULOG_CONFIG_POP_FS */
66 }
67 break;
68 default:
69 break;
70 }
71 }
72 for (i = 1; i < argc && !exit_loop; i += 2) {
73 const char* option = argv[i];
74 const char* param = argv[i + 1];
75 if (option != NULL && param != NULL && strlen(option) == 1) {
76 switch (option[0]) {
77 case 's':/* session */
78 session = strtoul(param, NULL, 10);
79 break;
80 case 'l':/* level */
81 level = strtoul(param, NULL, 10);
82 break;
83 case 'a':/* syslog watcher address */
84 update_net_cli(option[0], param);
85 break;
86 case 'p': /* syslog wacher port*/
87 update_net_cli(option[0], param);
88 break;
89 case 'n': /*tcpip on/off*/
90 update_net_cli(option[0], param);
91 break;
92 case 't':/* terminate record on fs */
93 fs_control_cli(option[0], param);
94 break;
95 default: /* unknown option */
96 exit_loop = true;
97 break;
98 }
99 } else {/* unknown format */
100 break;
101 }
102 }
103
104 if ((session < ulog_session_size) && (level <= LOG_NONE)) {
105 on_filter_level_changes((ulog_session_type_t)session, level);
106 }
107 }
108 #endif
109
110 extern int aos_cli_printf(const char *fmt, ...);
sync_log_cmd(char * buf,int len,int argc,char ** argv)111 static void sync_log_cmd(char *buf, int len, int argc, char **argv)
112 {
113 if (argc < 2) {
114 aos_cli_printf("log level : %s\r\n", get_sync_stop_level());
115 return;
116 } else if (argc == 2) {
117 const char* option = argv[1];
118 switch (option[0]) {
119 case 'A':
120 case 'F':
121 case 'E':
122 case 'W':
123 case 'I':
124 case 'D':
125 case 'N':
126 on_sync_filter_level_change(ulog_session_std, option[0]);
127 break;
128
129 default:
130 aos_cli_printf("unknown option %c, only support[AFEWID]\r\n", option[0]);
131 break;
132 }
133 }
134
135 }
136
137 static struct cli_command ulog_cli_cmd[] = {
138 { "loglevel","set sync log level", sync_log_cmd },
139 #if ULOG_CONFIG_ASYNC
140 { "ulog", "ulog [option param]", cmd_cli_ulog },
141 #endif
142 };
143
144 #endif /* AOS_COMP_CLI */
145
146 #if (ULOG_POP_CLOUD_ENABLE || ULOG_UPLOAD_LOG_FILE)
147 #include "cJSON.h"
148
on_ulog_handler(void * p,const unsigned short len,void * cmd)149 static int on_ulog_handler(void *p, const unsigned short len, void *cmd)
150 {
151 int rc = -1;
152 cJSON *root = NULL;
153 root = cJSON_Parse(cmd);
154 if (NULL != root) {
155 cJSON *ulog_cmd = NULL;
156 #if ULOG_POP_CLOUD_ENABLE
157 ulog_cmd = cJSON_GetObjectItem(root, "ulog level");
158 if (ulog_cmd != NULL && cJSON_IsNumber(ulog_cmd)) {
159 if(ULOG_POLICY_RQST == ulog_cmd->valueint) {
160 char buf[64];
161 snprintf(buf, sizeof(buf), ULOG_LEVEL_RSP, ulog_stop_filter_level(ulog_session_cloud));
162 rc = uagent_send(UAGENT_MOD_ULOG, ULOG_POLICY,
163 strlen(buf), buf, send_policy_object);
164
165 }
166
167 if (ulog_cmd->valueint <= LOG_NONE) {
168 on_filter_change(ulog_session_cloud, ulog_cmd->valueint);
169 rc = 0;
170 }
171 }
172 #endif
173
174 #if ULOG_UPLOAD_LOG_FILE
175 /* log list requset */
176 ulog_cmd = cJSON_GetObjectItem(root, "ulog list");
177
178 if (ulog_cmd != NULL && cJSON_IsString(ulog_cmd)) {
179 if (0 == strlen(ulog_cmd->valuestring)) {
180 char *buf = (char*)aos_malloc(1024);
181 memset(buf, 0, 1024);
182 if (NULL != buf) {
183 if (0 == aos_get_ulog_list(buf, 1024)) {
184 rc = uagent_send(UAGENT_MOD_ULOG, ULOG_LOG_LIST,
185 strlen(buf), buf, send_policy_object);
186 }
187 aos_free(buf);
188 }
189 }
190 }
191 /* request upload ulog file */
192 ulog_cmd = cJSON_GetObjectItem(root, "url");
193 if (NULL != ulog_cmd && cJSON_IsString(ulog_cmd)) {
194 cJSON *ulog_idx = cJSON_GetObjectItem(root, "idx");
195 if (NULL != ulog_idx && cJSON_IsNumber(ulog_idx)) {
196 rc = http_start(ulog_cmd->valuestring, ulog_idx->valueint);
197 }
198 }
199 #endif
200 cJSON_Delete(root);
201 }
202 return rc;
203 }
204
205 #ifndef MOD_VER
206 #define MOD_VER "1.0.0"
207 #endif
208 static uagent_func_node_t ulog_uagent_funclist[] = {
209 {ULOG_LEVEL_CHANGE, "uloglevel", on_ulog_handler, NULL, &ulog_uagent_funclist[1]},
210 {ULOG_POLICY, "ulogpolicy", NULL, NULL, &ulog_uagent_funclist[2]},
211 #if ULOG_POP_CLOUD_ENABLE
212 #if ULOG_UPLOAD_LOG_FILE
213 {ULOG_SHOW, "ulogshow", NULL, NULL, &ulog_uagent_funclist[3]},
214 #else /* !ULOG_UPLOAD_LOG_FILE */
215 {ULOG_SHOW, "ulogshow", NULL, NULL, NULL},
216 #endif
217 #endif /* ULOG_POP_CLOUD_ENABLE */
218
219 #if ULOG_UPLOAD_LOG_FILE
220 {ULOG_LOG_LIST, "loglist", NULL, NULL, NULL}
221 #endif
222 };
223
224 static mod_func_t ulog_uagent_func = {
225 { UAGENT_MOD_ULOG, sizeof(ulog_uagent_funclist) / sizeof(ulog_uagent_funclist[0]), "uLOG", MOD_VER },
226 ulog_uagent_funclist
227 };
228
229 #endif
230
ulog_init(void)231 void ulog_init(void)
232 {
233 if (!aos_ulog_init) {
234 log_init_mutex();
235 on_filter_level_changes(ulog_session_size, LOG_NONE);
236 #if ULOG_CONFIG_ASYNC
237 ulog_async_init();
238 #endif
239
240 #if AOS_COMP_CLI
241 aos_cli_register_commands(&ulog_cli_cmd[0], sizeof(ulog_cli_cmd) / sizeof(struct cli_command));
242 #endif
243 /*set default log output*/
244 if (aos_cust_output_func == NULL) {
245 aos_set_log_output(printf);
246 }
247
248 aos_ulog_init = true;
249 #if (ULOG_POP_CLOUD_ENABLE || ULOG_UPLOAD_LOG_FILE)
250
251 uagent_func_node_t * p = ulog_uagent_func.header;
252 if (NULL != p) {
253 while (NULL != p) {
254 if (0 != uagent_register(UAGENT_MOD_ULOG, "uLog", MOD_VER, p->func, p->func_name, p->service, p->argu)) {
255 LOGE("ULOG", "register into uagent fail");
256 }
257 p = p->next;
258 }
259 } else {
260 LOGE("ULOG", "register into uagent fail, table is null");
261 }
262 #endif
263 }
264 }
265
266