4abdcf97d7d1f536f4daaca3d7ef87ebce2cbaf1
[framework/system/dlog.git] / log.c
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifdef HAVE_PTHREADS
17 #include <pthread.h>
18 #endif
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdarg.h>
22 #include <fcntl.h>
23 #include <sys/uio.h>
24 #include <stdio.h>
25 #include <errno.h>
26 #include <dlog.h>
27 #ifdef SD_JOURNAL_SUPPORT
28 #include <systemd/sd-journal.h>
29 #endif
30 #define LOG_BUF_SIZE    1024
31
32 #define LOG_MAIN        "log_main"
33 #define LOG_RADIO       "log_radio"
34 #define LOG_SYSTEM      "log_system"
35 #define LOG_APPS        "log_apps"
36
37 static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1 };
38
39 static int g_logging_on = 1;
40 static int g_dlog_level = DLOG_SILENT;
41
42 static int __dlog_init(log_id_t, log_priority, const char *tag, const char *msg);
43 static int (*write_to_log)(log_id_t, log_priority, const char *tag, const char *msg) = __dlog_init;
44 #ifdef HAVE_PTHREADS
45 static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
46 #endif
47 static int __write_to_log_null(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
48 {
49         return -1;
50 }
51 #ifdef SD_JOURNAL_SUPPORT
52 static int dlog_pri_to_journal_pri(log_priority prio)
53 {
54         int journal_prio = LOG_DEBUG;
55
56         switch(prio) {
57         case DLOG_UNKNOWN:
58         case DLOG_DEFAULT:
59         case DLOG_VERBOSE:
60                 journal_prio = LOG_DEBUG;
61                 break;
62         case DLOG_DEBUG:
63                 journal_prio = LOG_DEBUG;
64                 break;
65         case DLOG_INFO:
66                 journal_prio = LOG_INFO;
67                 break;
68         case DLOG_WARN:
69                 journal_prio = LOG_WARNING;
70                 break;
71         case DLOG_ERROR:
72                 journal_prio = LOG_ERR;
73                 break;
74         case DLOG_FATAL:
75                 journal_prio = LOG_CRIT;
76                 break;
77         case DLOG_SILENT:
78         default:
79                 journal_prio = -1;
80                 break;
81         }
82         return journal_prio;
83 }
84 static int __write_to_log_kernel(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
85 {
86         sd_journal_print(dlog_pri_to_journal_pri(prio), "%s %s", tag, msg);
87         return 1;
88 }
89 #else
90 static int __write_to_log_kernel(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
91 {
92         ssize_t ret;
93         int log_fd;
94         struct iovec vec[3];
95
96         if (log_id < LOG_ID_APPS) {
97                 if(prio < g_dlog_level) {
98                         return 0;
99                 }
100         } else if (LOG_ID_MAX <= log_id) {
101                 return 0;
102         }
103         if (log_id < LOG_ID_MAX)
104                 log_fd = log_fds[log_id];
105         else
106                 return -1; // for TC
107
108         if (!tag)
109                 tag = "";
110
111         vec[0].iov_base = (unsigned char *) &prio;
112         vec[0].iov_len  = 1;
113         vec[1].iov_base = (void *) tag;
114         vec[1].iov_len  = strlen(tag) + 1;
115         vec[2].iov_base = (void *) msg;
116         vec[2].iov_len  = strlen(msg) + 1;
117
118         ret = writev(log_fd, vec, 3);
119
120         return ret;
121 }
122 #endif
123 void init_dlog_level(void)
124 {
125         char *dlog_level;
126         char *logging_mode;
127         if (g_logging_on) {
128                 logging_mode = getenv("TIZEN_PLATFORMLOGGING_MODE");
129                 if (!logging_mode)
130                                 g_logging_on = 0;
131                         else
132                                 g_logging_on = atoi(logging_mode);
133         }
134         if (g_logging_on) {
135                 dlog_level = getenv("TIZEN_DLOG_LEVEL");
136                 if (!dlog_level) {
137                         g_dlog_level = 8;
138                 } else {
139                         g_dlog_level = atoi(dlog_level);
140                 }
141         } else
142                 g_dlog_level = 8;
143 }
144 static int __dlog_init(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
145 {
146 #ifdef HAVE_PTHREADS
147         pthread_mutex_lock(&log_init_lock);
148 #endif
149         // get filtering info
150         // open device
151         if (write_to_log == __dlog_init) {
152 #ifdef SD_JOURNAL_SUPPORT
153                 write_to_log = __write_to_log_sd_journal_print;
154 #else
155                 init_dlog_level();
156
157                 log_fds[LOG_ID_MAIN] = open("/dev/"LOG_MAIN, O_WRONLY);
158                 log_fds[LOG_ID_RADIO] = open("/dev/"LOG_RADIO, O_WRONLY);
159                 log_fds[LOG_ID_SYSTEM] = open("/dev/"LOG_SYSTEM, O_WRONLY);
160                 log_fds[LOG_ID_APPS] = open("/dev/"LOG_APPS, O_WRONLY);
161
162                 if (log_fds[LOG_ID_MAIN] < 0 || log_fds[LOG_ID_RADIO] < 0) {
163                         fprintf(stderr, "open log dev is failed\n");
164                         write_to_log = __write_to_log_null;
165                 } else
166                         write_to_log = __write_to_log_kernel;
167
168                 if (log_fds[LOG_ID_SYSTEM] < 0)
169                         log_fds[LOG_ID_SYSTEM] = log_fds[LOG_ID_MAIN];
170
171                 if (log_fds[LOG_ID_APPS] < 0)
172                         log_fds[LOG_ID_APPS] = log_fds[LOG_ID_MAIN];
173 #endif
174         }
175 #ifdef HAVE_PTHREADS
176         pthread_mutex_unlock(&log_init_lock);
177 #endif
178         return write_to_log(log_id, prio, tag, msg);
179 }
180
181 int __dlog_vprint(log_id_t log_id, int prio, const char *tag, const char *fmt, va_list ap)
182 {
183         char buf[LOG_BUF_SIZE];
184
185         vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
186
187         return write_to_log(log_id, prio, tag, buf);
188 }
189
190 int __dlog_print(log_id_t log_id, int prio, const char *tag, const char *fmt, ...)
191 {
192         va_list ap;
193         char buf[LOG_BUF_SIZE];
194
195         va_start(ap, fmt);
196         vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
197         va_end(ap);
198
199         return write_to_log(log_id, prio, tag, buf);
200 }
201 int _get_logging_on(void)
202 {
203         return g_logging_on;
204 }