Commit 89419c6999cc7b960d6f40fbb6e9b785a81c38dd
Committed by
GitHub
1 parent
7d739dfa
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
Showing
20 changed files
with
598 additions
and
96 deletions
@@ -298,6 +298,18 @@ | @@ -298,6 +298,18 @@ | ||
298 | <groupId>com.github.ua-parser</groupId> | 298 | <groupId>com.github.ua-parser</groupId> |
299 | <artifactId>uap-java</artifactId> | 299 | <artifactId>uap-java</artifactId> |
300 | </dependency> | 300 | </dependency> |
301 | + <dependency> | ||
302 | + <groupId>org.springframework.boot</groupId> | ||
303 | + <artifactId>spring-boot-starter-actuator</artifactId> | ||
304 | + </dependency> | ||
305 | + <dependency> | ||
306 | + <groupId>io.micrometer</groupId> | ||
307 | + <artifactId>micrometer-core</artifactId> | ||
308 | + </dependency> | ||
309 | + <dependency> | ||
310 | + <groupId>io.micrometer</groupId> | ||
311 | + <artifactId>micrometer-registry-prometheus</artifactId> | ||
312 | + </dependency> | ||
301 | </dependencies> | 313 | </dependencies> |
302 | 314 | ||
303 | <build> | 315 | <build> |
@@ -219,6 +219,10 @@ public class ActorSystemContext { | @@ -219,6 +219,10 @@ public class ActorSystemContext { | ||
219 | @Getter | 219 | @Getter |
220 | private ClaimDevicesService claimDevicesService; | 220 | private ClaimDevicesService claimDevicesService; |
221 | 221 | ||
222 | + @Autowired | ||
223 | + @Getter | ||
224 | + private JsInvokeStats jsInvokeStats; | ||
225 | + | ||
222 | //TODO: separate context for TbCore and TbRuleEngine | 226 | //TODO: separate context for TbCore and TbRuleEngine |
223 | @Autowired(required = false) | 227 | @Autowired(required = false) |
224 | @Getter | 228 | @Getter |
@@ -272,19 +276,14 @@ public class ActorSystemContext { | @@ -272,19 +276,14 @@ public class ActorSystemContext { | ||
272 | @Getter | 276 | @Getter |
273 | private long statisticsPersistFrequency; | 277 | private long statisticsPersistFrequency; |
274 | 278 | ||
275 | - @Getter | ||
276 | - private final AtomicInteger jsInvokeRequestsCount = new AtomicInteger(0); | ||
277 | - @Getter | ||
278 | - private final AtomicInteger jsInvokeResponsesCount = new AtomicInteger(0); | ||
279 | - @Getter | ||
280 | - private final AtomicInteger jsInvokeFailuresCount = new AtomicInteger(0); | ||
281 | 279 | ||
282 | @Scheduled(fixedDelayString = "${actors.statistics.js_print_interval_ms}") | 280 | @Scheduled(fixedDelayString = "${actors.statistics.js_print_interval_ms}") |
283 | public void printStats() { | 281 | public void printStats() { |
284 | if (statisticsEnabled) { | 282 | if (statisticsEnabled) { |
285 | - if (jsInvokeRequestsCount.get() > 0 || jsInvokeResponsesCount.get() > 0 || jsInvokeFailuresCount.get() > 0) { | 283 | + if (jsInvokeStats.getRequests() > 0 || jsInvokeStats.getResponses() > 0 || jsInvokeStats.getFailures() > 0) { |
286 | log.info("Rule Engine JS Invoke Stats: requests [{}] responses [{}] failures [{}]", | 284 | log.info("Rule Engine JS Invoke Stats: requests [{}] responses [{}] failures [{}]", |
287 | - jsInvokeRequestsCount.getAndSet(0), jsInvokeResponsesCount.getAndSet(0), jsInvokeFailuresCount.getAndSet(0)); | 285 | + jsInvokeStats.getRequests(), jsInvokeStats.getResponses(), jsInvokeStats.getFailures()); |
286 | + jsInvokeStats.reset(); | ||
288 | } | 287 | } |
289 | } | 288 | } |
290 | } | 289 | } |
@@ -292,21 +292,21 @@ class DefaultTbContext implements TbContext { | @@ -292,21 +292,21 @@ class DefaultTbContext implements TbContext { | ||
292 | @Override | 292 | @Override |
293 | public void logJsEvalRequest() { | 293 | public void logJsEvalRequest() { |
294 | if (mainCtx.isStatisticsEnabled()) { | 294 | if (mainCtx.isStatisticsEnabled()) { |
295 | - mainCtx.getJsInvokeRequestsCount().incrementAndGet(); | 295 | + mainCtx.getJsInvokeStats().incrementRequests(); |
296 | } | 296 | } |
297 | } | 297 | } |
298 | 298 | ||
299 | @Override | 299 | @Override |
300 | public void logJsEvalResponse() { | 300 | public void logJsEvalResponse() { |
301 | if (mainCtx.isStatisticsEnabled()) { | 301 | if (mainCtx.isStatisticsEnabled()) { |
302 | - mainCtx.getJsInvokeResponsesCount().incrementAndGet(); | 302 | + mainCtx.getJsInvokeStats().incrementResponses(); |
303 | } | 303 | } |
304 | } | 304 | } |
305 | 305 | ||
306 | @Override | 306 | @Override |
307 | public void logJsEvalFailure() { | 307 | public void logJsEvalFailure() { |
308 | if (mainCtx.isStatisticsEnabled()) { | 308 | if (mainCtx.isStatisticsEnabled()) { |
309 | - mainCtx.getJsInvokeFailuresCount().incrementAndGet(); | 309 | + mainCtx.getJsInvokeStats().incrementFailures(); |
310 | } | 310 | } |
311 | } | 311 | } |
312 | 312 |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.service.metrics; | ||
17 | + | ||
18 | +import io.micrometer.core.instrument.Counter; | ||
19 | + | ||
20 | +public class StubCounter implements Counter { | ||
21 | + @Override | ||
22 | + public void increment(double amount) {} | ||
23 | + | ||
24 | + @Override | ||
25 | + public double count() { | ||
26 | + return 0; | ||
27 | + } | ||
28 | + | ||
29 | + @Override | ||
30 | + public Id getId() { | ||
31 | + return null; | ||
32 | + } | ||
33 | +} |
@@ -26,16 +26,7 @@ import org.thingsboard.server.common.msg.MsgType; | @@ -26,16 +26,7 @@ import org.thingsboard.server.common.msg.MsgType; | ||
26 | import org.thingsboard.server.common.msg.TbActorMsg; | 26 | import org.thingsboard.server.common.msg.TbActorMsg; |
27 | import org.thingsboard.server.common.msg.queue.ServiceType; | 27 | import org.thingsboard.server.common.msg.queue.ServiceType; |
28 | import org.thingsboard.server.common.msg.queue.TbCallback; | 28 | import org.thingsboard.server.common.msg.queue.TbCallback; |
29 | -import org.thingsboard.server.gen.transport.TransportProtos.DeviceStateServiceMsgProto; | ||
30 | -import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto; | ||
31 | -import org.thingsboard.server.gen.transport.TransportProtos.LocalSubscriptionServiceMsgProto; | ||
32 | -import org.thingsboard.server.gen.transport.TransportProtos.SubscriptionMgrMsgProto; | ||
33 | -import org.thingsboard.server.gen.transport.TransportProtos.TbAttributeUpdateProto; | ||
34 | -import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionCloseProto; | ||
35 | -import org.thingsboard.server.gen.transport.TransportProtos.TbTimeSeriesUpdateProto; | ||
36 | -import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; | ||
37 | -import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; | ||
38 | -import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; | 29 | +import org.thingsboard.server.gen.transport.TransportProtos.*; |
39 | import org.thingsboard.server.queue.TbQueueConsumer; | 30 | import org.thingsboard.server.queue.TbQueueConsumer; |
40 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 31 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
41 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; | 32 | import org.thingsboard.server.queue.discovery.PartitionChangeEvent; |
@@ -47,6 +38,7 @@ import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | @@ -47,6 +38,7 @@ import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | ||
47 | import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; | 38 | import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; |
48 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; | 39 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; |
49 | import org.thingsboard.server.service.state.DeviceStateService; | 40 | import org.thingsboard.server.service.state.DeviceStateService; |
41 | +import org.thingsboard.server.service.stats.StatsCounterFactory; | ||
50 | import org.thingsboard.server.service.subscription.SubscriptionManagerService; | 42 | import org.thingsboard.server.service.subscription.SubscriptionManagerService; |
51 | import org.thingsboard.server.service.subscription.TbLocalSubscriptionService; | 43 | import org.thingsboard.server.service.subscription.TbLocalSubscriptionService; |
52 | import org.thingsboard.server.service.subscription.TbSubscriptionUtils; | 44 | import org.thingsboard.server.service.subscription.TbSubscriptionUtils; |
@@ -81,18 +73,19 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | @@ -81,18 +73,19 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | ||
81 | private final TbLocalSubscriptionService localSubscriptionService; | 73 | private final TbLocalSubscriptionService localSubscriptionService; |
82 | private final SubscriptionManagerService subscriptionManagerService; | 74 | private final SubscriptionManagerService subscriptionManagerService; |
83 | private final TbCoreDeviceRpcService tbCoreDeviceRpcService; | 75 | private final TbCoreDeviceRpcService tbCoreDeviceRpcService; |
84 | - private final TbCoreConsumerStats stats = new TbCoreConsumerStats(); | 76 | + private final TbCoreConsumerStats stats; |
85 | 77 | ||
86 | public DefaultTbCoreConsumerService(TbCoreQueueFactory tbCoreQueueFactory, ActorSystemContext actorContext, | 78 | public DefaultTbCoreConsumerService(TbCoreQueueFactory tbCoreQueueFactory, ActorSystemContext actorContext, |
87 | DeviceStateService stateService, TbLocalSubscriptionService localSubscriptionService, | 79 | DeviceStateService stateService, TbLocalSubscriptionService localSubscriptionService, |
88 | SubscriptionManagerService subscriptionManagerService, DataDecodingEncodingService encodingService, | 80 | SubscriptionManagerService subscriptionManagerService, DataDecodingEncodingService encodingService, |
89 | - TbCoreDeviceRpcService tbCoreDeviceRpcService) { | 81 | + TbCoreDeviceRpcService tbCoreDeviceRpcService, StatsCounterFactory counterFactory) { |
90 | super(actorContext, encodingService, tbCoreQueueFactory.createToCoreNotificationsMsgConsumer()); | 82 | super(actorContext, encodingService, tbCoreQueueFactory.createToCoreNotificationsMsgConsumer()); |
91 | this.mainConsumer = tbCoreQueueFactory.createToCoreMsgConsumer(); | 83 | this.mainConsumer = tbCoreQueueFactory.createToCoreMsgConsumer(); |
92 | this.stateService = stateService; | 84 | this.stateService = stateService; |
93 | this.localSubscriptionService = localSubscriptionService; | 85 | this.localSubscriptionService = localSubscriptionService; |
94 | this.subscriptionManagerService = subscriptionManagerService; | 86 | this.subscriptionManagerService = subscriptionManagerService; |
95 | this.tbCoreDeviceRpcService = tbCoreDeviceRpcService; | 87 | this.tbCoreDeviceRpcService = tbCoreDeviceRpcService; |
88 | + this.stats = new TbCoreConsumerStats(counterFactory); | ||
96 | } | 89 | } |
97 | 90 | ||
98 | @PostConstruct | 91 | @PostConstruct |
@@ -228,6 +221,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | @@ -228,6 +221,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | ||
228 | public void printStats() { | 221 | public void printStats() { |
229 | if (statsEnabled) { | 222 | if (statsEnabled) { |
230 | stats.printStats(); | 223 | stats.printStats(); |
224 | + stats.reset(); | ||
231 | } | 225 | } |
232 | } | 226 | } |
233 | 227 |
@@ -52,6 +52,7 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrateg | @@ -52,6 +52,7 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrateg | ||
52 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | 52 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; |
53 | import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService; | 53 | import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService; |
54 | import org.thingsboard.server.service.stats.RuleEngineStatisticsService; | 54 | import org.thingsboard.server.service.stats.RuleEngineStatisticsService; |
55 | +import org.thingsboard.server.service.stats.StatsCounterFactory; | ||
55 | 56 | ||
56 | import javax.annotation.PostConstruct; | 57 | import javax.annotation.PostConstruct; |
57 | import javax.annotation.PreDestroy; | 58 | import javax.annotation.PreDestroy; |
@@ -79,6 +80,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -79,6 +80,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
79 | @Value("${queue.rule-engine.stats.enabled:true}") | 80 | @Value("${queue.rule-engine.stats.enabled:true}") |
80 | private boolean statsEnabled; | 81 | private boolean statsEnabled; |
81 | 82 | ||
83 | + private final StatsCounterFactory counterFactory; | ||
82 | private final TbRuleEngineSubmitStrategyFactory submitStrategyFactory; | 84 | private final TbRuleEngineSubmitStrategyFactory submitStrategyFactory; |
83 | private final TbRuleEngineProcessingStrategyFactory processingStrategyFactory; | 85 | private final TbRuleEngineProcessingStrategyFactory processingStrategyFactory; |
84 | private final TbRuleEngineQueueFactory tbRuleEngineQueueFactory; | 86 | private final TbRuleEngineQueueFactory tbRuleEngineQueueFactory; |
@@ -95,7 +97,8 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -95,7 +97,8 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
95 | TbQueueRuleEngineSettings ruleEngineSettings, | 97 | TbQueueRuleEngineSettings ruleEngineSettings, |
96 | TbRuleEngineQueueFactory tbRuleEngineQueueFactory, RuleEngineStatisticsService statisticsService, | 98 | TbRuleEngineQueueFactory tbRuleEngineQueueFactory, RuleEngineStatisticsService statisticsService, |
97 | ActorSystemContext actorContext, DataDecodingEncodingService encodingService, | 99 | ActorSystemContext actorContext, DataDecodingEncodingService encodingService, |
98 | - TbRuleEngineDeviceRpcService tbDeviceRpcService) { | 100 | + TbRuleEngineDeviceRpcService tbDeviceRpcService, |
101 | + StatsCounterFactory counterFactory) { | ||
99 | super(actorContext, encodingService, tbRuleEngineQueueFactory.createToRuleEngineNotificationsMsgConsumer()); | 102 | super(actorContext, encodingService, tbRuleEngineQueueFactory.createToRuleEngineNotificationsMsgConsumer()); |
100 | this.statisticsService = statisticsService; | 103 | this.statisticsService = statisticsService; |
101 | this.ruleEngineSettings = ruleEngineSettings; | 104 | this.ruleEngineSettings = ruleEngineSettings; |
@@ -103,6 +106,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -103,6 +106,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
103 | this.submitStrategyFactory = submitStrategyFactory; | 106 | this.submitStrategyFactory = submitStrategyFactory; |
104 | this.processingStrategyFactory = processingStrategyFactory; | 107 | this.processingStrategyFactory = processingStrategyFactory; |
105 | this.tbDeviceRpcService = tbDeviceRpcService; | 108 | this.tbDeviceRpcService = tbDeviceRpcService; |
109 | + this.counterFactory = counterFactory; | ||
106 | } | 110 | } |
107 | 111 | ||
108 | @PostConstruct | 112 | @PostConstruct |
@@ -111,7 +115,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -111,7 +115,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
111 | for (TbRuleEngineQueueConfiguration configuration : ruleEngineSettings.getQueues()) { | 115 | for (TbRuleEngineQueueConfiguration configuration : ruleEngineSettings.getQueues()) { |
112 | consumerConfigurations.putIfAbsent(configuration.getName(), configuration); | 116 | consumerConfigurations.putIfAbsent(configuration.getName(), configuration); |
113 | consumers.computeIfAbsent(configuration.getName(), queueName -> tbRuleEngineQueueFactory.createToRuleEngineMsgConsumer(configuration)); | 117 | consumers.computeIfAbsent(configuration.getName(), queueName -> tbRuleEngineQueueFactory.createToRuleEngineMsgConsumer(configuration)); |
114 | - consumerStats.put(configuration.getName(), new TbRuleEngineConsumerStats(configuration.getName())); | 118 | + consumerStats.put(configuration.getName(), new TbRuleEngineConsumerStats(configuration.getName(), counterFactory)); |
115 | } | 119 | } |
116 | submitExecutor = Executors.newSingleThreadExecutor(); | 120 | submitExecutor = Executors.newSingleThreadExecutor(); |
117 | } | 121 | } |
@@ -269,6 +273,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | @@ -269,6 +273,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< | ||
269 | consumerStats.forEach((queue, stats) -> { | 273 | consumerStats.forEach((queue, stats) -> { |
270 | stats.printStats(); | 274 | stats.printStats(); |
271 | statisticsService.reportQueueStats(ts, stats); | 275 | statisticsService.reportQueueStats(ts, stats); |
276 | + stats.reset(); | ||
272 | }); | 277 | }); |
273 | } | 278 | } |
274 | } | 279 | } |
@@ -17,76 +17,124 @@ package org.thingsboard.server.service.queue; | @@ -17,76 +17,124 @@ package org.thingsboard.server.service.queue; | ||
17 | 17 | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | import org.thingsboard.server.gen.transport.TransportProtos; | 19 | import org.thingsboard.server.gen.transport.TransportProtos; |
20 | +import org.thingsboard.server.service.stats.StatsCounter; | ||
21 | +import org.thingsboard.server.service.stats.StatsCounterFactory; | ||
22 | +import org.thingsboard.server.service.stats.StatsType; | ||
20 | 23 | ||
24 | +import java.util.*; | ||
21 | import java.util.concurrent.atomic.AtomicInteger; | 25 | import java.util.concurrent.atomic.AtomicInteger; |
22 | 26 | ||
23 | @Slf4j | 27 | @Slf4j |
24 | public class TbCoreConsumerStats { | 28 | public class TbCoreConsumerStats { |
29 | + public static final String TOTAL_MSGS = "totalMsgs"; | ||
30 | + public static final String SESSION_EVENTS = "sessionEvents"; | ||
31 | + public static final String GET_ATTRIBUTE = "getAttr"; | ||
32 | + public static final String ATTRIBUTE_SUBSCRIBES = "subToAttr"; | ||
33 | + public static final String RPC_SUBSCRIBES = "subToRpc"; | ||
34 | + public static final String TO_DEVICE_RPC_CALL_RESPONSES = "toDevRpc"; | ||
35 | + public static final String SUBSCRIPTION_INFO = "subInfo"; | ||
36 | + public static final String DEVICE_CLAIMS = "claimDevice"; | ||
37 | + public static final String DEVICE_STATES = "deviceState"; | ||
38 | + public static final String SUBSCRIPTION_MSGS = "subMsgs"; | ||
39 | + public static final String TO_CORE_NOTIFICATIONS = "coreNfs"; | ||
25 | 40 | ||
26 | - private final AtomicInteger totalCounter = new AtomicInteger(0); | ||
27 | - private final AtomicInteger sessionEventCounter = new AtomicInteger(0); | ||
28 | - private final AtomicInteger getAttributesCounter = new AtomicInteger(0); | ||
29 | - private final AtomicInteger subscribeToAttributesCounter = new AtomicInteger(0); | ||
30 | - private final AtomicInteger subscribeToRPCCounter = new AtomicInteger(0); | ||
31 | - private final AtomicInteger toDeviceRPCCallResponseCounter = new AtomicInteger(0); | ||
32 | - private final AtomicInteger subscriptionInfoCounter = new AtomicInteger(0); | ||
33 | - private final AtomicInteger claimDeviceCounter = new AtomicInteger(0); | 41 | + private final StatsCounter totalCounter; |
42 | + private final StatsCounter sessionEventCounter; | ||
43 | + private final StatsCounter getAttributesCounter; | ||
44 | + private final StatsCounter subscribeToAttributesCounter; | ||
45 | + private final StatsCounter subscribeToRPCCounter; | ||
46 | + private final StatsCounter toDeviceRPCCallResponseCounter; | ||
47 | + private final StatsCounter subscriptionInfoCounter; | ||
48 | + private final StatsCounter claimDeviceCounter; | ||
34 | 49 | ||
35 | - private final AtomicInteger deviceStateCounter = new AtomicInteger(0); | ||
36 | - private final AtomicInteger subscriptionMsgCounter = new AtomicInteger(0); | ||
37 | - private final AtomicInteger toCoreNotificationsCounter = new AtomicInteger(0); | 50 | + private final StatsCounter deviceStateCounter; |
51 | + private final StatsCounter subscriptionMsgCounter; | ||
52 | + private final StatsCounter toCoreNotificationsCounter; | ||
53 | + | ||
54 | + private final List<StatsCounter> counters = new ArrayList<>(); | ||
55 | + | ||
56 | + public TbCoreConsumerStats(StatsCounterFactory counterFactory) { | ||
57 | + String statsKey = StatsType.CORE.getName(); | ||
58 | + | ||
59 | + this.totalCounter = counterFactory.createStatsCounter(statsKey, TOTAL_MSGS); | ||
60 | + this.sessionEventCounter = counterFactory.createStatsCounter(statsKey, SESSION_EVENTS); | ||
61 | + this.getAttributesCounter = counterFactory.createStatsCounter(statsKey, GET_ATTRIBUTE); | ||
62 | + this.subscribeToAttributesCounter = counterFactory.createStatsCounter(statsKey, ATTRIBUTE_SUBSCRIBES); | ||
63 | + this.subscribeToRPCCounter = counterFactory.createStatsCounter(statsKey, RPC_SUBSCRIBES); | ||
64 | + this.toDeviceRPCCallResponseCounter = counterFactory.createStatsCounter(statsKey, TO_DEVICE_RPC_CALL_RESPONSES); | ||
65 | + this.subscriptionInfoCounter = counterFactory.createStatsCounter(statsKey, SUBSCRIPTION_INFO); | ||
66 | + this.claimDeviceCounter = counterFactory.createStatsCounter(statsKey, DEVICE_CLAIMS); | ||
67 | + this.deviceStateCounter = counterFactory.createStatsCounter(statsKey, DEVICE_STATES); | ||
68 | + this.subscriptionMsgCounter = counterFactory.createStatsCounter(statsKey, SUBSCRIPTION_MSGS); | ||
69 | + this.toCoreNotificationsCounter = counterFactory.createStatsCounter(statsKey, TO_CORE_NOTIFICATIONS); | ||
70 | + | ||
71 | + | ||
72 | + counters.add(totalCounter); | ||
73 | + counters.add(sessionEventCounter); | ||
74 | + counters.add(getAttributesCounter); | ||
75 | + counters.add(subscribeToAttributesCounter); | ||
76 | + counters.add(subscribeToRPCCounter); | ||
77 | + counters.add(toDeviceRPCCallResponseCounter); | ||
78 | + counters.add(subscriptionInfoCounter); | ||
79 | + counters.add(claimDeviceCounter); | ||
80 | + | ||
81 | + counters.add(deviceStateCounter); | ||
82 | + counters.add(subscriptionMsgCounter); | ||
83 | + counters.add(toCoreNotificationsCounter); | ||
84 | + } | ||
38 | 85 | ||
39 | public void log(TransportProtos.TransportToDeviceActorMsg msg) { | 86 | public void log(TransportProtos.TransportToDeviceActorMsg msg) { |
40 | - totalCounter.incrementAndGet(); | 87 | + totalCounter.increment(); |
41 | if (msg.hasSessionEvent()) { | 88 | if (msg.hasSessionEvent()) { |
42 | - sessionEventCounter.incrementAndGet(); | 89 | + sessionEventCounter.increment(); |
43 | } | 90 | } |
44 | if (msg.hasGetAttributes()) { | 91 | if (msg.hasGetAttributes()) { |
45 | - getAttributesCounter.incrementAndGet(); | 92 | + getAttributesCounter.increment(); |
46 | } | 93 | } |
47 | if (msg.hasSubscribeToAttributes()) { | 94 | if (msg.hasSubscribeToAttributes()) { |
48 | - subscribeToAttributesCounter.incrementAndGet(); | 95 | + subscribeToAttributesCounter.increment(); |
49 | } | 96 | } |
50 | if (msg.hasSubscribeToRPC()) { | 97 | if (msg.hasSubscribeToRPC()) { |
51 | - subscribeToRPCCounter.incrementAndGet(); | 98 | + subscribeToRPCCounter.increment(); |
52 | } | 99 | } |
53 | if (msg.hasToDeviceRPCCallResponse()) { | 100 | if (msg.hasToDeviceRPCCallResponse()) { |
54 | - toDeviceRPCCallResponseCounter.incrementAndGet(); | 101 | + toDeviceRPCCallResponseCounter.increment(); |
55 | } | 102 | } |
56 | if (msg.hasSubscriptionInfo()) { | 103 | if (msg.hasSubscriptionInfo()) { |
57 | - subscriptionInfoCounter.incrementAndGet(); | 104 | + subscriptionInfoCounter.increment(); |
58 | } | 105 | } |
59 | if (msg.hasClaimDevice()) { | 106 | if (msg.hasClaimDevice()) { |
60 | - claimDeviceCounter.incrementAndGet(); | 107 | + claimDeviceCounter.increment(); |
61 | } | 108 | } |
62 | } | 109 | } |
63 | 110 | ||
64 | public void log(TransportProtos.DeviceStateServiceMsgProto msg) { | 111 | public void log(TransportProtos.DeviceStateServiceMsgProto msg) { |
65 | - totalCounter.incrementAndGet(); | ||
66 | - deviceStateCounter.incrementAndGet(); | 112 | + totalCounter.increment(); |
113 | + deviceStateCounter.increment(); | ||
67 | } | 114 | } |
68 | 115 | ||
69 | public void log(TransportProtos.SubscriptionMgrMsgProto msg) { | 116 | public void log(TransportProtos.SubscriptionMgrMsgProto msg) { |
70 | - totalCounter.incrementAndGet(); | ||
71 | - subscriptionMsgCounter.incrementAndGet(); | 117 | + totalCounter.increment(); |
118 | + subscriptionMsgCounter.increment(); | ||
72 | } | 119 | } |
73 | 120 | ||
74 | public void log(TransportProtos.ToCoreNotificationMsg msg) { | 121 | public void log(TransportProtos.ToCoreNotificationMsg msg) { |
75 | - totalCounter.incrementAndGet(); | ||
76 | - toCoreNotificationsCounter.incrementAndGet(); | 122 | + totalCounter.increment(); |
123 | + toCoreNotificationsCounter.increment(); | ||
77 | } | 124 | } |
78 | 125 | ||
79 | public void printStats() { | 126 | public void printStats() { |
80 | - int total = totalCounter.getAndSet(0); | 127 | + int total = totalCounter.get(); |
81 | if (total > 0) { | 128 | if (total > 0) { |
82 | - log.info("Total [{}] sessionEvents [{}] getAttr [{}] subToAttr [{}] subToRpc [{}] toDevRpc [{}] subInfo [{}] claimDevice [{}]" + | ||
83 | - " deviceState [{}] subMgr [{}] coreNfs [{}]", | ||
84 | - total, sessionEventCounter.getAndSet(0), | ||
85 | - getAttributesCounter.getAndSet(0), subscribeToAttributesCounter.getAndSet(0), | ||
86 | - subscribeToRPCCounter.getAndSet(0), toDeviceRPCCallResponseCounter.getAndSet(0), | ||
87 | - subscriptionInfoCounter.getAndSet(0), claimDeviceCounter.getAndSet(0) | ||
88 | - , deviceStateCounter.getAndSet(0), subscriptionMsgCounter.getAndSet(0), toCoreNotificationsCounter.getAndSet(0)); | 129 | + StringBuilder stats = new StringBuilder(); |
130 | + counters.forEach(counter -> { | ||
131 | + stats.append(counter.getName()).append(" = [").append(counter.get()).append("] "); | ||
132 | + }); | ||
133 | + log.info("Core Stats: {}", stats); | ||
89 | } | 134 | } |
90 | } | 135 | } |
91 | 136 | ||
137 | + public void reset() { | ||
138 | + counters.forEach(StatsCounter::clear); | ||
139 | + } | ||
92 | } | 140 | } |
@@ -22,16 +22,16 @@ import org.thingsboard.server.common.msg.queue.RuleEngineException; | @@ -22,16 +22,16 @@ import org.thingsboard.server.common.msg.queue.RuleEngineException; | ||
22 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; | 22 | import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; |
23 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 23 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
24 | import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingResult; | 24 | import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingResult; |
25 | +import org.thingsboard.server.service.stats.StatsCounter; | ||
26 | +import org.thingsboard.server.service.stats.StatsCounterFactory; | ||
27 | +import org.thingsboard.server.service.stats.StatsType; | ||
25 | 28 | ||
26 | -import java.util.HashMap; | ||
27 | -import java.util.Map; | ||
28 | -import java.util.UUID; | 29 | +import java.util.*; |
29 | import java.util.concurrent.ConcurrentHashMap; | 30 | import java.util.concurrent.ConcurrentHashMap; |
30 | import java.util.concurrent.ConcurrentMap; | 31 | import java.util.concurrent.ConcurrentMap; |
31 | import java.util.concurrent.atomic.AtomicInteger; | 32 | import java.util.concurrent.atomic.AtomicInteger; |
32 | 33 | ||
33 | @Slf4j | 34 | @Slf4j |
34 | -@Data | ||
35 | public class TbRuleEngineConsumerStats { | 35 | public class TbRuleEngineConsumerStats { |
36 | 36 | ||
37 | public static final String TOTAL_MSGS = "totalMsgs"; | 37 | public static final String TOTAL_MSGS = "totalMsgs"; |
@@ -43,61 +43,72 @@ public class TbRuleEngineConsumerStats { | @@ -43,61 +43,72 @@ public class TbRuleEngineConsumerStats { | ||
43 | public static final String SUCCESSFUL_ITERATIONS = "successfulIterations"; | 43 | public static final String SUCCESSFUL_ITERATIONS = "successfulIterations"; |
44 | public static final String FAILED_ITERATIONS = "failedIterations"; | 44 | public static final String FAILED_ITERATIONS = "failedIterations"; |
45 | 45 | ||
46 | - private final AtomicInteger totalMsgCounter = new AtomicInteger(0); | ||
47 | - private final AtomicInteger successMsgCounter = new AtomicInteger(0); | ||
48 | - private final AtomicInteger tmpTimeoutMsgCounter = new AtomicInteger(0); | ||
49 | - private final AtomicInteger tmpFailedMsgCounter = new AtomicInteger(0); | 46 | + private final StatsCounter totalMsgCounter; |
47 | + private final StatsCounter successMsgCounter; | ||
48 | + private final StatsCounter tmpTimeoutMsgCounter; | ||
49 | + private final StatsCounter tmpFailedMsgCounter; | ||
50 | 50 | ||
51 | - private final AtomicInteger timeoutMsgCounter = new AtomicInteger(0); | ||
52 | - private final AtomicInteger failedMsgCounter = new AtomicInteger(0); | 51 | + private final StatsCounter timeoutMsgCounter; |
52 | + private final StatsCounter failedMsgCounter; | ||
53 | 53 | ||
54 | - private final AtomicInteger successIterationsCounter = new AtomicInteger(0); | ||
55 | - private final AtomicInteger failedIterationsCounter = new AtomicInteger(0); | 54 | + private final StatsCounter successIterationsCounter; |
55 | + private final StatsCounter failedIterationsCounter; | ||
56 | 56 | ||
57 | - private final Map<String, AtomicInteger> counters = new HashMap<>(); | 57 | + private final List<StatsCounter> counters = new ArrayList<>(); |
58 | private final ConcurrentMap<UUID, TbTenantRuleEngineStats> tenantStats = new ConcurrentHashMap<>(); | 58 | private final ConcurrentMap<UUID, TbTenantRuleEngineStats> tenantStats = new ConcurrentHashMap<>(); |
59 | private final ConcurrentMap<TenantId, RuleEngineException> tenantExceptions = new ConcurrentHashMap<>(); | 59 | private final ConcurrentMap<TenantId, RuleEngineException> tenantExceptions = new ConcurrentHashMap<>(); |
60 | 60 | ||
61 | private final String queueName; | 61 | private final String queueName; |
62 | 62 | ||
63 | - public TbRuleEngineConsumerStats(String queueName) { | 63 | + public TbRuleEngineConsumerStats(String queueName, StatsCounterFactory counterFactory) { |
64 | this.queueName = queueName; | 64 | this.queueName = queueName; |
65 | - counters.put(TOTAL_MSGS, totalMsgCounter); | ||
66 | - counters.put(SUCCESSFUL_MSGS, successMsgCounter); | ||
67 | - counters.put(TIMEOUT_MSGS, timeoutMsgCounter); | ||
68 | - counters.put(FAILED_MSGS, failedMsgCounter); | ||
69 | - | ||
70 | - counters.put(TMP_TIMEOUT, tmpTimeoutMsgCounter); | ||
71 | - counters.put(TMP_FAILED, tmpFailedMsgCounter); | ||
72 | - counters.put(SUCCESSFUL_ITERATIONS, successIterationsCounter); | ||
73 | - counters.put(FAILED_ITERATIONS, failedIterationsCounter); | 65 | + |
66 | + String statsKey = StatsType.RULE_ENGINE.getName() + "." + queueName; | ||
67 | + this.totalMsgCounter = counterFactory.createStatsCounter(statsKey, TOTAL_MSGS); | ||
68 | + this.successMsgCounter = counterFactory.createStatsCounter(statsKey, SUCCESSFUL_MSGS); | ||
69 | + this.timeoutMsgCounter = counterFactory.createStatsCounter(statsKey, TIMEOUT_MSGS); | ||
70 | + this.failedMsgCounter = counterFactory.createStatsCounter(statsKey, FAILED_MSGS); | ||
71 | + this.tmpTimeoutMsgCounter = counterFactory.createStatsCounter(statsKey, TMP_TIMEOUT); | ||
72 | + this.tmpFailedMsgCounter = counterFactory.createStatsCounter(statsKey, TMP_FAILED); | ||
73 | + this.successIterationsCounter = counterFactory.createStatsCounter(statsKey, SUCCESSFUL_ITERATIONS); | ||
74 | + this.failedIterationsCounter = counterFactory.createStatsCounter(statsKey, FAILED_ITERATIONS); | ||
75 | + | ||
76 | + counters.add(totalMsgCounter); | ||
77 | + counters.add(successMsgCounter); | ||
78 | + counters.add(timeoutMsgCounter); | ||
79 | + counters.add(failedMsgCounter); | ||
80 | + | ||
81 | + counters.add(tmpTimeoutMsgCounter); | ||
82 | + counters.add(tmpFailedMsgCounter); | ||
83 | + counters.add(successIterationsCounter); | ||
84 | + counters.add(failedIterationsCounter); | ||
74 | } | 85 | } |
75 | 86 | ||
76 | public void log(TbRuleEngineProcessingResult msg, boolean finalIterationForPack) { | 87 | public void log(TbRuleEngineProcessingResult msg, boolean finalIterationForPack) { |
77 | int success = msg.getSuccessMap().size(); | 88 | int success = msg.getSuccessMap().size(); |
78 | int pending = msg.getPendingMap().size(); | 89 | int pending = msg.getPendingMap().size(); |
79 | int failed = msg.getFailedMap().size(); | 90 | int failed = msg.getFailedMap().size(); |
80 | - totalMsgCounter.addAndGet(success + pending + failed); | ||
81 | - successMsgCounter.addAndGet(success); | 91 | + totalMsgCounter.add(success + pending + failed); |
92 | + successMsgCounter.add(success); | ||
82 | msg.getSuccessMap().values().forEach(m -> getTenantStats(m).logSuccess()); | 93 | msg.getSuccessMap().values().forEach(m -> getTenantStats(m).logSuccess()); |
83 | if (finalIterationForPack) { | 94 | if (finalIterationForPack) { |
84 | if (pending > 0 || failed > 0) { | 95 | if (pending > 0 || failed > 0) { |
85 | - timeoutMsgCounter.addAndGet(pending); | ||
86 | - failedMsgCounter.addAndGet(failed); | 96 | + timeoutMsgCounter.add(pending); |
97 | + failedMsgCounter.add(failed); | ||
87 | if (pending > 0) { | 98 | if (pending > 0) { |
88 | msg.getPendingMap().values().forEach(m -> getTenantStats(m).logTimeout()); | 99 | msg.getPendingMap().values().forEach(m -> getTenantStats(m).logTimeout()); |
89 | } | 100 | } |
90 | if (failed > 0) { | 101 | if (failed > 0) { |
91 | msg.getFailedMap().values().forEach(m -> getTenantStats(m).logFailed()); | 102 | msg.getFailedMap().values().forEach(m -> getTenantStats(m).logFailed()); |
92 | } | 103 | } |
93 | - failedIterationsCounter.incrementAndGet(); | 104 | + failedIterationsCounter.increment(); |
94 | } else { | 105 | } else { |
95 | - successIterationsCounter.incrementAndGet(); | 106 | + successIterationsCounter.increment(); |
96 | } | 107 | } |
97 | } else { | 108 | } else { |
98 | - failedIterationsCounter.incrementAndGet(); | ||
99 | - tmpTimeoutMsgCounter.addAndGet(pending); | ||
100 | - tmpFailedMsgCounter.addAndGet(failed); | 109 | + failedIterationsCounter.increment(); |
110 | + tmpTimeoutMsgCounter.add(pending); | ||
111 | + tmpFailedMsgCounter.add(failed); | ||
101 | if (pending > 0) { | 112 | if (pending > 0) { |
102 | msg.getPendingMap().values().forEach(m -> getTenantStats(m).logTmpTimeout()); | 113 | msg.getPendingMap().values().forEach(m -> getTenantStats(m).logTmpTimeout()); |
103 | } | 114 | } |
@@ -113,19 +124,31 @@ public class TbRuleEngineConsumerStats { | @@ -113,19 +124,31 @@ public class TbRuleEngineConsumerStats { | ||
113 | return tenantStats.computeIfAbsent(new UUID(reMsg.getTenantIdMSB(), reMsg.getTenantIdLSB()), TbTenantRuleEngineStats::new); | 124 | return tenantStats.computeIfAbsent(new UUID(reMsg.getTenantIdMSB(), reMsg.getTenantIdLSB()), TbTenantRuleEngineStats::new); |
114 | } | 125 | } |
115 | 126 | ||
127 | + public ConcurrentMap<UUID, TbTenantRuleEngineStats> getTenantStats() { | ||
128 | + return tenantStats; | ||
129 | + } | ||
130 | + | ||
131 | + public String getQueueName() { | ||
132 | + return queueName; | ||
133 | + } | ||
134 | + | ||
135 | + public ConcurrentMap<TenantId, RuleEngineException> getTenantExceptions() { | ||
136 | + return tenantExceptions; | ||
137 | + } | ||
138 | + | ||
116 | public void printStats() { | 139 | public void printStats() { |
117 | int total = totalMsgCounter.get(); | 140 | int total = totalMsgCounter.get(); |
118 | if (total > 0) { | 141 | if (total > 0) { |
119 | StringBuilder stats = new StringBuilder(); | 142 | StringBuilder stats = new StringBuilder(); |
120 | - counters.forEach((label, value) -> { | ||
121 | - stats.append(label).append(" = [").append(value.get()).append("] "); | 143 | + counters.forEach(counter -> { |
144 | + stats.append(counter.getName()).append(" = [").append(counter.get()).append("] "); | ||
122 | }); | 145 | }); |
123 | log.info("[{}] Stats: {}", queueName, stats); | 146 | log.info("[{}] Stats: {}", queueName, stats); |
124 | } | 147 | } |
125 | } | 148 | } |
126 | 149 | ||
127 | public void reset() { | 150 | public void reset() { |
128 | - counters.values().forEach(counter -> counter.set(0)); | 151 | + counters.forEach(StatsCounter::clear); |
129 | tenantStats.clear(); | 152 | tenantStats.clear(); |
130 | tenantExceptions.clear(); | 153 | tenantExceptions.clear(); |
131 | } | 154 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.service.stats; | ||
17 | + | ||
18 | +import org.springframework.beans.factory.annotation.Autowired; | ||
19 | +import org.springframework.stereotype.Service; | ||
20 | +import org.thingsboard.server.actors.JsInvokeStats; | ||
21 | + | ||
22 | +import javax.annotation.PostConstruct; | ||
23 | + | ||
24 | +@Service | ||
25 | +public class DefaultJsInvokeStats implements JsInvokeStats { | ||
26 | + private static final String REQUESTS = "requests"; | ||
27 | + private static final String RESPONSES = "responses"; | ||
28 | + private static final String FAILURES = "failures"; | ||
29 | + | ||
30 | + private StatsCounter requestsCounter; | ||
31 | + private StatsCounter responsesCounter; | ||
32 | + private StatsCounter failuresCounter; | ||
33 | + | ||
34 | + @Autowired | ||
35 | + private StatsCounterFactory counterFactory; | ||
36 | + | ||
37 | + @PostConstruct | ||
38 | + public void init() { | ||
39 | + String key = StatsType.JS_INVOKE.getName(); | ||
40 | + this.requestsCounter = counterFactory.createStatsCounter(key, REQUESTS); | ||
41 | + this.responsesCounter = counterFactory.createStatsCounter(key, RESPONSES); | ||
42 | + this.failuresCounter = counterFactory.createStatsCounter(key, FAILURES); | ||
43 | + } | ||
44 | + | ||
45 | + @Override | ||
46 | + public void incrementRequests(int amount) { | ||
47 | + requestsCounter.add(amount); | ||
48 | + } | ||
49 | + | ||
50 | + @Override | ||
51 | + public void incrementResponses(int amount) { | ||
52 | + responsesCounter.add(amount); | ||
53 | + } | ||
54 | + | ||
55 | + @Override | ||
56 | + public void incrementFailures(int amount) { | ||
57 | + failuresCounter.add(amount); | ||
58 | + } | ||
59 | + | ||
60 | + @Override | ||
61 | + public int getRequests() { | ||
62 | + return requestsCounter.get(); | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
66 | + public int getResponses() { | ||
67 | + return responsesCounter.get(); | ||
68 | + } | ||
69 | + | ||
70 | + @Override | ||
71 | + public int getFailures() { | ||
72 | + return failuresCounter.get(); | ||
73 | + } | ||
74 | + | ||
75 | + @Override | ||
76 | + public void reset() { | ||
77 | + requestsCounter.clear(); | ||
78 | + responsesCounter.clear(); | ||
79 | + failuresCounter.clear(); | ||
80 | + } | ||
81 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.service.stats; | ||
17 | + | ||
18 | +import org.thingsboard.server.queue.stats.QueueStats; | ||
19 | + | ||
20 | +public class DefaultQueueStats implements QueueStats { | ||
21 | + private final StatsCounter totalCounter; | ||
22 | + private final StatsCounter successfulCounter; | ||
23 | + private final StatsCounter failedCounter; | ||
24 | + | ||
25 | + public DefaultQueueStats(StatsCounter totalCounter, StatsCounter successfulCounter, StatsCounter failedCounter) { | ||
26 | + this.totalCounter = totalCounter; | ||
27 | + this.successfulCounter = successfulCounter; | ||
28 | + this.failedCounter = failedCounter; | ||
29 | + } | ||
30 | + | ||
31 | + @Override | ||
32 | + public void incrementTotal(int amount) { | ||
33 | + totalCounter.add(amount); | ||
34 | + } | ||
35 | + | ||
36 | + @Override | ||
37 | + public void incrementSuccessful(int amount) { | ||
38 | + successfulCounter.add(amount); | ||
39 | + } | ||
40 | + | ||
41 | + @Override | ||
42 | + public void incrementFailed(int amount) { | ||
43 | + failedCounter.add(amount); | ||
44 | + } | ||
45 | +} |
@@ -104,7 +104,6 @@ public class DefaultRuleEngineStatisticsService implements RuleEngineStatisticsS | @@ -104,7 +104,6 @@ public class DefaultRuleEngineStatisticsService implements RuleEngineStatisticsS | ||
104 | } | 104 | } |
105 | } | 105 | } |
106 | }); | 106 | }); |
107 | - ruleEngineStats.reset(); | ||
108 | } | 107 | } |
109 | 108 | ||
110 | private AssetId getServiceAssetId(TenantId tenantId, String queueName) { | 109 | private AssetId getServiceAssetId(TenantId tenantId, String queueName) { |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.service.stats; | ||
17 | + | ||
18 | +import io.micrometer.core.instrument.Counter; | ||
19 | + | ||
20 | +import java.util.concurrent.atomic.AtomicInteger; | ||
21 | + | ||
22 | +public class StatsCounter { | ||
23 | + private final AtomicInteger aiCounter; | ||
24 | + private final Counter micrometerCounter; | ||
25 | + private final String name; | ||
26 | + | ||
27 | + public StatsCounter(AtomicInteger aiCounter, Counter micrometerCounter, String name) { | ||
28 | + this.aiCounter = aiCounter; | ||
29 | + this.micrometerCounter = micrometerCounter; | ||
30 | + this.name = name; | ||
31 | + } | ||
32 | + | ||
33 | + public void increment() { | ||
34 | + aiCounter.incrementAndGet(); | ||
35 | + micrometerCounter.increment(); | ||
36 | + } | ||
37 | + | ||
38 | + public void clear() { | ||
39 | + aiCounter.set(0); | ||
40 | + } | ||
41 | + | ||
42 | + public int get() { | ||
43 | + return aiCounter.get(); | ||
44 | + } | ||
45 | + | ||
46 | + public void add(int delta){ | ||
47 | + aiCounter.addAndGet(delta); | ||
48 | + micrometerCounter.increment(delta); | ||
49 | + } | ||
50 | + | ||
51 | + public String getName() { | ||
52 | + return name; | ||
53 | + } | ||
54 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.service.stats; | ||
17 | + | ||
18 | +import io.micrometer.core.instrument.Counter; | ||
19 | +import io.micrometer.core.instrument.MeterRegistry; | ||
20 | +import org.springframework.beans.factory.annotation.Autowired; | ||
21 | +import org.springframework.beans.factory.annotation.Value; | ||
22 | +import org.springframework.stereotype.Service; | ||
23 | +import org.thingsboard.server.service.metrics.StubCounter; | ||
24 | + | ||
25 | +import java.util.concurrent.atomic.AtomicInteger; | ||
26 | + | ||
27 | +@Service | ||
28 | +public class StatsCounterFactory { | ||
29 | + private static final String STATS_NAME_TAG = "statsName"; | ||
30 | + | ||
31 | + private static final Counter STUB_COUNTER = new StubCounter(); | ||
32 | + | ||
33 | + @Autowired | ||
34 | + private MeterRegistry meterRegistry; | ||
35 | + | ||
36 | + @Value("${metrics.enabled}") | ||
37 | + private Boolean metricsEnabled; | ||
38 | + | ||
39 | + public StatsCounter createStatsCounter(String key, String statsName) { | ||
40 | + return new StatsCounter( | ||
41 | + new AtomicInteger(0), | ||
42 | + metricsEnabled ? | ||
43 | + meterRegistry.counter(key, STATS_NAME_TAG, statsName) | ||
44 | + : STUB_COUNTER, | ||
45 | + statsName | ||
46 | + ); | ||
47 | + } | ||
48 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.service.stats; | ||
17 | + | ||
18 | +public enum StatsType { | ||
19 | + RULE_ENGINE("ruleEngine"), CORE("core"), TRANSPORT("transport"), JS_INVOKE("jsInvoke"); | ||
20 | + | ||
21 | + private String name; | ||
22 | + | ||
23 | + StatsType(String name) { | ||
24 | + this.name = name; | ||
25 | + } | ||
26 | + | ||
27 | + public String getName() { | ||
28 | + return name; | ||
29 | + } | ||
30 | +} |
@@ -29,6 +29,10 @@ import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestM | @@ -29,6 +29,10 @@ import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestM | ||
29 | import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg; | 29 | import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponseMsg; |
30 | import org.thingsboard.server.queue.provider.TbCoreQueueFactory; | 30 | import org.thingsboard.server.queue.provider.TbCoreQueueFactory; |
31 | import org.thingsboard.server.queue.util.TbCoreComponent; | 31 | import org.thingsboard.server.queue.util.TbCoreComponent; |
32 | +import org.thingsboard.server.service.stats.DefaultQueueStats; | ||
33 | +import org.thingsboard.server.service.stats.StatsCounter; | ||
34 | +import org.thingsboard.server.service.stats.StatsCounterFactory; | ||
35 | +import org.thingsboard.server.service.stats.StatsType; | ||
32 | 36 | ||
33 | import javax.annotation.PostConstruct; | 37 | import javax.annotation.PostConstruct; |
34 | import javax.annotation.PreDestroy; | 38 | import javax.annotation.PreDestroy; |
@@ -41,9 +45,13 @@ import java.util.concurrent.*; | @@ -41,9 +45,13 @@ import java.util.concurrent.*; | ||
41 | @Service | 45 | @Service |
42 | @TbCoreComponent | 46 | @TbCoreComponent |
43 | public class TbCoreTransportApiService { | 47 | public class TbCoreTransportApiService { |
48 | + private static final String TOTAL_MSGS = "totalMsgs"; | ||
49 | + private static final String SUCCESSFUL_MSGS = "successfulMsgs"; | ||
50 | + private static final String FAILED_MSGS = "failedMsgs"; | ||
44 | 51 | ||
45 | private final TbCoreQueueFactory tbCoreQueueFactory; | 52 | private final TbCoreQueueFactory tbCoreQueueFactory; |
46 | private final TransportApiService transportApiService; | 53 | private final TransportApiService transportApiService; |
54 | + private final StatsCounterFactory counterFactory; | ||
47 | 55 | ||
48 | @Value("${queue.transport_api.max_pending_requests:10000}") | 56 | @Value("${queue.transport_api.max_pending_requests:10000}") |
49 | private int maxPendingRequests; | 57 | private int maxPendingRequests; |
@@ -58,9 +66,10 @@ public class TbCoreTransportApiService { | @@ -58,9 +66,10 @@ public class TbCoreTransportApiService { | ||
58 | private TbQueueResponseTemplate<TbProtoQueueMsg<TransportApiRequestMsg>, | 66 | private TbQueueResponseTemplate<TbProtoQueueMsg<TransportApiRequestMsg>, |
59 | TbProtoQueueMsg<TransportApiResponseMsg>> transportApiTemplate; | 67 | TbProtoQueueMsg<TransportApiResponseMsg>> transportApiTemplate; |
60 | 68 | ||
61 | - public TbCoreTransportApiService(TbCoreQueueFactory tbCoreQueueFactory, TransportApiService transportApiService) { | 69 | + public TbCoreTransportApiService(TbCoreQueueFactory tbCoreQueueFactory, TransportApiService transportApiService, StatsCounterFactory counterFactory) { |
62 | this.tbCoreQueueFactory = tbCoreQueueFactory; | 70 | this.tbCoreQueueFactory = tbCoreQueueFactory; |
63 | this.transportApiService = transportApiService; | 71 | this.transportApiService = transportApiService; |
72 | + this.counterFactory = counterFactory; | ||
64 | } | 73 | } |
65 | 74 | ||
66 | @PostConstruct | 75 | @PostConstruct |
@@ -69,6 +78,12 @@ public class TbCoreTransportApiService { | @@ -69,6 +78,12 @@ public class TbCoreTransportApiService { | ||
69 | TbQueueProducer<TbProtoQueueMsg<TransportApiResponseMsg>> producer = tbCoreQueueFactory.createTransportApiResponseProducer(); | 78 | TbQueueProducer<TbProtoQueueMsg<TransportApiResponseMsg>> producer = tbCoreQueueFactory.createTransportApiResponseProducer(); |
70 | TbQueueConsumer<TbProtoQueueMsg<TransportApiRequestMsg>> consumer = tbCoreQueueFactory.createTransportApiRequestConsumer(); | 79 | TbQueueConsumer<TbProtoQueueMsg<TransportApiRequestMsg>> consumer = tbCoreQueueFactory.createTransportApiRequestConsumer(); |
71 | 80 | ||
81 | + String key = StatsType.TRANSPORT.getName(); | ||
82 | + StatsCounter totalCounter = counterFactory.createStatsCounter(key, TOTAL_MSGS); | ||
83 | + StatsCounter successfulCounter = counterFactory.createStatsCounter(key, SUCCESSFUL_MSGS); | ||
84 | + StatsCounter failedCounter = counterFactory.createStatsCounter(key, FAILED_MSGS); | ||
85 | + DefaultQueueStats queueStats = new DefaultQueueStats(totalCounter, successfulCounter, failedCounter); | ||
86 | + | ||
72 | DefaultTbQueueResponseTemplate.DefaultTbQueueResponseTemplateBuilder | 87 | DefaultTbQueueResponseTemplate.DefaultTbQueueResponseTemplateBuilder |
73 | <TbProtoQueueMsg<TransportApiRequestMsg>, TbProtoQueueMsg<TransportApiResponseMsg>> builder = DefaultTbQueueResponseTemplate.builder(); | 88 | <TbProtoQueueMsg<TransportApiRequestMsg>, TbProtoQueueMsg<TransportApiResponseMsg>> builder = DefaultTbQueueResponseTemplate.builder(); |
74 | builder.requestTemplate(consumer); | 89 | builder.requestTemplate(consumer); |
@@ -78,6 +93,7 @@ public class TbCoreTransportApiService { | @@ -78,6 +93,7 @@ public class TbCoreTransportApiService { | ||
78 | builder.pollInterval(responsePollDuration); | 93 | builder.pollInterval(responsePollDuration); |
79 | builder.executor(transportCallbackExecutor); | 94 | builder.executor(transportCallbackExecutor); |
80 | builder.handler(transportApiService); | 95 | builder.handler(transportApiService); |
96 | + builder.stats(queueStats); | ||
81 | transportApiTemplate = builder.build(); | 97 | transportApiTemplate = builder.build(); |
82 | } | 98 | } |
83 | 99 |
@@ -754,3 +754,13 @@ service: | @@ -754,3 +754,13 @@ service: | ||
754 | id: "${TB_SERVICE_ID:}" | 754 | id: "${TB_SERVICE_ID:}" |
755 | tenant_id: "${TB_SERVICE_TENANT_ID:}" # empty or specific tenant id. | 755 | tenant_id: "${TB_SERVICE_TENANT_ID:}" # empty or specific tenant id. |
756 | 756 | ||
757 | +metrics: | ||
758 | + # Enable/disable actuator metrics. | ||
759 | + enabled: "${METRICS_ENABLED:false}" | ||
760 | + | ||
761 | +management: | ||
762 | + endpoints: | ||
763 | + web: | ||
764 | + exposure: | ||
765 | + # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). | ||
766 | + include: '${METRICS_ENDPOINTS_EXPOSE:info}' |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.actors; | ||
17 | + | ||
18 | +public interface JsInvokeStats { | ||
19 | + default void incrementRequests() { | ||
20 | + incrementRequests(1); | ||
21 | + } | ||
22 | + | ||
23 | + void incrementRequests(int amount); | ||
24 | + | ||
25 | + default void incrementResponses() { | ||
26 | + incrementResponses(1); | ||
27 | + } | ||
28 | + | ||
29 | + void incrementResponses(int amount); | ||
30 | + | ||
31 | + default void incrementFailures() { | ||
32 | + incrementFailures(1); | ||
33 | + } | ||
34 | + | ||
35 | + void incrementFailures(int amount); | ||
36 | + | ||
37 | + int getRequests(); | ||
38 | + | ||
39 | + int getResponses(); | ||
40 | + | ||
41 | + int getFailures(); | ||
42 | + | ||
43 | + void reset(); | ||
44 | +} |
@@ -23,6 +23,7 @@ import org.thingsboard.server.queue.TbQueueHandler; | @@ -23,6 +23,7 @@ import org.thingsboard.server.queue.TbQueueHandler; | ||
23 | import org.thingsboard.server.queue.TbQueueMsg; | 23 | import org.thingsboard.server.queue.TbQueueMsg; |
24 | import org.thingsboard.server.queue.TbQueueProducer; | 24 | import org.thingsboard.server.queue.TbQueueProducer; |
25 | import org.thingsboard.server.queue.TbQueueResponseTemplate; | 25 | import org.thingsboard.server.queue.TbQueueResponseTemplate; |
26 | +import org.thingsboard.server.queue.stats.QueueStats; | ||
26 | 27 | ||
27 | import java.util.List; | 28 | import java.util.List; |
28 | import java.util.UUID; | 29 | import java.util.UUID; |
@@ -44,6 +45,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | @@ -44,6 +45,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | ||
44 | private final ExecutorService loopExecutor; | 45 | private final ExecutorService loopExecutor; |
45 | private final ScheduledExecutorService timeoutExecutor; | 46 | private final ScheduledExecutorService timeoutExecutor; |
46 | private final ExecutorService callbackExecutor; | 47 | private final ExecutorService callbackExecutor; |
48 | + private final QueueStats stats; | ||
47 | private final int maxPendingRequests; | 49 | private final int maxPendingRequests; |
48 | private final long requestTimeout; | 50 | private final long requestTimeout; |
49 | 51 | ||
@@ -58,7 +60,8 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | @@ -58,7 +60,8 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | ||
58 | long pollInterval, | 60 | long pollInterval, |
59 | long requestTimeout, | 61 | long requestTimeout, |
60 | int maxPendingRequests, | 62 | int maxPendingRequests, |
61 | - ExecutorService executor) { | 63 | + ExecutorService executor, |
64 | + QueueStats stats) { | ||
62 | this.requestTemplate = requestTemplate; | 65 | this.requestTemplate = requestTemplate; |
63 | this.responseTemplate = responseTemplate; | 66 | this.responseTemplate = responseTemplate; |
64 | this.pendingRequests = new ConcurrentHashMap<>(); | 67 | this.pendingRequests = new ConcurrentHashMap<>(); |
@@ -66,6 +69,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | @@ -66,6 +69,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | ||
66 | this.pollInterval = pollInterval; | 69 | this.pollInterval = pollInterval; |
67 | this.requestTimeout = requestTimeout; | 70 | this.requestTimeout = requestTimeout; |
68 | this.callbackExecutor = executor; | 71 | this.callbackExecutor = executor; |
72 | + this.stats = stats; | ||
69 | this.timeoutExecutor = Executors.newSingleThreadScheduledExecutor(); | 73 | this.timeoutExecutor = Executors.newSingleThreadScheduledExecutor(); |
70 | this.loopExecutor = Executors.newSingleThreadExecutor(); | 74 | this.loopExecutor = Executors.newSingleThreadExecutor(); |
71 | } | 75 | } |
@@ -108,11 +112,13 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | @@ -108,11 +112,13 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | ||
108 | String responseTopic = bytesToString(responseTopicHeader); | 112 | String responseTopic = bytesToString(responseTopicHeader); |
109 | try { | 113 | try { |
110 | pendingRequestCount.getAndIncrement(); | 114 | pendingRequestCount.getAndIncrement(); |
115 | + stats.incrementTotal(); | ||
111 | AsyncCallbackTemplate.withCallbackAndTimeout(handler.handle(request), | 116 | AsyncCallbackTemplate.withCallbackAndTimeout(handler.handle(request), |
112 | response -> { | 117 | response -> { |
113 | pendingRequestCount.decrementAndGet(); | 118 | pendingRequestCount.decrementAndGet(); |
114 | response.getHeaders().put(REQUEST_ID_HEADER, uuidToBytes(requestId)); | 119 | response.getHeaders().put(REQUEST_ID_HEADER, uuidToBytes(requestId)); |
115 | responseTemplate.send(TopicPartitionInfo.builder().topic(responseTopic).build(), response, null); | 120 | responseTemplate.send(TopicPartitionInfo.builder().topic(responseTopic).build(), response, null); |
121 | + stats.incrementSuccessful(); | ||
116 | }, | 122 | }, |
117 | e -> { | 123 | e -> { |
118 | pendingRequestCount.decrementAndGet(); | 124 | pendingRequestCount.decrementAndGet(); |
@@ -121,6 +127,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | @@ -121,6 +127,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | ||
121 | } else { | 127 | } else { |
122 | log.trace("[{}] Failed to process the request: {}", requestId, request, e); | 128 | log.trace("[{}] Failed to process the request: {}", requestId, request, e); |
123 | } | 129 | } |
130 | + stats.incrementFailed(); | ||
124 | }, | 131 | }, |
125 | requestTimeout, | 132 | requestTimeout, |
126 | timeoutExecutor, | 133 | timeoutExecutor, |
@@ -128,6 +135,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | @@ -128,6 +135,7 @@ public class DefaultTbQueueResponseTemplate<Request extends TbQueueMsg, Response | ||
128 | } catch (Throwable e) { | 135 | } catch (Throwable e) { |
129 | pendingRequestCount.decrementAndGet(); | 136 | pendingRequestCount.decrementAndGet(); |
130 | log.warn("[{}] Failed to process the request: {}", requestId, request, e); | 137 | log.warn("[{}] Failed to process the request: {}", requestId, request, e); |
138 | + stats.incrementFailed(); | ||
131 | } | 139 | } |
132 | } | 140 | } |
133 | }); | 141 | }); |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.queue.stats; | ||
17 | + | ||
18 | +public interface QueueStats { | ||
19 | + default void incrementTotal() { | ||
20 | + incrementTotal(1); | ||
21 | + } | ||
22 | + | ||
23 | + void incrementTotal(int amount); | ||
24 | + | ||
25 | + default void incrementSuccessful() { | ||
26 | + incrementSuccessful(1); | ||
27 | + } | ||
28 | + | ||
29 | + void incrementSuccessful(int amount); | ||
30 | + | ||
31 | + | ||
32 | + default void incrementFailed() { | ||
33 | + incrementFailed(1); | ||
34 | + } | ||
35 | + | ||
36 | + void incrementFailed(int amount); | ||
37 | +} |
@@ -105,6 +105,7 @@ | @@ -105,6 +105,7 @@ | ||
105 | <ua-parser.version>1.4.3</ua-parser.version> | 105 | <ua-parser.version>1.4.3</ua-parser.version> |
106 | <commons-beanutils.version>1.9.4</commons-beanutils.version> | 106 | <commons-beanutils.version>1.9.4</commons-beanutils.version> |
107 | <commons-collections.version>3.2.2</commons-collections.version> | 107 | <commons-collections.version>3.2.2</commons-collections.version> |
108 | + <micrometer.version>1.5.2</micrometer.version> | ||
108 | </properties> | 109 | </properties> |
109 | 110 | ||
110 | <modules> | 111 | <modules> |
@@ -1371,6 +1372,21 @@ | @@ -1371,6 +1372,21 @@ | ||
1371 | <artifactId>struts-tiles</artifactId> | 1372 | <artifactId>struts-tiles</artifactId> |
1372 | <version>${struts.version}</version> | 1373 | <version>${struts.version}</version> |
1373 | </dependency> | 1374 | </dependency> |
1375 | + <dependency> | ||
1376 | + <groupId>org.springframework.boot</groupId> | ||
1377 | + <artifactId>spring-boot-starter-actuator</artifactId> | ||
1378 | + <version>${spring-boot.version}</version> | ||
1379 | + </dependency> | ||
1380 | + <dependency> | ||
1381 | + <groupId>io.micrometer</groupId> | ||
1382 | + <artifactId>micrometer-core</artifactId> | ||
1383 | + <version>${micrometer.version}</version> | ||
1384 | + </dependency> | ||
1385 | + <dependency> | ||
1386 | + <groupId>io.micrometer</groupId> | ||
1387 | + <artifactId>micrometer-registry-prometheus</artifactId> | ||
1388 | + <version>${micrometer.version}</version> | ||
1389 | + </dependency> | ||
1374 | </dependencies> | 1390 | </dependencies> |
1375 | </dependencyManagement> | 1391 | </dependencyManagement> |
1376 | 1392 |