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