1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3 * Copyright (c) 2015 Rockchip Electronics Co., Ltd.
4 */
5
6 #define MODULE_TAG "mpp_log"
7
8 #include <stdio.h>
9 #include <string.h>
10
11 #include "mpp_env.h"
12 #include "mpp_debug.h"
13 #include "mpp_common.h"
14
15 #include "os_log.h"
16
17 #define MPP_LOG_MAX_LEN 256
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22
23 RK_U32 mpp_debug = 0;
24
25 // TODO: add log timing information and switch flag
26 static const char *msg_log_warning = "log message is long\n";
27 static const char *msg_log_nothing = "\n";
28 static int mpp_log_level = MPP_LOG_INFO;
29 static MppLogCb mpp_log_ext_cb = NULL;
30 static void *mpp_log_ext_ctx = NULL;
31
32 static os_log_callback log_func[] = {
33 NULL, /* MPP_LOG_DEFAULT */
34 os_log_fatal, /* MPP_LOG_FATAL */
35 os_log_error, /* MPP_LOG_ERROR */
36 os_log_warn, /* MPP_LOG_WARN */
37 os_log_info, /* MPP_LOG_INFO */
38 os_log_debug, /* MPP_LOG_DEBUG */
39 os_log_trace, /* MPP_LOG_VERBOSE */
40 os_log_info, /* MPP_LOG_DEFAULT */
41 };
42
__mpp_log(os_log_callback func,const char * tag,const char * fmt,const char * fname,va_list args)43 static void __mpp_log(os_log_callback func, const char *tag, const char *fmt,
44 const char *fname, va_list args)
45 {
46 char msg[MPP_LOG_MAX_LEN + 1];
47 char *tmp = msg;
48 const char *buf = fmt;
49 size_t len_fmt = strnlen(fmt, MPP_LOG_MAX_LEN);
50 size_t len_name = (fname) ? (strnlen(fname, MPP_LOG_MAX_LEN)) : (0);
51 size_t buf_left = MPP_LOG_MAX_LEN;
52 size_t len_all = len_fmt + len_name;
53
54 if (NULL == tag)
55 tag = MODULE_TAG;
56
57 if (len_name) {
58 buf = msg;
59 buf_left -= snprintf(msg, buf_left, "%s ", fname);
60 tmp += len_name + 1;
61 }
62
63 if (len_all == 0) {
64 buf = msg_log_nothing;
65 } else if (len_all >= MPP_LOG_MAX_LEN) {
66 buf_left -= snprintf(tmp, buf_left, "%s", msg_log_warning);
67 buf = msg;
68 } else {
69 snprintf(tmp, buf_left, "%s", fmt);
70 if (fmt[len_fmt - 1] != '\n') {
71 tmp[len_fmt] = '\n';
72 tmp[len_fmt + 1] = '\0';
73 }
74 buf = msg;
75 }
76
77 func(tag, buf, args);
78 }
79
_mpp_log(const char * tag,const char * fmt,const char * fname,...)80 void _mpp_log(const char *tag, const char *fmt, const char *fname, ...)
81 {
82 va_list args;
83
84 mpp_logw("warning: use new logx function\n");
85
86 va_start(args, fname);
87 __mpp_log(os_log_info, tag, fmt, fname, args);
88 va_end(args);
89 }
90
_mpp_err(const char * tag,const char * fmt,const char * fname,...)91 void _mpp_err(const char *tag, const char *fmt, const char *fname, ...)
92 {
93 va_list args;
94
95 mpp_logw("warning: use new logx function\n");
96
97 va_start(args, fname);
98 __mpp_log(os_log_error, tag, fmt, fname, args);
99 va_end(args);
100 }
101
_mpp_log_l(int level,const char * tag,const char * fmt,const char * fname,...)102 void _mpp_log_l(int level, const char *tag, const char *fmt, const char *fname, ...)
103 {
104 va_list args;
105 int log_level;
106
107 if (mpp_log_ext_cb) {
108 va_start(args, fname);
109 mpp_log_ext_cb(mpp_log_ext_ctx, level, tag, fmt, fname, args);
110 va_end(args);
111 return;
112 }
113
114 if (level <= MPP_LOG_UNKNOWN || level >= MPP_LOG_SILENT)
115 return;
116
117 log_level = mpp_log_level;
118 if (log_level >= MPP_LOG_SILENT)
119 return;
120
121 if (level > log_level)
122 return;
123
124 va_start(args, fname);
125 __mpp_log(log_func[level], tag, fmt, fname, args);
126 va_end(args);
127 }
128
mpp_llog(int level,const char * tag,const char * fmt,const char * fname,...)129 void mpp_llog(int level, const char *tag, const char *fmt, const char *fname, ...)
130 {
131 va_list args;
132 char *log_buf = NULL;
133 int log_size = SZ_1K;
134 int log_base = 0;
135 int log_len = 0;
136 int log_level;
137 int i;
138
139 if (mpp_log_ext_cb) {
140 va_start(args, fname);
141 mpp_log_ext_cb(mpp_log_ext_ctx, level, tag, fmt, fname, args);
142 va_end(args);
143 return;
144 }
145
146 if (level <= MPP_LOG_UNKNOWN || level >= MPP_LOG_SILENT)
147 return;
148
149 log_level = mpp_log_level;
150 if (log_level >= MPP_LOG_SILENT)
151 return;
152
153 if (level > log_level)
154 return;
155
156 if (NULL == tag)
157 tag = MODULE_TAG;
158
159
160 va_start(args, fname);
161
162 /* get log len and create buffer */
163 do {
164 log_buf = (char *)malloc(log_size);
165 if (!log_buf)
166 break;
167
168 log_len = vsnprintf(log_buf, log_size - 1, fmt, args);
169 if (log_len < log_size - 1)
170 break;
171
172 free(log_buf);
173 log_size <<= 1;
174 } while (1);
175
176 va_end(args);
177
178 for (i = 0; i < log_len; i++) {
179 if (log_buf[i] == '\n') {
180 /* skip empty line */
181 if (log_base < i) {
182 log_buf[i] = '\0';
183 log_func[level](tag, log_buf + log_base, args);
184 /* restore \n */
185 log_buf[i] = '\n';
186 }
187
188 log_base = i + 1;
189 }
190 }
191
192 if (log_buf)
193 free(log_buf);
194 }
195
mpp_set_log_level(int level)196 void mpp_set_log_level(int level)
197 {
198 if (level <= MPP_LOG_UNKNOWN || level > MPP_LOG_SILENT) {
199 mpp_logw("log level should in range [%d : %d] invalid intput %d\n",
200 MPP_LOG_FATAL, MPP_LOG_SILENT, level);
201 level = MPP_LOG_INFO;
202 }
203
204 mpp_log_level = level;
205 }
206
mpp_get_log_level(void)207 int mpp_get_log_level(void)
208 {
209 int level;
210
211 mpp_env_get_u32("mpp_log_level", (RK_U32 *)&level, mpp_log_level);
212
213 if (level <= MPP_LOG_UNKNOWN || level > MPP_LOG_SILENT)
214 level = MPP_LOG_INFO;
215
216 mpp_log_level = level;
217
218 return level;
219 }
220
mpp_set_log_callback(void * ctx,MppLogCb cb)221 int mpp_set_log_callback(void *ctx, MppLogCb cb)
222 {
223 mpp_log_ext_cb = cb;
224 mpp_log_ext_ctx = ctx;
225
226 return 0;
227 }
228
229 #ifdef __cplusplus
230 }
231 #endif
232