1f51c6f3a14e48076549ee4ef4b9ea1d663a439c
[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
9 package org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard;
10
11 import akka.pattern.Patterns;
12 import akka.util.Timeout;
13 import com.google.common.base.Stopwatch;
14 import com.google.common.cache.Cache;
15 import com.google.common.cache.CacheBuilder;
16 import java.text.SimpleDateFormat;
17 import java.util.Date;
18 import java.util.List;
19 import java.util.Map;
20 import java.util.concurrent.TimeUnit;
21 import java.util.concurrent.atomic.AtomicLong;
22 import org.opendaylight.controller.cluster.datastore.Shard;
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 scala.concurrent.Await;
28
29 /**
30  * Maintains statistics for a shard.
31  *
32  * @author  Basheeruddin syedbahm@cisco.com
33  */
34 public class ShardStats extends AbstractMXBean implements ShardStatsMXBean {
35     public static String JMX_CATEGORY_SHARD = "Shards";
36
37     private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
38
39     private static final Cache<String, OnDemandRaftState> onDemandRaftStateCache =
40             CacheBuilder.newBuilder().expireAfterWrite(2, TimeUnit.SECONDS).build();
41
42     private long committedTransactionsCount;
43
44     private long readOnlyTransactionCount;
45
46     private long writeOnlyTransactionCount;
47
48     private long readWriteTransactionCount;
49
50     private long lastCommittedTransactionTime;
51
52     private long failedTransactionsCount;
53
54     private final AtomicLong failedReadTransactionsCount = new AtomicLong();
55
56     private long abortTransactionsCount;
57
58     private boolean followerInitialSyncStatus = false;
59
60     private Shard shard;
61
62     private String statRetrievalError;
63
64     private String statRetrievalTime;
65
66     private long leadershipChangeCount;
67
68     private long lastLeadershipChangeTime;
69
70     public ShardStats(final String shardName, final String mxBeanType) {
71         super(shardName, mxBeanType, JMX_CATEGORY_SHARD);
72     }
73
74     public void setShard(Shard shard) {
75         this.shard = shard;
76     }
77
78     private OnDemandRaftState getOnDemandRaftState() {
79         String name = getShardName();
80         OnDemandRaftState state = onDemandRaftStateCache.getIfPresent(name);
81         if(state == null) {
82             statRetrievalError = null;
83             statRetrievalTime = null;
84
85             if(shard != null) {
86                 Timeout timeout = new Timeout(10, TimeUnit.SECONDS);
87                 try {
88                     Stopwatch timer = Stopwatch.createStarted();
89
90                     state = (OnDemandRaftState) Await.result(Patterns.ask(shard.getSelf(),
91                             GetOnDemandRaftState.INSTANCE, timeout), timeout.duration());
92
93                     statRetrievalTime = timer.stop().toString();
94                     onDemandRaftStateCache.put(name, state);
95                 } catch (Exception e) {
96                     statRetrievalError = e.toString();
97                 }
98             }
99
100             state = state != null ? state : OnDemandRaftState.builder().build();
101         }
102
103         return state;
104     }
105
106     @Override
107     public String getShardName() {
108         return getMBeanName();
109     }
110
111     @Override
112     public long getCommittedTransactionsCount() {
113         return committedTransactionsCount;
114     }
115
116     @Override
117     public String getLeader() {
118         return getOnDemandRaftState().getLeader();
119     }
120
121     @Override
122     public String getRaftState() {
123         return getOnDemandRaftState().getRaftState();
124     }
125
126     @Override
127     public long getReadOnlyTransactionCount() {
128         return readOnlyTransactionCount;
129     }
130
131     @Override
132     public long getWriteOnlyTransactionCount() {
133         return writeOnlyTransactionCount;
134     }
135
136     @Override
137     public long getReadWriteTransactionCount() {
138         return readWriteTransactionCount;
139     }
140
141     @Override
142     public long getLastLogIndex() {
143         return getOnDemandRaftState().getLastLogIndex();
144     }
145
146     @Override
147     public long getLastLogTerm() {
148         return getOnDemandRaftState().getLastLogTerm();
149     }
150
151     @Override
152     public long getCurrentTerm() {
153         return getOnDemandRaftState().getCurrentTerm();
154     }
155
156     @Override
157     public long getCommitIndex() {
158         return getOnDemandRaftState().getCommitIndex();
159     }
160
161     @Override
162     public long getLastApplied() {
163         return getOnDemandRaftState().getLastApplied();
164     }
165
166     @Override
167     public long getLastIndex() {
168         return getOnDemandRaftState().getLastIndex();
169     }
170
171     @Override
172     public long getLastTerm() {
173         return getOnDemandRaftState().getLastTerm();
174     }
175
176     @Override
177     public long getSnapshotIndex() {
178         return getOnDemandRaftState().getSnapshotIndex();
179     }
180
181     @Override
182     public long getSnapshotTerm() {
183         return getOnDemandRaftState().getSnapshotTerm();
184     }
185
186     @Override
187     public long getReplicatedToAllIndex() {
188         return getOnDemandRaftState().getReplicatedToAllIndex();
189     }
190
191     @Override
192     public String getVotedFor() {
193         return getOnDemandRaftState().getVotedFor();
194     }
195
196     @Override
197     public boolean isSnapshotCaptureInitiated() {
198         return getOnDemandRaftState().isSnapshotCaptureInitiated();
199     }
200
201     @Override
202     public String getLastCommittedTransactionTime() {
203         return DATE_FORMAT.format(new Date(lastCommittedTransactionTime));
204     }
205
206     @Override
207     public long getFailedTransactionsCount() {
208         return failedTransactionsCount;
209     }
210
211     @Override
212     public long getFailedReadTransactionsCount() {
213         return failedReadTransactionsCount.get();
214     }
215
216     @Override
217     public long getAbortTransactionsCount() {
218         return abortTransactionsCount;
219     }
220
221     public long incrementCommittedTransactionCount() {
222         return ++committedTransactionsCount;
223     }
224
225     public long incrementReadOnlyTransactionCount() {
226         return ++readOnlyTransactionCount;
227     }
228
229     public long incrementWriteOnlyTransactionCount() {
230         return ++writeOnlyTransactionCount;
231     }
232
233     public long incrementReadWriteTransactionCount() {
234         return ++readWriteTransactionCount;
235     }
236
237     public long incrementFailedTransactionsCount() {
238         return ++failedTransactionsCount;
239     }
240
241     public long incrementFailedReadTransactionsCount() {
242         return failedReadTransactionsCount.incrementAndGet();
243     }
244
245     public long incrementAbortTransactionsCount ()
246     {
247         return ++abortTransactionsCount;
248     }
249
250     public void setLastCommittedTransactionTime(final long lastCommittedTransactionTime) {
251         this.lastCommittedTransactionTime = lastCommittedTransactionTime;
252     }
253
254     @Override
255     public long getInMemoryJournalDataSize(){
256         return getOnDemandRaftState().getInMemoryJournalDataSize();
257     }
258
259     @Override
260     public long getInMemoryJournalLogSize() {
261         return getOnDemandRaftState().getInMemoryJournalLogSize();
262     }
263
264     /**
265      * resets the counters related to transactions
266      */
267     @Override
268     public void resetTransactionCounters(){
269         committedTransactionsCount = 0;
270
271         readOnlyTransactionCount = 0;
272
273         writeOnlyTransactionCount = 0;
274
275         readWriteTransactionCount = 0;
276
277         lastCommittedTransactionTime = 0;
278
279         failedTransactionsCount = 0;
280
281         failedReadTransactionsCount.set(0);
282
283         abortTransactionsCount = 0;
284
285     }
286
287     public void setFollowerInitialSyncStatus(boolean followerInitialSyncStatus) {
288         this.followerInitialSyncStatus = followerInitialSyncStatus;
289     }
290
291     @Override
292     public boolean getFollowerInitialSyncStatus() {
293         return followerInitialSyncStatus;
294     }
295
296     @Override
297     public List<FollowerInfo> getFollowerInfo() {
298         return getOnDemandRaftState().getFollowerInfoList();
299     }
300
301     @Override
302     public String getPeerAddresses() {
303         StringBuilder builder = new StringBuilder();
304         int i = 0;
305         for(Map.Entry<String, String> e: getOnDemandRaftState().getPeerAddresses().entrySet()) {
306             if(i++ > 0) {
307                 builder.append(", ");
308             }
309
310             builder.append(e.getKey()).append(": ").append(e.getValue());
311         }
312
313         return builder.toString();
314     }
315
316     @Override
317     public String getStatRetrievalTime() {
318         getOnDemandRaftState();
319         return statRetrievalTime;
320     }
321
322     @Override
323     public String getStatRetrievalError() {
324         getOnDemandRaftState();
325         return statRetrievalError;
326     }
327
328     @Override
329     public long getLeadershipChangeCount() {
330         return leadershipChangeCount;
331     }
332
333     public void incrementLeadershipChangeCount() {
334         leadershipChangeCount++;
335         lastLeadershipChangeTime = System.currentTimeMillis();
336     }
337
338     @Override
339     public String getLastLeadershipChangeTime() {
340         return DATE_FORMAT.format(new Date(lastLeadershipChangeTime));
341     }
342
343     @Override
344     public int getPendingTxCommitQueueSize() {
345         return shard.getPendingTxCommitQueueSize();
346     }
347 }