date_format.cxx 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. //
  2. // date_format.cxx
  3. // logging
  4. //
  5. // Created by Sam Jaffe on 4/4/19.
  6. //
  7. #include <ctime>
  8. #include <functional>
  9. #include <string>
  10. #include "logger/exception.h"
  11. #include "logger/format.h"
  12. #include "logger/logger_fwd.h"
  13. #include "logger/logpacket.h"
  14. namespace logging {
  15. std::string fmt_time(struct timeval round, char const * const fmt) {
  16. struct tm time;
  17. // Supports localtime when requested, but you can't really test that
  18. if (strstr(fmt, "%z") || strstr(fmt, "%Z")) {
  19. localtime_r(&round.tv_sec, &time);
  20. } else {
  21. gmtime_r(&round.tv_sec, &time);
  22. }
  23. char buf[64] = {'\0'};
  24. std::strftime(buf, sizeof(buf), fmt, &time);
  25. return buf;
  26. }
  27. std::string fmt_time(struct timeval round, std::string const & fmt) {
  28. return fmt_time(round, fmt.c_str());
  29. }
  30. std::string fmt_time_with_milis(struct timeval round,
  31. std::string const & fmt) {
  32. char buf[64] = {'\0'};
  33. snprintf(buf, sizeof(buf), fmt.c_str(), round.tv_usec/1000);
  34. return fmt_time(round, buf);
  35. }
  36. string_generator get_date_formatter(std::string fmt) {
  37. if (fmt.find("%_ms") != std::string::npos) {
  38. size_t pos = 0;
  39. while ((pos = fmt.find("%", pos)) != std::string::npos) {
  40. fmt.replace(pos, 1, "%%");
  41. pos += 2;
  42. }
  43. fmt.replace(fmt.find("%%_ms"), 5, "%.03d");
  44. return [=](logpacket const & lp) {
  45. return fmt_time_with_milis(lp.time, fmt);
  46. };
  47. } else {
  48. return [=](logpacket const & lp) {
  49. return fmt_time(lp.time, fmt);
  50. };
  51. }
  52. }
  53. string_generator parse_date_format_string(char const * str) {
  54. char const * const end = strchr(str, '}');
  55. if (end == nullptr) {
  56. std::string error_msg{"expected date-format specifier to terminate"};
  57. throw format_parsing_exception{error_msg};
  58. }
  59. return get_date_formatter(std::string(str, end));
  60. }
  61. }