Commit d40bc488980abc04b60523ef83901f6a92e30932

Authored by Andrii Shvaika
1 parent c52c9a16

Ability to log number of active MQTT connections

@@ -702,6 +702,9 @@ transport: @@ -702,6 +702,9 @@ transport:
702 parallelism_level: "${SNMP_RESPONSE_PROCESSING_PARALLELISM_LEVEL:20}" 702 parallelism_level: "${SNMP_RESPONSE_PROCESSING_PARALLELISM_LEVEL:20}"
703 # to configure SNMP to work over UDP or TCP 703 # to configure SNMP to work over UDP or TCP
704 underlying_protocol: "${SNMP_UNDERLYING_PROTOCOL:udp}" 704 underlying_protocol: "${SNMP_UNDERLYING_PROTOCOL:udp}"
  705 + stats:
  706 + enabled: "${TB_TRANSPORT_STATS_ENABLED:true}"
  707 + print-interval-ms: "${TB_TRANSPORT_STATS_PRINT_INTERVAL_MS:60000}"
705 708
706 # Edges parameters 709 # Edges parameters
707 edges: 710 edges:
@@ -31,6 +31,7 @@ import org.thingsboard.server.transport.mqtt.adaptors.ProtoMqttAdaptor; @@ -31,6 +31,7 @@ import org.thingsboard.server.transport.mqtt.adaptors.ProtoMqttAdaptor;
31 import javax.annotation.PostConstruct; 31 import javax.annotation.PostConstruct;
32 import javax.annotation.PreDestroy; 32 import javax.annotation.PreDestroy;
33 import java.util.concurrent.ExecutorService; 33 import java.util.concurrent.ExecutorService;
  34 +import java.util.concurrent.atomic.AtomicInteger;
34 35
35 /** 36 /**
36 * Created by ashvayka on 04.10.18. 37 * Created by ashvayka on 04.10.18.
@@ -71,4 +72,19 @@ public class MqttTransportContext extends TransportContext { @@ -71,4 +72,19 @@ public class MqttTransportContext extends TransportContext {
71 @Getter 72 @Getter
72 @Value("${transport.mqtt.timeout:10000}") 73 @Value("${transport.mqtt.timeout:10000}")
73 private long timeout; 74 private long timeout;
  75 +
  76 + private final AtomicInteger connectionsCounter = new AtomicInteger();
  77 +
  78 + @PostConstruct
  79 + public void init() {
  80 + transportService.createGaugeStats("openConnections", connectionsCounter);
  81 + }
  82 +
  83 + public void channelRegistered() {
  84 + connectionsCounter.incrementAndGet();
  85 + }
  86 +
  87 + public void channelUnregistered() {
  88 + connectionsCounter.decrementAndGet();
  89 + }
74 } 90 }
@@ -147,6 +147,18 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement @@ -147,6 +147,18 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
147 } 147 }
148 148
149 @Override 149 @Override
  150 + public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
  151 + super.channelRegistered(ctx);
  152 + context.channelRegistered();
  153 + }
  154 +
  155 + @Override
  156 + public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
  157 + super.channelUnregistered(ctx);
  158 + context.channelUnregistered();
  159 + }
  160 +
  161 + @Override
150 public void channelRead(ChannelHandlerContext ctx, Object msg) { 162 public void channelRead(ChannelHandlerContext ctx, Object msg) {
151 log.trace("[{}] Processing msg: {}", sessionId, msg); 163 log.trace("[{}] Processing msg: {}", sessionId, msg);
152 try { 164 try {
@@ -39,7 +39,7 @@ public abstract class TransportContext { @@ -39,7 +39,7 @@ public abstract class TransportContext {
39 protected final ObjectMapper mapper = new ObjectMapper(); 39 protected final ObjectMapper mapper = new ObjectMapper();
40 40
41 @Autowired 41 @Autowired
42 - private TransportService transportService; 42 + protected TransportService transportService;
43 43
44 @Autowired 44 @Autowired
45 private TbServiceInfoProvider serviceInfoProvider; 45 private TbServiceInfoProvider serviceInfoProvider;
@@ -58,6 +58,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenR @@ -58,6 +58,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenR
58 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg; 58 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg;
59 59
60 import java.util.concurrent.ExecutorService; 60 import java.util.concurrent.ExecutorService;
  61 +import java.util.concurrent.atomic.AtomicInteger;
61 62
62 /** 63 /**
63 * Created by ashvayka on 04.10.18. 64 * Created by ashvayka on 04.10.18.
@@ -138,4 +139,6 @@ public interface TransportService { @@ -138,4 +139,6 @@ public interface TransportService {
138 ExecutorService getCallbackExecutor(); 139 ExecutorService getCallbackExecutor();
139 140
140 boolean hasSession(SessionInfoProto sessionInfo); 141 boolean hasSession(SessionInfoProto sessionInfo);
  142 +
  143 + void createGaugeStats(String openConnections, AtomicInteger connectionsCounter);
141 } 144 }
@@ -21,9 +21,11 @@ import com.google.common.util.concurrent.MoreExecutors; @@ -21,9 +21,11 @@ import com.google.common.util.concurrent.MoreExecutors;
21 import com.google.gson.Gson; 21 import com.google.gson.Gson;
22 import com.google.gson.JsonObject; 22 import com.google.gson.JsonObject;
23 import com.google.protobuf.ByteString; 23 import com.google.protobuf.ByteString;
  24 +import lombok.Getter;
24 import lombok.extern.slf4j.Slf4j; 25 import lombok.extern.slf4j.Slf4j;
25 import org.springframework.beans.factory.annotation.Value; 26 import org.springframework.beans.factory.annotation.Value;
26 import org.springframework.context.ApplicationEventPublisher; 27 import org.springframework.context.ApplicationEventPublisher;
  28 +import org.springframework.scheduling.annotation.Scheduled;
27 import org.springframework.stereotype.Service; 29 import org.springframework.stereotype.Service;
28 import org.thingsboard.common.util.ThingsBoardExecutors; 30 import org.thingsboard.common.util.ThingsBoardExecutors;
29 import org.thingsboard.common.util.ThingsBoardThreadFactory; 31 import org.thingsboard.common.util.ThingsBoardThreadFactory;
@@ -96,6 +98,7 @@ import javax.annotation.PostConstruct; @@ -96,6 +98,7 @@ import javax.annotation.PostConstruct;
96 import javax.annotation.PreDestroy; 98 import javax.annotation.PreDestroy;
97 import java.util.Collections; 99 import java.util.Collections;
98 import java.util.HashSet; 100 import java.util.HashSet;
  101 +import java.util.LinkedHashMap;
99 import java.util.List; 102 import java.util.List;
100 import java.util.Map; 103 import java.util.Map;
101 import java.util.Optional; 104 import java.util.Optional;
@@ -110,6 +113,7 @@ import java.util.concurrent.Executors; @@ -110,6 +113,7 @@ import java.util.concurrent.Executors;
110 import java.util.concurrent.ScheduledFuture; 113 import java.util.concurrent.ScheduledFuture;
111 import java.util.concurrent.TimeUnit; 114 import java.util.concurrent.TimeUnit;
112 import java.util.concurrent.atomic.AtomicInteger; 115 import java.util.concurrent.atomic.AtomicInteger;
  116 +import java.util.stream.Collectors;
113 117
114 /** 118 /**
115 * Created by ashvayka on 17.10.18. 119 * Created by ashvayka on 17.10.18.
@@ -135,6 +139,10 @@ public class DefaultTransportService implements TransportService { @@ -135,6 +139,10 @@ public class DefaultTransportService implements TransportService {
135 private long clientSideRpcTimeout; 139 private long clientSideRpcTimeout;
136 @Value("${queue.transport.poll_interval}") 140 @Value("${queue.transport.poll_interval}")
137 private int notificationsPollDuration; 141 private int notificationsPollDuration;
  142 + @Value("${transport.stats.enabled:false}")
  143 + private boolean statsEnabled;
  144 +
  145 + private final Map<String, Number> statsMap = new LinkedHashMap<>();
138 146
139 private final Gson gson = new Gson(); 147 private final Gson gson = new Gson();
140 private final TbTransportQueueFactory queueProvider; 148 private final TbTransportQueueFactory queueProvider;
@@ -1167,4 +1175,19 @@ public class DefaultTransportService implements TransportService { @@ -1167,4 +1175,19 @@ public class DefaultTransportService implements TransportService {
1167 public boolean hasSession(TransportProtos.SessionInfoProto sessionInfo) { 1175 public boolean hasSession(TransportProtos.SessionInfoProto sessionInfo) {
1168 return sessions.containsKey(toSessionId(sessionInfo)); 1176 return sessions.containsKey(toSessionId(sessionInfo));
1169 } 1177 }
  1178 +
  1179 + @Override
  1180 + public void createGaugeStats(String statsName, AtomicInteger number) {
  1181 + statsFactory.createGauge(StatsType.TRANSPORT + "." + statsName, number);
  1182 + statsMap.put(statsName, number);
  1183 + }
  1184 +
  1185 + @Scheduled(fixedDelayString = "${transport.stats.print-interval-ms:60000}")
  1186 + public void printStats() {
  1187 + if (statsEnabled) {
  1188 + String values = statsMap.entrySet().stream()
  1189 + .map(kv -> kv.getKey() + " [" + kv.getValue() + "]").collect(Collectors.joining(", "));
  1190 + log.info("Transport Stats: {}", values);
  1191 + }
  1192 + }
1170 } 1193 }
@@ -122,6 +122,9 @@ transport: @@ -122,6 +122,9 @@ transport:
122 log: 122 log:
123 enabled: "${TB_TRANSPORT_LOG_ENABLED:true}" 123 enabled: "${TB_TRANSPORT_LOG_ENABLED:true}"
124 max_length: "${TB_TRANSPORT_LOG_MAX_LENGTH:1024}" 124 max_length: "${TB_TRANSPORT_LOG_MAX_LENGTH:1024}"
  125 + stats:
  126 + enabled: "${TB_TRANSPORT_STATS_ENABLED:true}"
  127 + print-interval-ms: "${TB_TRANSPORT_STATS_PRINT_INTERVAL_MS:60000}"
125 128
126 queue: 129 queue:
127 type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ) 130 type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ)
@@ -94,6 +94,9 @@ transport: @@ -94,6 +94,9 @@ transport:
94 log: 94 log:
95 enabled: "${TB_TRANSPORT_LOG_ENABLED:true}" 95 enabled: "${TB_TRANSPORT_LOG_ENABLED:true}"
96 max_length: "${TB_TRANSPORT_LOG_MAX_LENGTH:1024}" 96 max_length: "${TB_TRANSPORT_LOG_MAX_LENGTH:1024}"
  97 + stats:
  98 + enabled: "${TB_TRANSPORT_STATS_ENABLED:true}"
  99 + print-interval-ms: "${TB_TRANSPORT_STATS_PRINT_INTERVAL_MS:60000}"
97 100
98 queue: 101 queue:
99 type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ) 102 type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ)
@@ -147,6 +147,9 @@ transport: @@ -147,6 +147,9 @@ transport:
147 paging_transmission_window: "${LWM2M_PAGING_TRANSMISSION_WINDOW:10000}" 147 paging_transmission_window: "${LWM2M_PAGING_TRANSMISSION_WINDOW:10000}"
148 # Use redis for Security and Registration stores 148 # Use redis for Security and Registration stores
149 redis.enabled: "${LWM2M_REDIS_ENABLED:false}" 149 redis.enabled: "${LWM2M_REDIS_ENABLED:false}"
  150 + stats:
  151 + enabled: "${TB_TRANSPORT_STATS_ENABLED:true}"
  152 + print-interval-ms: "${TB_TRANSPORT_STATS_PRINT_INTERVAL_MS:60000}"
150 153
151 queue: 154 queue:
152 type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ) 155 type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ)
@@ -127,6 +127,9 @@ transport: @@ -127,6 +127,9 @@ transport:
127 log: 127 log:
128 enabled: "${TB_TRANSPORT_LOG_ENABLED:true}" 128 enabled: "${TB_TRANSPORT_LOG_ENABLED:true}"
129 max_length: "${TB_TRANSPORT_LOG_MAX_LENGTH:1024}" 129 max_length: "${TB_TRANSPORT_LOG_MAX_LENGTH:1024}"
  130 + stats:
  131 + enabled: "${TB_TRANSPORT_STATS_ENABLED:true}"
  132 + print-interval-ms: "${TB_TRANSPORT_STATS_PRINT_INTERVAL_MS:60000}"
130 133
131 134
132 queue: 135 queue:
@@ -59,6 +59,9 @@ transport: @@ -59,6 +59,9 @@ transport:
59 log: 59 log:
60 enabled: "${TB_TRANSPORT_LOG_ENABLED:true}" 60 enabled: "${TB_TRANSPORT_LOG_ENABLED:true}"
61 max_length: "${TB_TRANSPORT_LOG_MAX_LENGTH:1024}" 61 max_length: "${TB_TRANSPORT_LOG_MAX_LENGTH:1024}"
  62 + stats:
  63 + enabled: "${TB_TRANSPORT_STATS_ENABLED:true}"
  64 + print-interval-ms: "${TB_TRANSPORT_STATS_PRINT_INTERVAL_MS:60000}"
62 65
63 queue: 66 queue:
64 type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ) 67 type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ)