-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Logging UTC time, not local time #215
Comments
I could change the private members of class gmt_formatter : public spdlog::pattern_formatter
{
public:
explicit gmt_formatter(const std::string& pattern) : pattern_formatter(pattern) {}
void format(spdlog::details::log_msg& msg) override
{
try
{
auto tm_time = spdlog::details::os::gmtime(spdlog::log_clock::to_time_t(msg.time));
for (auto &f : _formatters)
{
f->format(msg, tm_time);
}
//write eol
msg.formatted.write(spdlog::details::os::eol, spdlog::details::os::eol_size);
}
catch (const fmt::FormatError& e)
{
throw spdlog::spdlog_ex(fmt::format("formatting error while processing format string: {}", e.what()));
}
}
}; and then in main: ...
spdlog::set_formatter(std::make_shared<gmt_formatter>("%+"));
... |
I don't think that making internals of pattern_formatter protected instead of private is a good idea. This creates a dependency of the implementation of pattern_formatter. If you change the way of holding nested formatters (by some compile-time magic tricks) in some future version it breaks all derived classes. Another solution could be as follows: class pattern_formatter : public formatter
{
public :
... // all the current public stuff
protected :
virtual std::tm get_time(std::time_t t) {
return details::os::local_time(t);
}
private:
... // all the current private stuff and then in pattern_formatter::format: inline void spdlog::pattern_formatter::format(details::log_msg& msg)
{
try
{
auto tm_time = get_time(msg.time)); So I can write: class gmt_pattern_formatter : public spdlog::pattern_formatter
{
protected:
std::tm get_time(std::time_t t) override {
return spdlog::details::os::gmtime(t);
}
...
}; But price will be another virtual call. It could be very small price in many cases I think. |
I agree, but another virtual call in this critical path should not be taken lightly.. |
Because of that my first proposal is based on templates. |
The template idea while might be right, requirs too many changes. I am not even sure it worth it for such small feature.. especially since this won't solve the big picture. There could be many customization needed by different users. and then what? more templates? if the gmt need becomes popular I prefer just to add a flag to the ctor and solve this simple problem in a simple way. |
Ok. I see you point. |
It would have been a nice feature for myself too. |
I would like to also say that I need time to be formatted in UTC as well. I think a constructor flag would be very helpful for this. |
I implemented what I believe to be a minimal-impact, simple change to handle local vs. UTC time (with potential for future expansion without undue implementator burden). Please let me know if #451 seems reasonable! |
I have found myself in a situation where I need to use UTC-time in log files. But it seems that standard pattern formatter in spdlog always use details::os::local_time for conversion from std::time_t to std::tm.
So now I have a choice:
I don't like both of them. I think it is possible to slightly improve spdlog::pattern_formatter implementation:
Where local_time_provider will be:
And there also will be gm_time_provider:
It makes possible to do something like:
It you decide that this is an appropriate idea I could implement it in my spdlog fork and make pull request.
The text was updated successfully, but these errors were encountered: