Comments (10)
Thank you for reporting.
Could you send PR?
from spdlog.
This is kind of expected. If there are no args spdlog does’t treat the passed string as format string for performance reasons, and bypass the fmt formatting.
from spdlog.
@gabime Should I add a section to the FAQ page (https://github.com/gabime/spdlog/wiki/0.-FAQ) about this design?
from spdlog.
Is this the desired behavior? It seems this overload can be removed, as there is another overload that can cover the use cases of it:
spdlog/include/spdlog/logger.h
Lines 93 to 97 in 6230201
Firstly, my apology, I misunderstood the above overload, it is used to handle cases like SPDLOG_INFO(type_can_fmt{})
.
The std::string_view
fits the requirement of is_convertible_to_any_format_string
.
I tried to fix the problem by adding an overload of logger::log_()
, which will bypass the fmt formatting if there are no arguments, like the following:
...
void log_(source_loc loc, level::level_enum lvl, string_view_t msg) {
log_no_fmt_(loc, lvl, msg);
}
// copy from the `log(..., string_view_t)`
void log_no_fmt_(source_loc loc, level::level_enum lvl, string_view_t msg) {
bool log_enabled = should_log(lvl);
bool traceback_enabled = tracer_.enabled();
if (!log_enabled && !traceback_enabled) {
return;
}
details::log_msg log_msg(loc, name_, lvl, msg);
log_it_(log_msg, log_enabled, traceback_enabled);
}
However, it fails to compile with many errors of "error: the value of ‘msg’ is not usable in a constant expression", which is caused by using non-literal strings, e.g.:
// bench/latency.cpp
void bench_c_string(benchmark::State &state, std::shared_ptr<spdlog::logger> logger) {
const char *msg =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pharetra metus cursus "
"lacus placerat congue. Nulla egestas, mauris a tincidunt tempus, enim lectus volutpat mi, "
"eu consequat sem "
"libero nec massa. In dapibus ipsum a diam rhoncus gravida. Etiam non dapibus eros. Donec "
"fringilla dui sed "
"augue pretium, nec scelerisque est maximus. Nullam convallis, sem nec blandit maximus, "
"nisi turpis ornare "
"nisl, sit amet volutpat neque massa eu odio. Maecenas malesuada quam ex, posuere congue "
"nibh turpis duis.";
for (auto _ : state) {
logger->info(msg);
}
}
So the problem now is how to correctly detect non-literal strings and dispatch them to log_no_fmt_
?
Is there any effort to solve this problem before?
from spdlog.
Use fmt::runtime()
for non-literal characters: #2786
It is returns runtime object basic_runtime<char>
in fmt 9.1.0 (https://fmt.dev/9.1.0/api.html#_CPPv4N3fmt7runtimeE11string_view).
Note fmt::runtime()
returns runtime_format_string<>
fmt 10 and above (https://fmt.dev/10.0.0/api.html#_CPPv4N3fmt7runtimeE11string_view).
The template function log(source_loc loc, level::level_enum lvl, const T &msg)
does not fit because is_convertible_to_any_format_string<const T &>::value == true
when using fmt::runtime()
.
spdlog/include/spdlog/common.h
Lines 219 to 223 in 6230201
spdlog/include/spdlog/common.h
Lines 186 to 201 in 6230201
from spdlog.
Looking at the logging template function signatures, it seems that it would be very difficult to change the current implementation.
The only way to make the compile time check work with just a literal string would be to directly call log(source_loc loc, level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args)
that calls log_(source_loc loc, level::level_enum lvl, string_view_t fmt, Args &&...args)
.
spdlog/include/spdlog/logger.h
Lines 78 to 81 in 6230201
Since info(const T &msg)
cannot call log(source_loc loc, level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args)
, try calling log(source_loc loc, level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args)
directly.
spdlog/include/spdlog/logger.h
Lines 241 to 244 in 6230201
from spdlog.
Since
info(const T &msg)
cannot calllog(source_loc loc, level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args)
, try callinglog(source_loc loc, level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args)
directly.spdlog/include/spdlog/logger.h
Lines 241 to 244 in 6230201
There is another similar overload can achieve the compile-time check
spdlog/include/spdlog/logger.h
Lines 138 to 141 in 6230201
The problem is info("{}")
will resolve to the info(const T &msg)
overload.
Therefore, I tried to add the !is_convertible_to_any_format_string
requirement to info(const T &msg)
, which makes the info("{}")
resolve to info(format_string_t<Args...> fmt, Args &&...args)
, and compile-time check works for info("{}")
.
template <class T,
typename std::enable_if<!is_convertible_to_any_format_string<const T &>::value,
int>::type = 0>
void info(const T &msg) {
log(level::info, msg);
}
However, this modification makes non-literal strings resolve to the compile-time check overload, too.
std::string s = fmt::format("{}", 123);
// without modification: resolves to `info(const T&msg)`, compile ok
// with modification: resolves to `info(format_string_t<Args...> fmt, Args &&...args)`, compile fail (c++20) due to `s` is not constexpr
spdlog::info(s);
The problem here is there is no way to do different dispatch for constexpr argument and non-constexpr argument before c++23.
With c++23, the if consteval
feature seems can help in this problem.
from spdlog.
Yes, this problem cannot be avoided because if consteval
is not available in C++11.
If you really want to do a compile-time check when passing only string, you will have to call log(source_loc loc, level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args)
.
from spdlog.
@gabime Should I add a section to the FAQ page (https://github.com/gabime/spdlog/wiki/0.-FAQ) about this design?
If this is actually a FAQ then yes please
from spdlog.
If this is actually a FAQ then yes please
from spdlog.
Related Issues (20)
- sometimes print the log, and sometimes it don't. HOT 4
- Does spdlog support printf style logging? HOT 1
- 'parse': is not a member of 'fmt::v9::detail::fallback_formatter<std::basic_ostringstream<char,std::char_traits<char>,std::allocator<char>>,Char,void>' HOT 2
- Logging messages within a custom sink causes a dead lock? HOT 1
- does SPDLOG consider control characters encountered when printing a character array as string termination markers? HOT 1
- Set a log zone prefix to default logger HOT 2
- Memory overflow warning in pattern_formatter-inl.h HOT 1
- Is there a plan to update the included libfmt to fix fmtlib/fmt#3540? HOT 8
- C++20 Modules "'std::basic_string': redefinition" HOT 2
- Make source_loc more resilient to invalid data HOT 3
- Show the lower digits of numeric fields, such as thread-id HOT 2
- spdlog::init_thread_pool caused a Segmentation fault HOT 4
- Auto generate tweakme.h HOT 17
- Can't create directory and file like "D:/Logs/log.txt" HOT 14
- Header-only version 1.14.0 complie with errors HOT 6
- spdlog 1.14.0: undefined reference to `spdlog::get(char const*)' HOT 14
- vs编译工作正常, g++编译报错 HOT 5
- Async logging using MDC HOT 6
- Does the dist_sink support Factory pattern to create a new logger? HOT 3
- COMBINE "daily_file_sink" AND "rotating_file_sink" HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spdlog.