1 /******************************************************************************* 2 * thrill/common/json_logger.cpp 3 * 4 * Logger for statistical output in JSON format for post-processing. 5 * 6 * Part of Project Thrill - http://project-thrill.org 7 * 8 * Copyright (C) 2016 Timo Bingmann <tb@panthema.net> 9 * 10 * All rights reserved. Published under the BSD-2 license in the LICENSE file. 11 ******************************************************************************/ 12 13 #include <thrill/common/json_logger.hpp> 14 #include <thrill/common/logger.hpp> 15 #include <thrill/common/string.hpp> 16 17 #include <tlx/die.hpp> 18 19 #include <cerrno> 20 #include <chrono> 21 #include <cstring> 22 #include <fstream> 23 #include <iostream> 24 #include <string> 25 #include <vector> 26 27 namespace thrill { 28 namespace common { 29 30 /******************************************************************************/ 31 // JsonLogger 32 JsonLogger(const std::string & path)33JsonLogger::JsonLogger(const std::string& path) { 34 if (path.empty() || path == "/dev/null") { 35 // os_ remains nullptr 36 return; 37 } 38 if (path == "/dev/stdout") { 39 os_ = std::make_unique<std::ostream>(std::cout.rdbuf()); 40 return; 41 } 42 if (path == "/dev/stderr") { 43 os_ = std::make_unique<std::ostream>(std::cerr.rdbuf()); 44 return; 45 } 46 47 os_ = std::make_unique<std::ofstream>(path.c_str()); 48 if (!os_->good()) { 49 die("Could not open json log output: " 50 << path << " : " << strerror(errno)); 51 } 52 } 53 JsonLogger(JsonLogger * super)54JsonLogger::JsonLogger(JsonLogger* super) 55 : super_(super) { } 56 line()57JsonLine JsonLogger::line() { 58 if (super_ != nullptr) { 59 JsonLine out = super_->line(); 60 61 // append common key:value pairs 62 if (!common_.str_.empty()) 63 out << common_; 64 65 return out; 66 } 67 68 if (!os_) { 69 static std::ofstream dummy_of_; 70 return JsonLine(this, dummy_of_); 71 } 72 73 JsonLine out(this, *os_); 74 *os_ << '{'; 75 76 // output timestamp in microseconds 77 out << "ts" 78 << std::chrono::duration_cast<std::chrono::microseconds>( 79 std::chrono::system_clock::now().time_since_epoch()).count(); 80 81 // append common key:value pairs 82 if (!common_.str_.empty()) 83 out << common_; 84 85 return out; 86 } 87 88 } // namespace common 89 } // namespace thrill 90 91 /******************************************************************************/ 92