-
Notifications
You must be signed in to change notification settings - Fork 410
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
*: Combine LOG_XXX and LOG_FMT_XXX #5512
Changes from all commits
07adb49
f474f1d
b6fb81f
47c753f
d0823c1
8893e52
2c3f240
164c473
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright 2022 PingCAP, Ltd. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#pragma once | ||
|
||
#define TF_GET_1ST_ARG(a, ...) a | ||
#define TF_GET_2ND_ARG(a1, a2, ...) a2 | ||
#define TF_GET_3RD_ARG(a1, a2, a3, ...) a3 | ||
#define TF_GET_4TH_ARG(a1, a2, a3, a4, ...) a4 | ||
#define TF_GET_5TH_ARG(a1, a2, a3, a4, a5, ...) a5 | ||
#define TF_GET_6TH_ARG(a1, a2, a3, a4, a5, a6, ...) a6 | ||
#define TF_GET_7TH_ARG(a1, a2, a3, a4, a5, a6, a7, ...) a7 | ||
#define TF_GET_8TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, ...) a8 | ||
#define TF_GET_9TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, ...) a9 | ||
#define TF_GET_10TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, ...) a10 | ||
#define TF_GET_11TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, ...) a11 | ||
#define TF_GET_12TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, ...) a12 | ||
#define TF_GET_13TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, ...) a13 | ||
#define TF_GET_14TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, ...) a14 | ||
#define TF_GET_15TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, ...) a15 | ||
#define TF_GET_16TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, ...) a16 | ||
#define TF_GET_17TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, ...) a17 | ||
#define TF_GET_18TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, ...) a18 | ||
#define TF_GET_19TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, ...) a19 | ||
#define TF_GET_20TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, ...) a20 | ||
#define TF_GET_21TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, ...) a21 | ||
#define TF_GET_22TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, ...) a22 | ||
#define TF_GET_23TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, ...) a23 | ||
#define TF_GET_24TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, ...) a24 | ||
#define TF_GET_25TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, ...) a25 | ||
#define TF_GET_26TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, ...) a26 | ||
#define TF_GET_27TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, ...) a27 | ||
#define TF_GET_28TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, ...) a28 | ||
#define TF_GET_29TH_ARG(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, ...) a29 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
/// Macros for convenient usage of Poco logger. | ||
|
||
#include <Poco/Logger.h> | ||
#include <common/MacroUtils.h> | ||
#include <fmt/format.h> | ||
#include <fmt/ranges.h> | ||
|
||
|
@@ -26,17 +27,6 @@ | |
|
||
namespace LogFmtDetails | ||
{ | ||
template <typename... Ts> | ||
inline constexpr size_t numArgs(Ts &&...) | ||
{ | ||
return sizeof...(Ts); | ||
} | ||
template <typename T, typename... Ts> | ||
inline constexpr auto firstArg(T && x, Ts &&...) | ||
{ | ||
return std::forward<T>(x); | ||
} | ||
|
||
// https://stackoverflow.com/questions/8487986/file-macro-shows-full-path/54335644#54335644 | ||
template <typename T, size_t S> | ||
inline constexpr size_t getFileNameOffset(const T (&str)[S], size_t i = S - 1) | ||
|
@@ -50,8 +40,8 @@ inline constexpr size_t getFileNameOffset(T (&/*str*/)[1]) | |
return 0; | ||
} | ||
|
||
template <typename S, typename Ignored, typename... Args> | ||
std::string toCheckedFmtStr(const S & format, const Ignored &, Args &&... args) | ||
template <typename S, typename... Args> | ||
std::string toCheckedFmtStr(const S & format, Args &&... args) | ||
{ | ||
// The second arg is the same as `format`, just ignore | ||
// Apply `make_args_checked` for checks `format` validity at compile time. | ||
|
@@ -60,61 +50,58 @@ std::string toCheckedFmtStr(const S & format, const Ignored &, Args &&... args) | |
} | ||
} // namespace LogFmtDetails | ||
|
||
/// Logs a message to a specified logger with that level. | ||
|
||
#define LOG_IMPL(logger, PRIORITY, message) \ | ||
do \ | ||
{ \ | ||
if ((logger)->is((PRIORITY))) \ | ||
{ \ | ||
Poco::Message poco_message( \ | ||
/*source*/ (logger)->name(), \ | ||
/*text*/ message, \ | ||
/*prio*/ (PRIORITY), \ | ||
/*file*/ &__FILE__[LogFmtDetails::getFileNameOffset(__FILE__)], \ | ||
/*line*/ __LINE__); \ | ||
(logger)->log(poco_message); \ | ||
} \ | ||
} while (false) | ||
|
||
#define LOG_TRACE(logger, message) LOG_IMPL(logger, Poco::Message::PRIO_TRACE, message) | ||
#define LOG_DEBUG(logger, message) LOG_IMPL(logger, Poco::Message::PRIO_DEBUG, message) | ||
#define LOG_INFO(logger, message) LOG_IMPL(logger, Poco::Message::PRIO_INFORMATION, message) | ||
#define LOG_WARNING(logger, message) LOG_IMPL(logger, Poco::Message::PRIO_WARNING, message) | ||
#define LOG_ERROR(logger, message) LOG_IMPL(logger, Poco::Message::PRIO_ERROR, message) | ||
#define LOG_FATAL(logger, message) LOG_IMPL(logger, Poco::Message::PRIO_FATAL, message) | ||
|
||
|
||
/// Logs a message to a specified logger with that level. | ||
/// If more than one argument is provided, | ||
/// the first argument is interpreted as template with {}-substitutions | ||
/// and the latter arguments treat as values to substitute. | ||
/// If only one argument is provided, it is threat as message without substitutions. | ||
|
||
#define LOG_GET_FIRST_ARG(arg, ...) arg | ||
#define LOG_FMT_IMPL(logger, PRIORITY, ...) \ | ||
do \ | ||
{ \ | ||
if ((logger)->is((PRIORITY))) \ | ||
{ \ | ||
std::string formatted_message = LogFmtDetails::numArgs(__VA_ARGS__) > 1 \ | ||
? LogFmtDetails::toCheckedFmtStr( \ | ||
FMT_STRING(LOG_GET_FIRST_ARG(__VA_ARGS__)), \ | ||
__VA_ARGS__) \ | ||
: LogFmtDetails::firstArg(__VA_ARGS__); \ | ||
Poco::Message poco_message( \ | ||
/*source*/ (logger)->name(), \ | ||
/*text*/ formatted_message, \ | ||
/*prio*/ (PRIORITY), \ | ||
/*file*/ &__FILE__[LogFmtDetails::getFileNameOffset(__FILE__)], \ | ||
/*line*/ __LINE__); \ | ||
(logger)->log(poco_message); \ | ||
} \ | ||
#define LOG_INTERNAL(logger, PRIORITY, message) \ | ||
do \ | ||
{ \ | ||
Poco::Message poco_message( \ | ||
/*source*/ (logger)->name(), \ | ||
/*text*/ (message), \ | ||
/*prio*/ (PRIORITY), \ | ||
/*file*/ &__FILE__[LogFmtDetails::getFileNameOffset(__FILE__)], \ | ||
/*line*/ __LINE__); \ | ||
(logger)->log(poco_message); \ | ||
} while (false) | ||
|
||
#define LOG_FMT_TRACE(logger, ...) LOG_FMT_IMPL(logger, Poco::Message::PRIO_TRACE, __VA_ARGS__) | ||
#define LOG_FMT_DEBUG(logger, ...) LOG_FMT_IMPL(logger, Poco::Message::PRIO_DEBUG, __VA_ARGS__) | ||
#define LOG_FMT_INFO(logger, ...) LOG_FMT_IMPL(logger, Poco::Message::PRIO_INFORMATION, __VA_ARGS__) | ||
#define LOG_FMT_WARNING(logger, ...) LOG_FMT_IMPL(logger, Poco::Message::PRIO_WARNING, __VA_ARGS__) | ||
#define LOG_FMT_ERROR(logger, ...) LOG_FMT_IMPL(logger, Poco::Message::PRIO_ERROR, __VA_ARGS__) | ||
#define LOG_FMT_FATAL(logger, ...) LOG_FMT_IMPL(logger, Poco::Message::PRIO_FATAL, __VA_ARGS__) | ||
|
||
#define LOG_IMPL_0(logger, PRIORITY, message) \ | ||
do \ | ||
{ \ | ||
if ((logger)->is((PRIORITY))) \ | ||
LOG_INTERNAL(logger, PRIORITY, message); \ | ||
} while (false) | ||
|
||
#define LOG_IMPL_1(logger, PRIORITY, fmt_str, ...) \ | ||
do \ | ||
{ \ | ||
if ((logger)->is((PRIORITY))) \ | ||
{ \ | ||
auto _message = LogFmtDetails::toCheckedFmtStr(FMT_STRING(fmt_str), __VA_ARGS__); \ | ||
LOG_INTERNAL(logger, PRIORITY, _message); \ | ||
} \ | ||
} while (false) | ||
|
||
#define LOG_IMPL_CHOSER(...) TF_GET_29TH_ARG(__VA_ARGS__, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_1, LOG_IMPL_0) | ||
|
||
// clang-format off | ||
#define LOG_IMPL(logger, PRIORITY, ...) LOG_IMPL_CHOSER(__VA_ARGS__)(logger, PRIORITY, __VA_ARGS__) | ||
// clang-format on | ||
|
||
#define LOG_TRACE(logger, ...) LOG_IMPL(logger, Poco::Message::PRIO_TRACE, __VA_ARGS__) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to the doc:
Seems that we can even consider supporting named arguments (instead of fmt differently) in future? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does "named arguments" means a behavior like this?
As There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. spdlog may be a good alternative considering performance. It also has many convenient features. |
||
#define LOG_DEBUG(logger, ...) LOG_IMPL(logger, Poco::Message::PRIO_DEBUG, __VA_ARGS__) | ||
#define LOG_INFO(logger, ...) LOG_IMPL(logger, Poco::Message::PRIO_INFORMATION, __VA_ARGS__) | ||
#define LOG_WARNING(logger, ...) LOG_IMPL(logger, Poco::Message::PRIO_WARNING, __VA_ARGS__) | ||
#define LOG_ERROR(logger, ...) LOG_IMPL(logger, Poco::Message::PRIO_ERROR, __VA_ARGS__) | ||
#define LOG_FATAL(logger, ...) LOG_IMPL(logger, Poco::Message::PRIO_FATAL, __VA_ARGS__) | ||
|
||
#define LOG_FMT_TRACE(...) LOG_TRACE(__VA_ARGS__) | ||
#define LOG_FMT_DEBUG(...) LOG_DEBUG(__VA_ARGS__) | ||
#define LOG_FMT_INFO(...) LOG_INFO(__VA_ARGS__) | ||
#define LOG_FMT_WARNING(...) LOG_WARNING(__VA_ARGS__) | ||
#define LOG_FMT_ERROR(...) LOG_ERROR(__VA_ARGS__) | ||
#define LOG_FMT_FATAL(...) LOG_FATAL(__VA_ARGS__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you tell me why have 29 args?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because in our repo the maximum of arguments count is 26.