MIT License

项目介绍

michalber/spdmon 是一个托管在 GitHub 上的开源项目,主要使用 C++ 编写,采用 MIT License 许可证,目前获得 13 个 Star、4 次 Fork。

仓库全名
michalber/spdmon
开源许可证
MIT License
Star 数
13
Fork 数
4
未关闭 Issue
2

README 摘要

spdmon Progress monitor based on spdlog library. In just one function call visualize your loop progress! It is simple, header-only library. Just copy spdmon.hpp file into you project and you are ready to go. Main idea and algorithm is based on @epruesse progress monitor. Usage It can also be executed with additional spdlog::logger containing many sinks. In that case LoggerProgress will not include sinks writing logs…

完整内容见 GitHub 原始 README 或本页 。

常见问题

spdmon 用什么语言开发?

主要使用 C++ 编写,采用 MIT License 许可证,目前有 13 个 Star。

spdmon 可以免费商用吗?

仓库采用 MIT License 许可证,可免费使用与修改,商业使用请遵守许可证条款(例如保留版权声明与许可声明)。

如何获取 spdmon 的源码?

可以直接克隆仓库:git clone https://github.com/michalber/spdmon.git,默认分支为 main;安装与运行步骤见仓库 README。

spdmon 最近还在维护吗?

仓库最近一次更新为 2022年10月21日,当前有 2 个未关闭 Issue;Star 数为 13,可作为社区活跃度的参考。

关于

A simple to use progress bar for C++

描述取自 GitHub 官方 API,中文内容由 GitRead 中文社区 编辑团队整理。

简要分析

热度分
24
价值分
9
活跃状态
活跃

语言占比

C++
CMake
Shell

README

spdmon

Progress monitor based on spdlog library. In just one function call visualize your loop progress!
It is simple, header-only library. Just copy spdmon.hpp file into you project and you are ready to go.
Main idea and algorithm is based on @epruesse progress monitor.

Usage

std::vector<int> vec {0,1,2,3,4,5,6,7,8,9};
for(auto [logger, val] : spdmon::LogProgress(vec))
{
    logger->info("Hi info");
    std::this_thread::sleep_for(500ms);
}
Progress logger: 100% |████████████████████████████| 250000/250000 [00:00:33 / 00:00:00]

It can also be executed with additional spdlog::logger containing many sinks.
In that case LoggerProgress will not include sinks writing logs to stdout when creating temporary logger.

std::vector<spdlog::sink_ptr> sinks;
sinks.push_back(std::make_shared<spdlog::sinks::stdout_sink_mt>());
sinks.push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>("logfile", true));
auto combined_logger = std::make_shared<spdlog::logger>("name", begin(sinks), end(sinks));

spdmon::LoggerProgress monitor(combined_logger, "Progress", 40);

Main features of LoggerProgress:

  • Allows you to use default logger to send logs from many threads
  • Works only on Linux platform
  • Works with latest spdlog library
  • Refactor code with Google C++ Style Guide
  • Works only with stdout
  • It is not using std::recursive_mutex
  • It does not require any modification of spdlog library. Logging sink is based on spdlog::sinks::ansicolor_sink

Benchmarks

Below are some benchmarks done in Ubuntu 64 bit, Intel i5-8250U CPU @ 3.4GHz. I have compared progress monitor to native spdlog::sinks::ansicolor_sink. Used spdlog benchmark code.

Synchronous mode

[info] **************************************************************
[info] Single thread, 250,000 iterations
[info] **************************************************************
[spdlog::ansicolor_stdout_sink_mt]  [info]                Elapsed: 6.93 secs            36,083/sec
[Progress logger]                   [info]                Elapsed: 19.55 secs           12,788/sec
[Progress logger + monitor]         [info]                Elapsed: 27.51 secs            9,086/sec
[info] **************************************************************
[info] 10 threads, competing over the same logger object, 250,000 iterations
[info] **************************************************************
[spdlog::ansicolor_stdout_sink_mt]  [info]                Elapsed: 7.00 secs            35,703/sec
[Progress logger]                   [info]                Elapsed: 21.73 secs           11,507/sec
[Progress logger + monitor]         [info]                Elapsed: 29.70 secs            8,416/sec

Example usage

/*
 * Example usage code
*/

#include <thread>
#include <future>
#include "spdlog/sinks/stdout_sinks.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdmon/spdmon.hpp"

int main()
{
  /*
   * Create logger with many sinks. It can include stdout sinks
  */
  std::vector<spdlog::sink_ptr> sinks;
  sinks.push_back(std::make_shared<spdlog::sinks::stdout_sink_mt>());
  sinks.push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>("logfile", true));
  auto combined_logger = std::make_shared<spdlog::logger>("name", begin(sinks), end(sinks));

  /*
   * Create progress logger. It checks for all stdout sinks and discard them
   * Instead of them it creates custom one, logging to stdout with progress bar
   * and makes it global default logger.
  */
  spdmon::LoggerProgress monitor(combined_logger, "Progress", 40);

  /* We can get newly created logger from progress logger to log new data */
  auto new_logger = monitor.GetLogger();
  new_logger->set_pattern("[thread %t] %+");
  new_logger->set_level(spdlog::level::trace);

  /*
   * We use lambda function to be passed to different logging threads
  */
  auto print_lambda = [&monitor, &new_logger](auto duration, int count) {
    for (int i = 0; i < count; i++)
    {
      spdlog::trace("Hi trace");
      spdlog::debug("Hi debug");
      spdlog::info("Hi info");
      new_logger->warn("Hi warn");
      new_logger->error("Hi err");
      new_logger->critical("Hi critical");

      ++monitor;

      std::this_thread::sleep_for(duration);
    }
  };

  using namespace std::chrono_literals;

  /*
   * Create few threads which will be logging data through progress logger
   * and global logger
  */
  std::vector<std::thread> threads;
  threads.push_back(std::thread{print_lambda, 250ms, 10});
  threads.push_back(std::thread{print_lambda, 750ms, 10});
  threads.push_back(std::thread{print_lambda, 350ms, 10});
  threads.push_back(std::thread{print_lambda, 500ms, 10});

  /*
   * Wait for threads to finish their jobs
  */
  for (auto &t : threads)
  {
    if (t.joinable())
      t.join();
  }

  return 0;
}

Authors

Huge thank you to Elmar Pruesse for the idea and starting this project!

评论

暂无评论