tizen 2.3 release
[apps/livebox/data-provider-master.git] / src / critical_log.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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
17 #include <stdio.h>
18 #include <stdarg.h>
19 #include <stdlib.h>
20 #include <sys/time.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <libgen.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 #include <pthread.h>
27
28 #include <dlog.h>
29 #include <Eina.h>
30 #if defined(HAVE_LIVEBOX)
31 #include <dynamicbox_errno.h>
32 #include <dynamicbox_conf.h>
33 #else
34 #include "lite-errno.h"
35 #endif
36
37 #include "conf.h"
38 #include "debug.h"
39 #include "util.h"
40 #include "critical_log.h"
41
42 static struct {
43         FILE *fp;
44         int file_id;
45         int nr_of_lines;
46         char *filename;
47         pthread_mutex_t cri_lock;
48 } s_info = {
49         .fp = NULL,
50         .file_id = 0,
51         .nr_of_lines = 0,
52         .filename = NULL,
53         .cri_lock = PTHREAD_MUTEX_INITIALIZER,
54 };
55
56
57
58 static inline void rotate_log(void)
59 {
60         char *filename;
61         int namelen;
62
63         if (s_info.nr_of_lines < DYNAMICBOX_CONF_MAX_LOG_LINE) {
64                 return;
65         }
66
67         s_info.file_id = (s_info.file_id + 1) % DYNAMICBOX_CONF_MAX_LOG_FILE;
68
69         namelen = strlen(s_info.filename) + strlen(DYNAMICBOX_CONF_LOG_PATH) + 30;
70         filename = malloc(namelen);
71         if (filename) {
72                 snprintf(filename, namelen, "%s/%d_%s.%d", DYNAMICBOX_CONF_LOG_PATH, s_info.file_id, s_info.filename, getpid());
73
74                 if (s_info.fp) {
75                         if (fclose(s_info.fp) != 0) {
76                                 ErrPrint("fclose: %s\n", strerror(errno));
77                         }
78                 }
79
80                 s_info.fp = fopen(filename, "w+");
81                 if (!s_info.fp) {
82                         ErrPrint("Failed to open a file: %s\n", filename);
83                 }
84
85                 DbgFree(filename);
86         }
87
88         s_info.nr_of_lines = 0;
89 }
90
91
92
93 HAPI int critical_log(const char *func, int line, const char *fmt, ...)
94 {
95         va_list ap;
96         int ret;
97
98         if (!s_info.fp) {
99                 return DBOX_STATUS_ERROR_IO_ERROR;
100         }
101
102         CRITICAL_SECTION_BEGIN(&s_info.cri_lock);
103
104         fprintf(s_info.fp, "%lf [%s:%d] ", util_timestamp(), util_basename((char *)func), line);
105
106         va_start(ap, fmt);
107         ret = vfprintf(s_info.fp, fmt, ap);
108         va_end(ap);
109
110         fflush(s_info.fp);
111
112         s_info.nr_of_lines++;
113         rotate_log();
114
115         CRITICAL_SECTION_END(&s_info.cri_lock);
116         return ret;
117 }
118
119
120
121 HAPI int critical_log_init(const char *name)
122 {
123         int namelen;
124         char *filename;
125
126         if (s_info.fp) {
127                 return DBOX_STATUS_ERROR_NONE;
128         }
129
130         s_info.filename = strdup(name);
131         if (!s_info.filename) {
132                 ErrPrint("Failed to create a log file\n");
133                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
134         }
135
136         namelen = strlen(name) + strlen(DYNAMICBOX_CONF_LOG_PATH) + 30;
137
138         filename = malloc(namelen);
139         if (!filename) {
140                 ErrPrint("Failed to create a log file\n");
141                 DbgFree(s_info.filename);
142                 s_info.filename = NULL;
143                 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
144         }
145
146         snprintf(filename, namelen, "%s/%d_%s.%d", DYNAMICBOX_CONF_LOG_PATH, s_info.file_id, name, getpid());
147
148         s_info.fp = fopen(filename, "w+");
149         if (!s_info.fp) {
150                 ErrPrint("Failed to open log: %s\n", strerror(errno));
151                 DbgFree(s_info.filename);
152                 s_info.filename = NULL;
153                 DbgFree(filename);
154                 return DBOX_STATUS_ERROR_IO_ERROR;
155         }
156
157         DbgFree(filename);
158         return DBOX_STATUS_ERROR_NONE;
159 }
160
161
162
163 HAPI void critical_log_fini(void)
164 {
165         if (s_info.filename) {
166                 DbgFree(s_info.filename);
167                 s_info.filename = NULL;
168         }
169
170         if (s_info.fp) {
171                 if (fclose(s_info.fp) != 0) {
172                         ErrPrint("fclose: %s\n", strerror(errno));
173                 }
174                 s_info.fp = NULL;
175         }
176 }
177
178
179
180 /* End of a file */