💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

195 lines
3.7 KiB

  1. /*
  2. * Copyright (C) 2021 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "logger.hpp"
  20. #include "utility/timestamp.hpp"
  21. #include <iostream>
  22. namespace debug {
  23. logger::logger():
  24. os(&std::cout),
  25. auto_newline(true),
  26. timestamp_enabled(true),
  27. indent("| "),
  28. log_prefix(std::string()),
  29. log_postfix(std::string()),
  30. warning_prefix(std::string()),
  31. warning_postfix(std::string()),
  32. error_prefix(std::string()),
  33. error_postfix(std::string()),
  34. success_prefix(std::string()),
  35. success_postfix(std::string())
  36. {}
  37. logger::~logger()
  38. {}
  39. void logger::redirect(std::ostream* stream)
  40. {
  41. os = stream;
  42. }
  43. void logger::log(const std::string& text)
  44. {
  45. if (os)
  46. {
  47. std::string message = "";
  48. // Prepend timestamp
  49. if (timestamp_enabled)
  50. {
  51. message += timestamp();
  52. message += ": ";
  53. }
  54. // Prepend indentation
  55. for (std::size_t i = 0; i < tasks.size(); ++i)
  56. message += indent;
  57. // Append text
  58. message += (log_prefix + text + log_postfix);
  59. // Append newline
  60. if (auto_newline)
  61. message += "\n";
  62. // Add message to log history
  63. const std::lock_guard<std::mutex> history_lock(history_mutex);
  64. history += message;
  65. // Output message
  66. (*os) << message;
  67. // Flush output stream
  68. os->flush();
  69. }
  70. }
  71. void logger::warning(const std::string& text)
  72. {
  73. log(warning_prefix + text + warning_postfix);
  74. }
  75. void logger::error(const std::string& text)
  76. {
  77. log(error_prefix + text + error_postfix);
  78. }
  79. void logger::success(const std::string& text)
  80. {
  81. log(success_prefix + text + success_postfix);
  82. }
  83. void logger::set_auto_newline(bool enabled)
  84. {
  85. auto_newline = enabled;
  86. }
  87. void logger::set_timestamp(bool enabled)
  88. {
  89. timestamp_enabled = enabled;
  90. }
  91. void logger::set_indent(const std::string& indent)
  92. {
  93. this->indent = indent;
  94. }
  95. void logger::set_log_prefix(const std::string& prefix)
  96. {
  97. log_prefix = prefix;
  98. }
  99. void logger::set_log_postfix(const std::string& postfix)
  100. {
  101. log_postfix = postfix;
  102. }
  103. void logger::set_warning_prefix(const std::string& prefix)
  104. {
  105. warning_prefix = prefix;
  106. }
  107. void logger::set_warning_postfix(const std::string& postfix)
  108. {
  109. warning_postfix = postfix;
  110. }
  111. void logger::set_error_prefix(const std::string& prefix)
  112. {
  113. error_prefix = prefix;
  114. }
  115. void logger::set_error_postfix(const std::string& postfix)
  116. {
  117. error_postfix = postfix;
  118. }
  119. void logger::set_success_prefix(const std::string& prefix)
  120. {
  121. success_prefix = prefix;
  122. }
  123. void logger::set_success_postfix(const std::string& postfix)
  124. {
  125. success_postfix = postfix;
  126. }
  127. void logger::push_task(const std::string& description)
  128. {
  129. std::string message = description + "...";
  130. if (!auto_newline)
  131. message += "\n";
  132. log(message);
  133. tasks.push(description);
  134. }
  135. void logger::pop_task(int status)
  136. {
  137. if (tasks.empty())
  138. {
  139. return;
  140. }
  141. std::string message = tasks.top() + "... ";
  142. tasks.pop();
  143. if (status == EXIT_SUCCESS)
  144. {
  145. message += "success";
  146. if (!auto_newline)
  147. message += "\n";
  148. log(message);
  149. }
  150. else
  151. {
  152. message += "failed (" + std::to_string(status) + ")";
  153. if (!auto_newline)
  154. message += "\n";
  155. error(message);
  156. }
  157. }
  158. } // namespace debug