From 68c002bc55a6afd446983df11e7be45e6e19861d Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 28 Feb 2022 22:46:39 +0000 Subject: [PATCH] Plugin event counter example plugin. --- plugins/examples/CMakeLists.txt | 1 + plugins/examples/Makefile | 1 + .../plugin-event-stats/CMakeLists.txt | 26 ++++ plugins/examples/plugin-event-stats/Makefile | 29 ++++ .../mosquitto_plugin_event_stats.c | 145 ++++++++++++++++++ plugins/examples/plugin-event-stats/test.conf | 1 + plugins/examples/plugin-event-stats/test.sh | 3 + 7 files changed, 206 insertions(+) create mode 100644 plugins/examples/plugin-event-stats/CMakeLists.txt create mode 100644 plugins/examples/plugin-event-stats/Makefile create mode 100644 plugins/examples/plugin-event-stats/mosquitto_plugin_event_stats.c create mode 100644 plugins/examples/plugin-event-stats/test.conf create mode 100755 plugins/examples/plugin-event-stats/test.sh diff --git a/plugins/examples/CMakeLists.txt b/plugins/examples/CMakeLists.txt index b5d548df..dfa5018d 100644 --- a/plugins/examples/CMakeLists.txt +++ b/plugins/examples/CMakeLists.txt @@ -10,6 +10,7 @@ add_subdirectory(delayed-auth) add_subdirectory(force-retain) add_subdirectory(payload-modification) add_subdirectory(payload-size-stats) +add_subdirectory(plugin-event-stats) add_subdirectory(print-ip-on-publish) add_subdirectory(topic-modification) add_subdirectory(wildcard-temp) diff --git a/plugins/examples/Makefile b/plugins/examples/Makefile index 84da6435..25149ca2 100644 --- a/plugins/examples/Makefile +++ b/plugins/examples/Makefile @@ -9,6 +9,7 @@ DIRS= \ message-timestamp \ payload-modification \ payload-size-stats \ + plugin-event-stats \ print-ip-on-publish \ topic-modification \ wildcard-temp diff --git a/plugins/examples/plugin-event-stats/CMakeLists.txt b/plugins/examples/plugin-event-stats/CMakeLists.txt new file mode 100644 index 00000000..7f22c923 --- /dev/null +++ b/plugins/examples/plugin-event-stats/CMakeLists.txt @@ -0,0 +1,26 @@ +set (PLUGIN_NAME mosquitto_plugin_event_stats) + +add_library(${PLUGIN_NAME} MODULE + ${PLUGIN_NAME}.c +) + +target_include_directories(${PLUGIN_NAME} PRIVATE + "${OPENSSL_INCLUDE_DIR}" + "${STDBOOL_H_PATH}" + "${STDINT_H_PATH}" + "${mosquitto_SOURCE_DIR}" + "${mosquitto_SOURCE_DIR}/include" +) + +link_directories(${mosquitto_SOURCE_DIR}) + +set_target_properties(${PLUGIN_NAME} PROPERTIES + PREFIX "" + POSITION_INDEPENDENT_CODE 1 +) +if(WIN32) + target_link_libraries(${PLUGIN_NAME} mosquitto) +endif() + +# Don't install, these are example plugins only. +#install(TARGETS ${PLUGIN_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") diff --git a/plugins/examples/plugin-event-stats/Makefile b/plugins/examples/plugin-event-stats/Makefile new file mode 100644 index 00000000..d4e2bcbb --- /dev/null +++ b/plugins/examples/plugin-event-stats/Makefile @@ -0,0 +1,29 @@ +R=../../.. +include ${R}/config.mk + +.PHONY : all binary check clean reallyclean test install uninstall + +PLUGIN_NAME=mosquitto_plugin_event_stats +PLUGIN_CFLAGS+=-I${R}/include -I${R}/ + +all : binary + +binary : ${PLUGIN_NAME}.so + +${PLUGIN_NAME}.so : ${PLUGIN_NAME}.c + $(CROSS_COMPILE)$(CC) $(PLUGIN_CPPFLAGS) $(PLUGIN_CFLAGS) $(PLUGIN_LDFLAGS) -fPIC -shared $< -o $@ + +reallyclean : clean +clean: + -rm -f *.o ${PLUGIN_NAME}.so *.gcda *.gcno + +check: test +test: + +install: ${PLUGIN_NAME}.so + # Don't install, these are examples only. + #$(INSTALL) -d "${DESTDIR}$(libdir)" + #$(INSTALL) ${STRIP_OPTS} ${PLUGIN_NAME}.so "${DESTDIR}${libdir}/${PLUGIN_NAME}.so" + +uninstall : + -rm -f "${DESTDIR}${libdir}/${PLUGIN_NAME}.so" diff --git a/plugins/examples/plugin-event-stats/mosquitto_plugin_event_stats.c b/plugins/examples/plugin-event-stats/mosquitto_plugin_event_stats.c new file mode 100644 index 00000000..dec73307 --- /dev/null +++ b/plugins/examples/plugin-event-stats/mosquitto_plugin_event_stats.c @@ -0,0 +1,145 @@ +/* +Copyright (c) 2022 Cedalo Gmbh + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License 2.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + https://www.eclipse.org/legal/epl-2.0/ +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +/* + * Publish statistics on plugin event counts + * + * Compile with: + * gcc -I -fPIC -shared mosquitto_plugin_event_stats.c -o mosquitto_plugin_event_stats.so + * + * Use in config with: + * + * plugin /path/to/mosquitto_plugin_event_stats.so + * + * Note that this only works on Mosquitto 2.0 or later. + */ +#include "config.h" + +#include +#include +#include + +#include "mosquitto_broker.h" +#include "mosquitto_plugin.h" +#include "mosquitto.h" +#include "mqtt_protocol.h" + +#define MAX_EVT MOSQ_EVT_PERSIST_CLIENT_MSG_LOAD+1 +MOSQUITTO_PLUGIN_DECLARE_VERSION(5); + +static mosquitto_plugin_id_t *mosq_pid = NULL; + +static uint64_t evt_counts[MAX_EVT]; +static uint64_t last_evt_counts[MAX_EVT]; +static time_t last_report = 0; + +#define TOPIC_BASE "$SYS/broker/plugin/events/" + +const char evt_topics[][60] = { + "", /* No event */ + TOPIC_BASE "reload", /* MOSQ_EVT_RELOAD */ + TOPIC_BASE "acl_check", /* MOSQ_EVT_ACL_CHECK */ + TOPIC_BASE "auth/basic", /* MOSQ_EVT_BASIC_AUTH */ + TOPIC_BASE "auth/ext/start", /* MOSQ_EVT_EXT_AUTH_START */ + TOPIC_BASE "auth/ext/continue", /* MOSQ_EVT_EXT_AUTH_CONTINUE */ + TOPIC_BASE "control", /* MOSQ_EVT_CONTROL */ + TOPIC_BASE "message", /* MOSQ_EVT_MESSAGE */ + TOPIC_BASE "psk_key", /* MOSQ_EVT_PSK_KEY */ + TOPIC_BASE "tick", /* MOSQ_EVT_TICK */ + TOPIC_BASE "disconnect", /* MOSQ_EVT_DISCONNECT */ + TOPIC_BASE "connect", /* MOSQ_EVT_CONNECT */ + TOPIC_BASE "persist/restore", /* MOSQ_EVT_PERSIST_RESTORE */ + TOPIC_BASE "persist/config/add", /* MOSQ_EVT_PERSIST_CONFIG_ADD */ + TOPIC_BASE "persist/message/base/add", /* MOSQ_EVT_PERSIST_MSG_ADD */ + TOPIC_BASE "persist/message/base/delete", /* MOSQ_EVT_PERSIST_MSG_DELETE */ + TOPIC_BASE "persist/message/base/load", /* MOSQ_EVT_PERSIST_MSG_LOAD */ + TOPIC_BASE "persist/message/retain/add", /* MOSQ_EVT_PERSIST_RETAIN_ADD */ + TOPIC_BASE "persist/message/retain/delete", /* MOSQ_EVT_PERSIST_RETAIN_DELETE */ + TOPIC_BASE "persist/client/add", /* MOSQ_EVT_PERSIST_CLIENT_ADD */ + TOPIC_BASE "persist/client/delete", /* MOSQ_EVT_PERSIST_CLIENT_DELETE */ + TOPIC_BASE "persist/client/update", /* MOSQ_EVT_PERSIST_CLIENT_UPDATE */ + TOPIC_BASE "persist/subscription/add", /* MOSQ_EVT_PERSIST_SUBSCRIPTION_ADD */ + TOPIC_BASE "persist/subscription/delete", /* MOSQ_EVT_PERSIST_SUBSCRIPTION_DELETE */ + TOPIC_BASE "persist/message/client/add", /* MOSQ_EVT_PERSIST_CLIENT_MSG_ADD */ + TOPIC_BASE "persist/message/client/delete", /* MOSQ_EVT_PERSIST_CLIENT_MSG_DELETE */ + TOPIC_BASE "persist/message/client/update", /* MOSQ_EVT_PERSIST_CLIENT_MSG_UPDATE */ + TOPIC_BASE "persist/message/client/clear", /* MOSQ_EVT_PERSIST_CLIENT_MSG_CLEAR */ + TOPIC_BASE "persist/message/client/load", /* MOSQ_EVT_PERSIST_CLIENT_MSG_LOAD */ +}; + +static int callback_tick(int event, void *event_data, void *userdata) +{ + struct timespec ts; + char payload[40]; + int slen; + + UNUSED(event); + UNUSED(event_data); + UNUSED(userdata); + + clock_gettime(CLOCK_REALTIME, &ts); + if(last_report + 10 < ts.tv_sec){ + last_report = ts.tv_sec; + + for(int i=0; i MAX_EVT-1){ + return MOSQ_ERR_SUCCESS; + }else{ + evt_counts[event]++; + } + + return MOSQ_ERR_SUCCESS; +} + + +int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, struct mosquitto_opt *opts, int opt_count) +{ + UNUSED(user_data); + UNUSED(opts); + UNUSED(opt_count); + + memset(evt_counts, 0, sizeof(evt_counts)); + memset(last_evt_counts, 0, sizeof(last_evt_counts)); + + mosq_pid = identifier; + mosquitto_callback_register(mosq_pid, MOSQ_EVT_TICK, callback_tick, NULL, NULL); + for(int i=1; i