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;
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 org.checkerframework.checker.lock.qual.GuardedBy;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard.ShardStatsMXBean;
20 import org.opendaylight.controller.cluster.mgmt.api.FollowerInfo;
21 import org.opendaylight.controller.cluster.raft.base.messages.InitiateCaptureSnapshot;
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 final 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 readWriteTransactionCount;
49 private long lastCommittedTransactionTime;
51 private long failedTransactionsCount;
53 private final AtomicLong failedReadTransactionsCount = new AtomicLong();
55 private long abortTransactionsCount;
57 private boolean followerInitialSyncStatus = false;
59 private String statRetrievalError;
61 private long leadershipChangeCount;
63 private long lastLeadershipChangeTime;
65 ShardStats(final String shardName, final String mxBeanType, final @Nullable Shard shard) {
66 super(shardName, mxBeanType, JMX_CATEGORY_SHARD);
68 stateCache = new OnDemandShardStateCache(shardName, shard != null ? shard.self() : null);
71 @SuppressWarnings("checkstyle:IllegalCatch")
72 private OnDemandRaftState getOnDemandRaftState() {
74 final OnDemandRaftState state = stateCache.get();
75 statRetrievalError = null;
77 } catch (Exception e) {
78 statRetrievalError = e.getCause().toString();
79 return OnDemandRaftState.builder().build();
83 private static String formatMillis(final long timeMillis) {
84 synchronized (DATE_FORMAT) {
85 return DATE_FORMAT.format(new Date(timeMillis));
90 public String getShardName() {
91 return getMBeanName();
95 public long getCommittedTransactionsCount() {
96 return committedTransactionsCount;
100 public String getLeader() {
101 return getOnDemandRaftState().getLeader();
105 public String getRaftState() {
106 return getOnDemandRaftState().getRaftState();
110 public long getReadOnlyTransactionCount() {
111 return readOnlyTransactionCount;
115 public long getReadWriteTransactionCount() {
116 return readWriteTransactionCount;
120 public long getLastLogIndex() {
121 return getOnDemandRaftState().getLastLogIndex();
125 public long getLastLogTerm() {
126 return getOnDemandRaftState().getLastLogTerm();
130 public long getCurrentTerm() {
131 return getOnDemandRaftState().getCurrentTerm();
135 public long getCommitIndex() {
136 return getOnDemandRaftState().getCommitIndex();
140 public long getLastApplied() {
141 return getOnDemandRaftState().getLastApplied();
145 public long getLastIndex() {
146 return getOnDemandRaftState().getLastIndex();
150 public long getLastTerm() {
151 return getOnDemandRaftState().getLastTerm();
155 public long getSnapshotIndex() {
156 return getOnDemandRaftState().getSnapshotIndex();
160 public long getSnapshotTerm() {
161 return getOnDemandRaftState().getSnapshotTerm();
165 public long getReplicatedToAllIndex() {
166 return getOnDemandRaftState().getReplicatedToAllIndex();
170 public String getVotedFor() {
171 return getOnDemandRaftState().getVotedFor();
175 public boolean isVoting() {
176 return getOnDemandRaftState().isVoting();
180 public String getPeerVotingStates() {
181 return MAP_JOINER.join(getOnDemandRaftState().getPeerVotingStates());
185 public boolean isSnapshotCaptureInitiated() {
186 return getOnDemandRaftState().isSnapshotCaptureInitiated();
190 public String getLastCommittedTransactionTime() {
191 return formatMillis(lastCommittedTransactionTime);
195 public long getFailedTransactionsCount() {
196 return failedTransactionsCount;
200 public long getFailedReadTransactionsCount() {
201 return failedReadTransactionsCount.get();
205 public long getAbortTransactionsCount() {
206 return abortTransactionsCount;
209 public long incrementCommittedTransactionCount() {
210 return ++committedTransactionsCount;
213 public long incrementReadOnlyTransactionCount() {
214 return ++readOnlyTransactionCount;
217 public long incrementReadWriteTransactionCount() {
218 return ++readWriteTransactionCount;
221 public long incrementFailedTransactionsCount() {
222 return ++failedTransactionsCount;
225 public long incrementFailedReadTransactionsCount() {
226 return failedReadTransactionsCount.incrementAndGet();
229 public long incrementAbortTransactionsCount() {
230 return ++abortTransactionsCount;
233 public void setLastCommittedTransactionTime(final long lastCommittedTransactionTime) {
234 this.lastCommittedTransactionTime = lastCommittedTransactionTime;
238 public long getInMemoryJournalDataSize() {
239 return getOnDemandRaftState().getInMemoryJournalDataSize();
243 public long getInMemoryJournalLogSize() {
244 return getOnDemandRaftState().getInMemoryJournalLogSize();
248 * Resets the counters related to transactions.
251 public void resetTransactionCounters() {
252 committedTransactionsCount = 0;
254 readOnlyTransactionCount = 0;
256 readWriteTransactionCount = 0;
258 lastCommittedTransactionTime = 0;
260 failedTransactionsCount = 0;
262 failedReadTransactionsCount.set(0);
264 abortTransactionsCount = 0;
268 public void setFollowerInitialSyncStatus(final boolean followerInitialSyncStatus) {
269 this.followerInitialSyncStatus = followerInitialSyncStatus;
273 public boolean getFollowerInitialSyncStatus() {
274 return followerInitialSyncStatus;
278 public List<FollowerInfo> getFollowerInfo() {
279 return getOnDemandRaftState().getFollowerInfoList();
283 public String getPeerAddresses() {
284 return MAP_JOINER.join(getOnDemandRaftState().getPeerAddresses());
288 public String getStatRetrievalTime() {
289 getOnDemandRaftState();
290 return stateCache.getStatRetrievaelTime();
294 public String getStatRetrievalError() {
295 getOnDemandRaftState();
296 return statRetrievalError;
300 public long getLeadershipChangeCount() {
301 return leadershipChangeCount;
304 public void incrementLeadershipChangeCount() {
305 leadershipChangeCount++;
306 lastLeadershipChangeTime = System.currentTimeMillis();
310 public String getLastLeadershipChangeTime() {
311 return formatMillis(lastLeadershipChangeTime);
315 public int getPendingTxCommitQueueSize() {
316 return shard != null ? shard.getPendingTxCommitQueueSize() : -1;
320 public int getTxCohortCacheSize() {
321 return shard != null ? shard.getCohortCacheSize() : -1;
325 public void captureSnapshot() {
327 shard.getSelf().tell(new InitiateCaptureSnapshot(), ActorRef.noSender());