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