From 95c098a807893fd385e60744b3c462677b97c26c Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 24 Nov 2020 10:56:57 +0000 Subject: [PATCH] Integrate debugging only xtreport code. --- config.mk | 8 +++ src/Makefile | 6 +- src/loop.c | 3 + src/mosquitto_broker_internal.h | 8 +++ src/xtreport.c | 123 ++++++++++++++++++++++++++++++++ 5 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 src/xtreport.c diff --git a/config.mk b/config.mk index 8a59ce94..e4a33eab 100644 --- a/config.mk +++ b/config.mk @@ -114,6 +114,10 @@ WITH_CONTROL:=yes # Build the broker with the jemalloc allocator WITH_JEMALLOC:=no +# Build with xtreport capability. This is for debugging purposes and is +# probably of no particular interest to end users. +WITH_XTREPORT=no + # ============================================================================= # End of user configuration # ============================================================================= @@ -365,6 +369,10 @@ ifeq ($(WITH_CJSON),yes) CLIENT_STATIC_LDADD:=$(CLIENT_STATIC_LDADD) -lcjson endif +ifeq ($(WITH_XTREPORT),yes) + BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_XTREPORT +endif + BROKER_LDADD:=${BROKER_LDADD} ${LDADD} CLIENT_LDADD:=${CLIENT_LDADD} ${LDADD} PASSWD_LDADD:=${PASSWD_LDADD} ${LDADD} diff --git a/src/Makefile b/src/Makefile index 01f4ebdc..292547cd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -77,7 +77,8 @@ OBJS= mosquitto.o \ util_topic.o \ websockets.o \ will_delay.o \ - will_mosq.o + will_mosq.o \ + xtreport.o mosquitto : ${OBJS} ${CROSS_COMPILE}${CC} ${BROKER_LDFLAGS} $^ -o $@ $(BROKER_LDADD) @@ -304,6 +305,9 @@ will_delay.o : will_delay.c mosquitto_broker_internal.h will_mosq.o : ../lib/will_mosq.c ../lib/will_mosq.h ${CROSS_COMPILE}${CC} $(BROKER_CPPFLAGS) $(BROKER_CFLAGS) -c $< -o $@ +xtreport.o : xtreport.c + ${CROSS_COMPILE}${CC} $(BROKER_CPPFLAGS) $(BROKER_CFLAGS) -c $< -o $@ + plugin_defer.so : plugin_defer.c ../include/mosquitto_plugin.h ../include/mosquitto_broker.h mosquitto_broker_internal.h ${CROSS_COMPILE}${CC} -I. -I../lib -fPIC -shared $< -o $@ diff --git a/src/loop.c b/src/loop.c index cad7425c..fa15202d 100644 --- a/src/loop.c +++ b/src/loop.c @@ -210,6 +210,9 @@ int mosquitto_main_loop(struct mosquitto__listener_sock *listensock, int listens if(flag_tree_print){ sub__tree_print(db.subs, 0); flag_tree_print = false; +#ifdef WITH_XTREPORT + xtreport(); +#endif } #ifdef WITH_WEBSOCKETS for(i=0; ilistener_count; i++){ diff --git a/src/mosquitto_broker_internal.h b/src/mosquitto_broker_internal.h index 4d02d94b..fb7a5636 100644 --- a/src/mosquitto_broker_internal.h +++ b/src/mosquitto_broker_internal.h @@ -919,5 +919,13 @@ void will_delay__check(void); void will_delay__send_all(void); void will_delay__remove(struct mosquitto *mosq); + +/* ============================================================ + * Other + * ============================================================ */ +#ifdef WITH_XTREPORT +void xtreport(void); +#endif + #endif diff --git a/src/xtreport.c b/src/xtreport.c new file mode 100644 index 00000000..bb087306 --- /dev/null +++ b/src/xtreport.c @@ -0,0 +1,123 @@ +/* +Copyright (c) 2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifdef WITH_XTREPORT + +/* This file allows reporting of internal parameters to a kcachegrind + * compatible output file. It is for debugging purposes only and is most likely + * of no interest to end users. + */ +#include "config.h" + +#include +#include + +#include "mosquitto_broker_internal.h" +#include "mosquitto_internal.h" +#include "net_mosq.h" + + +static void client_cost(FILE *fptr, struct mosquitto *context, int fn_index) +{ + size_t pkt_count, pkt_bytes; + size_t cmsg_count, cmsg_bytes; + struct mosquitto__packet *pkt_tmp; + size_t tBytes; + + pkt_count = 1; + pkt_bytes = context->in_packet.packet_length; + if(context->current_out_packet){ + pkt_count++; + pkt_bytes += context->current_out_packet->packet_length; + } + pkt_tmp = context->out_packet; + while(pkt_tmp){ + pkt_count++; + pkt_bytes += pkt_tmp->packet_length; + pkt_tmp = pkt_tmp->next; + } + + cmsg_count = (size_t)context->msgs_in.msg_count; + cmsg_bytes = context->msgs_in.msg_bytes; + cmsg_count += (size_t)context->msgs_out.msg_count; + cmsg_bytes += context->msgs_out.msg_bytes; + + tBytes = pkt_bytes + cmsg_bytes; + if(context->id){ + tBytes += strlen(context->id); + } + fprintf(fptr, "%d %ld %lu %lu %lu %lu %d\n", fn_index, + tBytes, + pkt_count, cmsg_count, + pkt_bytes, cmsg_bytes, + context->sock == INVALID_SOCKET?0:context->sock); +} + + +void xtreport(void) +{ + pid_t pid; + char filename[40]; + FILE *fptr; + struct mosquitto *context, *ctxt_tmp; + int fn_index = 2; + static int iter = 1; + + pid = getpid(); + snprintf(filename, 40, "/tmp/xtmosquitto.kcg.%d.%d", pid, iter); + iter++; + fptr = fopen(filename, "wt"); + if(fptr == NULL) return; + + fprintf(fptr, "# callgrind format\n"); + fprintf(fptr, "version: 1\n"); + fprintf(fptr, "creator: mosquitto\n"); + fprintf(fptr, "pid: %d\n", pid); + fprintf(fptr, "cmd: mosquitto\n\n"); + + fprintf(fptr, "positions: line\n"); + fprintf(fptr, "event: tB : total bytes\n"); + fprintf(fptr, "event: pkt : currently queued packets\n"); + fprintf(fptr, "event: cmsg : currently pending client messages\n"); + fprintf(fptr, "event: pktB : currently queued packet bytes\n"); + fprintf(fptr, "event: cmsgB : currently pending client message bytes\n"); + fprintf(fptr, "events: tB pkt cmsg pktB cmsgB sock\n"); + + fprintf(fptr, "fn=(1) clients\n"); + fprintf(fptr, "1 0 0 0 0 0 0\n"); + + fn_index = 2; + HASH_ITER(hh_id, db.contexts_by_id, context, ctxt_tmp){ + if(context->id){ + fprintf(fptr, "cfn=(%d) %s\n", fn_index, context->id); + }else{ + fprintf(fptr, "cfn=(%d) unknown\n", fn_index); + } + fprintf(fptr, "calls=1 %d\n", fn_index); + client_cost(fptr, context, fn_index); + fn_index++; + } + + fn_index = 2; + HASH_ITER(hh_id, db.contexts_by_id, context, ctxt_tmp){ + fprintf(fptr, "fn=(%d)\n", fn_index); + client_cost(fptr, context, fn_index); + fn_index++; + } + + fclose(fptr); +} +#endif