2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard;
11 import akka.actor.ActorRef;
12 import akka.pattern.Patterns;
13 import akka.util.Timeout;
14 import com.google.common.base.Stopwatch;
15 import com.google.common.cache.Cache;
16 import com.google.common.cache.CacheBuilder;
17 import java.text.SimpleDateFormat;
18 import java.util.Date;
19 import java.util.List;
21 import java.util.concurrent.TimeUnit;
22 import java.util.concurrent.atomic.AtomicLong;
23 import org.opendaylight.controller.cluster.raft.client.messages.FollowerInfo;
24 import org.opendaylight.controller.cluster.raft.client.messages.GetOnDemandRaftState;
25 import org.opendaylight.controller.cluster.raft.client.messages.OnDemandRaftState;
26 import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
27 import org.opendaylight.controller.md.sal.common.util.jmx.QueuedNotificationManagerMXBeanImpl;
28 import org.opendaylight.controller.md.sal.common.util.jmx.ThreadExecutorStatsMXBeanImpl;
29 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
30 import org.opendaylight.yangtools.util.concurrent.QueuedNotificationManager;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33 import scala.concurrent.Await;
36 * Maintains statistics for a shard.
38 * @author Basheeruddin syedbahm@cisco.com
40 public class ShardStats extends AbstractMXBean implements ShardStatsMXBean {
41 public static String JMX_CATEGORY_SHARD = "Shards";
43 private static final Logger LOG = LoggerFactory.getLogger(ShardStats.class);
45 private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
47 private static final Cache<String, OnDemandRaftState> onDemandRaftStateCache =
48 CacheBuilder.newBuilder().expireAfterWrite(2, TimeUnit.SECONDS).build();
50 private long committedTransactionsCount;
52 private long readOnlyTransactionCount;
54 private long writeOnlyTransactionCount;
56 private long readWriteTransactionCount;
58 private long lastCommittedTransactionTime;
60 private long failedTransactionsCount;
62 private final AtomicLong failedReadTransactionsCount = new AtomicLong();
64 private long abortTransactionsCount;
66 private ThreadExecutorStatsMXBeanImpl notificationExecutorStatsBean;
68 private QueuedNotificationManagerMXBeanImpl notificationManagerStatsBean;
70 private boolean followerInitialSyncStatus = false;
72 private ActorRef shardActor;
74 private String statRetrievalError;
76 private String statRetrievalTime;
78 private long leadershipChangeCount;
80 private long lastLeadershipChangeTime;
82 public ShardStats(final String shardName, final String mxBeanType) {
83 super(shardName, mxBeanType, JMX_CATEGORY_SHARD);
86 public void setNotificationManager(final QueuedNotificationManager<?, ?> manager) {
87 this.notificationManagerStatsBean = new QueuedNotificationManagerMXBeanImpl(manager,
88 "notification-manager", getMBeanType(), getMBeanCategory());
90 this.notificationExecutorStatsBean = ThreadExecutorStatsMXBeanImpl.create(manager.getExecutor());
93 public void setShardActor(ActorRef shardActor) {
94 this.shardActor = shardActor;
97 private OnDemandRaftState getOnDemandRaftState() {
98 String name = getShardName();
99 OnDemandRaftState state = onDemandRaftStateCache.getIfPresent(name);
101 statRetrievalError = null;
102 statRetrievalTime = null;
104 if(shardActor != null) {
105 Timeout timeout = new Timeout(10, TimeUnit.SECONDS);
107 Stopwatch timer = Stopwatch.createStarted();
109 state = (OnDemandRaftState) Await.result(Patterns.ask(shardActor,
110 GetOnDemandRaftState.INSTANCE, timeout), timeout.duration());
112 statRetrievalTime = timer.stop().toString();
113 onDemandRaftStateCache.put(name, state);
114 } catch (Exception e) {
115 statRetrievalError = e.toString();
119 state = state != null ? state : OnDemandRaftState.builder().build();
126 public String getShardName() {
127 return getMBeanName();
131 public long getCommittedTransactionsCount() {
132 return committedTransactionsCount;
136 public String getLeader() {
137 return getOnDemandRaftState().getLeader();
141 public String getRaftState() {
142 return getOnDemandRaftState().getRaftState();
146 public long getReadOnlyTransactionCount() {
147 return readOnlyTransactionCount;
151 public long getWriteOnlyTransactionCount() {
152 return writeOnlyTransactionCount;
156 public long getReadWriteTransactionCount() {
157 return readWriteTransactionCount;
161 public long getLastLogIndex() {
162 return getOnDemandRaftState().getLastLogIndex();
166 public long getLastLogTerm() {
167 return getOnDemandRaftState().getLastLogTerm();
171 public long getCurrentTerm() {
172 return getOnDemandRaftState().getCurrentTerm();
176 public long getCommitIndex() {
177 return getOnDemandRaftState().getCommitIndex();
181 public long getLastApplied() {
182 return getOnDemandRaftState().getLastApplied();
186 public long getLastIndex() {
187 return getOnDemandRaftState().getLastIndex();
191 public long getLastTerm() {
192 return getOnDemandRaftState().getLastTerm();
196 public long getSnapshotIndex() {
197 return getOnDemandRaftState().getSnapshotIndex();
201 public long getSnapshotTerm() {
202 return getOnDemandRaftState().getSnapshotTerm();
206 public long getReplicatedToAllIndex() {
207 return getOnDemandRaftState().getReplicatedToAllIndex();
211 public String getVotedFor() {
212 return getOnDemandRaftState().getVotedFor();
216 public boolean isSnapshotCaptureInitiated() {
217 return getOnDemandRaftState().isSnapshotCaptureInitiated();
221 public String getLastCommittedTransactionTime() {
222 return DATE_FORMAT.format(new Date(lastCommittedTransactionTime));
226 public long getFailedTransactionsCount() {
227 return failedTransactionsCount;
231 public long getFailedReadTransactionsCount() {
232 return failedReadTransactionsCount.get();
236 public long getAbortTransactionsCount() {
237 return abortTransactionsCount;
240 public long incrementCommittedTransactionCount() {
241 return ++committedTransactionsCount;
244 public long incrementReadOnlyTransactionCount() {
245 return ++readOnlyTransactionCount;
248 public long incrementWriteOnlyTransactionCount() {
249 return ++writeOnlyTransactionCount;
252 public long incrementReadWriteTransactionCount() {
253 return ++readWriteTransactionCount;
256 public long incrementFailedTransactionsCount() {
257 return ++failedTransactionsCount;
260 public long incrementFailedReadTransactionsCount() {
261 return failedReadTransactionsCount.incrementAndGet();
264 public long incrementAbortTransactionsCount ()
266 return ++abortTransactionsCount;
269 public void setLastCommittedTransactionTime(final long lastCommittedTransactionTime) {
270 this.lastCommittedTransactionTime = lastCommittedTransactionTime;
274 public long getInMemoryJournalDataSize(){
275 return getOnDemandRaftState().getInMemoryJournalDataSize();
279 public long getInMemoryJournalLogSize() {
280 return getOnDemandRaftState().getInMemoryJournalLogSize();
284 * resets the counters related to transactions
287 public void resetTransactionCounters(){
288 committedTransactionsCount = 0;
290 readOnlyTransactionCount = 0;
292 writeOnlyTransactionCount = 0;
294 readWriteTransactionCount = 0;
296 lastCommittedTransactionTime = 0;
298 failedTransactionsCount = 0;
300 failedReadTransactionsCount.set(0);
302 abortTransactionsCount = 0;
306 public void setDataStore(final InMemoryDOMDataStore store) {
307 setNotificationManager(store.getDataChangeListenerNotificationManager());
310 public void setFollowerInitialSyncStatus(boolean followerInitialSyncStatus) {
311 this.followerInitialSyncStatus = followerInitialSyncStatus;
315 public boolean getFollowerInitialSyncStatus() {
316 return followerInitialSyncStatus;
320 public List<FollowerInfo> getFollowerInfo() {
321 return getOnDemandRaftState().getFollowerInfoList();
325 public String getPeerAddresses() {
326 StringBuilder builder = new StringBuilder();
328 for(Map.Entry<String, String> e: getOnDemandRaftState().getPeerAddresses().entrySet()) {
330 builder.append(", ");
333 builder.append(e.getKey()).append(": ").append(e.getValue());
336 return builder.toString();
340 public String getStatRetrievalTime() {
341 getOnDemandRaftState();
342 return statRetrievalTime;
346 public String getStatRetrievalError() {
347 getOnDemandRaftState();
348 return statRetrievalError;
352 public long getLeadershipChangeCount() {
353 return leadershipChangeCount;
356 public void incrementLeadershipChangeCount() {
357 leadershipChangeCount++;
358 lastLeadershipChangeTime = System.currentTimeMillis();
362 public String getLastLeadershipChangeTime() {
363 return DATE_FORMAT.format(new Date(lastLeadershipChangeTime));