Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
ncs1 committed Mar 26, 2024
2 parents 9face8b + fd4a341 commit c9591e2
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 26 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Ubuntu-amd64

on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: cmake build
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
- name: cmake make
run: cmake --build build --parallel 3
- name: test
run: ./build/aixlog_example
16 changes: 16 additions & 0 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Windows-win64

on: [push, pull_request]

jobs:
build:
runs-on: windows-latest

steps:
- uses: actions/checkout@v2
- name: cmake build
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
- name: cmake make
run: cmake --build build --parallel 3
- name: test
run: build\Debug\aixlog_example.exe
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ build

#test binary
aixlog_example
all.log

#vscode
.vscode
Expand Down
22 changes: 20 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
# \_/\_/(__)(_/\_)\____/ \__/ \___/

# This file is part of aixlog
# Copyright (C) 2017-2020 Johannes Pohl
# Copyright (C) 2017-2021 Johannes Pohl

# This software may be modified and distributed under the terms
# of the MIT license. See the LICENSE file for details.

cmake_minimum_required(VERSION 3.0.0)

project(aixlog VERSION 1.4.0 LANGUAGES CXX)
project(aixlog VERSION 1.5.0 LANGUAGES CXX)
set(PROJECT_DESCRIPTION "Header-only C++ logging library")
set(PROJECT_URL "https://github.com/badaix/aixlog")

Expand Down Expand Up @@ -40,3 +40,21 @@ endif (BUILD_EXAMPLE)


install(FILES include/aixlog.hpp DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")

FIND_PROGRAM(CLANG_FORMAT "clang-format")
IF(CLANG_FORMAT)
set(CHECK_CXX_SOURCE_FILES
${CMAKE_SOURCE_DIR}/include/aixlog.hpp
${CMAKE_SOURCE_DIR}/aixlog_example.cpp
)

ADD_CUSTOM_TARGET(
reformat
COMMAND
${CLANG_FORMAT}
-i
-style=file
${CHECK_CXX_SOURCE_FILES}
COMMENT "Auto formatting of all source files"
)
ENDIF()
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2017-2020 Johannes Pohl
Copyright (c) 2017-2021 Johannes Pohl

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
61 changes: 57 additions & 4 deletions aixlog_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
\_/\_/(__)(_/\_)\____/ \__/ \___/
This file is part of aixlog
Copyright (C) 2017-2020 Johannes Pohl
Copyright (C) 2017-2021 Johannes Pohl
This software may be modified and distributed under the terms
of the MIT license. See the LICENSE file for details.
Expand All @@ -17,6 +17,33 @@
using namespace std;


/// Log Conditional to log only every x-th message
struct EveryXConditional : public AixLog::Conditional
{
/// c'tor
/// @param every_x log only every_x-th line
EveryXConditional(size_t every_x) : every_x_(every_x), x_th_(0)
{
}

/// check if this is the x-th log message
/// @return true if this is the x-th log message
bool is_true() const override
{
if (++x_th_ == every_x_)
{
x_th_ = 0;
return true;
}
return false;
}

private:
size_t every_x_;
mutable size_t x_th_;
};


int main(int /*argc*/, char** /*argv*/)
{
AixLog::Log::init<AixLog::SinkCout>(AixLog::Severity::trace);
Expand All @@ -31,9 +58,9 @@ int main(int /*argc*/, char** /*argv*/)
filter.add_filter("LOG_TAG:DEBUG");
auto sink_cout = make_shared<AixLog::SinkCout>(filter);
AixLog::Filter filter_syslog;
// log lines with tag "SYSLOG" to syslog
filter_syslog.add_filter("SYSLOG:TRACE");
auto sink_syslog = make_shared<AixLog::SinkSyslog>("aixlog example", filter_syslog);
// log lines with tag "SYSLOG" to syslog
filter_syslog.add_filter("SYSLOG:TRACE");
auto sink_syslog = make_shared<AixLog::SinkNative>("aixlog example", filter_syslog);

AixLog::Log::init({sink_cout, sink_syslog});

Expand All @@ -59,6 +86,10 @@ int main(int /*argc*/, char** /*argv*/)
<< "\n\tfile: " << metadata.function.file << "\n";
})});

#ifdef WIN32
AixLog::Log::instance().add_logsink<AixLog::SinkOutputDebugString>(AixLog::Severity::trace);
#endif

/// Log with info severity
LOG(INFO) << "LOG(INFO)\n";
/// ... with a tag
Expand Down Expand Up @@ -87,8 +118,30 @@ int main(int /*argc*/, char** /*argv*/)
LOG(FATAL) << "LOG(FATAL) " << COLOR(red) << "red" << COLOR(none) << ", default color (using macros)\n";
LOG(FATAL) << "LOG(FATAL) " << AixLog::TextColor(AixLog::Color::yellow, AixLog::Color::blue) << "yellow on blue background" << AixLog::Color::none
<< ", default color\n";
#ifndef WIN32
LOG(FATAL) << "LOG(FATAL) " << COLOR(yellow, blue) << "yellow on blue background" << COLOR(none) << ", default color (using macros)\n";
#endif

AixLog::Severity severity(AixLog::Severity::debug);
LOG(severity) << "LOG(severity) << severity\n";

EveryXConditional every_x(3);
LOG(INFO) << every_x << "1st will not be logged\n";
LOG(INFO) << every_x << "2nd will not be logged\n";
LOG(INFO) << every_x << "3rd will be logged\n";
LOG(INFO) << every_x << "4th will not be logged\n";
LOG(INFO) << every_x << "5th will not be logged\n";
LOG(INFO) << every_x << "6th will be logged\n";

AixLog::Conditional not_every_3(AixLog::Conditional::EvalFunc([] {
static size_t n(0);
return (++n % 3 != 0);
}));

LOG(INFO) << not_every_3 << "1st will be logged\n";
LOG(INFO) << not_every_3 << "2nd will be logged\n";
LOG(INFO) << not_every_3 << "3rd will not be logged\n";
LOG(INFO) << not_every_3 << "4th will be logged\n";
LOG(INFO) << not_every_3 << "5th will be logged\n";
LOG(INFO) << not_every_3 << "6th will not be logged\n";
}
56 changes: 37 additions & 19 deletions include/aixlog.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
/ _\ ( )( \/ )( ) / \ / __)
/ \ )( ) ( / (_/\( O )( (_ \
\_/\_/(__)(_/\_)\____/ \__/ \___/
version 1.4.0
version 1.5.0
https://github.com/badaix/aixlog
This file is part of aixlog
Copyright (C) 2017-2020 Johannes Pohl
Copyright (C) 2017-2021 Johannes Pohl
This software may be modified and distributed under the terms
of the MIT license. See the LICENSE file for details.
Expand Down Expand Up @@ -178,7 +178,7 @@ enum class Severity : std::int8_t

static Severity to_severity(std::string severity, Severity def = Severity::info)
{
std::transform(severity.begin(), severity.end(), severity.begin(), [](unsigned char c) { return std::tolower(c); });
std::transform(severity.begin(), severity.end(), severity.begin(), [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
if (severity == "trace")
return Severity::trace;
else if (severity == "debug")
Expand Down Expand Up @@ -269,26 +269,29 @@ struct TextColor
*/
struct Conditional
{
Conditional() : Conditional(true)
using EvalFunc = std::function<bool()>;

Conditional() : func_([](void) { return true; })
{
}

Conditional(bool value) : is_true_(value)
Conditional(const EvalFunc& func) : func_(func)
{
}

void set(bool value)
Conditional(bool value) : func_([value](void) { return value; })
{
is_true_ = value;
}

bool is_true() const
virtual ~Conditional() = default;

virtual bool is_true() const
{
return is_true_;
return func_();
}

private:
bool is_true_;
protected:
EvalFunc func_;
};

/**
Expand Down Expand Up @@ -601,7 +604,7 @@ class Log : public std::basic_streambuf<char, std::char_traits<char>>
}

protected:
Log() noexcept : last_buffer_(nullptr)
Log() noexcept : last_buffer_(nullptr), do_log_(true)
{
std::clog.rdbuf(this);
std::clog << Severity() << Tag() << Function() << Conditional() << AixLog::Color::NONE << std::flush;
Expand All @@ -617,7 +620,7 @@ class Log : public std::basic_streambuf<char, std::char_traits<char>>
std::lock_guard<std::recursive_mutex> lock(mutex_);
if (!get_stream().str().empty())
{
if (conditional_.is_true())
if (do_log_)
{
for (const auto& sink : log_sinks_)
{
Expand All @@ -639,7 +642,7 @@ class Log : public std::basic_streambuf<char, std::char_traits<char>>
{
if (c == '\n')
sync();
else
else if (do_log_)
get_stream() << static_cast<char>(c);
}
else
Expand Down Expand Up @@ -667,11 +670,14 @@ class Log : public std::basic_streambuf<char, std::char_traits<char>>
return *last_buffer_;
}

/// one buffer per thread to avoid mixed log lines
std::map<std::thread::id, std::stringstream> buffer_;
/// the last thread id
std::thread::id last_id_;
/// the last buffer
std::stringstream* last_buffer_ = nullptr;
Metadata metadata_;
Conditional conditional_;
bool do_log_;
std::vector<log_sink_ptr> log_sinks_;
std::recursive_mutex mutex_;
};
Expand Down Expand Up @@ -843,8 +849,12 @@ struct SinkOutputDebugString : public Sink

void log(const Metadata& metadata, const std::string& message) override
{
#ifdef UNICODE
std::wstring wide = std::wstring(message.begin(), message.end());
OutputDebugString(wide.c_str());
#else
OutputDebugString(message.c_str());
#endif
}
};
#endif
Expand Down Expand Up @@ -1004,8 +1014,12 @@ struct SinkEventLog : public Sink
{
SinkEventLog(const std::string& ident, const Filter& filter) : Sink(filter)
{
#ifdef UNICODE
std::wstring wide = std::wstring(ident.begin(), ident.end()); // stijnvdb: RegisterEventSource expands to RegisterEventSourceW which takes wchar_t
event_log = RegisterEventSource(NULL, wide.c_str());
#else
event_log = RegisterEventSource(NULL, ident.c_str());
#endif
}

WORD get_type(Severity severity) const
Expand All @@ -1031,11 +1045,15 @@ struct SinkEventLog : public Sink

void log(const Metadata& metadata, const std::string& message) override
{
#ifdef UNICODE
std::wstring wide = std::wstring(message.begin(), message.end());
// We need this temp variable because we cannot take address of rValue
const wchar_t* c_str = wide.c_str();

const auto* c_str = wide.c_str();
ReportEvent(event_log, get_type(metadata.severity), 0, 0, NULL, 1, 0, &c_str, NULL);
#else
const auto* c_str = message.c_str();
ReportEvent(event_log, get_type(metadata.severity), 0, 0, NULL, 1, 0, &c_str, NULL);
#endif
}

protected:
Expand Down Expand Up @@ -1131,7 +1149,7 @@ static std::ostream& operator<<(std::ostream& os, const Severity& log_severity)
log->metadata_.timestamp = nullptr;
log->metadata_.tag = nullptr;
log->metadata_.function = nullptr;
log->conditional_.set(true);
log->do_log_ = true;
}
}
else
Expand Down Expand Up @@ -1192,7 +1210,7 @@ static std::ostream& operator<<(std::ostream& os, const Conditional& conditional
if (log != nullptr)
{
std::lock_guard<std::recursive_mutex> lock(log->mutex_);
log->conditional_.set(conditional.is_true());
log->do_log_ = conditional.is_true();
}
return os;
}
Expand Down

0 comments on commit c9591e2

Please sign in to comment.