pattern_formatter.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
  2. // Distributed under the MIT License (http://opensource.org/licenses/MIT)
  3. #pragma once
  4. #include <spdlog/common.h>
  5. #include <spdlog/details/log_msg.h>
  6. #include <spdlog/details/os.h>
  7. #include <spdlog/formatter.h>
  8. #include <chrono>
  9. #include <ctime>
  10. #include <memory>
  11. #include <string>
  12. #include <unordered_map>
  13. #include <vector>
  14. namespace spdlog {
  15. namespace details {
  16. // padding information.
  17. struct padding_info {
  18. enum class pad_side { left, right, center };
  19. padding_info() = default;
  20. padding_info(size_t width, padding_info::pad_side side, bool truncate)
  21. : width_(width),
  22. side_(side),
  23. truncate_(truncate),
  24. enabled_(true) {}
  25. bool enabled() const { return enabled_; }
  26. size_t width_ = 0;
  27. pad_side side_ = pad_side::left;
  28. bool truncate_ = false;
  29. bool enabled_ = false;
  30. };
  31. class SPDLOG_API flag_formatter {
  32. public:
  33. explicit flag_formatter(padding_info padinfo)
  34. : padinfo_(padinfo) {}
  35. flag_formatter() = default;
  36. virtual ~flag_formatter() = default;
  37. virtual void format(const details::log_msg &msg,
  38. const std::tm &tm_time,
  39. memory_buf_t &dest) = 0;
  40. protected:
  41. padding_info padinfo_;
  42. };
  43. } // namespace details
  44. class SPDLOG_API custom_flag_formatter : public details::flag_formatter {
  45. public:
  46. virtual std::unique_ptr<custom_flag_formatter> clone() const = 0;
  47. void set_padding_info(const details::padding_info &padding) {
  48. flag_formatter::padinfo_ = padding;
  49. }
  50. };
  51. class SPDLOG_API pattern_formatter final : public formatter {
  52. public:
  53. using custom_flags = std::unordered_map<char, std::unique_ptr<custom_flag_formatter>>;
  54. explicit pattern_formatter(std::string pattern,
  55. pattern_time_type time_type = pattern_time_type::local,
  56. std::string eol = spdlog::details::os::default_eol,
  57. custom_flags custom_user_flags = custom_flags());
  58. // use default pattern is not given
  59. explicit pattern_formatter(pattern_time_type time_type = pattern_time_type::local,
  60. std::string eol = spdlog::details::os::default_eol);
  61. pattern_formatter(const pattern_formatter &other) = delete;
  62. pattern_formatter &operator=(const pattern_formatter &other) = delete;
  63. std::unique_ptr<formatter> clone() const override;
  64. void format(const details::log_msg &msg, memory_buf_t &dest) override;
  65. template <typename T, typename... Args>
  66. pattern_formatter &add_flag(char flag, Args &&...args) {
  67. custom_handlers_[flag] = details::make_unique<T>(std::forward<Args>(args)...);
  68. return *this;
  69. }
  70. void set_pattern(std::string pattern);
  71. void need_localtime(bool need = true);
  72. private:
  73. std::string pattern_;
  74. std::string eol_;
  75. pattern_time_type pattern_time_type_;
  76. bool need_localtime_;
  77. std::tm cached_tm_;
  78. std::chrono::seconds last_log_secs_;
  79. std::vector<std::unique_ptr<details::flag_formatter>> formatters_;
  80. custom_flags custom_handlers_;
  81. std::tm get_time_(const details::log_msg &msg);
  82. template <typename Padder>
  83. void handle_flag_(char flag, details::padding_info padding);
  84. // Extract given pad spec (e.g. %8X)
  85. // Advance the given it pass the end of the padding spec found (if any)
  86. // Return padding.
  87. static details::padding_info handle_padspec_(std::string::const_iterator &it,
  88. std::string::const_iterator end);
  89. void compile_pattern_(const std::string &pattern);
  90. };
  91. } // namespace spdlog
  92. #ifdef SPDLOG_HEADER_ONLY
  93. #include "pattern_formatter-inl.h"
  94. #endif