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.time.Instant;
14 import java.time.ZoneId;
15 import java.time.format.DateTimeFormatter;
16 import java.util.List;
17 import java.util.concurrent.atomic.AtomicLong;
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard.ShardStatsMXBean;
21 import org.opendaylight.controller.cluster.mgmt.api.FollowerInfo;
22 import org.opendaylight.controller.cluster.raft.base.messages.InitiateCaptureSnapshot;
23 import org.opendaylight.controller.cluster.raft.client.messages.OnDemandRaftState;
24 import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
27 * Maintains statistics for a shard.
29 * @author Basheeruddin syedbahm@cisco.com
31 final class ShardStats extends AbstractMXBean implements ShardStatsMXBean {
32 public static final String JMX_CATEGORY_SHARD = "Shards";
34 private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS")
35 .withZone(ZoneId.systemDefault());
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 static ShardStats create(final String shardName, final String mxBeanType, final @NonNull Shard shard) {
72 String finalMXBeanType = mxBeanType != null ? mxBeanType : "DistDataStore";
73 ShardStats shardStatsMBeanImpl = new ShardStats(shardName, finalMXBeanType, shard);
74 shardStatsMBeanImpl.registerMBean();
75 return shardStatsMBeanImpl;
78 @SuppressWarnings("checkstyle:IllegalCatch")
79 private OnDemandRaftState getOnDemandRaftState() {
81 final OnDemandRaftState state = stateCache.get();
82 statRetrievalError = null;
84 } catch (Exception e) {
85 statRetrievalError = e.getCause().toString();
86 return OnDemandRaftState.builder().build();
90 private static String formatMillis(final long timeMillis) {
91 return DATE_FORMATTER.format(Instant.ofEpochMilli(timeMillis));
95 public String getShardName() {
96 return getMBeanName();
100 public long getCommittedTransactionsCount() {
101 return committedTransactionsCount;
105 public String getLeader() {
106 return getOnDemandRaftState().getLeader();
110 public String getRaftState() {
111 return getOnDemandRaftState().getRaftState();
115 public long getReadOnlyTransactionCount() {
116 return readOnlyTransactionCount;
120 public long getReadWriteTransactionCount() {
121 return readWriteTransactionCount;
125 public long getLastLogIndex() {
126 return getOnDemandRaftState().getLastLogIndex();
130 public long getLastLogTerm() {
131 return getOnDemandRaftState().getLastLogTerm();
135 public long getCurrentTerm() {
136 return getOnDemandRaftState().getCurrentTerm();
140 public long getCommitIndex() {
141 return getOnDemandRaftState().getCommitIndex();
145 public long getLastApplied() {
146 return getOnDemandRaftState().getLastApplied();
150 public long getLastIndex() {
151 return getOnDemandRaftState().getLastIndex();
155 public long getLastTerm() {
156 return getOnDemandRaftState().getLastTerm();
160 public long getSnapshotIndex() {
161 return getOnDemandRaftState().getSnapshotIndex();
165 public long getSnapshotTerm() {
166 return getOnDemandRaftState().getSnapshotTerm();
170 public long getReplicatedToAllIndex() {
171 return getOnDemandRaftState().getReplicatedToAllIndex();
175 public String getVotedFor() {
176 return getOnDemandRaftState().getVotedFor();
180 public boolean isVoting() {
181 return getOnDemandRaftState().isVoting();
185 public String getPeerVotingStates() {
186 return MAP_JOINER.join(getOnDemandRaftState().getPeerVotingStates());
190 public boolean isSnapshotCaptureInitiated() {
191 return getOnDemandRaftState().isSnapshotCaptureInitiated();
195 public String getLastCommittedTransactionTime() {
196 return formatMillis(lastCommittedTransactionTime);
200 public long getFailedTransactionsCount() {
201 return failedTransactionsCount;
205 public long getFailedReadTransactionsCount() {
206 return failedReadTransactionsCount.get();
210 public long getAbortTransactionsCount() {
211 return abortTransactionsCount;
214 public long incrementCommittedTransactionCount() {
215 return ++committedTransactionsCount;
218 public long incrementReadOnlyTransactionCount() {
219 return ++readOnlyTransactionCount;
222 public long incrementReadWriteTransactionCount() {
223 return ++readWriteTransactionCount;
226 public long incrementFailedTransactionsCount() {
227 return ++failedTransactionsCount;
230 public long incrementFailedReadTransactionsCount() {
231 return failedReadTransactionsCount.incrementAndGet();
234 public long incrementAbortTransactionsCount() {
235 return ++abortTransactionsCount;
238 public void setLastCommittedTransactionTime(final long lastCommittedTransactionTime) {
239 this.lastCommittedTransactionTime = lastCommittedTransactionTime;
243 public long getInMemoryJournalDataSize() {
244 return getOnDemandRaftState().getInMemoryJournalDataSize();
248 public long getInMemoryJournalLogSize() {
249 return getOnDemandRaftState().getInMemoryJournalLogSize();
253 * Resets the counters related to transactions.
256 public void resetTransactionCounters() {
257 committedTransactionsCount = 0;
259 readOnlyTransactionCount = 0;
261 readWriteTransactionCount = 0;
263 lastCommittedTransactionTime = 0;
265 failedTransactionsCount = 0;
267 failedReadTransactionsCount.set(0);
269 abortTransactionsCount = 0;
273 public void setFollowerInitialSyncStatus(final boolean followerInitialSyncStatus) {
274 this.followerInitialSyncStatus = followerInitialSyncStatus;
278 public boolean getFollowerInitialSyncStatus() {
279 return followerInitialSyncStatus;
283 public List<FollowerInfo> getFollowerInfo() {
284 return getOnDemandRaftState().getFollowerInfoList();
288 public String getPeerAddresses() {
289 return MAP_JOINER.join(getOnDemandRaftState().getPeerAddresses());
293 public String getStatRetrievalTime() {
294 getOnDemandRaftState();
295 return stateCache.getStatRetrievaelTime();
299 public String getStatRetrievalError() {
300 getOnDemandRaftState();
301 return statRetrievalError;
305 public long getLeadershipChangeCount() {
306 return leadershipChangeCount;
309 public void incrementLeadershipChangeCount() {
310 leadershipChangeCount++;
311 lastLeadershipChangeTime = System.currentTimeMillis();
315 public String getLastLeadershipChangeTime() {
316 return formatMillis(lastLeadershipChangeTime);
320 public int getPendingTxCommitQueueSize() {
321 return shard != null ? shard.getPendingTxCommitQueueSize() : -1;
325 public int getTxCohortCacheSize() {
326 return shard != null ? shard.getCohortCacheSize() : -1;
330 public void captureSnapshot() {
332 shard.getSelf().tell(new InitiateCaptureSnapshot(), ActorRef.noSender());