1 /*
2  *  Tvheadend - logging
3  *  Copyright (C) 2012 Adam Sutton
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 #ifndef __TVH_LOGGING_H__
19 #define __TVH_LOGGING_H__
20 
21 #include <sys/types.h>
22 #include "build.h"
23 #if ENABLE_ANDROID
24 #include <syslog.h>
25 #else
26 #include <sys/syslog.h>
27 #endif
28 #include <pthread.h>
29 #include <stdarg.h>
30 #include <time.h>
31 
32 #include "atomic.h"
33 #include "clock.h"
34 #include "htsmsg.h"
35 
36 typedef struct {
37   int64_t last;
38   size_t count;
39 } tvhlog_limit_t;
40 
41 typedef struct {
42   const char *name;
43   const char *desc;
44 } tvhlog_subsys_t;
45 
46 /* Config */
47 extern int              tvhlog_level;
48 extern char            *tvhlog_path;
49 extern int              tvhlog_options;
50 extern pthread_mutex_t  tvhlog_mutex;
51 extern tvhlog_subsys_t  tvhlog_subsystems[];
52 
53 /* Initialise */
54 void tvhlog_init       ( int level, int options, const char *path );
55 void tvhlog_start      ( void );
56 void tvhlog_end        ( void );
57 void tvhlog_set_debug  ( const char *subsys );
58 void tvhlog_get_debug  ( char *subsys, size_t len );
59 void tvhlog_set_trace  ( const char *subsys );
60 void tvhlog_get_trace  ( char *subsys, size_t len );
61 void tvhlogv           ( const char *file, int line, int severity,
62                          int subsys, const char *fmt, va_list *args );
63 void _tvhlog           ( const char *file, int line, int severity,
64                          int subsys, const char *fmt, ... )
65   __attribute__((format(printf,5,6)));
66 void _tvhlog_hexdump   ( const char *file, int line, int severity,
67                          int subsys, const uint8_t *data, ssize_t len );
tvhlog_limit_reset(tvhlog_limit_t * limit)68 static inline void tvhlog_limit_reset ( tvhlog_limit_t *limit )
69   { limit->last = 0; limit->count = 0; }
tvhlog_limit(tvhlog_limit_t * limit,uint32_t delay)70 static inline int tvhlog_limit ( tvhlog_limit_t *limit, uint32_t delay )
71   { int64_t t = mclk(); limit->count++;
72     if (limit->last + sec2mono(delay) < t) { limit->last = t; return 1; }
73     return 0; }
74 
75 
76 /* Options */
77 #define TVHLOG_OPT_DBG_SYSLOG   0x0001
78 #define TVHLOG_OPT_DBG_STDERR   0x0002
79 #define TVHLOG_OPT_DBG_FILE     0x0004
80 #define TVHLOG_OPT_SYSLOG       0x0010
81 #define TVHLOG_OPT_STDERR       0x0020
82 #define TVHLOG_OPT_MILLIS       0x0100
83 #define TVHLOG_OPT_DECORATE     0x0200
84 #define TVHLOG_OPT_FILELINE     0x0400
85 #define TVHLOG_OPT_THREAD       0x0800
86 #define TVHLOG_OPT_LIBAV        0x1000
87 #define TVHLOG_OPT_ALL          0xFFFF
88 
89 /* Levels */
90 #ifndef LOG_TRACE
91 #define LOG_TRACE (LOG_DEBUG+1)
92 #endif
93 
94 #define LOG_TVH_NOTIFY 0x40000000
95 
96 /* Subsystems */
97 enum {
98   LS_NONE,
99   LS_START,
100   LS_STOP,
101   LS_CRASH,
102   LS_MAIN,
103   LS_GTIMER,
104   LS_MTIMER,
105   LS_CPU,
106   LS_THREAD,
107   LS_TVHPOLL,
108   LS_TIME,
109   LS_SPAWN,
110   LS_FSMONITOR,
111   LS_LOCK,
112   LS_UUID,
113   LS_IDNODE,
114   LS_URL,
115   LS_TCP,
116   LS_RTSP,
117   LS_UPNP,
118   LS_SETTINGS,
119   LS_CONFIG,
120   LS_ACCESS,
121   LS_CRON,
122   LS_DBUS,
123   LS_AVAHI,
124   LS_BONJOUR,
125   LS_API,
126   LS_HTTP,
127   LS_HTTPC,
128   LS_HTSP,
129   LS_HTSP_SUB,
130   LS_HTSP_REQ,
131   LS_HTSP_ANS,
132   LS_IMAGECACHE,
133   LS_TBL,
134   LS_TBL_BASE,
135   LS_TBL_CSA,
136   LS_TBL_EIT,
137   LS_TBL_TIME,
138   LS_TBL_ATSC,
139   LS_TBL_PASS,
140   LS_TBL_SATIP,
141   LS_FASTSCAN,
142   LS_PARSER,
143   LS_TS,
144   LS_GLOBALHEADERS,
145   LS_TSFIX,
146   LS_HEVC,
147   LS_MUXER,
148   LS_PASS,
149   LS_AUDIOES,
150   LS_MKV,
151   LS_SERVICE,
152   LS_CHANNEL,
153   LS_SUBSCRIPTION,
154   LS_SERVICE_MAPPER,
155   LS_BOUQUET,
156   LS_ESFILTER,
157   LS_PROFILE,
158   LS_DESCRAMBLER,
159   LS_DESCRAMBLER_EMM,
160   LS_CACLIENT,
161   LS_CSA,
162   LS_CAPMT,
163   LS_CWC,
164   LS_DVBCAM,
165   LS_DVR,
166   LS_DVR_INOTIFY,
167   LS_EPG,
168   LS_EPGDB,
169   LS_EPGGRAB,
170   LS_CHARSET,
171   LS_DVB,
172   LS_MPEGTS,
173   LS_MUXSCHED,
174   LS_LIBAV,
175   LS_TRANSCODE,
176   LS_IPTV,
177   LS_IPTV_PCR,
178   LS_IPTV_SUB,
179   LS_LINUXDVB,
180   LS_DISEQC,
181   LS_EN50221,
182   LS_EN50494,
183   LS_SATIP,
184   LS_SATIPS,
185   LS_TVHDHOMERUN,
186   LS_PSIP,
187   LS_OPENTV,
188   LS_PYEPG,
189   LS_XMLTV,
190   LS_WEBUI,
191   LS_TIMESHIFT,
192   LS_SCANFILE,
193   LS_TSFILE,
194   LS_TSDEBUG,
195   LS_LAST     /* keep this last */
196 };
197 
198 /* Macros */
199 #define tvhlog(severity, subsys, fmt, ...)\
200   _tvhlog(__FILE__, __LINE__, severity | LOG_TVH_NOTIFY, subsys, fmt, ##__VA_ARGS__)
201 #define tvhlog_spawn(severity, subsys, fmt, ...)\
202   _tvhlog(__FILE__, __LINE__, severity, subsys, fmt, ##__VA_ARGS__)
203 #if ENABLE_TRACE
204 #define tvhtrace_enabled() (LOG_TRACE <= atomic_get(&tvhlog_level))
205 #define tvhtrace(subsys, fmt, ...) \
206   do { \
207     if (tvhtrace_enabled()) \
208       _tvhlog(__FILE__, __LINE__, LOG_TRACE, subsys, fmt, ##__VA_ARGS__); \
209   } while (0)
210 #define tvhlog_hexdump(subsys, data, len) \
211   do { \
212     if (tvhtrace_enabled()) \
213       _tvhlog_hexdump(__FILE__, __LINE__, LOG_TRACE, subsys, (uint8_t*)data, len); \
214   } while (0)
215 #else
tvhtrace_no_warnings(const char * fmt,...)216 static inline void tvhtrace_no_warnings(const char *fmt, ...) { (void)fmt; }
217 #define tvhtrace_enabled() 0
218 #define tvhtrace(subsys, fmt, ...) do { tvhtrace_no_warnings(NULL, subsys, fmt, ##__VA_ARGS__); } while (0)
219 #define tvhlog_hexdump(subsys, data, len) do { tvhtrace_no_warnings(NULL, subsys, data, len); } while (0)
220 #endif
221 
222 #define tvhftrace(subsys, fcn, ...) do { \
223   tvhtrace(subsys, "%s() enter", #fcn); \
224   fcn(__VA_ARGS__); \
225   tvhtrace(subsys, "%s() leave", #fcn); \
226 } while (0)
227 
228 #define tvhdebug(...)  tvhlog(LOG_DEBUG,   ##__VA_ARGS__)
229 #define tvhinfo(...)   tvhlog(LOG_INFO,    ##__VA_ARGS__)
230 #define tvhwarn(...)   tvhlog(LOG_WARNING, ##__VA_ARGS__)
231 #define tvhnotice(...) tvhlog(LOG_NOTICE,  ##__VA_ARGS__)
232 #define tvherror(...)  tvhlog(LOG_ERR,     ##__VA_ARGS__)
233 #define tvhalert(...)  tvhlog(LOG_ALERT,   ##__VA_ARGS__)
234 
235 void tvhlog_backtrace_printf(const char *fmt, ...);
236 
237 #endif /* __TVH_LOGGING_H__ */
238