My Project
shell_log.cpp
1 /*
2  * uuid-console - Microcontroller console shell
3  * Copyright 2019,2021-2022 Simon Arlott
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include <uuid/console.h>
20 
21 #include <Arduino.h>
22 
23 #include <algorithm>
24 #include <memory>
25 #if UUID_CONSOLE_THREAD_SAFE
26 # include <mutex>
27 #endif
28 #include <string>
29 
30 #include <uuid/log.h>
31 
32 #ifndef PSTR_ALIGN
33 # define PSTR_ALIGN 4
34 #endif
35 
36 namespace uuid {
37 
38 namespace console {
39 
41 static const char __pstr__logger_name[] __attribute__((__aligned__(PSTR_ALIGN))) PROGMEM = "shell";
43 
45  static const uuid::log::Logger logger_instance{reinterpret_cast<const __FlashStringHelper *>(__pstr__logger_name), uuid::log::Facility::LPR};
46 
47  return logger_instance;
48 }
49 
50 Shell::QueuedLogMessage::QueuedLogMessage(unsigned long id, std::shared_ptr<uuid::log::Message> &&content)
51  : id_(id), content_(std::move(content)) {
52 
53 }
54 
55 void Shell::operator<<(std::shared_ptr<uuid::log::Message> message) {
56 #if UUID_CONSOLE_THREAD_SAFE
57  std::lock_guard<std::mutex> lock{mutex_};
58 #endif
59 
60  if (log_messages_.size() >= maximum_log_messages_) {
61  log_messages_.pop_front();
62  }
63 
64  log_messages_.emplace_back(log_message_id_++, std::move(message));
65 }
66 
69 }
70 
73 }
74 
76 #if UUID_CONSOLE_THREAD_SAFE
77  std::lock_guard<std::mutex> lock{mutex_};
78 #endif
79 
80  return maximum_log_messages_;
81 }
82 
83 void Shell::maximum_log_messages(size_t count) {
84 #if UUID_CONSOLE_THREAD_SAFE
85  std::lock_guard<std::mutex> lock{mutex_};
86 #endif
87 
88  maximum_log_messages_ = std::max((size_t)1, count);
89  while (log_messages_.size() > maximum_log_messages_) {
90  log_messages_.pop_front();
91  }
92 }
93 
95 #if UUID_CONSOLE_THREAD_SAFE
96  std::unique_lock<std::mutex> lock{mutex_};
97 #endif
98 
99  if (log_messages_.empty())
100  return;
101 
102  size_t count = std::max((size_t)1, MAX_LOG_MESSAGES);
103  auto message = log_messages_.front();
104 
105  log_messages_.pop_front();
106 #if UUID_CONSOLE_THREAD_SAFE
107  lock.unlock();
108 #endif
109 
110  if (mode_ != Mode::DELAY) {
112  prompt_displayed_ = false;
113  }
114 
115  while (1) {
116  print(uuid::log::format_timestamp_ms(message.content_->uptime_ms, 3));
117  printf(F(" %c %lu: [%S] "), uuid::log::format_level_char(message.content_->level), message.id_, message.content_->name);
118  println(message.content_->text);
119 
120  ::yield();
121 
122  count--;
123  if (count == 0) {
124  break;
125  }
126 
127 #if UUID_CONSOLE_THREAD_SAFE
128  lock.lock();
129 #endif
130  if (log_messages_.empty()) {
131 #if UUID_CONSOLE_THREAD_SAFE
132  lock.unlock();
133 #endif
134  break;
135  }
136 
137  message = log_messages_.front();
138  log_messages_.pop_front();
139 #if UUID_CONSOLE_THREAD_SAFE
140  lock.unlock();
141 #endif
142  }
143 
144  display_prompt();
145 }
146 
147 } // namespace console
148 
149 } // namespace uuid
uuid::console::Shell::maximum_log_messages
size_t maximum_log_messages() const
Get the maximum number of queued log messages.
Definition: shell_log.cpp:75
uuid::log::Logger
Logger instance used to make log messages.
Definition: log.h:347
uuid::console::Shell::display_prompt
void display_prompt()
Output a prompt on the shell.
Definition: shell_prompt.cpp:54
uuid::console::Shell::log_messages_
std::list< QueuedLogMessage > log_messages_
Definition: console.h:1623
uuid::console::Shell::print
size_t print(const std::string &data)
Output a string.
Definition: shell_print.cpp:30
uuid::console::Shell::log_message_id_
unsigned long log_message_id_
Definition: console.h:1622
uuid::console::Shell::MAX_LOG_MESSAGES
static constexpr size_t MAX_LOG_MESSAGES
Definition: console.h:775
uuid::console::Shell::logger
static const uuid::log::Logger & logger()
Get the built-in uuid::log::Logger instance for shells.
Definition: shell_log.cpp:44
uuid::console::Shell::println
size_t println(const std::string &data)
Output a string followed by CRLF end of line characters.
Definition: shell_print.cpp:38
uuid::console::Shell::log_level
uuid::log::Level log_level() const
Get the current log level.
Definition: shell_log.cpp:67
uuid::log::Level
Level
Severity level of log messages.
Definition: log.h:84
uuid::log::Logger::register_handler
static void register_handler(Handler *handler, Level level)
Register a log handler.
Definition: log.cpp:71
uuid::log::Logger::get_log_level
static Level get_log_level(const Handler *handler)
Get the current log level of a handler.
Definition: log.cpp:96
uuid::console::Shell::operator<<
virtual void operator<<(std::shared_ptr< uuid::log::Message > message)
Add a new log message.
Definition: shell_log.cpp:55
uuid::console::Shell::printf
size_t printf(const char *format,...)
Output a message.
Definition: shell_print.cpp:44
uuid::console::Shell::QueuedLogMessage::QueuedLogMessage
QueuedLogMessage(unsigned long id, std::shared_ptr< uuid::log::Message > &&content)
Create a queued log message.
Definition: shell_log.cpp:50
uuid::console::Shell::Mode::DELAY
@ DELAY
uuid
Common utilities.
Definition: get_uptime_ms.cpp:28
uuid::log::format_timestamp_ms
std::string format_timestamp_ms(uint64_t timestamp_ms, unsigned int days_width)
Format a system uptime timestamp as a string.
Definition: format_timestamp_ms.cpp:31
uuid::console::Shell::erase_current_line
virtual void erase_current_line()
Output ANSI escape sequence to erase the current line.
Definition: shell_print.cpp:131
uuid::console::Shell::output_logs
void output_logs()
Output queued log messages for this shell.
Definition: shell_log.cpp:94
uuid::log::format_level_char
char format_level_char(Level level)
Format a log level as a single character.
Definition: format_level_char.cpp:25
uuid::console::Shell::prompt_displayed_
bool prompt_displayed_
Definition: console.h:1631
uuid::console::Shell::mode_
Mode mode_
Definition: console.h:1628
uuid::console::Shell::maximum_log_messages_
size_t maximum_log_messages_
Definition: console.h:1624
uuid::console::Shell::mutex_
std::mutex mutex_
Definition: console.h:1620