Remove duplicate code between stream_logger and console_writer

This commit is contained in:
Marcus Holland-Moritz 2023-08-04 13:34:52 +02:00
parent 7615b2e827
commit 03d474c912
4 changed files with 52 additions and 94 deletions

View File

@ -35,7 +35,7 @@ namespace dwarfs {
class progress;
class console_writer : public logger {
class console_writer : public stream_logger {
public:
using get_term_width_type = std::function<size_t()>;
@ -46,25 +46,20 @@ class console_writer : public logger {
get_term_width_type get_term_width, level_type threshold,
display_mode mode = NORMAL, bool verbose = false);
void write(level_type level, const std::string& output, char const* file,
int line) override;
void update(const progress& p, bool last);
private:
void preamble() override;
void postamble() override;
std::string_view get_newline() const override;
void rewind();
std::ostream& os_;
std::mutex mx_;
std::atomic<level_type> threshold_;
std::string statebuf_;
double frac_;
std::atomic<size_t> counter_{0};
progress_mode const pg_mode_;
get_term_width_type get_term_width_;
display_mode const mode_;
bool const color_;
bool const with_context_;
bool const debug_progress_;
bool writing_{false};
speedometer<uint64_t> read_speed_;

View File

@ -88,9 +88,19 @@ class stream_logger : public logger {
void set_threshold(level_type threshold);
void set_with_context(bool with_context) { with_context_ = with_context; }
protected:
virtual void preamble();
virtual void postamble();
virtual std::string_view get_newline() const;
std::ostream& log_stream() const { return os_; }
std::mutex& log_mutex() const { return mx_; }
bool log_is_colored() const { return color_; }
level_type log_threshold() const { return threshold_.load(); }
private:
std::ostream& os_;
std::mutex mx_;
std::mutex mutable mx_;
std::atomic<level_type> threshold_;
bool const color_;
bool with_context_;

View File

@ -84,22 +84,13 @@ console_writer::console_writer(std::ostream& os, progress_mode pg_mode,
get_term_width_type get_term_width,
level_type threshold, display_mode mode,
bool with_context)
: os_(os)
, threshold_(threshold)
: stream_logger(os, threshold, with_context)
, frac_(0.0)
, pg_mode_(pg_mode)
, get_term_width_(get_term_width)
, mode_(mode)
, color_(stream_is_fancy_terminal(os))
, with_context_(with_context)
, debug_progress_(is_debug_progress())
, read_speed_{std::chrono::seconds(5)} {
if (threshold > level_type::INFO) {
set_policy<debug_logger_policy>();
} else {
set_policy<prod_logger_policy>();
}
}
, read_speed_{std::chrono::seconds(5)} {}
void console_writer::rewind() {
if (!statebuf_.empty()) {
@ -114,83 +105,34 @@ void console_writer::rewind() {
break;
}
os_ << '\r';
auto& os = log_stream();
os << '\r';
for (int i = 0; i < lines; ++i) {
os_ << "\x1b[A";
os << "\x1b[A";
}
}
}
void console_writer::write(level_type level, const std::string& output,
char const* file, int line) {
if (level <= threshold_) {
auto t = get_current_time_string();
const char* prefix = "";
const char* suffix = "";
const char* newline = pg_mode_ != NONE ? "\x1b[K\n" : "\n";
void console_writer::preamble() { rewind(); }
if (color_) {
switch (level) {
case ERROR:
prefix = terminal_color(termcolor::BOLD_RED);
suffix = terminal_color(termcolor::NORMAL);
break;
case WARN:
prefix = terminal_color(termcolor::BOLD_YELLOW);
suffix = terminal_color(termcolor::NORMAL);
break;
default:
break;
}
}
char lchar = logger::level_char(level);
std::string context;
size_t context_len = 0;
if (with_context_ && file) {
context = get_logger_context(file, line);
context_len = context.size();
if (color_) {
context = folly::to<std::string>(
suffix, terminal_color(termcolor::MAGENTA), context,
terminal_color(termcolor::NORMAL), prefix);
}
}
folly::small_vector<std::string_view, 2> lines;
folly::split('\n', output, lines);
if (lines.back().empty()) {
lines.pop_back();
}
std::lock_guard lock(mx_);
rewind();
for (auto l : lines) {
os_ << prefix << lchar << ' ' << t << ' ' << context << l << suffix
<< newline;
std::fill(t.begin(), t.end(), '.');
context.assign(context_len, ' ');
}
if (pg_mode_ == UNICODE || pg_mode_ == ASCII) {
os_ << statebuf_;
}
void console_writer::postamble() {
if (pg_mode_ == UNICODE || pg_mode_ == ASCII) {
log_stream() << statebuf_;
}
}
std::string_view console_writer::get_newline() const {
return pg_mode_ != NONE ? "\x1b[K\n" : "\n";
}
void console_writer::update(const progress& p, bool last) {
if (pg_mode_ == NONE && !last) {
return;
}
const char* newline = pg_mode_ != NONE ? "\x1b[K\n" : "\n";
auto newline = get_newline();
std::ostringstream oss;
lazy_value width(get_term_width_);
@ -220,7 +162,7 @@ void console_writer::update(const progress& p, bool last) {
if (fancy) {
oss << terminal_colored(p.status(width.get()), termcolor::BOLD_CYAN,
color_)
log_is_colored())
<< newline;
}
@ -282,9 +224,9 @@ void console_writer::update(const progress& p, bool last) {
}
if (pg_mode_ == NONE) {
if (INFO <= threshold_) {
std::lock_guard lock(mx_);
os_ << oss.str();
if (INFO <= log_threshold()) {
std::lock_guard lock(log_mutex());
log_stream() << oss.str();
}
return;
}
@ -312,12 +254,12 @@ void console_writer::update(const progress& p, bool last) {
if (tmp != statebuf_) {
auto t = get_current_time_string();
statebuf_ = tmp;
std::lock_guard lock(mx_);
os_ << "- " << t << statebuf_ << "\n";
std::lock_guard lock(log_mutex());
log_stream() << "- " << t << statebuf_ << "\n";
}
if (last) {
std::lock_guard lock(mx_);
os_ << oss.str();
std::lock_guard lock(log_mutex());
log_stream() << oss.str();
}
} else {
oss << progress_bar(width.get() - 6, frac_, pg_mode_ == UNICODE)
@ -326,13 +268,13 @@ void console_writer::update(const progress& p, bool last) {
++counter_;
std::lock_guard lock(mx_);
std::lock_guard lock(log_mutex());
rewind();
statebuf_ = oss.str();
os_ << statebuf_;
log_stream() << statebuf_;
}
}

View File

@ -70,12 +70,17 @@ stream_logger::stream_logger(std::ostream& os, level_type threshold,
set_threshold(threshold);
}
void stream_logger::preamble() {}
void stream_logger::postamble() {}
std::string_view stream_logger::get_newline() const { return "\n"; }
void stream_logger::write(level_type level, const std::string& output,
char const* file, int line) {
if (level <= threshold_) {
auto t = get_current_time_string();
const char* prefix = "";
const char* suffix = "";
auto newline = get_newline();
if (color_) {
switch (level) {
@ -130,13 +135,19 @@ void stream_logger::write(level_type level, const std::string& output,
}
std::lock_guard lock(mx_);
preamble();
for (auto l : lines) {
os_ << prefix << lchar << ' ' << t << ' ' << context << l << suffix
<< "\n";
<< newline;
std::fill(t.begin(), t.end(), '.');
context.assign(context_len, ' ');
}
postamble();
// TODO: this needs to be done differently for console_writer
#if DWARFS_SYMBOLIZE
if (threshold_ == TRACE) {
os_ << printer.str();