summaryrefslogtreecommitdiff
path: root/protocols/Telegram/tdlib/td/tdutils/test/log.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Telegram/tdlib/td/tdutils/test/log.cpp')
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/test/log.cpp187
1 files changed, 187 insertions, 0 deletions
diff --git a/protocols/Telegram/tdlib/td/tdutils/test/log.cpp b/protocols/Telegram/tdlib/td/tdutils/test/log.cpp
new file mode 100644
index 0000000000..34af21353c
--- /dev/null
+++ b/protocols/Telegram/tdlib/td/tdutils/test/log.cpp
@@ -0,0 +1,187 @@
+//
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+#include "td/utils/AsyncFileLog.h"
+#include "td/utils/benchmark.h"
+#include "td/utils/CombinedLog.h"
+#include "td/utils/FileLog.h"
+#include "td/utils/format.h"
+#include "td/utils/logging.h"
+#include "td/utils/MemoryLog.h"
+#include "td/utils/NullLog.h"
+#include "td/utils/port/path.h"
+#include "td/utils/port/thread.h"
+#include "td/utils/Slice.h"
+#include "td/utils/SliceBuilder.h"
+#include "td/utils/tests.h"
+#include "td/utils/TsFileLog.h"
+#include "td/utils/TsLog.h"
+
+#include <functional>
+#include <limits>
+
+char disable_linker_warning_about_empty_file_tdutils_test_log_cpp TD_UNUSED;
+
+#if !TD_THREAD_UNSUPPORTED
+template <class Log>
+class LogBenchmark final : public td::Benchmark {
+ public:
+ LogBenchmark(std::string name, int threads_n, bool test_full_logging, std::function<td::unique_ptr<Log>()> creator)
+ : name_(std::move(name))
+ , threads_n_(threads_n)
+ , test_full_logging_(test_full_logging)
+ , creator_(std::move(creator)) {
+ }
+ std::string get_description() const final {
+ return PSTRING() << name_ << " " << (test_full_logging_ ? "ERROR" : "PLAIN") << " "
+ << td::tag("threads_n", threads_n_);
+ }
+ void start_up() final {
+ log_ = creator_();
+ threads_.resize(threads_n_);
+ }
+ void tear_down() final {
+ if (log_ == nullptr) {
+ return;
+ }
+ for (const auto &path : log_->get_file_paths()) {
+ td::unlink(path).ignore();
+ }
+ log_.reset();
+ }
+ void run(int n) final {
+ auto old_log_interface = td::log_interface;
+ if (log_ != nullptr) {
+ td::log_interface = log_.get();
+ }
+
+ for (auto &thread : threads_) {
+ thread = td::thread([this, n] { this->run_thread(n); });
+ }
+ for (auto &thread : threads_) {
+ thread.join();
+ }
+
+ td::log_interface = old_log_interface;
+ }
+
+ void run_thread(int n) {
+ auto str = PSTRING() << "#" << n << " : fsjklfdjsklfjdsklfjdksl\n";
+ for (int i = 0; i < n; i++) {
+ if (i % 10000 == 0 && log_ != nullptr) {
+ log_->after_rotation();
+ }
+ if (test_full_logging_) {
+ LOG(ERROR) << str;
+ } else {
+ LOG(PLAIN) << str;
+ }
+ }
+ }
+
+ private:
+ std::string name_;
+ td::unique_ptr<td::LogInterface> log_;
+ int threads_n_{0};
+ bool test_full_logging_{false};
+ std::function<td::unique_ptr<Log>()> creator_;
+ std::vector<td::thread> threads_;
+};
+
+template <class F>
+static void bench_log(std::string name, F &&f) {
+ for (auto test_full_logging : {false, true}) {
+ for (auto threads_n : {1, 4, 8}) {
+ bench(LogBenchmark<typename decltype(f())::element_type>(name, threads_n, test_full_logging, f));
+ }
+ }
+}
+
+TEST(Log, Bench) {
+ bench_log("NullLog", [] { return td::make_unique<td::NullLog>(); });
+
+ // bench_log("Default", []() -> td::unique_ptr<td::NullLog> { return nullptr; });
+
+ bench_log("MemoryLog", [] { return td::make_unique<td::MemoryLog<1 << 20>>(); });
+
+ bench_log("CombinedLogEmpty", [] { return td::make_unique<td::CombinedLog>(); });
+
+ bench_log("CombinedLogMemory", [] {
+ auto result = td::make_unique<td::CombinedLog>();
+ static td::NullLog null_log;
+ static td::MemoryLog<1 << 20> memory_log;
+ result->set_first(&null_log);
+ result->set_second(&memory_log);
+ result->set_first_verbosity_level(VERBOSITY_NAME(DEBUG));
+ result->set_second_verbosity_level(VERBOSITY_NAME(DEBUG));
+ return result;
+ });
+
+ bench_log("TsFileLog",
+ [] { return td::TsFileLog::create("tmplog", std::numeric_limits<td::int64>::max(), false).move_as_ok(); });
+
+ bench_log("FileLog + TsLog", [] {
+ class FileLog final : public td::LogInterface {
+ public:
+ FileLog() {
+ file_log_.init("tmplog", std::numeric_limits<td::int64>::max(), false).ensure();
+ ts_log_.init(&file_log_);
+ }
+ void do_append(int log_level, td::CSlice slice) final {
+ static_cast<td::LogInterface &>(ts_log_).do_append(log_level, slice);
+ }
+ std::vector<std::string> get_file_paths() final {
+ return file_log_.get_file_paths();
+ }
+
+ private:
+ td::FileLog file_log_;
+ td::TsLog ts_log_{nullptr};
+ };
+ return td::make_unique<FileLog>();
+ });
+
+ bench_log("FileLog", [] {
+ class FileLog final : public td::LogInterface {
+ public:
+ FileLog() {
+ file_log_.init("tmplog", std::numeric_limits<td::int64>::max(), false).ensure();
+ }
+ void do_append(int log_level, td::CSlice slice) final {
+ static_cast<td::LogInterface &>(file_log_).do_append(log_level, slice);
+ }
+ std::vector<std::string> get_file_paths() final {
+ return file_log_.get_file_paths();
+ }
+
+ private:
+ td::FileLog file_log_;
+ };
+ return td::make_unique<FileLog>();
+ });
+
+#if !TD_EVENTFD_UNSUPPORTED
+ bench_log("AsyncFileLog", [] {
+ class AsyncFileLog final : public td::LogInterface {
+ public:
+ AsyncFileLog() {
+ file_log_.init("tmplog", std::numeric_limits<td::int64>::max()).ensure();
+ }
+ void do_append(int log_level, td::CSlice slice) final {
+ static_cast<td::LogInterface &>(file_log_).do_append(log_level, slice);
+ }
+ std::vector<std::string> get_file_paths() final {
+ return static_cast<td::LogInterface &>(file_log_).get_file_paths();
+ }
+
+ private:
+ td::AsyncFileLog file_log_;
+ };
+ return td::make_unique<AsyncFileLog>();
+ });
+#endif
+}
+#endif