1*3117ece4Schristos /* 2*3117ece4Schristos * Copyright (c) Meta Platforms, Inc. and affiliates. 3*3117ece4Schristos * All rights reserved. 4*3117ece4Schristos * 5*3117ece4Schristos * This source code is licensed under both the BSD-style license (found in the 6*3117ece4Schristos * LICENSE file in the root directory of this source tree) and the GPLv2 (found 7*3117ece4Schristos * in the COPYING file in the root directory of this source tree). 8*3117ece4Schristos */ 9*3117ece4Schristos #pragma once 10*3117ece4Schristos 11*3117ece4Schristos #include <cstdio> 12*3117ece4Schristos #include <mutex> 13*3117ece4Schristos 14*3117ece4Schristos namespace pzstd { 15*3117ece4Schristos 16*3117ece4Schristos constexpr int kLogError = 1; 17*3117ece4Schristos constexpr int kLogInfo = 2; 18*3117ece4Schristos constexpr int kLogDebug = 3; 19*3117ece4Schristos constexpr int kLogVerbose = 4; 20*3117ece4Schristos 21*3117ece4Schristos class Logger { 22*3117ece4Schristos std::mutex mutex_; 23*3117ece4Schristos FILE* out_; 24*3117ece4Schristos const int level_; 25*3117ece4Schristos 26*3117ece4Schristos using Clock = std::chrono::system_clock; 27*3117ece4Schristos Clock::time_point lastUpdate_; 28*3117ece4Schristos std::chrono::milliseconds refreshRate_; 29*3117ece4Schristos 30*3117ece4Schristos public: 31*3117ece4Schristos explicit Logger(int level, FILE* out = stderr) 32*3117ece4Schristos : out_(out), level_(level), lastUpdate_(Clock::now()), 33*3117ece4Schristos refreshRate_(150) {} 34*3117ece4Schristos 35*3117ece4Schristos 36*3117ece4Schristos bool logsAt(int level) { 37*3117ece4Schristos return level <= level_; 38*3117ece4Schristos } 39*3117ece4Schristos 40*3117ece4Schristos template <typename... Args> 41*3117ece4Schristos void operator()(int level, const char *fmt, Args... args) { 42*3117ece4Schristos if (level > level_) { 43*3117ece4Schristos return; 44*3117ece4Schristos } 45*3117ece4Schristos std::lock_guard<std::mutex> lock(mutex_); 46*3117ece4Schristos std::fprintf(out_, fmt, args...); 47*3117ece4Schristos } 48*3117ece4Schristos 49*3117ece4Schristos template <typename... Args> 50*3117ece4Schristos void update(int level, const char *fmt, Args... args) { 51*3117ece4Schristos if (level > level_) { 52*3117ece4Schristos return; 53*3117ece4Schristos } 54*3117ece4Schristos std::lock_guard<std::mutex> lock(mutex_); 55*3117ece4Schristos auto now = Clock::now(); 56*3117ece4Schristos if (now - lastUpdate_ > refreshRate_) { 57*3117ece4Schristos lastUpdate_ = now; 58*3117ece4Schristos std::fprintf(out_, "\r"); 59*3117ece4Schristos std::fprintf(out_, fmt, args...); 60*3117ece4Schristos } 61*3117ece4Schristos } 62*3117ece4Schristos 63*3117ece4Schristos void clear(int level) { 64*3117ece4Schristos if (level > level_) { 65*3117ece4Schristos return; 66*3117ece4Schristos } 67*3117ece4Schristos std::lock_guard<std::mutex> lock(mutex_); 68*3117ece4Schristos std::fprintf(out_, "\r%79s\r", ""); 69*3117ece4Schristos } 70*3117ece4Schristos }; 71*3117ece4Schristos 72*3117ece4Schristos } 73