b3234766e6eb1c17c1a1d6e3318c8c05b283b8e1
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / jmx / mbeans / shard / ShardStats.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard;
9
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;
24
25 /**
26  * Maintains statistics for a shard.
27  *
28  * @author  Basheeruddin syedbahm@cisco.com
29  */
30 public class ShardStats extends AbstractMXBean implements ShardStatsMXBean {
31     public static final String JMX_CATEGORY_SHARD = "Shards";
32
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");
36
37     private static final MapJoiner MAP_JOINER = Joiner.on(", ").withKeyValueSeparator(": ");
38
39     private final Shard shard;
40
41     private final OnDemandShardStateCache stateCache;
42
43     private long committedTransactionsCount;
44
45     private long readOnlyTransactionCount;
46
47     private long writeOnlyTransactionCount;
48
49     private long readWriteTransactionCount;
50
51     private long lastCommittedTransactionTime;
52
53     private long failedTransactionsCount;
54
55     private final AtomicLong failedReadTransactionsCount = new AtomicLong();
56
57     private long abortTransactionsCount;
58
59     private boolean followerInitialSyncStatus = false;
60
61     private String statRetrievalError;
62
63     private long leadershipChangeCount;
64
65     private long lastLeadershipChangeTime;
66
67     public ShardStats(final String shardName, final String mxBeanType, final @Nullable Shard shard) {
68         super(shardName, mxBeanType, JMX_CATEGORY_SHARD);
69         this.shard = shard;
70         stateCache = new OnDemandShardStateCache(shardName, shard != null ? shard.self() : null);
71     }
72
73     @SuppressWarnings("checkstyle:IllegalCatch")
74     private OnDemandRaftState getOnDemandRaftState() {
75         try {
76             final OnDemandRaftState state = stateCache.get();
77             statRetrievalError = null;
78             return state;
79         } catch (Exception e) {
80             statRetrievalError = e.getCause().toString();
81             return OnDemandRaftState.builder().build();
82         }
83     }
84
85     private static String formatMillis(final long timeMillis) {
86         synchronized (DATE_FORMAT) {
87             return DATE_FORMAT.format(new Date(timeMillis));
88         }
89     }
90
91     @Override
92     public String getShardName() {
93         return getMBeanName();
94     }
95
96     @Override
97     public long getCommittedTransactionsCount() {
98         return committedTransactionsCount;
99     }
100
101     @Override
102     public String getLeader() {
103         return getOnDemandRaftState().getLeader();
104     }
105
106     @Override
107     public String getRaftState() {
108         return getOnDemandRaftState().getRaftState();
109     }
110
111     @Override
112     public long getReadOnlyTransactionCount() {
113         return readOnlyTransactionCount;
114     }
115
116     @Override
117     public long getWriteOnlyTransactionCount() {
118         return writeOnlyTransactionCount;
119     }
120
121     @Override
122     public long getReadWriteTransactionCount() {
123         return readWriteTransactionCount;
124     }
125
126     @Override
127     public long getLastLogIndex() {
128         return getOnDemandRaftState().getLastLogIndex();
129     }
130
131     @Override
132     public long getLastLogTerm() {
133         return getOnDemandRaftState().getLastLogTerm();
134     }
135
136     @Override
137     public long getCurrentTerm() {
138         return getOnDemandRaftState().getCurrentTerm();
139     }
140
141     @Override
142     public long getCommitIndex() {
143         return getOnDemandRaftState().getCommitIndex();
144     }
145
146     @Override
147     public long getLastApplied() {
148         return getOnDemandRaftState().getLastApplied();
149     }
150
151     @Override
152     public long getLastIndex() {
153         return getOnDemandRaftState().getLastIndex();
154     }
155
156     @Override
157     public long getLastTerm() {
158         return getOnDemandRaftState().getLastTerm();
159     }
160
161     @Override
162     public long getSnapshotIndex() {
163         return getOnDemandRaftState().getSnapshotIndex();
164     }
165
166     @Override
167     public long getSnapshotTerm() {
168         return getOnDemandRaftState().getSnapshotTerm();
169     }
170
171     @Override
172     public long getReplicatedToAllIndex() {
173         return getOnDemandRaftState().getReplicatedToAllIndex();
174     }
175
176     @Override
177     public String getVotedFor() {
178         return getOnDemandRaftState().getVotedFor();
179     }
180
181     @Override
182     public boolean isVoting() {
183         return getOnDemandRaftState().isVoting();
184     }
185
186     @Override
187     public String getPeerVotingStates() {
188         return MAP_JOINER.join(getOnDemandRaftState().getPeerVotingStates());
189     }
190
191     @Override
192     public boolean isSnapshotCaptureInitiated() {
193         return getOnDemandRaftState().isSnapshotCaptureInitiated();
194     }
195
196     @Override
197     public String getLastCommittedTransactionTime() {
198         return formatMillis(lastCommittedTransactionTime);
199     }
200
201     @Override
202     public long getFailedTransactionsCount() {
203         return failedTransactionsCount;
204     }
205
206     @Override
207     public long getFailedReadTransactionsCount() {
208         return failedReadTransactionsCount.get();
209     }
210
211     @Override
212     public long getAbortTransactionsCount() {
213         return abortTransactionsCount;
214     }
215
216     public long incrementCommittedTransactionCount() {
217         return ++committedTransactionsCount;
218     }
219
220     public long incrementReadOnlyTransactionCount() {
221         return ++readOnlyTransactionCount;
222     }
223
224     public long incrementWriteOnlyTransactionCount() {
225         return ++writeOnlyTransactionCount;
226     }
227
228     public long incrementReadWriteTransactionCount() {
229         return ++readWriteTransactionCount;
230     }
231
232     public long incrementFailedTransactionsCount() {
233         return ++failedTransactionsCount;
234     }
235
236     public long incrementFailedReadTransactionsCount() {
237         return failedReadTransactionsCount.incrementAndGet();
238     }
239
240     public long incrementAbortTransactionsCount() {
241         return ++abortTransactionsCount;
242     }
243
244     public void setLastCommittedTransactionTime(final long lastCommittedTransactionTime) {
245         this.lastCommittedTransactionTime = lastCommittedTransactionTime;
246     }
247
248     @Override
249     public long getInMemoryJournalDataSize() {
250         return getOnDemandRaftState().getInMemoryJournalDataSize();
251     }
252
253     @Override
254     public long getInMemoryJournalLogSize() {
255         return getOnDemandRaftState().getInMemoryJournalLogSize();
256     }
257
258     /**
259      * Resets the counters related to transactions.
260      */
261     @Override
262     public void resetTransactionCounters() {
263         committedTransactionsCount = 0;
264
265         readOnlyTransactionCount = 0;
266
267         writeOnlyTransactionCount = 0;
268
269         readWriteTransactionCount = 0;
270
271         lastCommittedTransactionTime = 0;
272
273         failedTransactionsCount = 0;
274
275         failedReadTransactionsCount.set(0);
276
277         abortTransactionsCount = 0;
278
279     }
280
281     public void setFollowerInitialSyncStatus(final boolean followerInitialSyncStatus) {
282         this.followerInitialSyncStatus = followerInitialSyncStatus;
283     }
284
285     @Override
286     public boolean getFollowerInitialSyncStatus() {
287         return followerInitialSyncStatus;
288     }
289
290     @Override
291     public List<FollowerInfo> getFollowerInfo() {
292         return getOnDemandRaftState().getFollowerInfoList();
293     }
294
295     @Override
296     public String getPeerAddresses() {
297         return MAP_JOINER.join(getOnDemandRaftState().getPeerAddresses());
298     }
299
300     @Override
301     public String getStatRetrievalTime() {
302         getOnDemandRaftState();
303         return stateCache.getStatRetrievaelTime();
304     }
305
306     @Override
307     public String getStatRetrievalError() {
308         getOnDemandRaftState();
309         return statRetrievalError;
310     }
311
312     @Override
313     public long getLeadershipChangeCount() {
314         return leadershipChangeCount;
315     }
316
317     public void incrementLeadershipChangeCount() {
318         leadershipChangeCount++;
319         lastLeadershipChangeTime = System.currentTimeMillis();
320     }
321
322     @Override
323     public String getLastLeadershipChangeTime() {
324         return formatMillis(lastLeadershipChangeTime);
325     }
326
327     @Override
328     public int getPendingTxCommitQueueSize() {
329         return shard != null ? shard.getPendingTxCommitQueueSize() : -1;
330     }
331
332     @Override
333     public int getTxCohortCacheSize() {
334         return shard != null ? shard.getCohortCacheSize() : -1;
335     }
336
337     @Override
338     public void captureSnapshot() {
339         if (shard != null) {
340             shard.getSelf().tell(new InitiateCaptureSnapshot(), ActorRef.noSender());
341         }
342     }
343 }