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
8 package org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard;
10 import akka.actor.ActorRef;
11 import com.google.common.base.Joiner;
12 import com.google.common.base.Joiner.MapJoiner;
13 import java.text.SimpleDateFormat;
14 import java.util.Date;
15 import java.util.List;
16 import java.util.concurrent.atomic.AtomicLong;
17 import javax.annotation.concurrent.GuardedBy;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.opendaylight.controller.cluster.datastore.Shard;
20 import org.opendaylight.controller.cluster.raft.base.messages.InitiateCaptureSnapshot;
21 import org.opendaylight.controller.cluster.raft.client.messages.FollowerInfo;
22 import org.opendaylight.controller.cluster.raft.client.messages.OnDemandRaftState;
23 import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
26 * Maintains statistics for a shard.
28 * @author Basheeruddin syedbahm@cisco.com
30 public class ShardStats extends AbstractMXBean implements ShardStatsMXBean {
31 public static final String JMX_CATEGORY_SHARD = "Shards";
33 // FIXME: migrate this to Java 8 thread-safe time
34 @GuardedBy("DATE_FORMAT")
35 private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
37 private static final MapJoiner MAP_JOINER = Joiner.on(", ").withKeyValueSeparator(": ");
39 private final Shard shard;
41 private final OnDemandShardStateCache stateCache;
43 private long committedTransactionsCount;
45 private long readOnlyTransactionCount;
47 private long writeOnlyTransactionCount;
49 private long readWriteTransactionCount;
51 private long lastCommittedTransactionTime;
53 private long failedTransactionsCount;
55 private final AtomicLong failedReadTransactionsCount = new AtomicLong();
57 private long abortTransactionsCount;
59 private boolean followerInitialSyncStatus = false;
61 private String statRetrievalError;
63 private long leadershipChangeCount;
65 private long lastLeadershipChangeTime;
67 public ShardStats(final String shardName, final String mxBeanType, final @Nullable Shard shard) {
68 super(shardName, mxBeanType, JMX_CATEGORY_SHARD);
70 stateCache = new OnDemandShardStateCache(shardName, shard != null ? shard.self() : null);
73 @SuppressWarnings("checkstyle:IllegalCatch")
74 private OnDemandRaftState getOnDemandRaftState() {
76 final OnDemandRaftState state = stateCache.get();
77 statRetrievalError = null;
79 } catch (Exception e) {
80 statRetrievalError = e.getCause().toString();
81 return OnDemandRaftState.builder().build();
85 private static String formatMillis(final long timeMillis) {
86 synchronized (DATE_FORMAT) {
87 return DATE_FORMAT.format(new Date(timeMillis));
92 public String getShardName() {
93 return getMBeanName();
97 public long getCommittedTransactionsCount() {
98 return committedTransactionsCount;
102 public String getLeader() {
103 return getOnDemandRaftState().getLeader();
107 public String getRaftState() {
108 return getOnDemandRaftState().getRaftState();
112 public long getReadOnlyTransactionCount() {
113 return readOnlyTransactionCount;
117 public long getWriteOnlyTransactionCount() {
118 return writeOnlyTransactionCount;
122 public long getReadWriteTransactionCount() {
123 return readWriteTransactionCount;
127 public long getLastLogIndex() {
128 return getOnDemandRaftState().getLastLogIndex();
132 public long getLastLogTerm() {
133 return getOnDemandRaftState().getLastLogTerm();
137 public long getCurrentTerm() {
138 return getOnDemandRaftState().getCurrentTerm();
142 public long getCommitIndex() {
143 return getOnDemandRaftState().getCommitIndex();
147 public long getLastApplied() {
148 return getOnDemandRaftState().getLastApplied();
152 public long getLastIndex() {
153 return getOnDemandRaftState().getLastIndex();
157 public long getLastTerm() {
158 return getOnDemandRaftState().getLastTerm();
162 public long getSnapshotIndex() {
163 return getOnDemandRaftState().getSnapshotIndex();
167 public long getSnapshotTerm() {
168 return getOnDemandRaftState().getSnapshotTerm();
172 public long getReplicatedToAllIndex() {
173 return getOnDemandRaftState().getReplicatedToAllIndex();
177 public String getVotedFor() {
178 return getOnDemandRaftState().getVotedFor();
182 public boolean isVoting() {
183 return getOnDemandRaftState().isVoting();
187 public String getPeerVotingStates() {
188 return MAP_JOINER.join(getOnDemandRaftState().getPeerVotingStates());
192 public boolean isSnapshotCaptureInitiated() {
193 return getOnDemandRaftState().isSnapshotCaptureInitiated();
197 public String getLastCommittedTransactionTime() {
198 return formatMillis(lastCommittedTransactionTime);
202 public long getFailedTransactionsCount() {
203 return failedTransactionsCount;
207 public long getFailedReadTransactionsCount() {
208 return failedReadTransactionsCount.get();
212 public long getAbortTransactionsCount() {
213 return abortTransactionsCount;
216 public long incrementCommittedTransactionCount() {
217 return ++committedTransactionsCount;
220 public long incrementReadOnlyTransactionCount() {
221 return ++readOnlyTransactionCount;
224 public long incrementWriteOnlyTransactionCount() {
225 return ++writeOnlyTransactionCount;
228 public long incrementReadWriteTransactionCount() {
229 return ++readWriteTransactionCount;
232 public long incrementFailedTransactionsCount() {
233 return ++failedTransactionsCount;
236 public long incrementFailedReadTransactionsCount() {
237 return failedReadTransactionsCount.incrementAndGet();
240 public long incrementAbortTransactionsCount() {
241 return ++abortTransactionsCount;
244 public void setLastCommittedTransactionTime(final long lastCommittedTransactionTime) {
245 this.lastCommittedTransactionTime = lastCommittedTransactionTime;
249 public long getInMemoryJournalDataSize() {
250 return getOnDemandRaftState().getInMemoryJournalDataSize();
254 public long getInMemoryJournalLogSize() {
255 return getOnDemandRaftState().getInMemoryJournalLogSize();
259 * Resets the counters related to transactions.
262 public void resetTransactionCounters() {
263 committedTransactionsCount = 0;
265 readOnlyTransactionCount = 0;
267 writeOnlyTransactionCount = 0;
269 readWriteTransactionCount = 0;
271 lastCommittedTransactionTime = 0;
273 failedTransactionsCount = 0;
275 failedReadTransactionsCount.set(0);
277 abortTransactionsCount = 0;
281 public void setFollowerInitialSyncStatus(final boolean followerInitialSyncStatus) {
282 this.followerInitialSyncStatus = followerInitialSyncStatus;
286 public boolean getFollowerInitialSyncStatus() {
287 return followerInitialSyncStatus;
291 public List<FollowerInfo> getFollowerInfo() {
292 return getOnDemandRaftState().getFollowerInfoList();
296 public String getPeerAddresses() {
297 return MAP_JOINER.join(getOnDemandRaftState().getPeerAddresses());
301 public String getStatRetrievalTime() {
302 getOnDemandRaftState();
303 return stateCache.getStatRetrievaelTime();
307 public String getStatRetrievalError() {
308 getOnDemandRaftState();
309 return statRetrievalError;
313 public long getLeadershipChangeCount() {
314 return leadershipChangeCount;
317 public void incrementLeadershipChangeCount() {
318 leadershipChangeCount++;
319 lastLeadershipChangeTime = System.currentTimeMillis();
323 public String getLastLeadershipChangeTime() {
324 return formatMillis(lastLeadershipChangeTime);
328 public int getPendingTxCommitQueueSize() {
329 return shard != null ? shard.getPendingTxCommitQueueSize() : -1;
333 public int getTxCohortCacheSize() {
334 return shard != null ? shard.getCohortCacheSize() : -1;
338 public void captureSnapshot() {
340 shard.getSelf().tell(new InitiateCaptureSnapshot(), ActorRef.noSender());