Commit d40bc488980abc04b60523ef83901f6a92e30932
1 parent
c52c9a16
Ability to log number of active MQTT connections
Showing
11 changed files
with
73 additions
and
1 deletions
@@ -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) |