Remy's Fast MQTT Logger is a C++ 17 application that connects to an MQTT broker, subscribes to a topic, and logs messages received from the broker to syslog (with configurable facility) and optionally to stdout.
Connection failures are handled with automatic reconnect.
Every message is logged on a separate thread in a thread pool, which is what makes is fast and able to process thousands of messages per second. Using Pipe Viewer to measure lines per second from a test broker:
$ ./remys_fast_mqtt_logger -b test.mosquitto.org:1883 | pv --line-mode --rate --average-rate >/dev/null
[4.79k/s] (3.35k/s)
This is similar to mosquitto_sub:
$ mosquitto_sub -h test.mosquitto.org -p 1883 -t "#" | pv --line-mode --rate --average-rate >/dev/null
[3.39k/s] (3.37k/s)
It is designed for use cases where logging MQTT message data needs to be centralized or handled by a logging service like syslog.
It is cross-platform, meaning that if you don't have
syslog.h, it will also compile and run, but it only
prints to STDOUT.
- Connects to an MQTT broker with user authentication (username and password).
- Connects to an MQTT broker using client certificates.
- Subscribes to a topic (
#by default, can be customized via argument). - Logs received MQTT messages to syslog with customizable log facility.
- Optionally logs messages to stdout.
The following libraries are required to build and run the application:
PAHO MQTT C++ Client: The application uses the Paho MQTT C++ library.syslog.h: For logging messages to syslog.
Install dependencies:
- On Ubuntu/Debian:
sudo apt install libpaho-mqttpp3-dev libsyslog-dev build-essential- On RedHat/CentOS:
sudo yum install paho-mqtt-c++ syslog-devel gcc-c++ makeClone or download the repository:
- Clone the repository from GitHub or download the source code to your local system.
Build the application:
To compile the application, use CMake:
cd remys_fast_mqtt_logger
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
The binary accepts the following arguments:
remys_fast_mqtt_logger [OPTIONS]The program can be configured with command line options or ENVIRONMENT variables. The latter don't end up in your shell history.
-
-b BROKER, --broker=BROKER- The MQTT broker URL (including the port) to connect to.
- Example:
tcp://test.mosquitto.org:1883. - Example:
ssl://test.mosquitto.org:8883.
-
-t TOPIC, --topic=TOPIC- The MQTT topic to subscribe to.
- Default is
#(subscribe to all topics).
-
-u USERNAME, --username=USERNAME- Username for authenticating with the MQTT broker. (optional)
-
-p PASSWORD, --password=PASSWORD- Password for authenticating with the MQTT broker. (optional)
-
-f FACILITY, --facility=FACILITY- The syslog facility to log to. Must prefix with
LOG_. - Default is
LOG_LOCAL6.
- The syslog facility to log to. Must prefix with
-
-s, --no-log-to-stderr- Disable logging to STDERR
- Default is disabled, meaning messages will be logged to both stderr and syslog unless specified.
-
-A, --ca-file- Path to CA file that authenticates the broker to the client (optional)
-
-C, --client-cert- Path to client certificate file (optional)
-
-K, --client-key- Path to client key file (optional)
-
-P, --client-key-password- Password for client key file (optional).
- If not provided but key has a password, you will be asked interactively on CLI.
If any of --ca-file, --client-cert or --client-key is given,
all three must be provided.
You can configure the application using the following environment variables:
BROKER: MQTT broker URL (e.g., mqtt.example.com:1883).USERNAME: MQTT username.PASSWORD: MQTT password.TOPIC: MQTT topic to subscribe to (default: #).FACILITY: Syslog facility (default: LOG_LOCAL6).NO_LOG_TO_STDERR: Disable logging to STDERR (default: on)CA_FILE: Path to CA file that authenticates the broker to the clientCLIENT_CERT: Path to client certificate fileCLIENT_KEY: Path to client key fileCLIENT_KEY_PASSWORD: Password for client key file
Basic usage:
./remys_fast_mqtt_logger -b "mqtt.example.com:1883" \
-t "home/livingroom/temperature" \
-u "user" \
-p "password"Log to a specific syslog facility:
./remys_fast_mqtt_logger -b "mqtt.example.com:1883" \
-t "home/livingroom/temperature" \
-u "user" \
-p "password" \
-f "LOG_INFO"Disable logging to stdout:
./remys_fast_mqtt_logger -b "mqtt.example.com:1883" \
-t "home/livingroom/temperature" \
-u "user" \
-p "password" \
-sBy default, logs are written to the LOG_LOCAL6 facility.
You can change this using the -f argument.
Below is a list of valid syslog facilities that can be used:
LOG_AUTHLOG_AUTHPRIVLOG_CRONLOG_DAEMONLOG_FTPLOG_KERNLOG_LPRLOG_MAILLOG_NEWSLOG_SYSLOGLOG_USERLOG_UUCPLOG_LOCAL0LOG_LOCAL1LOG_LOCAL2LOG_LOCAL3LOG_LOCAL4LOG_LOCAL5LOG_LOCAL6(default)LOG_LOCAL7
To view logs for LOG_LOCAL6 in syslog or journalctl:
journalctl SYSLOG_FACILITY=22Or to view logs directly in syslog:
tail -f /var/log/syslogYou can save logs to /var/log/mqtt_msgs.log if you have configured rsyslog accordingly:
sudo nano /etc/rsyslog.d/30-local6.conf
Add:
local6.* /var/log/mqtt_msgs.log
Then:
sudo touch /var/log/mqtt_msgs.log
sudo chmod 644 /var/log/mqtt_msgs.log
sudo chown syslog:adm /var/log/mqtt_msgs.log
Configure logrotate to not delete these logs:
sudo nano /etc/logrotate.d/remys_fast_mqtt_logger
Contents:
/var/log/mqtt_msgs.log {
missingok
notifempty
size 100M
rotate 9999
compress
delaycompress
create 0644 root root
sharedscripts
postrotate
systemctl reload rsyslog > /dev/null 2>&1 || true
endscript
}
To build and run the application with Docker, use the following commands inside the git checkout.
Build the Docker image:
docker build -t mqtt-logger .
Or, use my image and run the Docker container:
docker run -d --name remys_fast_mqtt_logger --env BROKER=test.mosquitto.org raymii/remys_fast_mqtt_logger:latest
docker logs -f remys_fast_mqtt_logger
There is also a docker-compose.yml file included
which you can edit and use:
docker compose up -d
docker compose logs -f
[+] Running 1/1
✔ Container mqtt_logger-remys-fast-mqtt-logger-1 Created0.0s
Attaching to remys-fast-mqtt-logger-1
remys-fast-mqtt-logger-1 | topic='/116484256345/0/current', qos='0', retained='true', msg='1.87'
remys-fast-mqtt-logger-1 | topic='/116484256345/0/efficiency', qos='0', retained='true', msg='95.015'
remys-fast-mqtt-logger-1 | topic='/116484256345/0/frequency', qos='0', retained='true', msg='49.96'
remys-fast-mqtt-logger-1 | topic='/116484256345/0/power', qos='0', retained='true', msg='442.2'
remys-fast-mqtt-logger-1 | topic='/116484256345/0/powerfactor', qos='0', retained='true', msg='0.999'
remys-fast-mqtt-logger-1 | topic='/116484256345/0/temperature', qos='0', retained='true', msg='28.6'
remys-fast-mqtt-logger-1 | topic='/116484256345/0/voltage', qos='0', retained='true', msg='236.3'
remys-fast-mqtt-logger-1 | topic='/116484256345/0/yieldday', qos='0', retained='true', msg='5547'
remys-fast-mqtt-logger-1 | topic='/116484256345/0/reactivepower', qos='0', retained='true', msg='0.3'
remys-fast-mqtt-logger-1 | topic='SHRDZM/483FDA46C2EE/483FDA46C2EE/sensor', qos='0', retained='false', msg='{
remys-fast-mqtt-logger-1 | "lasterror":"cipherkey not set!",
Gracefully stopping... (press Ctrl+C again to force)
[+] Stopping 1/1
This project is licensed under the GNU AGPLv3 License. See the LICENSE file for more details.