Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[easylog]add async write mode for easylog #238

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 35 additions & 3 deletions include/easylog/easylog.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* limitations under the License.
*/
#pragma once
#include <asio.hpp>
#include <asio/thread_pool.hpp>
#include <functional>
#include <string_view>
#include <utility>
Expand All @@ -31,7 +33,16 @@ class logger {
return instance;
}

void operator+=(const record_t &record) { write(record); }
void operator+=(record_t &&record) {
if (async_mode_) {
asio::post(pool_, [this, record = std::move(record)]() mutable {
write(record);
});
}
else {
write(record);
}
}

void write(const record_t &record) {
append_format(record);
Expand Down Expand Up @@ -64,6 +75,13 @@ class logger {
appenders_.emplace_back(std::move(fn));
}

void drain() {
if (async_mode_) {
pool_.wait();
}
}
void enable_async() { async_mode_ = true; }

private:
logger() = default;
logger(const logger &) = default;
Expand Down Expand Up @@ -113,15 +131,19 @@ class logger {
std::cout << std::flush;
}

for (auto &fn : appenders_) {
fn(std::string_view(str));
if (!appenders_.empty()) {
for (auto &fn : appenders_) {
fn(std::string_view(str));
}
}
}

Severity min_severity_;
bool enable_console_ = true;
appender *appender_ = nullptr;
std::vector<std::function<void(std::string_view)>> appenders_;
bool async_mode_ = false;
asio::thread_pool pool_{1};
};

template <size_t Id = 0>
Expand All @@ -132,6 +154,16 @@ inline void init_log(Severity min_severity, const std::string &filename = "",
max_file_size, max_files, flush_every_time);
}

template <size_t Id = 0>
void drain() {
logger<Id>::instance().drain();
}

template <size_t Id = 0>
void enable_async() {
logger<Id>::instance().enable_async();
}

template <size_t Id = 0>
inline void flush() {
logger<Id>::instance().flush();
Expand Down
13 changes: 8 additions & 5 deletions include/easylog/record.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ class record_t {
buf_len_ = str.size();
}

record_t(const record_t &) = delete;
record_t(record_t &&) = default;

Severity get_severity() const { return severity_; }

const char *get_message() const { return ss_.data(); }
Expand All @@ -114,10 +117,10 @@ class record_t {

auto get_time_point() const { return tm_point_; }

record_t &ref() { return *this; }
record_t &&ref() { return std::move(*this); }

template <typename T>
record_t &operator<<(const T &data) {
record_t &&operator<<(const T &data) {
using U = std::remove_cvref_t<T>;
if constexpr (std::is_floating_point_v<U>) {
char temp[40];
Expand All @@ -140,14 +143,14 @@ class record_t {
ss_.append(data);
}

return *this;
return std::move(*this);
}

template <typename... Args>
record_t &sprintf(const char *fmt, Args... args) {
record_t &&sprintf(const char *fmt, Args... args) {
printf_string_format(fmt, args...);

return *this;
return std::move(*this);
}

private:
Expand Down
4 changes: 4 additions & 0 deletions src/easylog/benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ if (glog_FOUND)
target_compile_definitions(easylog_benchmark PRIVATE HAVE_GLOG)
target_link_libraries(easylog_benchmark PRIVATE glog::glog)
endif ()

target_include_directories(easylog_benchmark PRIVATE
${yaLanTingLibs_SOURCE_DIR}/thirdparty/asio
)
31 changes: 20 additions & 11 deletions src/easylog/benchmark/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,34 +47,43 @@ class ScopedTimer {
uint64_t *m_ns = nullptr;
};

bool first_init = true;
void test_glog() {
#ifdef HAVE_GLOG
std::filesystem::remove("glog.txt");
FLAGS_log_dir = ".";
FLAGS_minloglevel = google::GLOG_INFO;
FLAGS_timestamp_in_logfile_name = false;
google::SetLogDestination(google::INFO, "glog.txt");
google::InitGoogleLogging("glog");
if (first_init) {
FLAGS_log_dir = ".";
FLAGS_minloglevel = google::GLOG_INFO;
FLAGS_timestamp_in_logfile_name = false;
google::SetLogDestination(google::INFO, "glog.txt");
google::InitGoogleLogging("glog");
first_init = false;
}

{
ScopedTimer timer("glog ");
for (int i = 0; i < 5000; i++)
LOG(INFO) << "Hello, it is a long string test! " << 42 << 21 << 2.5;
for (int i = 0; i < 10000; i++)
LOG(INFO) << "Hello, it is a long string test! " << 42 << 21 << 2.5 << i;
}
#endif
}

void test_easylog() {
std::filesystem::remove("easylog.txt");
easylog::init_log(Severity::DEBUG, "easylog.txt", false, 1024 * 1024, 1);
easylog::enable_async();
{
ScopedTimer timer("easylog");
for (int i = 0; i < 5000; i++)
ELOG(INFO) << "Hello, it is a long string test! " << 42 << 21 << 2.5;
for (int i = 0; i < 10000; i++)
ELOG(INFO) << "Hello, it is a long string test! " << 42 << 21 << 2.5 << i;

easylog::drain();
}
}

int main() {
test_glog();
test_easylog();
for (int i = 0; i < 10; i++) {
test_glog();
test_easylog();
}
}
7 changes: 5 additions & 2 deletions src/easylog/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ add_executable(test_easylog
add_test(NAME test_easylog COMMAND test_easylog)
target_compile_definitions(test_easylog PRIVATE STRUCT_PACK_ENABLE_UNPORTABLE_TYPE)
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
target_link_libraries(test_easylog PRIVATE yalantinglibs::easylog doctest)
target_link_libraries(test_easylog PRIVATE yalantinglibs::easylog -lpthread doctest)
else()
target_link_libraries(test_easylog PRIVATE yalantinglibs::easylog doctest -lstdc++fs)
target_link_libraries(test_easylog PRIVATE yalantinglibs::easylog -lpthread doctest -lstdc++fs)
endif()

target_include_directories(test_easylog PRIVATE
${yaLanTingLibs_SOURCE_DIR}/thirdparty/asio
)