1 // libTorrent - BitTorrent library
2 // Copyright (C) 2005-2011, Jari Sundell
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 //
18 // In addition, as a special exception, the copyright holders give
19 // permission to link the code of portions of this program with the
20 // OpenSSL library under certain conditions as described in each
21 // individual source file, and distribute linked combinations
22 // including the two.
23 //
24 // You must obey the GNU General Public License in all respects for
25 // all of the code used other than OpenSSL.  If you modify file(s)
26 // with this exception, you may extend this exception to your version
27 // of the file(s), but you are not obligated to do so.  If you do not
28 // wish to do so, delete this exception statement from your version.
29 // If you delete this exception statement from all source files in the
30 // program, then also delete it here.
31 //
32 // Contact:  Jari Sundell <jaris@ifi.uio.no>
33 //
34 //           Skomakerveien 33
35 //           3185 Skoppum, NORWAY
36 
37 #ifndef LIBTORRENT_UTILS_LOG_H
38 #define LIBTORRENT_UTILS_LOG_H
39 
40 #include <bitset>
41 #include <string>
42 #include <vector>
43 #include lt_tr1_array
44 #include lt_tr1_functional
45 #include <torrent/common.h>
46 
47 namespace torrent {
48 
49 // TODO: Add option_strings support.
50 enum {
51   LOG_CRITICAL,
52   LOG_ERROR,
53   LOG_WARN,
54   LOG_NOTICE,
55   LOG_INFO,
56   LOG_DEBUG,
57 
58   LOG_CONNECTION_CRITICAL,
59   LOG_CONNECTION_ERROR,
60   LOG_CONNECTION_WARN,
61   LOG_CONNECTION_NOTICE,
62   LOG_CONNECTION_INFO,
63   LOG_CONNECTION_DEBUG,
64 
65   LOG_DHT_CRITICAL,
66   LOG_DHT_ERROR,
67   LOG_DHT_WARN,
68   LOG_DHT_NOTICE,
69   LOG_DHT_INFO,
70   LOG_DHT_DEBUG,
71 
72   LOG_PEER_CRITICAL,
73   LOG_PEER_ERROR,
74   LOG_PEER_WARN,
75   LOG_PEER_NOTICE,
76   LOG_PEER_INFO,
77   LOG_PEER_DEBUG,
78 
79   LOG_SOCKET_CRITICAL,
80   LOG_SOCKET_ERROR,
81   LOG_SOCKET_WARN,
82   LOG_SOCKET_NOTICE,
83   LOG_SOCKET_INFO,
84   LOG_SOCKET_DEBUG,
85 
86   LOG_STORAGE_CRITICAL,
87   LOG_STORAGE_ERROR,
88   LOG_STORAGE_WARN,
89   LOG_STORAGE_NOTICE,
90   LOG_STORAGE_INFO,
91   LOG_STORAGE_DEBUG,
92 
93   LOG_THREAD_CRITICAL,
94   LOG_THREAD_ERROR,
95   LOG_THREAD_WARN,
96   LOG_THREAD_NOTICE,
97   LOG_THREAD_INFO,
98   LOG_THREAD_DEBUG,
99 
100   LOG_TRACKER_CRITICAL,
101   LOG_TRACKER_ERROR,
102   LOG_TRACKER_WARN,
103   LOG_TRACKER_NOTICE,
104   LOG_TRACKER_INFO,
105   LOG_TRACKER_DEBUG,
106 
107   LOG_TORRENT_CRITICAL,
108   LOG_TORRENT_ERROR,
109   LOG_TORRENT_WARN,
110   LOG_TORRENT_NOTICE,
111   LOG_TORRENT_INFO,
112   LOG_TORRENT_DEBUG,
113 
114   LOG_NON_CASCADING,
115 
116   LOG_DHT_ALL,
117   LOG_DHT_MANAGER,
118   LOG_DHT_NODE,
119   LOG_DHT_ROUTER,
120   LOG_DHT_SERVER,
121 
122   LOG_INSTRUMENTATION_MEMORY,
123   LOG_INSTRUMENTATION_MINCORE,
124   LOG_INSTRUMENTATION_CHOKE,
125   LOG_INSTRUMENTATION_POLLING,
126   LOG_INSTRUMENTATION_TRANSFERS,
127 
128   LOG_PEER_LIST_EVENTS,
129 
130   LOG_PROTOCOL_PIECE_EVENTS,
131   LOG_PROTOCOL_METADATA_EVENTS,
132   LOG_PROTOCOL_NETWORK_ERRORS,
133   LOG_PROTOCOL_STORAGE_ERRORS,
134 
135   LOG_RESUME_DATA,
136 
137   LOG_RPC_EVENTS,
138   LOG_RPC_DUMP,
139 
140   LOG_UI_EVENTS,
141 
142   LOG_GROUP_MAX_SIZE
143 };
144 
145 #define lt_log_is_valid(log_group) (torrent::log_groups[log_group].valid())
146 
147 #define lt_log_print(log_group, ...)                                    \
148   if (torrent::log_groups[log_group].valid())                           \
149     torrent::log_groups[log_group].internal_print(NULL, NULL, NULL, 0, __VA_ARGS__);
150 
151 #define lt_log_print_info(log_group, log_info, log_subsystem, ...)      \
152   if (torrent::log_groups[log_group].valid())                           \
153     torrent::log_groups[log_group].internal_print(&log_info->hash(), log_subsystem, NULL, 0, __VA_ARGS__);
154 
155 #define lt_log_print_data(log_group, log_data, log_subsystem, ...)      \
156   if (torrent::log_groups[log_group].valid())                           \
157     torrent::log_groups[log_group].internal_print(&log_data->hash(), log_subsystem, NULL, 0, __VA_ARGS__);
158 
159 #define lt_log_print_dump(log_group, log_dump_data, log_dump_size, ...) \
160   if (torrent::log_groups[log_group].valid())                           \
161     torrent::log_groups[log_group].internal_print(NULL, NULL, log_dump_data, log_dump_size, __VA_ARGS__); \
162 
163 #define lt_log_print_hash(log_group, log_hash, log_subsystem, ...)      \
164   if (torrent::log_groups[log_group].valid())                           \
165     torrent::log_groups[log_group].internal_print(&log_hash, log_subsystem, NULL, 0, __VA_ARGS__);
166 
167 #define lt_log_print_info_dump(log_group, log_dump_data, log_dump_size, log_info, log_subsystem, ...) \
168   if (torrent::log_groups[log_group].valid())                           \
169     torrent::log_groups[log_group].internal_print(&log_info->hash(), log_subsystem, log_dump_data, log_dump_size, __VA_ARGS__); \
170 
171 #define lt_log_print_subsystem(log_group, log_subsystem, ...)           \
172   if (torrent::log_groups[log_group].valid())                           \
173     torrent::log_groups[log_group].internal_print(NULL, log_subsystem, NULL, 0, __VA_ARGS__);
174 
175 class log_buffer;
176 
177 typedef std::function<void (const char*, unsigned int, int)> log_slot;
178 
179 class LIBTORRENT_EXPORT log_group {
180 public:
181   typedef std::bitset<64> outputs_type;
182 
log_group()183   log_group() : m_first(NULL), m_last(NULL) {
184     m_outputs.reset();
185     m_cached_outputs.reset();
186   }
187 
valid()188   bool                valid() const { return m_first != NULL; }
empty()189   bool                empty() const { return m_first == NULL; }
190 
size_outputs()191   size_t              size_outputs() const { return std::distance(m_first, m_last); }
192 
max_size_outputs()193   static size_t       max_size_outputs() { return 64; }
194 
195   //
196   // Internal:
197   //
198 
199   void                internal_print(const HashString* hash, const char* subsystem,
200                                      const void* dump_data, size_t dump_size,
201                                      const char* fmt, ...);
202 
outputs()203   const outputs_type& outputs() const                    { return m_outputs; }
cached_outputs()204   const outputs_type& cached_outputs() const             { return m_cached_outputs; }
205 
clear_cached_outputs()206   void                clear_cached_outputs()             { m_cached_outputs = m_outputs; }
207 
set_outputs(const outputs_type & val)208   void                set_outputs(const outputs_type& val)        { m_outputs = val; }
set_cached_outputs(const outputs_type & val)209   void                set_cached_outputs(const outputs_type& val) { m_cached_outputs = val; }
210 
set_output_at(size_t index,bool val)211   void                set_output_at(size_t index, bool val)       { m_outputs[index] = val; }
212 
set_cached(log_slot * f,log_slot * l)213   void                set_cached(log_slot* f, log_slot* l)        { m_first = f; m_last = l; }
214 
215 private:
216   outputs_type        m_outputs;
217   outputs_type        m_cached_outputs;
218 
219   log_slot*           m_first;
220   log_slot*           m_last;
221 };
222 
223 typedef std::array<log_group, LOG_GROUP_MAX_SIZE> log_group_list;
224 
225 extern log_group_list  log_groups LIBTORRENT_EXPORT;
226 
227 void log_initialize() LIBTORRENT_EXPORT;
228 void log_cleanup() LIBTORRENT_EXPORT;
229 
230 void log_open_output(const char* name, log_slot slot) LIBTORRENT_EXPORT;
231 void log_close_output(const char* name) LIBTORRENT_EXPORT;
232 void log_close_output_str(const std::string name) LIBTORRENT_EXPORT;
233 
234 void log_add_group_output(int group, const char* name) LIBTORRENT_EXPORT;
235 void log_remove_group_output(int group, const char* name) LIBTORRENT_EXPORT;
236 
237 void log_add_child(int group, int child) LIBTORRENT_EXPORT;
238 void log_remove_child(int group, int child) LIBTORRENT_EXPORT;
239 
240 void        log_open_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT;
241 void        log_open_gz_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT;
242 log_buffer* log_open_log_buffer(const char* name) LIBTORRENT_EXPORT;
243 
244 //
245 // Implementation:
246 //
247 
log_close_output_str(const std::string name)248 inline void log_close_output_str(const std::string name) { log_close_output(name.c_str()); }
249 
250 }
251 
252 #endif
253