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