Skip to content

Commit

Permalink
Add new setting 'log_level'
Browse files Browse the repository at this point in the history
  • Loading branch information
halfgaar committed Mar 17, 2024
1 parent 60a66a3 commit 3962225
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 18 deletions.
4 changes: 2 additions & 2 deletions FlashMQTests/tst_maintests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1060,10 +1060,10 @@ void MainTests::testSavingSessions()

void MainTests::testParsePacketHelper(const std::string &topic, uint8_t from_qos, bool retain)
{
Logger::getInstance()->setFlags(false, false, true);
Logger::getInstance()->setFlags(LogLevel::None, false);

Settings settings;
settings.logDebug = false;
settings.logLevel = LogLevel::Info;
std::shared_ptr<SubscriptionStore> store(new SubscriptionStore());
PluginLoader pluginLoader;
std::shared_ptr<ThreadData> t(new ThreadData(0, settings, pluginLoader));
Expand Down
28 changes: 28 additions & 0 deletions configfileparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ ConfigFileParser::ConfigFileParser(const std::string &path) :
validKeys.insert("max_packet_size");
validKeys.insert("log_debug");
validKeys.insert("log_subscriptions");
validKeys.insert("log_level");
validKeys.insert("mosquitto_password_file");
validKeys.insert("mosquitto_acl_file");
validKeys.insert("allow_anonymous");
Expand Down Expand Up @@ -724,6 +725,8 @@ void ConfigFileParser::loadFile(bool test)

if (testKeyValidity(key, "quiet", validKeys))
{
Logger::getInstance()->log(LOG_WARNING) << "The config option '" << key << "' is deprecated. Use log_level instead.";

bool tmp = stringTruthiness(value);
tmpSettings.quiet = tmp;
}
Expand Down Expand Up @@ -774,10 +777,35 @@ void ConfigFileParser::loadFile(bool test)

if (testKeyValidity(key, "log_debug", validKeys))
{
Logger::getInstance()->log(LOG_WARNING) << "The config option '" << key << "' is deprecated. Use log_level instead.";

bool tmp = stringTruthiness(value);
tmpSettings.logDebug = tmp;
}

if (testKeyValidity(key, "log_level", validKeys))
{
const std::string v = str_tolower(value);
LogLevel level = LogLevel::None;

if (v == "debug")
level = LogLevel::Debug;
else if (v == "info")
level = LogLevel::Info;
else if (v == "notice")
level = LogLevel::Notice;
else if (v == "warning")
level = LogLevel::Warning;
else if (v == "error")
level = LogLevel::Warning;
else if (v == "none")
level = LogLevel::None;
else
throw ConfigFileException("Invalid log level: " + value);

tmpSettings.logLevel = level;
}

if (testKeyValidity(key, "log_subscriptions", validKeys))
{
bool tmp = stringTruthiness(value);
Expand Down
1 change: 1 addition & 0 deletions flashmq_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#define LOG_NOTICE 0x02
#define LOG_WARNING 0x04
#define LOG_ERR 0x08
#define LOG_ERROR 0x08
#define LOG_DEBUG 0x10
#define LOG_SUBSCRIBE 0x20
#define LOG_UNSUBSCRIBE 0x40
Expand Down
53 changes: 44 additions & 9 deletions logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,24 +172,59 @@ void Logger::setLogPath(const std::string &path)
this->logPath = path;
}

void Logger::setFlags(bool logDebug, bool logSubscriptions, bool quiet)
/**
* @brief Logger::setFlags sets the log level based on a maximum desired level.
* @param level Level based on the defines LOG_*.
* @param logSubscriptions
* @param quiet
*
* The log levels are mosquitto-compatible, and while the terminology is similar to the syslog standard, they are unfortunately
* not in order of verbosity/priority. So, we use our own enum for the config setting, so that DEBUG is indeed more verbose than INFO.
*
* The subscriptions flag is still set explicitly, because you may want that irrespective of the log level.
*/
void Logger::setFlags(LogLevel level, bool logSubscriptions)
{
curLogLevel = LOG_ERR | LOG_WARNING | LOG_NOTICE | LOG_INFO | LOG_SUBSCRIBE | LOG_UNSUBSCRIBE ;
curLogLevel = 0;

if (logDebug)
if (level <= LogLevel::Debug)
curLogLevel |= LOG_DEBUG;
else
curLogLevel &= ~LOG_DEBUG;
if (level <= LogLevel::Info)
curLogLevel |= LOG_INFO;
if (level <= LogLevel::Notice)
curLogLevel |= LOG_NOTICE;
if (level <= LogLevel::Warning)
curLogLevel |= LOG_WARNING;
if (level <= LogLevel::Error)
curLogLevel |= LOG_ERR;

if (logSubscriptions)
curLogLevel |= (LOG_UNSUBSCRIBE | LOG_SUBSCRIBE);
else
curLogLevel &= ~(LOG_UNSUBSCRIBE | LOG_SUBSCRIBE);
}

if (!quiet)
curLogLevel |= (LOG_NOTICE | LOG_INFO);
else
curLogLevel &= ~(LOG_NOTICE | LOG_INFO);
/**
* @brief Logger::setFlags is provided for backwards compatability
* @param logDebug
* @param quiet
*/
void Logger::setFlags(std::optional<bool> logDebug, std::optional<bool> quiet)
{
if (logDebug)
{
if (logDebug.value())
curLogLevel |= LOG_DEBUG;
else
curLogLevel &= ~LOG_DEBUG;
}

// It only makes sense to allow quiet to mute things in backward compatability mode, not enable LOG_NOTICE and LOG_INFO again.
if (quiet)
{
if (quiet.value())
curLogLevel &= ~(LOG_NOTICE | LOG_INFO);
}
}

void Logger::quit()
Expand Down
14 changes: 13 additions & 1 deletion logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,21 @@ See LICENSE for license details.
#include <queue>
#include <thread>
#include <sstream>
#include <optional>
#include "semaphore.h"

#include "flashmq_plugin.h"

enum class LogLevel
{
Debug,
Info,
Notice,
Warning,
Error,
None
};

int logSslError(const char *str, size_t len, void *u);

/**
Expand Down Expand Up @@ -82,7 +93,8 @@ class Logger
void noLongerLogToStd();

void setLogPath(const std::string &path);
void setFlags(bool logDebug, bool logSubscriptions, bool quiet);
void setFlags(LogLevel level, bool logSubscriptions);
void setFlags(std::optional<bool> logDebug, std::optional<bool> quiet);

void quit();

Expand Down
3 changes: 2 additions & 1 deletion mainapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,8 @@ void MainApp::loadConfig(bool reload)

logger->setLogPath(settings.logPath);
logger->queueReOpen();
logger->setFlags(settings.logDebug, settings.logSubscriptions, settings.quiet);
logger->setFlags(settings.logLevel, settings.logSubscriptions);
logger->setFlags(settings.logDebug, settings.quiet);

setlimits();

Expand Down
13 changes: 12 additions & 1 deletion man/flashmq.conf.5
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
\\$2 \(la\\$1\(ra\\$3
..
.if \n(.g .mso www.tmac
.TH flashmq.conf 5 "16 March 2024" "" ""
.TH flashmq.conf 5 "17 March 2024" "" ""
.SH NAME
flashmq.conf \- FlashMQ configuration file format
.SH SYNOPSIS
Expand Down Expand Up @@ -63,9 +63,18 @@ This configuration parameter sets the path to FlashMQ's log file. If you omit th

Default value: \*(T<\fI/var/log/flashmq/flashmq.log\fR\*(T>
.TP
\*(T<\fBlog_level\fR\*(T> \fIinfo/notice/warning/error/none\fR
Set the log level to specified level and above. That means \fInotice\fR will log \fInotice\fR, \fIwarning\fR and \fIerror\fR.

Use this setting over the deprecated \*(T<\fBlog_debug\fR\*(T> and \*(T<\fBquiet\fR\*(T>. If you do have those directives, they override the \*(T<\fBlog_level\fR\*(T>, for backwards compatability reasons.

Default value: \*(T<info\*(T>.
.TP
\*(T<\fBlog_debug\fR\*(T> \fItrue/false\fR
Debug logging obviously creates a lot of log noise, so should only be done to diagnose problems.

Deprecated. Use \*(T<\fBlog_level\fR\*(T> instead.

Default value: \*(T<false\*(T>
.TP
\*(T<\fBlog_subscriptions\fR\*(T> \fItrue/false\fR
Expand Down Expand Up @@ -145,6 +154,8 @@ Default value: \*(T<1209600\*(T>
\*(T<\fBquiet\fR\*(T> \fItrue/false\fR
Don't log LOG_INFO and LOG_NOTICE. This is useful when you have a lot of foot traffic, because otherwise the log gets filled with connect/disconnect notices.

Deprecated. Use \*(T<\fBlog_level\fR\*(T> instead.

Default value: \*(T<false\*(T>
.TP
\*(T<\fBstorage_dir\fR\*(T> \fI/path/to/dir\fR
Expand Down
20 changes: 20 additions & 0 deletions man/flashmq.conf.5.dbk5
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,29 @@
</para>
</listitem>
</varlistentry>
<varlistentry xml:id="log_level">
<term><option>log_level</option> <replaceable>info/notice/warning/error/none</replaceable></term>
<listitem>
<para>
Set the log level to specified level and above. That means <replaceable>notice</replaceable> will log <replaceable>notice</replaceable>, <replaceable>warning</replaceable> and <replaceable>error</replaceable>.
</para>
<para>
Use this setting over the deprecated <option>log_debug</option> and <option>quiet</option>. If you do have those directives, they override the <option>log_level</option>, for backwards compatability reasons.
</para>
<para>
Default value: <literal>info</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry xml:id="log_debug">
<term><option>log_debug</option> <replaceable>true/false</replaceable></term>
<listitem>
<para>
Debug logging obviously creates a lot of log noise, so should only be done to diagnose problems.
</para>
<para>
Deprecated. Use <option>log_level</option> instead.
</para>
<para>
Default value: <literal>false</literal>
</para>
Expand Down Expand Up @@ -291,6 +308,9 @@
<para>
Don't log LOG_INFO and LOG_NOTICE. This is useful when you have a lot of foot traffic, because otherwise the log gets filled with connect/disconnect notices.
</para>
<para>
Deprecated. Use <option>log_level</option> instead.
</para>
<para>
Default value: <literal>false</literal>
</para>
Expand Down
20 changes: 20 additions & 0 deletions man/flashmq.conf.5.html
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,28 @@
</dd>


<dt id="log_level"><code class="option">log_level</code> <code class="replaceable">info/notice/warning/error/none</code><a class="hash-anchor" href="#log_level">#</a></dt>
<dd>
<p>
Set the log level to specified level and above. That means <code class="replaceable">notice</code> will log <code class="replaceable">notice</code>, <code class="replaceable">warning</code> and <code class="replaceable">error</code>.
</p>
<p>
Use this setting over the deprecated <code class="option">log_debug</code> and <code class="option">quiet</code>. If you do have those directives, they override the <code class="option">log_level</code>, for backwards compatability reasons.
</p>
<p>
Default value: <code class="literal">info</code>.
</p>
</dd>


<dt id="log_debug"><code class="option">log_debug</code> <code class="replaceable">true/false</code><a class="hash-anchor" href="#log_debug">#</a></dt>
<dd>
<p>
Debug logging obviously creates a lot of log noise, so should only be done to diagnose problems.
</p>
<p>
Deprecated. Use <code class="option">log_level</code> instead.
</p>
<p>
Default value: <code class="literal">false</code>
</p>
Expand Down Expand Up @@ -346,6 +363,9 @@
<p>
Don't log LOG_INFO and LOG_NOTICE. This is useful when you have a lot of foot traffic, because otherwise the log gets filled with connect/disconnect notices.
</p>
<p>
Deprecated. Use <code class="option">log_level</code> instead.
</p>
<p>
Default value: <code class="literal">false</code>
</p>
Expand Down
11 changes: 7 additions & 4 deletions settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ See LICENSE for license details.
#include <memory>
#include <list>
#include <limits>
#include <optional>

#include "mosquittoauthoptcompatwrap.h"
#include "listener.h"
Expand Down Expand Up @@ -57,22 +58,24 @@ class Settings
// Actual config options with their defaults.
std::string pluginPath;
std::string logPath;
bool quiet = false;
std::optional<bool> quiet;
bool allowUnsafeClientidChars = false;
bool allowUnsafeUsernameChars = false;
bool pluginSerializeInit = false;
bool pluginSerializeAuthChecks = false;
bool logSubscriptions = false;
int clientInitialBufferSize = 1024; // Must be power of 2
uint32_t maxPacketSize = ABSOLUTE_MAX_PACKET_SIZE;
uint32_t clientMaxWriteBufferSize = 1048576;
uint16_t maxIncomingTopicAliasValue = 65535;
uint16_t maxOutgoingTopicAliasValue = 65535;
#ifdef TESTING
bool logDebug = true;
std::optional<bool> logDebug;
LogLevel logLevel = LogLevel::Debug;
#else
bool logDebug = false;
std::optional<bool> logDebug;
LogLevel logLevel = LogLevel::Info;
#endif
bool logSubscriptions = false;
std::string mosquittoPasswordFile;
std::string mosquittoAclFile;
bool allowAnonymous = false;
Expand Down

0 comments on commit 3962225

Please sign in to comment.