-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathchlog.hpp
140 lines (107 loc) · 4.16 KB
/
chlog.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#ifndef _CH_FRB_LOG_HPP
#define _CH_FRB_LOG_HPP
#include <thread>
#include <sstream>
#include <iostream>
#include <zmq.hpp>
namespace ch_frb_io {
#if 0
}; // pacify emacs c-mode
#endif
// printf into a string...
std::string
__attribute__ ((format(printf,1,2)))
stringprintf(const char* format, ...);
enum log_level {
log_level_debug = 1,
log_level_info = 2,
log_level_warn = 3,
log_level_err = 4,
};
// Not meant to be called directly; called by preprocessor macro expansion
void chime_log(enum log_level lev, const char* file, int line, const char* function, const std::string &logmsg, bool do_assert=false);
// Not meant to be called directly; called by preprocessor macro expansion
void
__attribute__ ((format(printf,5,6)))
chime_logf(enum log_level lev, const char* file, int line, const char* function, const char* pattern, ...);
// This is the main logging method to use in CHIME/FRB code for
// distributed logging:
//
// chlog("Hello world: " << 1 << ", " << 2 << ", " << 3);
//
#define chlog(...) \
do { \
std::ostringstream ss; \
ss << __VA_ARGS__; \
chime_log(ch_frb_io::log_level_info, __FILE__, __LINE__, __PRETTY_FUNCTION__, ss.str()); \
} while(0)
// Like chlog, but takes a printf-style format string and arguments.
//
// chlogf("Hello world: I am %03i", 7);
//
#define chlogf(pat, ...) \
do { \
chime_logf(log_level_info, __FILE__, __LINE__, __PRETTY_FUNCTION__, pat, __VA_ARGS__); \
} while(0)
// If we wanted to compile-out log messages below a certain log level,
// we could do:
#define chdebug(...) {}
// Assert that THING is true; log THING and bail out.
// FIXME -- bail out w/ assert() rather than exit(-1) ??
#define chassert(THING) \
do { if (!(THING)) { \
chime_log(log_level_info, __FILE__, __LINE__, __PRETTY_FUNCTION__, "Assertion failed: " #THING, true); \
usleep(1000000); \
exit(-1); \
} } while(0)
/*
Initializes the CHIME/FRB distributed logging socket for this node.
If a ZeroMQ context is passed in, it will be used to create the
socket. Otherwise, a new context will be created.
NOTE, if a context is passed in, you likely will need to call
chime_log_quit() to guarantee that the socket is closed before the
ZeroMQ context is deleted.
(When a context is not passed in, an atexit() handler is registered
to clean up.)
*/
void chime_log_open_socket(zmq::context_t* ctx = NULL);
// Cleans up the distributed logging system.
void chime_log_close_socket();
// Enable/disable logging to cout as well as to the network.
void chime_log_local(bool);
// Sets a mnemonic name for this client; default is hostname
void chime_log_set_name(const std::string &name);
// Sets a mnemonic name for the current thread
void chime_log_set_thread_name(const std::string &name);
/*
Starts sending log messages to the given server address (ZeroMQ
address string, like "tcp://127.0.0.1:6667").
*/
void chime_log_add_server(const std::string &port);
void chime_log_remove_server(const std::string &port);
////////
// A simple log server that prints messages to cout.
////////
class chime_log_server {
public:
chime_log_server(std::ostream& out = std::cout,
zmq::context_t* ctx = NULL,
const std::string &hostname = "*",
int port = -1);
~chime_log_server();
std::string get_address();
// Runs main serving loop. Never returns.
void run();
// Starts a new thread to run this server.
std::thread start();
// Signals the server thread to stop.
void stop();
protected:
std::ostream& _out;
zmq::socket_t* _socket;
std::string _address;
zmq::context_t* _ctx;
bool _quit;
};
}
#endif