42cf02e48b78a6b27b4b4ddda48c9d9ad4fc2953
[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 #include <pthread.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <stdarg.h>
20 #include <fcntl.h>
21 #include <sys/uio.h>
22 #include <stdio.h>
23 #include <errno.h>
24 #include <dlog.h>
25 #ifdef SD_JOURNAL_SUPPORT
26 #include <systemd/sd-journal.h>
27 #endif
28 #define LOG_BUF_SIZE    1024
29
30 #define LOG_MAIN        "log_main"
31 #define LOG_RADIO       "log_radio"
32 #define LOG_SYSTEM      "log_system"
33 #define LOG_APPS        "log_apps"
34
35 static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1 };
36
37 static int g_logging_on = 1;
38 static int g_dlog_level = DLOG_SILENT;
39
40 static int __dlog_init(log_id_t, log_priority, const char *tag, const char *msg);
41 static int (*write_to_log)(log_id_t, log_priority, const char *tag, const char *msg) = __dlog_init;
42 static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
43 static int __write_to_log_null(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
44 {
45         return -1;
46 }
47 #ifdef SD_JOURNAL_SUPPORT
48 static int dlog_pri_to_journal_pri(log_priority prio)
49 {
50         int journal_prio = LOG_DEBUG;
51
52         switch(prio) {
53         case DLOG_UNKNOWN:
54         case DLOG_DEFAULT:
55         case DLOG_VERBOSE:
56                 journal_prio = LOG_DEBUG;
57                 break;
58         case DLOG_DEBUG:
59                 journal_prio = LOG_DEBUG;
60                 break;
61         case DLOG_INFO:
62                 journal_prio = LOG_INFO;
63                 break;
64         case DLOG_WARN:
65                 journal_prio = LOG_WARNING;
66                 break;
67         case DLOG_ERROR:
68                 journal_prio = LOG_ERR;
69                 break;
70         case DLOG_FATAL:
71                 journal_prio = LOG_CRIT;
72                 break;
73         case DLOG_SILENT:
74         default:
75                 journal_prio = -1;
76                 break;
77         }
78         return journal_prio;
79 }
80 static int __write_to_log_sd_journal_print(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
81 {
82         sd_journal_print(dlog_pri_to_journal_pri(prio), "%s %s", tag, msg);
83         return 1;
84 }
85 #else
86 static int __write_to_log_kernel(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
87 {
88         ssize_t ret;
89         int log_fd;
90         struct iovec vec[3];
91
92         if (log_id < LOG_ID_APPS) {
93                 if(prio < g_dlog_level) {
94                         return 0;
95                 }
96         } else if (LOG_ID_MAX <= log_id) {
97                 return 0;
98         }
99         if (log_id < LOG_ID_MAX)
100                 log_fd = log_fds[log_id];
101         else
102                 return -1; // for TC
103
104         if (!tag)
105                 tag = "";
106
107         vec[0].iov_base = (unsigned char *) &prio;
108         vec[0].iov_len  = 1;
109         vec[1].iov_base = (void *) tag;
110         vec[1].iov_len  = strlen(tag) + 1;
111         vec[2].iov_base = (void *) msg;
112         vec[2].iov_len  = strlen(msg) + 1;
113
114         ret = writev(log_fd, vec, 3);
115
116         return ret;
117 }
118 #endif
119 void init_dlog_level(void)
120 {
121         char *dlog_level_env;
122         char *logging_mode_env;
123         if (g_logging_on) {
124                 logging_mode_env = getenv("TIZEN_PLATFORMLOGGING_MODE");
125                 if (!logging_mode_env)
126                                 g_logging_on = 0;
127                         else
128                                 g_logging_on = atoi(logging_mode_env);
129         }
130         if (g_logging_on) {
131                 dlog_level_env = getenv("TIZEN_DLOG_LEVEL");
132                 if (!dlog_level_env) {
133                         g_dlog_level = 8;
134                 } else {
135                         g_dlog_level = atoi(dlog_level_env);
136                 }
137         } else
138                 g_dlog_level = 8;
139 }
140 static int __dlog_init(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
141 {
142         pthread_mutex_lock(&log_init_lock);
143 #ifdef SD_JOURNAL_SUPPORT
144         write_to_log = __write_to_log_sd_journal_print;
145 #else
146         // get filtering info
147         // open device
148         if (write_to_log == __dlog_init) {
149                 init_dlog_level();
150
151                 log_fds[LOG_ID_MAIN] = open("/dev/"LOG_MAIN, O_WRONLY);
152                 log_fds[LOG_ID_RADIO] = open("/dev/"LOG_RADIO, O_WRONLY);
153                 log_fds[LOG_ID_SYSTEM] = open("/dev/"LOG_SYSTEM, O_WRONLY);
154                 log_fds[LOG_ID_APPS] = open("/dev/"LOG_APPS, O_WRONLY);
155
156                 if (log_fds[LOG_ID_MAIN] < 0 || log_fds[LOG_ID_RADIO] < 0) {
157                         fprintf(stderr, "open log dev is failed\n");
158                         write_to_log = __write_to_log_null;
159                 } else
160                         write_to_log = __write_to_log_kernel;
161
162                 if (log_fds[LOG_ID_SYSTEM] < 0)
163                         log_fds[LOG_ID_SYSTEM] = log_fds[LOG_ID_MAIN];
164
165                 if (log_fds[LOG_ID_APPS] < 0)
166                         log_fds[LOG_ID_APPS] = log_fds[LOG_ID_MAIN];
167         }
168 #endif
169         pthread_mutex_unlock(&log_init_lock);
170         return write_to_log(log_id, prio, tag, msg);
171 }
172
173 int __dlog_vprint(log_id_t log_id, int prio, const char *tag, const char *fmt, va_list ap)
174 {
175         char buf[LOG_BUF_SIZE];
176
177         vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
178
179         return write_to_log(log_id, prio, tag, buf);
180 }
181
182 int __dlog_print(log_id_t log_id, int prio, const char *tag, const char *fmt, ...)
183 {
184         va_list ap;
185         char buf[LOG_BUF_SIZE];
186
187         va_start(ap, fmt);
188         vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
189         va_end(ap);
190
191         return write_to_log(log_id, prio, tag, buf);
192 }
193 int _get_logging_on(void)
194 {
195         return g_logging_on;
196 }