24 #include <graphlab/util/event_log.hpp>
25 #include <graphlab/util/timer.hpp>
26 #include <graphlab/logger/assertions.hpp>
28 #define EVENT_BAR_WIDTH 40
29 #define BAR_CHARACTER '#'
33 static std::ofstream eventlog_file;
34 static mutex eventlog_file_mutex;
35 static bool eventlog_file_open =
false;
37 static timer event_timer;
38 static bool event_timer_started =
false;
39 static mutex event_timer_mutex;
42 void event_log::initialize(std::ostream &ostrm,
43 size_t flush_interval_ms,
44 event_print_type event_print) {
47 flush_interval = flush_interval_ms;
48 print_method = event_print;
50 event_timer_mutex.
lock();
51 if (event_timer_started ==
false) {
52 event_timer_started =
true;
55 event_timer_mutex.
unlock();
61 if (event_print == LOG_FILE) {
62 eventlog_file_mutex.
lock();
63 if (!eventlog_file_open) {
64 eventlog_file_open =
true;
65 eventlog_file.open(
"eventlog.txt");
68 eventlog_file_mutex.
unlock();
73 event_log::~event_log() {
78 printing_thread.join();
79 if (print_method != LOG_FILE) {
81 if (hascounter.first_bit(pos)) {
83 (*out) << descriptions[pos] <<
":\t" << totalcounter[pos].value <<
" Events\n";
84 }
while(hascounter.next_bit(pos));
89 if (hascounter.first_bit(pos)) {
91 std::cout << descriptions[pos] <<
":\t" << totalcounter[pos].value <<
" Events\n";
92 }
while(hascounter.next_bit(pos));
98 void event_log::immediate_event(
unsigned char eventid) {
104 void event_log::close() {
111 void event_log::add_event_type(
unsigned char eventid,
112 std::string description) {
113 descriptions[eventid] = description;
114 max_desc_length = std::max(max_desc_length, description.length());
115 ASSERT_MSG(max_desc_length <= 30,
"Event Description length must be <= 30 characters");
116 counters[eventid].value = 0;
117 hascounter.set_bit(eventid);
120 void event_log::add_immediate_event_type(
unsigned char eventid, std::string description) {
121 descriptions[eventid] = description;
122 max_desc_length = std::max(max_desc_length, description.length());
123 ASSERT_MSG(max_desc_length <= 30,
"Event Description length must be <= 30 characters");
124 counters[eventid].value = 0;
127 void event_log::flush() {
129 if (!hascounter.first_bit(pos))
return;
131 double timegap = curtime - prevtime;
134 if (hasevents ==
false && noeventctr == 1)
return;
136 bool found_events =
false;
137 if (print_method == NUMBER) {
139 size_t ctrval = counters[pos].exchange(0);
140 found_events = found_events || ctrval > 0;
141 (*out) << pos <<
":\t" << curtime <<
"\t" << ctrval <<
"\t" << 1000 * ctrval / timegap <<
" /s\n";
142 }
while(hascounter.next_bit(pos));
144 if (!immediate_events.empty()) {
145 std::vector<std::pair<unsigned char, size_t> > cur;
146 cur.swap(immediate_events);
147 for (
size_t i = 0;i < cur.size(); ++i) {
148 (*out) << (size_t)cur[i].first <<
":\t" << cur[i].second <<
"\t" << -1 <<
"\t" << 0 <<
" /s\n";
153 else if (print_method == DESCRIPTION) {
155 size_t ctrval = counters[pos].exchange(0);
156 found_events = found_events || ctrval > 0;
157 (*out) << descriptions[pos] <<
":\t" << curtime <<
"\t" << ctrval <<
"\t" << 1000 * ctrval / timegap <<
" /s\n";
158 }
while(hascounter.next_bit(pos));
159 if (!immediate_events.empty()) {
160 std::vector<std::pair<unsigned char, size_t> > cur;
161 cur.swap(immediate_events);
162 for (
size_t i = 0;i < cur.size(); ++i) {
163 (*out) << descriptions[cur[i].first] <<
":\t" << cur[i].second <<
"\t" << -1 <<
"\t" << 0 <<
" /s\n";
168 else if (print_method == LOG_FILE) {
169 eventlog_file_mutex.
lock();
171 size_t ctrval = counters[pos].exchange(0);
172 found_events = found_events || ctrval > 0;
173 (*out) << descriptions[pos] <<
":\t" << curtime <<
"\t" << ctrval <<
"\t" << 1000 * ctrval / timegap <<
"\n";
174 }
while(hascounter.next_bit(pos));
175 if (!immediate_events.empty()) {
176 std::vector<std::pair<unsigned char, size_t> > cur;
177 cur.swap(immediate_events);
178 for (
size_t i = 0;i < cur.size(); ++i) {
179 (*out) << descriptions[cur[i].first] <<
":\t" << cur[i].second <<
"\t" << -1 <<
"\t" << 0 <<
" /s\n";
182 eventlog_file_mutex.
unlock();
185 else if (print_method == RATE_BAR) {
186 (*out) <<
"Time: " <<
"+"<<timegap <<
"\t" << curtime <<
"\n";
189 memset(spacebuf,
' ', EVENT_BAR_WIDTH);
190 memset(pbuf, BAR_CHARACTER, 60);
192 size_t ctrval = counters[pos].exchange(0);
193 found_events = found_events || ctrval > 0;
194 maxcounter[pos] = std::max(maxcounter[pos], ctrval);
196 size_t mc = maxcounter[pos];
197 if (mc > 0) barlen = ctrval * EVENT_BAR_WIDTH / mc;
198 if (barlen > EVENT_BAR_WIDTH) barlen = EVENT_BAR_WIDTH;
201 spacebuf[max_desc_length - descriptions[pos].length() + 1] = 0;
202 (*out) << descriptions[pos] << spacebuf <<
"|" << pbuf;
203 spacebuf[max_desc_length - descriptions[pos].length() + 1] =
' ';
204 pbuf[barlen] = BAR_CHARACTER;
206 spacebuf[EVENT_BAR_WIDTH - barlen] =
'\0';
207 (*out) << spacebuf <<
"| " << ctrval <<
" : " << mc <<
" \n";
208 spacebuf[EVENT_BAR_WIDTH - barlen] =
' ';
210 }
while(hascounter.next_bit(pos));
213 if (found_events ==
false) {
223 void event_log::thread_loop() {
226 if (flush_interval == 0) {
231 my_sleep_ms(flush_interval);
233 if (flush_interval > 0) flush();