Skip to content

Commit

Permalink
Added per-channel message_level filter
Browse files Browse the repository at this point in the history
  • Loading branch information
MitchBradley committed Dec 14, 2023
1 parent 41a2d2c commit 2240a02
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 48 deletions.
6 changes: 6 additions & 0 deletions FluidNC/src/Channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,9 @@ void Channel::ack(Error status) {
msg << static_cast<int>(status);
}
}

void Channel::print_msg(MsgLevel level, const char* msg) {
if (_message_level >= level) {
println(msg);
}
}
9 changes: 3 additions & 6 deletions FluidNC/src/Channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class Channel : public Stream {
public:
static const int maxLine = 255;

int _message_level = MsgLevelVerbose;

protected:
std::string _name;
char _line[maxLine];
Expand Down Expand Up @@ -75,11 +77,6 @@ class Channel : public Stream {

UTF8 _utf8;

// Set this to false to suppress messages sent to AllChannels
// It is useful for IO Expanders that do not want to be spammed
// with chitchat
bool _all_messages = true;

public:
Channel(const char* name, bool addCR = false) : _name(name), _linelen(0), _addCR(addCR) {}
Channel(const char* name, int num, bool addCR = false) {
Expand Down Expand Up @@ -140,7 +137,7 @@ class Channel : public Stream {
int read() override { return -1; }
int available() override { return _queue.size(); }

bool all_messages() { return _all_messages; }
virtual void print_msg(MsgLevel level, const char* msg);

uint32_t setReportInterval(uint32_t ms);
uint32_t getReportInterval() { return _reportInterval; }
Expand Down
13 changes: 10 additions & 3 deletions FluidNC/src/Logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,22 @@
#include "Serial.h"
#include "SettingsDefinitions.h"

EnumItem messageLevels2[] = {
{ MsgLevelNone, "None" }, { MsgLevelError, "Error" }, { MsgLevelWarning, "Warn" },
{ MsgLevelInfo, "Info" }, { MsgLevelDebug, "Debug" }, { MsgLevelVerbose, "Verbose" },
};

bool atMsgLevel(MsgLevel level) {
return message_level == nullptr || message_level->get() >= level;
}

LogStream::LogStream(Channel& channel, const char* name) : _channel(channel) {
LogStream::LogStream(Channel& channel, MsgLevel level, const char* name) : _channel(channel), _level(level) {
_line = new std::string();
print(name);
}
LogStream::LogStream(const char* name) : LogStream(allChannels, name) {}

LogStream::LogStream(Channel& channel, const char* name) : LogStream(channel, MsgLevelNone, name) {}
LogStream::LogStream(MsgLevel level, const char* name) : LogStream(allChannels, level, name) {}

size_t LogStream::write(uint8_t c) {
*_line += (char)c;
Expand All @@ -25,5 +32,5 @@ LogStream::~LogStream() {
if ((*_line).length() && (*_line)[0] == '[') {
*_line += ']';
}
send_line(_channel, _line);
send_line(_channel, _level, _line);
}
41 changes: 23 additions & 18 deletions FluidNC/src/Logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include <cstdint>
#include "EnumItem.h"

class Channel;

Expand All @@ -16,6 +17,8 @@ enum MsgLevel {
MsgLevelVerbose = 5,
};

extern EnumItem messageLevels2[];

// How to use logging? Well, the basics are pretty simple:
//
// - The syntax is like standard iostream's.
Expand All @@ -34,13 +37,15 @@ enum MsgLevel {
class LogStream : public Print {
public:
LogStream(Channel& channel, const char* name);
LogStream(const char* name);
LogStream(Channel& channel, MsgLevel level, const char* name);
LogStream(MsgLevel level, const char* name);
size_t write(uint8_t c) override;
~LogStream();

private:
Channel& _channel;
std::string* _line;
MsgLevel _level;
};

extern bool atMsgLevel(MsgLevel level);
Expand All @@ -50,21 +55,21 @@ extern bool atMsgLevel(MsgLevel level);
// Note: these '{'..'}' scopes are here for a reason: the destructor should flush.

// #define log_bare(prefix, x) { LogStream ss(prefix); ss << x; }
#define log_msg(x) { LogStream ss("[MSG:"); ss << x; }
#define log_verbose(x) if (atMsgLevel(MsgLevelVerbose)) { LogStream ss("[MSG:VRB: "); ss << x; }
#define log_debug(x) if (atMsgLevel(MsgLevelDebug)) { LogStream ss("[MSG:DBG: "); ss << x; }
#define log_info(x) if (atMsgLevel(MsgLevelInfo)) { LogStream ss("[MSG:INFO: "); ss << x; }
#define log_warn(x) if (atMsgLevel(MsgLevelWarning)) { LogStream ss("[MSG:WARN: "); ss << x; }
#define log_error(x) if (atMsgLevel(MsgLevelError)) { LogStream ss("[MSG:ERR: "); ss << x; }
#define log_fatal(x) { LogStream ss("[MSG:FATAL: "); ss << x; Assert(false, "A fatal error occurred."); }

#define log_msg_to(out, x) { LogStream ss(out, "[MSG:"); ss << x; }
#define log_verbose_to(out, x) if (atMsgLevel(MsgLevelVerbose)) { LogStream ss(out, "[MSG:VRB: "); ss << x; }
#define log_debug_to(out, x) if (atMsgLevel(MsgLevelDebug)) { LogStream ss(out, "[MSG:DBG: "); ss << x; }
#define log_info_to(out, x) if (atMsgLevel(MsgLevelInfo)) { LogStream ss(out, "[MSG:INFO: "); ss << x; }
#define log_warn_to(out, x) if (atMsgLevel(MsgLevelWarning)) { LogStream ss(out, "[MSG:WARN: "); ss << x; }
#define log_error_to(out, x) if (atMsgLevel(MsgLevelError)) { LogStream ss(out, "[MSG:ERR: "); ss << x; }
#define log_fatal_to(out, x) { LogStream ss(out, "[MSG:FATAL: "); ss << x; Assert(false, "A fatal error occurred."); }
#define log_msg(x) { LogStream ss(MsgLevelNone, "[MSG:"); ss << x; }
#define log_verbose(x) if (atMsgLevel(MsgLevelVerbose)) { LogStream ss(MsgLevelVerbose, "[MSG:VRB: "); ss << x; }
#define log_debug(x) if (atMsgLevel(MsgLevelDebug)) { LogStream ss(MsgLevelDebug, "[MSG:DBG: "); ss << x; }
#define log_info(x) if (atMsgLevel(MsgLevelInfo)) { LogStream ss(MsgLevelInfo, "[MSG:INFO: "); ss << x; }
#define log_warn(x) if (atMsgLevel(MsgLevelWarning)) { LogStream ss(MsgLevelWarning, "[MSG:WARN: "); ss << x; }
#define log_error(x) if (atMsgLevel(MsgLevelError)) { LogStream ss(MsgLevelError, "[MSG:ERR: "); ss << x; }
#define log_fatal(x) { LogStream ss(MsgLevelNone, "[MSG:FATAL: "); ss << x; Assert(false, "A fatal error occurred."); }

#define log_msg_to(out, x) { LogStream ss(out, MsgLevelNone, "[MSG:"); ss << x; }
#define log_verbose_to(out, x) if (atMsgLevel(MsgLevelVerbose)) { LogStream ss(out, MsgLevelVerbose, "[MSG:VRB: "); ss << x; }
#define log_debug_to(out, x) if (atMsgLevel(MsgLevelDebug)) { LogStream ss(out, MsgLevelDebug, "[MSG:DBG: "); ss << x; }
#define log_info_to(out, x) if (atMsgLevel(MsgLevelInfo)) { LogStream ss(out, MsgLevelInfo, "[MSG:INFO: "); ss << x; }
#define log_warn_to(out, x) if (atMsgLevel(MsgLevelWarning)) { LogStream ss(out, MsgLevelWarning, "[MSG:WARN: "); ss << x; }
#define log_error_to(out, x) if (atMsgLevel(MsgLevelError)) { LogStream ss(out, MsgLevelError, "[MSG:ERR: "); ss << x; }
#define log_fatal_to(out, x) { LogStream ss(out, MsgLevelNone, "[MSG:FATAL: "); ss << x; Assert(false, "A fatal error occurred."); }

// GET_MACRO is a preprocessor trick to let log_to() behave differently
// with 2 arguments vs 3. The 2 argument case is super efficient
Expand All @@ -76,5 +81,5 @@ extern bool atMsgLevel(MsgLevel level);
#define GET_MACRO(_1,_2,_3, NAME, ...) NAME
#define log_to(...) GET_MACRO(__VA_ARGS__, log_to3, log_to2)(__VA_ARGS__)

#define log_to2(out, prefix) send_line(out, prefix)
#define log_to3(out, prefix, x) { LogStream ss(out, prefix); ss << x; }
#define log_to2(out, prefix) send_line(out, MsgLevelNone, prefix)
#define log_to3(out, prefix, x) { LogStream ss(out, MsgLevelNone, prefix); ss << x; }
23 changes: 12 additions & 11 deletions FluidNC/src/Protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ xQueueHandle message_queue;
struct LogMessage {
Channel* channel;
void* line;
MsgLevel level;
bool isString;
};

Expand All @@ -108,12 +109,12 @@ void drain_messages() {
// memory does not need to be reclaimed later.
// This is the most efficient form, but it only works
// with fixed messages.
void send_line(Channel& channel, const char* line) {
void send_line(Channel& channel, MsgLevel level, const char* line) {
if (outputTask) {
LogMessage msg { &channel, (void*)line, false };
LogMessage msg { &channel, (void*)line, level, false };
while (!xQueueSend(message_queue, &msg, 10)) {}
} else {
channel.println(line);
channel.print_msg(level, line);
}
}

Expand All @@ -125,12 +126,12 @@ void send_line(Channel& channel, const char* line) {
// the pointer to reclaim the memory.
// This form has intermediate efficiency, as the string
// is allocated once and freed once.
void send_line(Channel& channel, const std::string* line) {
void send_line(Channel& channel, MsgLevel level, const std::string* line) {
if (outputTask) {
LogMessage msg { &channel, (void*)line, true };
LogMessage msg { &channel, (void*)line, level, true };
while (!xQueueSend(message_queue, &msg, 10)) {}
} else {
channel.println(line->c_str());
channel.print_msg(level, line->c_str());
delete line;
}
}
Expand All @@ -146,11 +147,11 @@ void send_line(Channel& channel, const std::string* line) {
// This is the least efficient form, requiring two strings
// to be allocated and freed, with an intermediate copy.
// It is used only rarely.
void send_line(Channel& channel, const std::string& line) {
void send_line(Channel& channel, MsgLevel level, const std::string& line) {
if (outputTask) {
send_line(channel, new std::string(line));
send_line(channel, level, new std::string(line));
} else {
channel.println(line.c_str());
channel.print_msg(level, line.c_str());
}
}

Expand All @@ -161,11 +162,11 @@ void output_loop(void* unused) {
if (xQueueReceive(message_queue, &message, portMAX_DELAY)) {
if (message.isString) {
std::string* s = static_cast<std::string*>(message.line);
message.channel->println(s->c_str());
message.channel->print_msg(message.level, s->c_str());
delete s;
} else {
const char* cp = static_cast<const char*>(message.line);
message.channel->println(cp);
message.channel->print_msg(message.level, cp);
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions FluidNC/src/Protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ inline void protocol_send_event(Event* evt, int arg) {

void protocol_send_event_from_ISR(Event* evt, void* arg = 0);

void send_line(Channel& channel, const char* message);
void send_line(Channel& channel, const std::string* message);
void send_line(Channel& channel, const std::string& message);
void send_line(Channel& channel, MsgLevel level, const char* message);
void send_line(Channel& channel, MsgLevel level, const std::string* message);
void send_line(Channel& channel, MsgLevel level, const std::string& message);

void drain_messages();

Expand Down
16 changes: 10 additions & 6 deletions FluidNC/src/Serial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,7 @@ void AllChannels::flushRx() {
size_t AllChannels::write(uint8_t data) {
_mutex_general.lock();
for (auto channel : _channelq) {
if (channel->all_messages()) {
channel->write(data);
}
channel->write(data);
}
_mutex_general.unlock();
return 1;
Expand Down Expand Up @@ -169,13 +167,19 @@ void AllChannels::stopJob() {
size_t AllChannels::write(const uint8_t* buffer, size_t length) {
_mutex_general.lock();
for (auto channel : _channelq) {
if (channel->all_messages()) {
channel->write(buffer, length);
}
channel->write(buffer, length);
}
_mutex_general.unlock();
return length;
}
void AllChannels::print_msg(MsgLevel level, const char* msg) {
_mutex_general.lock();
for (auto channel : _channelq) {
channel->print_msg(level, msg);
}
_mutex_general.unlock();
}

Channel* AllChannels::find(const std::string& name) {
_mutex_general.lock();
for (auto channel : _channelq) {
Expand Down
2 changes: 2 additions & 0 deletions FluidNC/src/Serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class AllChannels : public Channel {
size_t write(uint8_t data) override;
size_t write(const uint8_t* buffer, size_t length) override;

void print_msg(MsgLevel level, const char* msg) override;

void flushRx();

void notifyWco();
Expand Down
2 changes: 1 addition & 1 deletion FluidNC/src/UartChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class UartChannel : public Channel, public Configuration::Configurable {
void group(Configuration::HandlerBase& handler) override {
handler.item("report_interval_ms", _report_interval_ms);
handler.item("uart_num", _uart_num);
handler.item("all_messages", _all_messages);
handler.item("message_level", _message_level, messageLevels2);
}
};

Expand Down

0 comments on commit 2240a02

Please sign in to comment.