Prometheus Metrics (#3052)
* Moved resetting ruleEngineStats to Consumer * Moved counters to Map in TbCoreConsumerStats * Added actuator and MetricsService * Added metrics to core and rule_engine consumers * Replaced summary with counters * Removed most setters and getters from TbRuleEngine stats * Added stats to Transport consumer * Added JsInvoke actuator stats * Removed MetricsService
This commit is contained in:
		
							parent
							
								
									7d739dfaae
								
							
						
					
					
						commit
						89419c6999
					
				@ -298,6 +298,18 @@
 | 
				
			|||||||
            <groupId>com.github.ua-parser</groupId>
 | 
					            <groupId>com.github.ua-parser</groupId>
 | 
				
			||||||
            <artifactId>uap-java</artifactId>
 | 
					            <artifactId>uap-java</artifactId>
 | 
				
			||||||
        </dependency>
 | 
					        </dependency>
 | 
				
			||||||
 | 
					        <dependency>
 | 
				
			||||||
 | 
					            <groupId>org.springframework.boot</groupId>
 | 
				
			||||||
 | 
					            <artifactId>spring-boot-starter-actuator</artifactId>
 | 
				
			||||||
 | 
					        </dependency>
 | 
				
			||||||
 | 
					        <dependency>
 | 
				
			||||||
 | 
					            <groupId>io.micrometer</groupId>
 | 
				
			||||||
 | 
					            <artifactId>micrometer-core</artifactId>
 | 
				
			||||||
 | 
					        </dependency>
 | 
				
			||||||
 | 
					        <dependency>
 | 
				
			||||||
 | 
					            <groupId>io.micrometer</groupId>
 | 
				
			||||||
 | 
					            <artifactId>micrometer-registry-prometheus</artifactId>
 | 
				
			||||||
 | 
					        </dependency>
 | 
				
			||||||
    </dependencies>
 | 
					    </dependencies>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <build>
 | 
					    <build>
 | 
				
			||||||
 | 
				
			|||||||
@ -219,6 +219,10 @@ public class ActorSystemContext {
 | 
				
			|||||||
    @Getter
 | 
					    @Getter
 | 
				
			||||||
    private ClaimDevicesService claimDevicesService;
 | 
					    private ClaimDevicesService claimDevicesService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Autowired
 | 
				
			||||||
 | 
					    @Getter
 | 
				
			||||||
 | 
					    private JsInvokeStats jsInvokeStats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //TODO: separate context for TbCore and TbRuleEngine
 | 
					    //TODO: separate context for TbCore and TbRuleEngine
 | 
				
			||||||
    @Autowired(required = false)
 | 
					    @Autowired(required = false)
 | 
				
			||||||
    @Getter
 | 
					    @Getter
 | 
				
			||||||
@ -272,19 +276,14 @@ public class ActorSystemContext {
 | 
				
			|||||||
    @Getter
 | 
					    @Getter
 | 
				
			||||||
    private long statisticsPersistFrequency;
 | 
					    private long statisticsPersistFrequency;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Getter
 | 
					 | 
				
			||||||
    private final AtomicInteger jsInvokeRequestsCount = new AtomicInteger(0);
 | 
					 | 
				
			||||||
    @Getter
 | 
					 | 
				
			||||||
    private final AtomicInteger jsInvokeResponsesCount = new AtomicInteger(0);
 | 
					 | 
				
			||||||
    @Getter
 | 
					 | 
				
			||||||
    private final AtomicInteger jsInvokeFailuresCount = new AtomicInteger(0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Scheduled(fixedDelayString = "${actors.statistics.js_print_interval_ms}")
 | 
					    @Scheduled(fixedDelayString = "${actors.statistics.js_print_interval_ms}")
 | 
				
			||||||
    public void printStats() {
 | 
					    public void printStats() {
 | 
				
			||||||
        if (statisticsEnabled) {
 | 
					        if (statisticsEnabled) {
 | 
				
			||||||
            if (jsInvokeRequestsCount.get() > 0 || jsInvokeResponsesCount.get() > 0 || jsInvokeFailuresCount.get() > 0) {
 | 
					            if (jsInvokeStats.getRequests() > 0 || jsInvokeStats.getResponses() > 0 || jsInvokeStats.getFailures() > 0) {
 | 
				
			||||||
                log.info("Rule Engine JS Invoke Stats: requests [{}] responses [{}] failures [{}]",
 | 
					                log.info("Rule Engine JS Invoke Stats: requests [{}] responses [{}] failures [{}]",
 | 
				
			||||||
                        jsInvokeRequestsCount.getAndSet(0), jsInvokeResponsesCount.getAndSet(0), jsInvokeFailuresCount.getAndSet(0));
 | 
					                        jsInvokeStats.getRequests(), jsInvokeStats.getResponses(), jsInvokeStats.getFailures());
 | 
				
			||||||
 | 
					                jsInvokeStats.reset();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -292,21 +292,21 @@ class DefaultTbContext implements TbContext {
 | 
				
			|||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void logJsEvalRequest() {
 | 
					    public void logJsEvalRequest() {
 | 
				
			||||||
        if (mainCtx.isStatisticsEnabled()) {
 | 
					        if (mainCtx.isStatisticsEnabled()) {
 | 
				
			||||||
            mainCtx.getJsInvokeRequestsCount().incrementAndGet();
 | 
					            mainCtx.getJsInvokeStats().incrementRequests();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void logJsEvalResponse() {
 | 
					    public void logJsEvalResponse() {
 | 
				
			||||||
        if (mainCtx.isStatisticsEnabled()) {
 | 
					        if (mainCtx.isStatisticsEnabled()) {
 | 
				
			||||||
            mainCtx.getJsInvokeResponsesCount().incrementAndGet();
 | 
					            mainCtx.getJsInvokeStats().incrementResponses();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void logJsEvalFailure() {
 | 
					    public void logJsEvalFailure() {
 | 
				
			||||||
        if (mainCtx.isStatisticsEnabled()) {
 | 
					        if (mainCtx.isStatisticsEnabled()) {
 | 
				
			||||||
            mainCtx.getJsInvokeFailuresCount().incrementAndGet();
 | 
					            mainCtx.getJsInvokeStats().incrementFailures();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright © 2016-2020 The Thingsboard Authors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package org.thingsboard.server.service.metrics;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import io.micrometer.core.instrument.Counter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class StubCounter implements Counter {
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void increment(double amount) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public double count() {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public Id getId() {
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -26,16 +26,7 @@ import org.thingsboard.server.common.msg.MsgType;
 | 
				
			|||||||
import org.thingsboard.server.common.msg.TbActorMsg;
 | 
					import org.thingsboard.server.common.msg.TbActorMsg;
 | 
				
			||||||
import org.thingsboard.server.common.msg.queue.ServiceType;
 | 
					import org.thingsboard.server.common.msg.queue.ServiceType;
 | 
				
			||||||
import org.thingsboard.server.common.msg.queue.TbCallback;
 | 
					import org.thingsboard.server.common.msg.queue.TbCallback;
 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.DeviceStateServiceMsgProto;
 | 
					import org.thingsboard.server.gen.transport.TransportProtos.*;
 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto;
 | 
					 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.LocalSubscriptionServiceMsgProto;
 | 
					 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.SubscriptionMgrMsgProto;
 | 
					 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.TbAttributeUpdateProto;
 | 
					 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionCloseProto;
 | 
					 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.TbTimeSeriesUpdateProto;
 | 
					 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
 | 
					 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
 | 
					 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
 | 
					 | 
				
			||||||
import org.thingsboard.server.queue.TbQueueConsumer;
 | 
					import org.thingsboard.server.queue.TbQueueConsumer;
 | 
				
			||||||
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
 | 
					import org.thingsboard.server.queue.common.TbProtoQueueMsg;
 | 
				
			||||||
import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
 | 
					import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
 | 
				
			||||||
@ -47,6 +38,7 @@ import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
 | 
				
			|||||||
import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;
 | 
					import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;
 | 
				
			||||||
import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg;
 | 
					import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg;
 | 
				
			||||||
import org.thingsboard.server.service.state.DeviceStateService;
 | 
					import org.thingsboard.server.service.state.DeviceStateService;
 | 
				
			||||||
 | 
					import org.thingsboard.server.service.stats.StatsCounterFactory;
 | 
				
			||||||
import org.thingsboard.server.service.subscription.SubscriptionManagerService;
 | 
					import org.thingsboard.server.service.subscription.SubscriptionManagerService;
 | 
				
			||||||
import org.thingsboard.server.service.subscription.TbLocalSubscriptionService;
 | 
					import org.thingsboard.server.service.subscription.TbLocalSubscriptionService;
 | 
				
			||||||
import org.thingsboard.server.service.subscription.TbSubscriptionUtils;
 | 
					import org.thingsboard.server.service.subscription.TbSubscriptionUtils;
 | 
				
			||||||
@ -81,18 +73,19 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
 | 
				
			|||||||
    private final TbLocalSubscriptionService localSubscriptionService;
 | 
					    private final TbLocalSubscriptionService localSubscriptionService;
 | 
				
			||||||
    private final SubscriptionManagerService subscriptionManagerService;
 | 
					    private final SubscriptionManagerService subscriptionManagerService;
 | 
				
			||||||
    private final TbCoreDeviceRpcService tbCoreDeviceRpcService;
 | 
					    private final TbCoreDeviceRpcService tbCoreDeviceRpcService;
 | 
				
			||||||
    private final TbCoreConsumerStats stats = new TbCoreConsumerStats();
 | 
					    private final TbCoreConsumerStats stats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public DefaultTbCoreConsumerService(TbCoreQueueFactory tbCoreQueueFactory, ActorSystemContext actorContext,
 | 
					    public DefaultTbCoreConsumerService(TbCoreQueueFactory tbCoreQueueFactory, ActorSystemContext actorContext,
 | 
				
			||||||
                                        DeviceStateService stateService, TbLocalSubscriptionService localSubscriptionService,
 | 
					                                        DeviceStateService stateService, TbLocalSubscriptionService localSubscriptionService,
 | 
				
			||||||
                                        SubscriptionManagerService subscriptionManagerService, DataDecodingEncodingService encodingService,
 | 
					                                        SubscriptionManagerService subscriptionManagerService, DataDecodingEncodingService encodingService,
 | 
				
			||||||
                                        TbCoreDeviceRpcService tbCoreDeviceRpcService) {
 | 
					                                        TbCoreDeviceRpcService tbCoreDeviceRpcService, StatsCounterFactory counterFactory) {
 | 
				
			||||||
        super(actorContext, encodingService, tbCoreQueueFactory.createToCoreNotificationsMsgConsumer());
 | 
					        super(actorContext, encodingService, tbCoreQueueFactory.createToCoreNotificationsMsgConsumer());
 | 
				
			||||||
        this.mainConsumer = tbCoreQueueFactory.createToCoreMsgConsumer();
 | 
					        this.mainConsumer = tbCoreQueueFactory.createToCoreMsgConsumer();
 | 
				
			||||||
        this.stateService = stateService;
 | 
					        this.stateService = stateService;
 | 
				
			||||||
        this.localSubscriptionService = localSubscriptionService;
 | 
					        this.localSubscriptionService = localSubscriptionService;
 | 
				
			||||||
        this.subscriptionManagerService = subscriptionManagerService;
 | 
					        this.subscriptionManagerService = subscriptionManagerService;
 | 
				
			||||||
        this.tbCoreDeviceRpcService = tbCoreDeviceRpcService;
 | 
					        this.tbCoreDeviceRpcService = tbCoreDeviceRpcService;
 | 
				
			||||||
 | 
					        this.stats = new TbCoreConsumerStats(counterFactory);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @PostConstruct
 | 
					    @PostConstruct
 | 
				
			||||||
@ -228,6 +221,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
 | 
				
			|||||||
    public void printStats() {
 | 
					    public void printStats() {
 | 
				
			||||||
        if (statsEnabled) {
 | 
					        if (statsEnabled) {
 | 
				
			||||||
            stats.printStats();
 | 
					            stats.printStats();
 | 
				
			||||||
 | 
					            stats.reset();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -52,6 +52,7 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrateg
 | 
				
			|||||||
import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
 | 
					import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
 | 
				
			||||||
import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService;
 | 
					import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService;
 | 
				
			||||||
import org.thingsboard.server.service.stats.RuleEngineStatisticsService;
 | 
					import org.thingsboard.server.service.stats.RuleEngineStatisticsService;
 | 
				
			||||||
 | 
					import org.thingsboard.server.service.stats.StatsCounterFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.PostConstruct;
 | 
					import javax.annotation.PostConstruct;
 | 
				
			||||||
import javax.annotation.PreDestroy;
 | 
					import javax.annotation.PreDestroy;
 | 
				
			||||||
@ -79,6 +80,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<
 | 
				
			|||||||
    @Value("${queue.rule-engine.stats.enabled:true}")
 | 
					    @Value("${queue.rule-engine.stats.enabled:true}")
 | 
				
			||||||
    private boolean statsEnabled;
 | 
					    private boolean statsEnabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private final StatsCounterFactory counterFactory;
 | 
				
			||||||
    private final TbRuleEngineSubmitStrategyFactory submitStrategyFactory;
 | 
					    private final TbRuleEngineSubmitStrategyFactory submitStrategyFactory;
 | 
				
			||||||
    private final TbRuleEngineProcessingStrategyFactory processingStrategyFactory;
 | 
					    private final TbRuleEngineProcessingStrategyFactory processingStrategyFactory;
 | 
				
			||||||
    private final TbRuleEngineQueueFactory tbRuleEngineQueueFactory;
 | 
					    private final TbRuleEngineQueueFactory tbRuleEngineQueueFactory;
 | 
				
			||||||
@ -95,7 +97,8 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<
 | 
				
			|||||||
                                              TbQueueRuleEngineSettings ruleEngineSettings,
 | 
					                                              TbQueueRuleEngineSettings ruleEngineSettings,
 | 
				
			||||||
                                              TbRuleEngineQueueFactory tbRuleEngineQueueFactory, RuleEngineStatisticsService statisticsService,
 | 
					                                              TbRuleEngineQueueFactory tbRuleEngineQueueFactory, RuleEngineStatisticsService statisticsService,
 | 
				
			||||||
                                              ActorSystemContext actorContext, DataDecodingEncodingService encodingService,
 | 
					                                              ActorSystemContext actorContext, DataDecodingEncodingService encodingService,
 | 
				
			||||||
                                              TbRuleEngineDeviceRpcService tbDeviceRpcService) {
 | 
					                                              TbRuleEngineDeviceRpcService tbDeviceRpcService,
 | 
				
			||||||
 | 
					                                              StatsCounterFactory counterFactory) {
 | 
				
			||||||
        super(actorContext, encodingService, tbRuleEngineQueueFactory.createToRuleEngineNotificationsMsgConsumer());
 | 
					        super(actorContext, encodingService, tbRuleEngineQueueFactory.createToRuleEngineNotificationsMsgConsumer());
 | 
				
			||||||
        this.statisticsService = statisticsService;
 | 
					        this.statisticsService = statisticsService;
 | 
				
			||||||
        this.ruleEngineSettings = ruleEngineSettings;
 | 
					        this.ruleEngineSettings = ruleEngineSettings;
 | 
				
			||||||
@ -103,6 +106,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<
 | 
				
			|||||||
        this.submitStrategyFactory = submitStrategyFactory;
 | 
					        this.submitStrategyFactory = submitStrategyFactory;
 | 
				
			||||||
        this.processingStrategyFactory = processingStrategyFactory;
 | 
					        this.processingStrategyFactory = processingStrategyFactory;
 | 
				
			||||||
        this.tbDeviceRpcService = tbDeviceRpcService;
 | 
					        this.tbDeviceRpcService = tbDeviceRpcService;
 | 
				
			||||||
 | 
					        this.counterFactory = counterFactory;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @PostConstruct
 | 
					    @PostConstruct
 | 
				
			||||||
@ -111,7 +115,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<
 | 
				
			|||||||
        for (TbRuleEngineQueueConfiguration configuration : ruleEngineSettings.getQueues()) {
 | 
					        for (TbRuleEngineQueueConfiguration configuration : ruleEngineSettings.getQueues()) {
 | 
				
			||||||
            consumerConfigurations.putIfAbsent(configuration.getName(), configuration);
 | 
					            consumerConfigurations.putIfAbsent(configuration.getName(), configuration);
 | 
				
			||||||
            consumers.computeIfAbsent(configuration.getName(), queueName -> tbRuleEngineQueueFactory.createToRuleEngineMsgConsumer(configuration));
 | 
					            consumers.computeIfAbsent(configuration.getName(), queueName -> tbRuleEngineQueueFactory.createToRuleEngineMsgConsumer(configuration));
 | 
				
			||||||
            consumerStats.put(configuration.getName(), new TbRuleEngineConsumerStats(configuration.getName()));
 | 
					            consumerStats.put(configuration.getName(), new TbRuleEngineConsumerStats(configuration.getName(), counterFactory));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        submitExecutor = Executors.newSingleThreadExecutor();
 | 
					        submitExecutor = Executors.newSingleThreadExecutor();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -269,6 +273,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<
 | 
				
			|||||||
            consumerStats.forEach((queue, stats) -> {
 | 
					            consumerStats.forEach((queue, stats) -> {
 | 
				
			||||||
                stats.printStats();
 | 
					                stats.printStats();
 | 
				
			||||||
                statisticsService.reportQueueStats(ts, stats);
 | 
					                statisticsService.reportQueueStats(ts, stats);
 | 
				
			||||||
 | 
					                stats.reset();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -17,76 +17,124 @@ package org.thingsboard.server.service.queue;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import lombok.extern.slf4j.Slf4j;
 | 
					import lombok.extern.slf4j.Slf4j;
 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos;
 | 
					import org.thingsboard.server.gen.transport.TransportProtos;
 | 
				
			||||||
 | 
					import org.thingsboard.server.service.stats.StatsCounter;
 | 
				
			||||||
 | 
					import org.thingsboard.server.service.stats.StatsCounterFactory;
 | 
				
			||||||
 | 
					import org.thingsboard.server.service.stats.StatsType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.*;
 | 
				
			||||||
import java.util.concurrent.atomic.AtomicInteger;
 | 
					import java.util.concurrent.atomic.AtomicInteger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Slf4j
 | 
					@Slf4j
 | 
				
			||||||
public class TbCoreConsumerStats {
 | 
					public class TbCoreConsumerStats {
 | 
				
			||||||
 | 
					    public static final String TOTAL_MSGS = "totalMsgs";
 | 
				
			||||||
 | 
					    public static final String SESSION_EVENTS = "sessionEvents";
 | 
				
			||||||
 | 
					    public static final String GET_ATTRIBUTE = "getAttr";
 | 
				
			||||||
 | 
					    public static final String ATTRIBUTE_SUBSCRIBES = "subToAttr";
 | 
				
			||||||
 | 
					    public static final String RPC_SUBSCRIBES = "subToRpc";
 | 
				
			||||||
 | 
					    public static final String TO_DEVICE_RPC_CALL_RESPONSES = "toDevRpc";
 | 
				
			||||||
 | 
					    public static final String SUBSCRIPTION_INFO = "subInfo";
 | 
				
			||||||
 | 
					    public static final String DEVICE_CLAIMS = "claimDevice";
 | 
				
			||||||
 | 
					    public static final String DEVICE_STATES = "deviceState";
 | 
				
			||||||
 | 
					    public static final String SUBSCRIPTION_MSGS = "subMsgs";
 | 
				
			||||||
 | 
					    public static final String TO_CORE_NOTIFICATIONS = "coreNfs";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final AtomicInteger totalCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter totalCounter;
 | 
				
			||||||
    private final AtomicInteger sessionEventCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter sessionEventCounter;
 | 
				
			||||||
    private final AtomicInteger getAttributesCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter getAttributesCounter;
 | 
				
			||||||
    private final AtomicInteger subscribeToAttributesCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter subscribeToAttributesCounter;
 | 
				
			||||||
    private final AtomicInteger subscribeToRPCCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter subscribeToRPCCounter;
 | 
				
			||||||
    private final AtomicInteger toDeviceRPCCallResponseCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter toDeviceRPCCallResponseCounter;
 | 
				
			||||||
    private final AtomicInteger subscriptionInfoCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter subscriptionInfoCounter;
 | 
				
			||||||
    private final AtomicInteger claimDeviceCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter claimDeviceCounter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final AtomicInteger deviceStateCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter deviceStateCounter;
 | 
				
			||||||
    private final AtomicInteger subscriptionMsgCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter subscriptionMsgCounter;
 | 
				
			||||||
    private final AtomicInteger toCoreNotificationsCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter toCoreNotificationsCounter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private final List<StatsCounter> counters = new ArrayList<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public TbCoreConsumerStats(StatsCounterFactory counterFactory) {
 | 
				
			||||||
 | 
					        String statsKey = StatsType.CORE.getName();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.totalCounter = counterFactory.createStatsCounter(statsKey, TOTAL_MSGS);
 | 
				
			||||||
 | 
					        this.sessionEventCounter = counterFactory.createStatsCounter(statsKey, SESSION_EVENTS);
 | 
				
			||||||
 | 
					        this.getAttributesCounter = counterFactory.createStatsCounter(statsKey, GET_ATTRIBUTE);
 | 
				
			||||||
 | 
					        this.subscribeToAttributesCounter = counterFactory.createStatsCounter(statsKey, ATTRIBUTE_SUBSCRIBES);
 | 
				
			||||||
 | 
					        this.subscribeToRPCCounter = counterFactory.createStatsCounter(statsKey, RPC_SUBSCRIBES);
 | 
				
			||||||
 | 
					        this.toDeviceRPCCallResponseCounter = counterFactory.createStatsCounter(statsKey, TO_DEVICE_RPC_CALL_RESPONSES);
 | 
				
			||||||
 | 
					        this.subscriptionInfoCounter = counterFactory.createStatsCounter(statsKey, SUBSCRIPTION_INFO);
 | 
				
			||||||
 | 
					        this.claimDeviceCounter = counterFactory.createStatsCounter(statsKey, DEVICE_CLAIMS);
 | 
				
			||||||
 | 
					        this.deviceStateCounter = counterFactory.createStatsCounter(statsKey, DEVICE_STATES);
 | 
				
			||||||
 | 
					        this.subscriptionMsgCounter = counterFactory.createStatsCounter(statsKey, SUBSCRIPTION_MSGS);
 | 
				
			||||||
 | 
					        this.toCoreNotificationsCounter = counterFactory.createStatsCounter(statsKey, TO_CORE_NOTIFICATIONS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        counters.add(totalCounter);
 | 
				
			||||||
 | 
					        counters.add(sessionEventCounter);
 | 
				
			||||||
 | 
					        counters.add(getAttributesCounter);
 | 
				
			||||||
 | 
					        counters.add(subscribeToAttributesCounter);
 | 
				
			||||||
 | 
					        counters.add(subscribeToRPCCounter);
 | 
				
			||||||
 | 
					        counters.add(toDeviceRPCCallResponseCounter);
 | 
				
			||||||
 | 
					        counters.add(subscriptionInfoCounter);
 | 
				
			||||||
 | 
					        counters.add(claimDeviceCounter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        counters.add(deviceStateCounter);
 | 
				
			||||||
 | 
					        counters.add(subscriptionMsgCounter);
 | 
				
			||||||
 | 
					        counters.add(toCoreNotificationsCounter);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void log(TransportProtos.TransportToDeviceActorMsg msg) {
 | 
					    public void log(TransportProtos.TransportToDeviceActorMsg msg) {
 | 
				
			||||||
        totalCounter.incrementAndGet();
 | 
					        totalCounter.increment();
 | 
				
			||||||
        if (msg.hasSessionEvent()) {
 | 
					        if (msg.hasSessionEvent()) {
 | 
				
			||||||
            sessionEventCounter.incrementAndGet();
 | 
					            sessionEventCounter.increment();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (msg.hasGetAttributes()) {
 | 
					        if (msg.hasGetAttributes()) {
 | 
				
			||||||
            getAttributesCounter.incrementAndGet();
 | 
					            getAttributesCounter.increment();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (msg.hasSubscribeToAttributes()) {
 | 
					        if (msg.hasSubscribeToAttributes()) {
 | 
				
			||||||
            subscribeToAttributesCounter.incrementAndGet();
 | 
					            subscribeToAttributesCounter.increment();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (msg.hasSubscribeToRPC()) {
 | 
					        if (msg.hasSubscribeToRPC()) {
 | 
				
			||||||
            subscribeToRPCCounter.incrementAndGet();
 | 
					            subscribeToRPCCounter.increment();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (msg.hasToDeviceRPCCallResponse()) {
 | 
					        if (msg.hasToDeviceRPCCallResponse()) {
 | 
				
			||||||
            toDeviceRPCCallResponseCounter.incrementAndGet();
 | 
					            toDeviceRPCCallResponseCounter.increment();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (msg.hasSubscriptionInfo()) {
 | 
					        if (msg.hasSubscriptionInfo()) {
 | 
				
			||||||
            subscriptionInfoCounter.incrementAndGet();
 | 
					            subscriptionInfoCounter.increment();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (msg.hasClaimDevice()) {
 | 
					        if (msg.hasClaimDevice()) {
 | 
				
			||||||
            claimDeviceCounter.incrementAndGet();
 | 
					            claimDeviceCounter.increment();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void log(TransportProtos.DeviceStateServiceMsgProto msg) {
 | 
					    public void log(TransportProtos.DeviceStateServiceMsgProto msg) {
 | 
				
			||||||
        totalCounter.incrementAndGet();
 | 
					        totalCounter.increment();
 | 
				
			||||||
        deviceStateCounter.incrementAndGet();
 | 
					        deviceStateCounter.increment();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void log(TransportProtos.SubscriptionMgrMsgProto msg) {
 | 
					    public void log(TransportProtos.SubscriptionMgrMsgProto msg) {
 | 
				
			||||||
        totalCounter.incrementAndGet();
 | 
					        totalCounter.increment();
 | 
				
			||||||
        subscriptionMsgCounter.incrementAndGet();
 | 
					        subscriptionMsgCounter.increment();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void log(TransportProtos.ToCoreNotificationMsg msg) {
 | 
					    public void log(TransportProtos.ToCoreNotificationMsg msg) {
 | 
				
			||||||
        totalCounter.incrementAndGet();
 | 
					        totalCounter.increment();
 | 
				
			||||||
        toCoreNotificationsCounter.incrementAndGet();
 | 
					        toCoreNotificationsCounter.increment();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void printStats() {
 | 
					    public void printStats() {
 | 
				
			||||||
        int total = totalCounter.getAndSet(0);
 | 
					        int total = totalCounter.get();
 | 
				
			||||||
        if (total > 0) {
 | 
					        if (total > 0) {
 | 
				
			||||||
            log.info("Total [{}] sessionEvents [{}] getAttr [{}] subToAttr [{}] subToRpc [{}] toDevRpc [{}] subInfo [{}] claimDevice [{}]" +
 | 
					            StringBuilder stats = new StringBuilder();
 | 
				
			||||||
                            " deviceState [{}] subMgr [{}] coreNfs [{}]",
 | 
					            counters.forEach(counter -> {
 | 
				
			||||||
                    total, sessionEventCounter.getAndSet(0),
 | 
					                stats.append(counter.getName()).append(" = [").append(counter.get()).append("] ");
 | 
				
			||||||
                    getAttributesCounter.getAndSet(0), subscribeToAttributesCounter.getAndSet(0),
 | 
					            });
 | 
				
			||||||
                    subscribeToRPCCounter.getAndSet(0), toDeviceRPCCallResponseCounter.getAndSet(0),
 | 
					            log.info("Core Stats: {}", stats);
 | 
				
			||||||
                    subscriptionInfoCounter.getAndSet(0), claimDeviceCounter.getAndSet(0)
 | 
					 | 
				
			||||||
                    , deviceStateCounter.getAndSet(0), subscriptionMsgCounter.getAndSet(0), toCoreNotificationsCounter.getAndSet(0));
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void reset() {
 | 
				
			||||||
 | 
					        counters.forEach(StatsCounter::clear);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -22,16 +22,16 @@ import org.thingsboard.server.common.msg.queue.RuleEngineException;
 | 
				
			|||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
 | 
					import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
 | 
				
			||||||
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
 | 
					import org.thingsboard.server.queue.common.TbProtoQueueMsg;
 | 
				
			||||||
import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingResult;
 | 
					import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingResult;
 | 
				
			||||||
 | 
					import org.thingsboard.server.service.stats.StatsCounter;
 | 
				
			||||||
 | 
					import org.thingsboard.server.service.stats.StatsCounterFactory;
 | 
				
			||||||
 | 
					import org.thingsboard.server.service.stats.StatsType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.*;
 | 
				
			||||||
import java.util.Map;
 | 
					 | 
				
			||||||
import java.util.UUID;
 | 
					 | 
				
			||||||
import java.util.concurrent.ConcurrentHashMap;
 | 
					import java.util.concurrent.ConcurrentHashMap;
 | 
				
			||||||
import java.util.concurrent.ConcurrentMap;
 | 
					import java.util.concurrent.ConcurrentMap;
 | 
				
			||||||
import java.util.concurrent.atomic.AtomicInteger;
 | 
					import java.util.concurrent.atomic.AtomicInteger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Slf4j
 | 
					@Slf4j
 | 
				
			||||||
@Data
 | 
					 | 
				
			||||||
public class TbRuleEngineConsumerStats {
 | 
					public class TbRuleEngineConsumerStats {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final String TOTAL_MSGS = "totalMsgs";
 | 
					    public static final String TOTAL_MSGS = "totalMsgs";
 | 
				
			||||||
@ -43,61 +43,72 @@ public class TbRuleEngineConsumerStats {
 | 
				
			|||||||
    public static final String SUCCESSFUL_ITERATIONS = "successfulIterations";
 | 
					    public static final String SUCCESSFUL_ITERATIONS = "successfulIterations";
 | 
				
			||||||
    public static final String FAILED_ITERATIONS = "failedIterations";
 | 
					    public static final String FAILED_ITERATIONS = "failedIterations";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final AtomicInteger totalMsgCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter totalMsgCounter;
 | 
				
			||||||
    private final AtomicInteger successMsgCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter successMsgCounter;
 | 
				
			||||||
    private final AtomicInteger tmpTimeoutMsgCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter tmpTimeoutMsgCounter;
 | 
				
			||||||
    private final AtomicInteger tmpFailedMsgCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter tmpFailedMsgCounter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final AtomicInteger timeoutMsgCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter timeoutMsgCounter;
 | 
				
			||||||
    private final AtomicInteger failedMsgCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter failedMsgCounter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final AtomicInteger successIterationsCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter successIterationsCounter;
 | 
				
			||||||
    private final AtomicInteger failedIterationsCounter = new AtomicInteger(0);
 | 
					    private final StatsCounter failedIterationsCounter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final Map<String, AtomicInteger> counters = new HashMap<>();
 | 
					    private final List<StatsCounter> counters = new ArrayList<>();
 | 
				
			||||||
    private final ConcurrentMap<UUID, TbTenantRuleEngineStats> tenantStats = new ConcurrentHashMap<>();
 | 
					    private final ConcurrentMap<UUID, TbTenantRuleEngineStats> tenantStats = new ConcurrentHashMap<>();
 | 
				
			||||||
    private final ConcurrentMap<TenantId, RuleEngineException> tenantExceptions = new ConcurrentHashMap<>();
 | 
					    private final ConcurrentMap<TenantId, RuleEngineException> tenantExceptions = new ConcurrentHashMap<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final String queueName;
 | 
					    private final String queueName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public TbRuleEngineConsumerStats(String queueName) {
 | 
					    public TbRuleEngineConsumerStats(String queueName, StatsCounterFactory counterFactory) {
 | 
				
			||||||
        this.queueName = queueName;
 | 
					        this.queueName = queueName;
 | 
				
			||||||
        counters.put(TOTAL_MSGS, totalMsgCounter);
 | 
					 | 
				
			||||||
        counters.put(SUCCESSFUL_MSGS, successMsgCounter);
 | 
					 | 
				
			||||||
        counters.put(TIMEOUT_MSGS, timeoutMsgCounter);
 | 
					 | 
				
			||||||
        counters.put(FAILED_MSGS, failedMsgCounter);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        counters.put(TMP_TIMEOUT, tmpTimeoutMsgCounter);
 | 
					        String statsKey = StatsType.RULE_ENGINE.getName() + "." + queueName;
 | 
				
			||||||
        counters.put(TMP_FAILED, tmpFailedMsgCounter);
 | 
					        this.totalMsgCounter = counterFactory.createStatsCounter(statsKey, TOTAL_MSGS);
 | 
				
			||||||
        counters.put(SUCCESSFUL_ITERATIONS, successIterationsCounter);
 | 
					        this.successMsgCounter = counterFactory.createStatsCounter(statsKey, SUCCESSFUL_MSGS);
 | 
				
			||||||
        counters.put(FAILED_ITERATIONS, failedIterationsCounter);
 | 
					        this.timeoutMsgCounter = counterFactory.createStatsCounter(statsKey, TIMEOUT_MSGS);
 | 
				
			||||||
 | 
					        this.failedMsgCounter = counterFactory.createStatsCounter(statsKey, FAILED_MSGS);
 | 
				
			||||||
 | 
					        this.tmpTimeoutMsgCounter = counterFactory.createStatsCounter(statsKey, TMP_TIMEOUT);
 | 
				
			||||||
 | 
					        this.tmpFailedMsgCounter = counterFactory.createStatsCounter(statsKey, TMP_FAILED);
 | 
				
			||||||
 | 
					        this.successIterationsCounter = counterFactory.createStatsCounter(statsKey, SUCCESSFUL_ITERATIONS);
 | 
				
			||||||
 | 
					        this.failedIterationsCounter = counterFactory.createStatsCounter(statsKey, FAILED_ITERATIONS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        counters.add(totalMsgCounter);
 | 
				
			||||||
 | 
					        counters.add(successMsgCounter);
 | 
				
			||||||
 | 
					        counters.add(timeoutMsgCounter);
 | 
				
			||||||
 | 
					        counters.add(failedMsgCounter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        counters.add(tmpTimeoutMsgCounter);
 | 
				
			||||||
 | 
					        counters.add(tmpFailedMsgCounter);
 | 
				
			||||||
 | 
					        counters.add(successIterationsCounter);
 | 
				
			||||||
 | 
					        counters.add(failedIterationsCounter);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void log(TbRuleEngineProcessingResult msg, boolean finalIterationForPack) {
 | 
					    public void log(TbRuleEngineProcessingResult msg, boolean finalIterationForPack) {
 | 
				
			||||||
        int success = msg.getSuccessMap().size();
 | 
					        int success = msg.getSuccessMap().size();
 | 
				
			||||||
        int pending = msg.getPendingMap().size();
 | 
					        int pending = msg.getPendingMap().size();
 | 
				
			||||||
        int failed = msg.getFailedMap().size();
 | 
					        int failed = msg.getFailedMap().size();
 | 
				
			||||||
        totalMsgCounter.addAndGet(success + pending + failed);
 | 
					        totalMsgCounter.add(success + pending + failed);
 | 
				
			||||||
        successMsgCounter.addAndGet(success);
 | 
					        successMsgCounter.add(success);
 | 
				
			||||||
        msg.getSuccessMap().values().forEach(m -> getTenantStats(m).logSuccess());
 | 
					        msg.getSuccessMap().values().forEach(m -> getTenantStats(m).logSuccess());
 | 
				
			||||||
        if (finalIterationForPack) {
 | 
					        if (finalIterationForPack) {
 | 
				
			||||||
            if (pending > 0 || failed > 0) {
 | 
					            if (pending > 0 || failed > 0) {
 | 
				
			||||||
                timeoutMsgCounter.addAndGet(pending);
 | 
					                timeoutMsgCounter.add(pending);
 | 
				
			||||||
                failedMsgCounter.addAndGet(failed);
 | 
					                failedMsgCounter.add(failed);
 | 
				
			||||||
                if (pending > 0) {
 | 
					                if (pending > 0) {
 | 
				
			||||||
                    msg.getPendingMap().values().forEach(m -> getTenantStats(m).logTimeout());
 | 
					                    msg.getPendingMap().values().forEach(m -> getTenantStats(m).logTimeout());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (failed > 0) {
 | 
					                if (failed > 0) {
 | 
				
			||||||
                    msg.getFailedMap().values().forEach(m -> getTenantStats(m).logFailed());
 | 
					                    msg.getFailedMap().values().forEach(m -> getTenantStats(m).logFailed());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                failedIterationsCounter.incrementAndGet();
 | 
					                failedIterationsCounter.increment();
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                successIterationsCounter.incrementAndGet();
 | 
					                successIterationsCounter.increment();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            failedIterationsCounter.incrementAndGet();
 | 
					            failedIterationsCounter.increment();
 | 
				
			||||||
            tmpTimeoutMsgCounter.addAndGet(pending);
 | 
					            tmpTimeoutMsgCounter.add(pending);
 | 
				
			||||||
            tmpFailedMsgCounter.addAndGet(failed);
 | 
					            tmpFailedMsgCounter.add(failed);
 | 
				
			||||||
            if (pending > 0) {
 | 
					            if (pending > 0) {
 | 
				
			||||||
                msg.getPendingMap().values().forEach(m -> getTenantStats(m).logTmpTimeout());
 | 
					                msg.getPendingMap().values().forEach(m -> getTenantStats(m).logTmpTimeout());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -113,19 +124,31 @@ public class TbRuleEngineConsumerStats {
 | 
				
			|||||||
        return tenantStats.computeIfAbsent(new UUID(reMsg.getTenantIdMSB(), reMsg.getTenantIdLSB()), TbTenantRuleEngineStats::new);
 | 
					        return tenantStats.computeIfAbsent(new UUID(reMsg.getTenantIdMSB(), reMsg.getTenantIdLSB()), TbTenantRuleEngineStats::new);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public ConcurrentMap<UUID, TbTenantRuleEngineStats> getTenantStats() {
 | 
				
			||||||
 | 
					        return tenantStats;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getQueueName() {
 | 
				
			||||||
 | 
					        return queueName;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public ConcurrentMap<TenantId, RuleEngineException> getTenantExceptions() {
 | 
				
			||||||
 | 
					        return tenantExceptions;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void printStats() {
 | 
					    public void printStats() {
 | 
				
			||||||
        int total = totalMsgCounter.get();
 | 
					        int total = totalMsgCounter.get();
 | 
				
			||||||
        if (total > 0) {
 | 
					        if (total > 0) {
 | 
				
			||||||
            StringBuilder stats = new StringBuilder();
 | 
					            StringBuilder stats = new StringBuilder();
 | 
				
			||||||
            counters.forEach((label, value) -> {
 | 
					            counters.forEach(counter -> {
 | 
				
			||||||
                stats.append(label).append(" = [").append(value.get()).append("] ");
 | 
					                stats.append(counter.getName()).append(" = [").append(counter.get()).append("] ");
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            log.info("[{}] Stats: {}", queueName, stats);
 | 
					            log.info("[{}] Stats: {}", queueName, stats);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void reset() {
 | 
					    public void reset() {
 | 
				
			||||||
        counters.values().forEach(counter -> counter.set(0));
 | 
					        counters.forEach(StatsCounter::clear);
 | 
				
			||||||
        tenantStats.clear();
 | 
					        tenantStats.clear();
 | 
				
			||||||
        tenantExceptions.clear();
 | 
					        tenantExceptions.clear();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright © 2016-2020 The Thingsboard Authors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package org.thingsboard.server.service.stats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.springframework.beans.factory.annotation.Autowired;
 | 
				
			||||||
 | 
					import org.springframework.stereotype.Service;
 | 
				
			||||||
 | 
					import org.thingsboard.server.actors.JsInvokeStats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.annotation.PostConstruct;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Service
 | 
				
			||||||
 | 
					public class DefaultJsInvokeStats implements JsInvokeStats {
 | 
				
			||||||
 | 
					    private static final String REQUESTS = "requests";
 | 
				
			||||||
 | 
					    private static final String RESPONSES = "responses";
 | 
				
			||||||
 | 
					    private static final String FAILURES = "failures";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private StatsCounter requestsCounter;
 | 
				
			||||||
 | 
					    private StatsCounter responsesCounter;
 | 
				
			||||||
 | 
					    private StatsCounter failuresCounter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Autowired
 | 
				
			||||||
 | 
					    private StatsCounterFactory counterFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @PostConstruct
 | 
				
			||||||
 | 
					    public void init() {
 | 
				
			||||||
 | 
					        String key = StatsType.JS_INVOKE.getName();
 | 
				
			||||||
 | 
					        this.requestsCounter = counterFactory.createStatsCounter(key, REQUESTS);
 | 
				
			||||||
 | 
					        this.responsesCounter = counterFactory.createStatsCounter(key, RESPONSES);
 | 
				
			||||||
 | 
					        this.failuresCounter = counterFactory.createStatsCounter(key, FAILURES);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void incrementRequests(int amount) {
 | 
				
			||||||
 | 
					        requestsCounter.add(amount);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void incrementResponses(int amount) {
 | 
				
			||||||
 | 
					        responsesCounter.add(amount);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void incrementFailures(int amount) {
 | 
				
			||||||
 | 
					        failuresCounter.add(amount);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public int getRequests() {
 | 
				
			||||||
 | 
					        return requestsCounter.get();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public int getResponses() {
 | 
				
			||||||
 | 
					        return responsesCounter.get();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public int getFailures() {
 | 
				
			||||||
 | 
					        return failuresCounter.get();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void reset() {
 | 
				
			||||||
 | 
					        requestsCounter.clear();
 | 
				
			||||||
 | 
					        responsesCounter.clear();
 | 
				
			||||||
 | 
					        failuresCounter.clear();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright © 2016-2020 The Thingsboard Authors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package org.thingsboard.server.service.stats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.thingsboard.server.queue.stats.QueueStats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class DefaultQueueStats implements QueueStats {
 | 
				
			||||||
 | 
					    private final StatsCounter totalCounter;
 | 
				
			||||||
 | 
					    private final StatsCounter successfulCounter;
 | 
				
			||||||
 | 
					    private final StatsCounter failedCounter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public DefaultQueueStats(StatsCounter totalCounter, StatsCounter successfulCounter, StatsCounter failedCounter) {
 | 
				
			||||||
 | 
					        this.totalCounter = totalCounter;
 | 
				
			||||||
 | 
					        this.successfulCounter = successfulCounter;
 | 
				
			||||||
 | 
					        this.failedCounter = failedCounter;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void incrementTotal(int amount) {
 | 
				
			||||||
 | 
					        totalCounter.add(amount);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void incrementSuccessful(int amount) {
 | 
				
			||||||
 | 
					        successfulCounter.add(amount);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void incrementFailed(int amount) {
 | 
				
			||||||
 | 
					        failedCounter.add(amount);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -104,7 +104,6 @@ public class DefaultRuleEngineStatisticsService implements RuleEngineStatisticsS
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        ruleEngineStats.reset();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private AssetId getServiceAssetId(TenantId tenantId, String queueName) {
 | 
					    private AssetId getServiceAssetId(TenantId tenantId, String queueName) {
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright © 2016-2020 The Thingsboard Authors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package org.thingsboard.server.service.stats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import io.micrometer.core.instrument.Counter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.concurrent.atomic.AtomicInteger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class StatsCounter {
 | 
				
			||||||
 | 
					    private final AtomicInteger aiCounter;
 | 
				
			||||||
 | 
					    private final Counter micrometerCounter;
 | 
				
			||||||
 | 
					    private final String name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public StatsCounter(AtomicInteger aiCounter, Counter micrometerCounter, String name) {
 | 
				
			||||||
 | 
					        this.aiCounter = aiCounter;
 | 
				
			||||||
 | 
					        this.micrometerCounter = micrometerCounter;
 | 
				
			||||||
 | 
					        this.name = name;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void increment() {
 | 
				
			||||||
 | 
					        aiCounter.incrementAndGet();
 | 
				
			||||||
 | 
					        micrometerCounter.increment();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void clear() {
 | 
				
			||||||
 | 
					        aiCounter.set(0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public int get() {
 | 
				
			||||||
 | 
					        return aiCounter.get();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void add(int delta){
 | 
				
			||||||
 | 
					        aiCounter.addAndGet(delta);
 | 
				
			||||||
 | 
					        micrometerCounter.increment(delta);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getName() {
 | 
				
			||||||
 | 
					        return name;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright © 2016-2020 The Thingsboard Authors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package org.thingsboard.server.service.stats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import io.micrometer.core.instrument.Counter;
 | 
				
			||||||
 | 
					import io.micrometer.core.instrument.MeterRegistry;
 | 
				
			||||||
 | 
					import org.springframework.beans.factory.annotation.Autowired;
 | 
				
			||||||
 | 
					import org.springframework.beans.factory.annotation.Value;
 | 
				
			||||||
 | 
					import org.springframework.stereotype.Service;
 | 
				
			||||||
 | 
					import org.thingsboard.server.service.metrics.StubCounter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.concurrent.atomic.AtomicInteger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Service
 | 
				
			||||||
 | 
					public class StatsCounterFactory {
 | 
				
			||||||
 | 
					    private static final String STATS_NAME_TAG = "statsName";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static final Counter STUB_COUNTER = new StubCounter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Autowired
 | 
				
			||||||
 | 
					    private MeterRegistry meterRegistry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Value("${metrics.enabled}")
 | 
				
			||||||
 | 
					    private Boolean metricsEnabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public StatsCounter createStatsCounter(String key, String statsName) {
 | 
				
			||||||
 | 
					        return new StatsCounter(
 | 
				
			||||||
 | 
					                new AtomicInteger(0),
 | 
				
			||||||
 | 
					                metricsEnabled ?
 | 
				
			||||||
 | 
					                        meterRegistry.counter(key, STATS_NAME_TAG, statsName)
 | 
				
			||||||
 | 
					                        : STUB_COUNTER,
 | 
				
			||||||
 | 
					                statsName
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright © 2016-2020 The Thingsboard Authors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package org.thingsboard.server.service.stats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public enum StatsType {
 | 
				
			||||||
 | 
					    RULE_ENGINE("ruleEngine"), CORE("core"), TRANSPORT("transport"), JS_INVOKE("jsInvoke");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private String name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    StatsType(String name) {
 | 
				
			||||||
 | 
					        this.name = name;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getName() {
 | 
				
			||||||
 | 
					        return name;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -29,6 +29,10 @@ import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestM
 | 
				
			|||||||
import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg;
 | 
					import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg;
 | 
				
			||||||
import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
 | 
					import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
 | 
				
			||||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
					import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
				
			||||||
 | 
					import org.thingsboard.server.service.stats.DefaultQueueStats;
 | 
				
			||||||
 | 
					import org.thingsboard.server.service.stats.StatsCounter;
 | 
				
			||||||
 | 
					import org.thingsboard.server.service.stats.StatsCounterFactory;
 | 
				
			||||||
 | 
					import org.thingsboard.server.service.stats.StatsType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.PostConstruct;
 | 
					import javax.annotation.PostConstruct;
 | 
				
			||||||
import javax.annotation.PreDestroy;
 | 
					import javax.annotation.PreDestroy;
 | 
				
			||||||
@ -41,9 +45,13 @@ import java.util.concurrent.*;
 | 
				
			|||||||
@Service
 | 
					@Service
 | 
				
			||||||
@TbCoreComponent
 | 
					@TbCoreComponent
 | 
				
			||||||
public class TbCoreTransportApiService {
 | 
					public class TbCoreTransportApiService {
 | 
				
			||||||
 | 
					    private static final String TOTAL_MSGS = "totalMsgs";
 | 
				
			||||||
 | 
					    private static final String SUCCESSFUL_MSGS = "successfulMsgs";
 | 
				
			||||||
 | 
					    private static final String FAILED_MSGS = "failedMsgs";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final TbCoreQueueFactory tbCoreQueueFactory;
 | 
					    private final TbCoreQueueFactory tbCoreQueueFactory;
 | 
				
			||||||
    private final TransportApiService transportApiService;
 | 
					    private final TransportApiService transportApiService;
 | 
				
			||||||
 | 
					    private final StatsCounterFactory counterFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Value("${queue.transport_api.max_pending_requests:10000}")
 | 
					    @Value("${queue.transport_api.max_pending_requests:10000}")
 | 
				
			||||||
    private int maxPendingRequests;
 | 
					    private int maxPendingRequests;
 | 
				
			||||||
@ -58,9 +66,10 @@ public class TbCoreTransportApiService {
 | 
				
			|||||||
    private TbQueueResponseTemplate<TbProtoQueueMsg<TransportApiRequestMsg>,
 | 
					    private TbQueueResponseTemplate<TbProtoQueueMsg<TransportApiRequestMsg>,
 | 
				
			||||||
            TbProtoQueueMsg<TransportApiResponseMsg>> transportApiTemplate;
 | 
					            TbProtoQueueMsg<TransportApiResponseMsg>> transportApiTemplate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public TbCoreTransportApiService(TbCoreQueueFactory tbCoreQueueFactory, TransportApiService transportApiService) {
 | 
					    public TbCoreTransportApiService(TbCoreQueueFactory tbCoreQueueFactory, TransportApiService transportApiService, StatsCounterFactory counterFactory) {
 | 
				
			||||||
        this.tbCoreQueueFactory = tbCoreQueueFactory;
 | 
					        this.tbCoreQueueFactory = tbCoreQueueFactory;
 | 
				
			||||||
        this.transportApiService = transportApiService;
 | 
					        this.transportApiService = transportApiService;
 | 
				
			||||||
 | 
					        this.counterFactory = counterFactory;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @PostConstruct
 | 
					    @PostConstruct
 | 
				
			||||||
@ -69,6 +78,12 @@ public class TbCoreTransportApiService {
 | 
				
			|||||||
        TbQueueProducer<TbProtoQueueMsg<TransportApiResponseMsg>> producer = tbCoreQueueFactory.createTransportApiResponseProducer();
 | 
					        TbQueueProducer<TbProtoQueueMsg<TransportApiResponseMsg>> producer = tbCoreQueueFactory.createTransportApiResponseProducer();
 | 
				
			||||||
        TbQueueConsumer<TbProtoQueueMsg<TransportApiRequestMsg>> consumer = tbCoreQueueFactory.createTransportApiRequestConsumer();
 | 
					        TbQueueConsumer<TbProtoQueueMsg<TransportApiRequestMsg>> consumer = tbCoreQueueFactory.createTransportApiRequestConsumer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String key = StatsType.TRANSPORT.getName();
 | 
				
			||||||
 | 
					        StatsCounter totalCounter = counterFactory.createStatsCounter(key, TOTAL_MSGS);
 | 
				
			||||||
 | 
					        StatsCounter successfulCounter = counterFactory.createStatsCounter(key, SUCCESSFUL_MSGS);
 | 
				
			||||||
 | 
					        StatsCounter failedCounter = counterFactory.createStatsCounter(key, FAILED_MSGS);
 | 
				
			||||||
 | 
					        DefaultQueueStats queueStats = new DefaultQueueStats(totalCounter, successfulCounter, failedCounter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DefaultTbQueueResponseTemplate.DefaultTbQueueResponseTemplateBuilder
 | 
					        DefaultTbQueueResponseTemplate.DefaultTbQueueResponseTemplateBuilder
 | 
				
			||||||
                <TbProtoQueueMsg<TransportApiRequestMsg>, TbProtoQueueMsg<TransportApiResponseMsg>> builder = DefaultTbQueueResponseTemplate.builder();
 | 
					                <TbProtoQueueMsg<TransportApiRequestMsg>, TbProtoQueueMsg<TransportApiResponseMsg>> builder = DefaultTbQueueResponseTemplate.builder();
 | 
				
			||||||
        builder.requestTemplate(consumer);
 | 
					        builder.requestTemplate(consumer);
 | 
				
			||||||
@ -78,6 +93,7 @@ public class TbCoreTransportApiService {
 | 
				
			|||||||
        builder.pollInterval(responsePollDuration);
 | 
					        builder.pollInterval(responsePollDuration);
 | 
				
			||||||
        builder.executor(transportCallbackExecutor);
 | 
					        builder.executor(transportCallbackExecutor);
 | 
				
			||||||
        builder.handler(transportApiService);
 | 
					        builder.handler(transportApiService);
 | 
				
			||||||
 | 
					        builder.stats(queueStats);
 | 
				
			||||||
        transportApiTemplate = builder.build();
 | 
					        transportApiTemplate = builder.build();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -754,3 +754,13 @@ service:
 | 
				
			|||||||
  id: "${TB_SERVICE_ID:}"
 | 
					  id: "${TB_SERVICE_ID:}"
 | 
				
			||||||
  tenant_id: "${TB_SERVICE_TENANT_ID:}" # empty or specific tenant id.
 | 
					  tenant_id: "${TB_SERVICE_TENANT_ID:}" # empty or specific tenant id.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					metrics:
 | 
				
			||||||
 | 
					  # Enable/disable actuator metrics.
 | 
				
			||||||
 | 
					  enabled: "${METRICS_ENABLED:false}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					management:
 | 
				
			||||||
 | 
					  endpoints:
 | 
				
			||||||
 | 
					    web:
 | 
				
			||||||
 | 
					      exposure:
 | 
				
			||||||
 | 
					        # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics).
 | 
				
			||||||
 | 
					        include: '${METRICS_ENDPOINTS_EXPOSE:info}'
 | 
				
			||||||
@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright © 2016-2020 The Thingsboard Authors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package org.thingsboard.server.actors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public interface JsInvokeStats {
 | 
				
			||||||
 | 
					    default void incrementRequests() {
 | 
				
			||||||
 | 
					        incrementRequests(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void incrementRequests(int amount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    default void incrementResponses() {
 | 
				
			||||||
 | 
					        incrementResponses(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void incrementResponses(int amount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    default void incrementFailures() {
 | 
				
			||||||
 | 
					        incrementFailures(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void incrementFailures(int amount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int getRequests();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int getResponses();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int getFailures();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void reset();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -23,6 +23,7 @@ import org.thingsboard.server.queue.TbQueueHandler;
 | 
				
			|||||||
import org.thingsboard.server.queue.TbQueueMsg;
 | 
					import org.thingsboard.server.queue.TbQueueMsg;
 | 
				
			||||||
import org.thingsboard.server.queue.TbQueueProducer;
 | 
					import org.thingsboard.server.queue.TbQueueProducer;
 | 
				
			||||||
import org.thingsboard.server.queue.TbQueueResponseTemplate;
 | 
					import org.thingsboard.server.queue.TbQueueResponseTemplate;
 | 
				
			||||||
 | 
					import org.thingsboard.server.queue.stats.QueueStats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.UUID;
 | 
					import java.util.UUID;
 | 
				
			||||||
@ -44,6 +45,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response
 | 
				
			|||||||
    private final ExecutorService loopExecutor;
 | 
					    private final ExecutorService loopExecutor;
 | 
				
			||||||
    private final ScheduledExecutorService timeoutExecutor;
 | 
					    private final ScheduledExecutorService timeoutExecutor;
 | 
				
			||||||
    private final ExecutorService callbackExecutor;
 | 
					    private final ExecutorService callbackExecutor;
 | 
				
			||||||
 | 
					    private final QueueStats stats;
 | 
				
			||||||
    private final int maxPendingRequests;
 | 
					    private final int maxPendingRequests;
 | 
				
			||||||
    private final long requestTimeout;
 | 
					    private final long requestTimeout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -58,7 +60,8 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response
 | 
				
			|||||||
                                          long pollInterval,
 | 
					                                          long pollInterval,
 | 
				
			||||||
                                          long requestTimeout,
 | 
					                                          long requestTimeout,
 | 
				
			||||||
                                          int maxPendingRequests,
 | 
					                                          int maxPendingRequests,
 | 
				
			||||||
                                          ExecutorService executor) {
 | 
					                                          ExecutorService executor,
 | 
				
			||||||
 | 
					                                          QueueStats stats) {
 | 
				
			||||||
        this.requestTemplate = requestTemplate;
 | 
					        this.requestTemplate = requestTemplate;
 | 
				
			||||||
        this.responseTemplate = responseTemplate;
 | 
					        this.responseTemplate = responseTemplate;
 | 
				
			||||||
        this.pendingRequests = new ConcurrentHashMap<>();
 | 
					        this.pendingRequests = new ConcurrentHashMap<>();
 | 
				
			||||||
@ -66,6 +69,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response
 | 
				
			|||||||
        this.pollInterval = pollInterval;
 | 
					        this.pollInterval = pollInterval;
 | 
				
			||||||
        this.requestTimeout = requestTimeout;
 | 
					        this.requestTimeout = requestTimeout;
 | 
				
			||||||
        this.callbackExecutor = executor;
 | 
					        this.callbackExecutor = executor;
 | 
				
			||||||
 | 
					        this.stats = stats;
 | 
				
			||||||
        this.timeoutExecutor = Executors.newSingleThreadScheduledExecutor();
 | 
					        this.timeoutExecutor = Executors.newSingleThreadScheduledExecutor();
 | 
				
			||||||
        this.loopExecutor = Executors.newSingleThreadExecutor();
 | 
					        this.loopExecutor = Executors.newSingleThreadExecutor();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -108,11 +112,13 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response
 | 
				
			|||||||
                            String responseTopic = bytesToString(responseTopicHeader);
 | 
					                            String responseTopic = bytesToString(responseTopicHeader);
 | 
				
			||||||
                            try {
 | 
					                            try {
 | 
				
			||||||
                                pendingRequestCount.getAndIncrement();
 | 
					                                pendingRequestCount.getAndIncrement();
 | 
				
			||||||
 | 
					                                stats.incrementTotal();
 | 
				
			||||||
                                AsyncCallbackTemplate.withCallbackAndTimeout(handler.handle(request),
 | 
					                                AsyncCallbackTemplate.withCallbackAndTimeout(handler.handle(request),
 | 
				
			||||||
                                        response -> {
 | 
					                                        response -> {
 | 
				
			||||||
                                            pendingRequestCount.decrementAndGet();
 | 
					                                            pendingRequestCount.decrementAndGet();
 | 
				
			||||||
                                            response.getHeaders().put(REQUEST_ID_HEADER, uuidToBytes(requestId));
 | 
					                                            response.getHeaders().put(REQUEST_ID_HEADER, uuidToBytes(requestId));
 | 
				
			||||||
                                            responseTemplate.send(TopicPartitionInfo.builder().topic(responseTopic).build(), response, null);
 | 
					                                            responseTemplate.send(TopicPartitionInfo.builder().topic(responseTopic).build(), response, null);
 | 
				
			||||||
 | 
					                                            stats.incrementSuccessful();
 | 
				
			||||||
                                        },
 | 
					                                        },
 | 
				
			||||||
                                        e -> {
 | 
					                                        e -> {
 | 
				
			||||||
                                            pendingRequestCount.decrementAndGet();
 | 
					                                            pendingRequestCount.decrementAndGet();
 | 
				
			||||||
@ -121,6 +127,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response
 | 
				
			|||||||
                                            } else {
 | 
					                                            } else {
 | 
				
			||||||
                                                log.trace("[{}] Failed to process the request: {}", requestId, request, e);
 | 
					                                                log.trace("[{}] Failed to process the request: {}", requestId, request, e);
 | 
				
			||||||
                                            }
 | 
					                                            }
 | 
				
			||||||
 | 
					                                            stats.incrementFailed();
 | 
				
			||||||
                                        },
 | 
					                                        },
 | 
				
			||||||
                                        requestTimeout,
 | 
					                                        requestTimeout,
 | 
				
			||||||
                                        timeoutExecutor,
 | 
					                                        timeoutExecutor,
 | 
				
			||||||
@ -128,6 +135,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response
 | 
				
			|||||||
                            } catch (Throwable e) {
 | 
					                            } catch (Throwable e) {
 | 
				
			||||||
                                pendingRequestCount.decrementAndGet();
 | 
					                                pendingRequestCount.decrementAndGet();
 | 
				
			||||||
                                log.warn("[{}] Failed to process the request: {}", requestId, request, e);
 | 
					                                log.warn("[{}] Failed to process the request: {}", requestId, request, e);
 | 
				
			||||||
 | 
					                                stats.incrementFailed();
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright © 2016-2020 The Thingsboard Authors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package org.thingsboard.server.queue.stats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public interface QueueStats {
 | 
				
			||||||
 | 
					    default void incrementTotal() {
 | 
				
			||||||
 | 
					        incrementTotal(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void incrementTotal(int amount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    default void incrementSuccessful() {
 | 
				
			||||||
 | 
					        incrementSuccessful(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void incrementSuccessful(int amount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    default void incrementFailed() {
 | 
				
			||||||
 | 
					        incrementFailed(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void incrementFailed(int amount);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										16
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								pom.xml
									
									
									
									
									
								
							@ -105,6 +105,7 @@
 | 
				
			|||||||
        <ua-parser.version>1.4.3</ua-parser.version>
 | 
					        <ua-parser.version>1.4.3</ua-parser.version>
 | 
				
			||||||
        <commons-beanutils.version>1.9.4</commons-beanutils.version>
 | 
					        <commons-beanutils.version>1.9.4</commons-beanutils.version>
 | 
				
			||||||
        <commons-collections.version>3.2.2</commons-collections.version>
 | 
					        <commons-collections.version>3.2.2</commons-collections.version>
 | 
				
			||||||
 | 
					        <micrometer.version>1.5.2</micrometer.version>
 | 
				
			||||||
    </properties>
 | 
					    </properties>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <modules>
 | 
					    <modules>
 | 
				
			||||||
@ -1371,6 +1372,21 @@
 | 
				
			|||||||
                <artifactId>struts-tiles</artifactId>
 | 
					                <artifactId>struts-tiles</artifactId>
 | 
				
			||||||
                <version>${struts.version}</version>
 | 
					                <version>${struts.version}</version>
 | 
				
			||||||
            </dependency>
 | 
					            </dependency>
 | 
				
			||||||
 | 
					            <dependency>
 | 
				
			||||||
 | 
					                <groupId>org.springframework.boot</groupId>
 | 
				
			||||||
 | 
					                <artifactId>spring-boot-starter-actuator</artifactId>
 | 
				
			||||||
 | 
					                <version>${spring-boot.version}</version>
 | 
				
			||||||
 | 
					            </dependency>
 | 
				
			||||||
 | 
					            <dependency>
 | 
				
			||||||
 | 
					                <groupId>io.micrometer</groupId>
 | 
				
			||||||
 | 
					                <artifactId>micrometer-core</artifactId>
 | 
				
			||||||
 | 
					                <version>${micrometer.version}</version>
 | 
				
			||||||
 | 
					            </dependency>
 | 
				
			||||||
 | 
					            <dependency>
 | 
				
			||||||
 | 
					                <groupId>io.micrometer</groupId>
 | 
				
			||||||
 | 
					                <artifactId>micrometer-registry-prometheus</artifactId>
 | 
				
			||||||
 | 
					                <version>${micrometer.version}</version>
 | 
				
			||||||
 | 
					            </dependency>
 | 
				
			||||||
        </dependencies>
 | 
					        </dependencies>
 | 
				
			||||||
    </dependencyManagement>
 | 
					    </dependencyManagement>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user