001/*
002 * Copyright 2008-2020 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2008-2020 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2015-2020 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.ldap.sdk.unboundidds.monitors;
037
038
039
040import java.util.ArrayList;
041import java.util.Collections;
042import java.util.Date;
043import java.util.LinkedHashMap;
044import java.util.Map;
045
046import com.unboundid.ldap.sdk.Attribute;
047import com.unboundid.ldap.sdk.Entry;
048import com.unboundid.util.NotMutable;
049import com.unboundid.util.StaticUtils;
050import com.unboundid.util.ThreadSafety;
051import com.unboundid.util.ThreadSafetyLevel;
052
053import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*;
054
055
056
057/**
058 * This class defines a monitor entry that provides basic information about the
059 * Berkeley DB Java Edition environment in use for a backend.
060 * <BR>
061 * <BLOCKQUOTE>
062 *   <B>NOTE:</B>  This class, and other classes within the
063 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
064 *   supported for use against Ping Identity, UnboundID, and
065 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
066 *   for proprietary functionality or for external specifications that are not
067 *   considered stable or mature enough to be guaranteed to work in an
068 *   interoperable way with other types of LDAP servers.
069 * </BLOCKQUOTE>
070 * <BR>
071 * The information that is provided includes:
072 * <UL>
073 *   <LI>The backend ID for the associated backend.</LI>
074 *   <LI>The version string for the Berkeley DB Java Edition library.</LI>
075 *   <LI>The path to the directory containing the database environment
076 *       files.</LI>
077 *   <LI>The amount of space consumed by the database files.</LI>
078 *   <LI>The amount of memory currently consumed by the database cache.</LI>
079 *   <LI>The maximum amount of memory that may be consumed by the database
080 *       cache.</LI>
081 *   <LI>The percent of the total memory allowed for the database cache that is
082 *       currently in use.</LI>
083 *   <LI>Whether a checkpoint is currently in progress.</LI>
084 *   <LI>The total number of checkpoints that have been completed.</LI>
085 *   <LI>The time that the last completed checkpoint began.</LI>
086 *   <LI>The time that the last completed checkpoint ended.</LI>
087 *   <LI>The total duration of all checkpoints completed.</LI>
088 *   <LI>The average duration of all checkpoints completed.</LI>
089 *   <LI>The duration of the last checkpoint completed.</LI>
090 *   <LI>The length of time since the last checkpoint.</LI>
091 *   <LI>The number of log files that the cleaner needs to examine.</LI>
092 *   <LI>The number of nodes evicted from the database cache.</LI>
093 *   <LI>The number of random-access disk reads performed.</LI>
094 *   <LI>The number of random-access disk writes performed.</LI>
095 *   <LI>The number of sequential disk reads performed.</LI>
096 *   <LI>The number of sequential disk writes performed.</LI>
097 *   <LI>The number of active transactions in the database environment.</LI>
098 *   <LI>The number of read locks held in the database environment.</LI>
099 *   <LI>The number of write locks held in the database environment.</LI>
100 *   <LI>The number of transactions waiting on locks.</LI>
101 *   <LI>A set of generic statistics about the database environment.</LI>
102 *   <LI>A set of generic statistics about the lock subsystem for the database
103 *       environment.</LI>
104 *   <LI>A set of generic statistics about the transaction subsystem for the
105 *       database environment.</LI>
106 * </UL>
107 * The JE environment monitor entries provided by the server can be
108 * retrieved using the {@link MonitorManager#getJEEnvironmentMonitorEntries}
109 * method.  These entries provide specific methods for accessing information
110 * about the JE environment (e.g., the
111 * {@link JEEnvironmentMonitorEntry#getJEVersion} method can be used to retrieve
112 * the Berkeley DB JE version).  Alternately, this information may be accessed
113 * using the generic API.  See the {@link MonitorManager} class documentation
114 * for an example that demonstrates the use of the generic API for accessing
115 * monitor data.
116 */
117@NotMutable()
118@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
119public final class JEEnvironmentMonitorEntry
120       extends MonitorEntry
121{
122  /**
123   * The structural object class used in JE environment monitor entries.
124   */
125  static final String JE_ENVIRONMENT_MONITOR_OC =
126       "ds-je-environment-monitor-entry";
127
128
129
130  /**
131   * The name of the attribute that contains the number of active transactions.
132   */
133  private static final String ATTR_ACTIVE_TXNS = "active-transaction-count";
134
135
136
137  /**
138   * The name of the attribute that contains the average duration of the all
139   * checkpoints in milliseconds.
140   */
141  private static final String ATTR_AVERAGE_CHECKPOINT_DURATION_MILLIS =
142       "average-checkpoint-duration-millis";
143
144
145
146  /**
147   * The name of the attribute that contains the backend ID for the associated
148   * backend.
149   */
150  private static final String ATTR_BACKEND_ID = "backend-id";
151
152
153
154  /**
155   * The name of the attribute that contains the DB cache percent full.
156   */
157  private static final String ATTR_CACHE_PCT_FULL = "db-cache-percent-full";
158
159
160
161  /**
162   * The name of the attribute that indicates whether a checkpoint is currently
163   * in progress.
164   */
165  private static final String ATTR_CHECKPOINT_IN_PROGRESS =
166       "checkpoint-in-progress";
167
168
169
170  /**
171   * The name of the attribute that contains the cleaner backlog.
172   */
173  private static final String ATTR_CLEANER_BACKLOG = "cleaner-backlog";
174
175
176
177  /**
178   * The name of the attribute that contains the current DB cache size.
179   */
180  private static final String ATTR_CURRENT_CACHE_SIZE = "current-db-cache-size";
181
182
183
184  /**
185   * The name of the attribute that contains the path to the DB directory.
186   */
187  private static final String ATTR_DB_DIRECTORY = "db-directory";
188
189
190
191  /**
192   * The name of the attribute that contains the DB on-disk size.
193   */
194  private static final String ATTR_DB_ON_DISK_SIZE = "db-on-disk-size";
195
196
197
198  /**
199   * The name of the attribute that contains the Berkeley DB JE version string.
200   */
201  private static final String ATTR_JE_VERSION = "je-version";
202
203
204
205  /**
206   * The name of the attribute that contains the duration of the last checkpoint
207   * in milliseconds.
208   */
209  private static final String ATTR_LAST_CHECKPOINT_DURATION_MILLIS =
210       "last-checkpoint-duration-millis";
211
212
213
214  /**
215   * The name of the attribute that contains the time the last checkpoint began.
216   */
217  private static final String ATTR_LAST_CHECKPOINT_START_TIME =
218       "last-checkpoint-start-time";
219
220
221
222  /**
223   * The name of the attribute that contains the time the last checkpoint ended.
224   */
225  private static final String ATTR_LAST_CHECKPOINT_STOP_TIME =
226       "last-checkpoint-stop-time";
227
228
229
230  /**
231   * The name of the attribute that contains the time of the last checkpoint.
232   *
233   * @deprecated  Use {@link #ATTR_LAST_CHECKPOINT_STOP_TIME} instead.
234   */
235  @Deprecated()
236  private static final String ATTR_LAST_CHECKPOINT_TIME =
237       "last-checkpoint-time";
238
239
240
241  /**
242   * The name of the attribute that contains the maximum cache size.
243   */
244  private static final String ATTR_MAX_CACHE_SIZE = "max-db-cache-size";
245
246
247
248  /**
249   * The name of the attribute that contains the length of time in milliseconds
250   * since the last checkpoint.
251   */
252  private static final String ATTR_MILLIS_SINCE_LAST_CHECKPOINT =
253       "millis-since-last-checkpoint";
254
255
256
257  /**
258   * The name of the attribute that contains the number of nodes evicted from
259   * the cache.
260   */
261  private static final String ATTR_NODES_EVICTED = "nodes-evicted";
262
263
264
265  /**
266   * The name of the attribute that contains the number of checkpoints
267   * processed.
268   */
269  private static final String ATTR_NUM_CHECKPOINTS = "num-checkpoints";
270
271
272
273  /**
274   * The name of the attribute that contains the number of read locks held.
275   */
276  private static final String ATTR_NUM_READ_LOCKS = "read-locks-held";
277
278
279
280  /**
281   * The name of the attribute that contains the total duration of the all
282   * checkpoints in milliseconds.
283   */
284  private static final String ATTR_TOTAL_CHECKPOINT_DURATION_MILLIS =
285       "total-checkpoint-duration-millis";
286
287
288
289  /**
290   * The name of the attribute that contains the number of transactions waiting
291   * on locks.
292   */
293  private static final String ATTR_NUM_WAITING_TXNS =
294       "transactions-waiting-on-locks";
295
296
297
298  /**
299   * The name of the attribute that contains the number of write locks held.
300   */
301  private static final String ATTR_NUM_WRITE_LOCKS = "write-locks-held";
302
303
304
305  /**
306   * The name of the attribute that contains the number of random reads.
307   */
308  private static final String ATTR_RANDOM_READS = "random-read-count";
309
310
311
312  /**
313   * The name of the attribute that contains the number of random writes.
314   */
315  private static final String ATTR_RANDOM_WRITES = "random-write-count";
316
317
318
319  /**
320   * The name of the attribute that contains the number of sequential reads.
321   */
322  private static final String ATTR_SEQUENTIAL_READS = "sequential-read-count";
323
324
325
326  /**
327   * The name of the attribute that contains the number of sequential writes.
328   */
329  private static final String ATTR_SEQUENTIAL_WRITES = "sequential-write-count";
330
331
332
333  /**
334   * The prefix that will be used for attribute names that contain generic
335   * environment statistics.
336   */
337  private static final String ATTR_PREFIX_ENV_STAT = "je-env-stat-";
338
339
340
341  /**
342   * The prefix that will be used for attribute names that contain generic lock
343   * statistics.
344   */
345  private static final String ATTR_PREFIX_LOCK_STAT = "je-lock-stat-";
346
347
348
349  /**
350   * The prefix that will be used for attribute names that contain generic
351   * transaction statistics.
352   */
353  private static final String ATTR_PREFIX_TXN_STAT = "je-txn-stat-";
354
355
356
357  /**
358   * The name that will be used for the property that contains generic
359   * environment statistics.
360   */
361  private static final String PROPERTY_ENV_STATS = "je-env-stats";
362
363
364
365  /**
366   * The name that will be used for the property that contains generic lock
367   * statistics.
368   */
369  private static final String PROPERTY_LOCK_STATS = "je-lock-stats";
370
371
372
373  /**
374   * The name that will be used for the property that contains generic
375   * transaction statistics.
376   */
377  private static final String PROPERTY_TXN_STATS = "je-txn-stats";
378
379
380
381  /**
382   * The serial version UID for this serializable class.
383   */
384  private static final long serialVersionUID = 2557783119454069632L;
385
386
387
388  // Indicates whether a checkpoint is currently in progress.
389  private final Boolean checkpointInProgress;
390
391  // The time the last checkpoint began.
392  private final Date lastCheckpointStartTime;
393
394  // The time the last checkpoint ended.
395  private final Date lastCheckpointStopTime;
396
397  /**
398   * The time the last checkpoint ended.
399   *
400   * @deprecated  Use lastCheckpointStopTime instead.
401   */
402  @Deprecated
403  private final Date lastCheckpointTime;
404
405  // The number of active transactions.
406  private final Long activeTransactionCount;
407
408  // The average duration for all checkpoints.
409  private final Long averageCheckpointDurationMillis;
410
411  // The current cleaner backlog.
412  private final Long cleanerBacklog;
413
414  // The current DB cache size.
415  private final Long currentDBCacheSize;
416
417  // The current DB cache percent full.
418  private final Long dbCachePercentFull;
419
420  // The current DB on-disk size.
421  private final Long dbOnDiskSize;
422
423  // The duration for the last checkpoint.
424  private final Long lastCheckpointDurationMillis;
425
426  // The maximum allowed DB cache size.
427  private final Long maxDBCacheSize;
428
429  // The length of time since the last checkpoint.
430  private final Long millisSinceLastCheckpoint;
431
432  // The number of nodes evicted from the DB cache.
433  private final Long nodesEvicted;
434
435  // The number of checkpoints completed.
436  private final Long numCheckpoints;
437
438  // The number of random reads performed.
439  private final Long randomReads;
440
441  // The number of random writes performed.
442  private final Long randomWrites;
443
444  // The number of read locks held.
445  private final Long readLocksHeld;
446
447  // The number of sequential reads performed.
448  private final Long sequentialReads;
449
450  // The number of sequential writes performed.
451  private final Long sequentialWrites;
452
453  // The total duration for all checkpoints.
454  private final Long totalCheckpointDurationMillis;
455
456  // The number of transactions waiting on locks.
457  private final Long transactionsWaitingOnLocks;
458
459  // The number of write locks held.
460  private final Long writeLocksHeld;
461
462  // The set of generic environment statistics.
463  private final Map<String,String> envStats;
464
465  // The set of generic lock statistics.
466  private final Map<String,String> lockStats;
467
468  // The set of generic transaction statistics.
469  private final Map<String,String> txnStats;
470
471  // The backend ID for the associated backend.
472  private final String backendID;
473
474  // The path to the directory containing the database files.
475  private final String dbDirectory;
476
477  // The Berkeley DB JE version string.
478  private final String jeVersion;
479
480
481
482  /**
483   * Creates a new JE environment monitor entry from the provided entry.
484   *
485   * @param  entry  The entry to be parsed as a JE environment monitor entry.
486   *                It must not be {@code null}.
487   */
488  @SuppressWarnings("deprecation")
489  public JEEnvironmentMonitorEntry(final Entry entry)
490  {
491    super(entry);
492
493    activeTransactionCount     = getLong(ATTR_ACTIVE_TXNS);
494    cleanerBacklog             = getLong(ATTR_CLEANER_BACKLOG);
495    currentDBCacheSize         = getLong(ATTR_CURRENT_CACHE_SIZE);
496    dbCachePercentFull         = getLong(ATTR_CACHE_PCT_FULL);
497    dbOnDiskSize               = getLong(ATTR_DB_ON_DISK_SIZE);
498    maxDBCacheSize             = getLong(ATTR_MAX_CACHE_SIZE);
499    nodesEvicted               = getLong(ATTR_NODES_EVICTED);
500    randomReads                = getLong(ATTR_RANDOM_READS);
501    randomWrites               = getLong(ATTR_RANDOM_WRITES);
502    readLocksHeld              = getLong(ATTR_NUM_READ_LOCKS);
503    sequentialReads            = getLong(ATTR_SEQUENTIAL_READS);
504    sequentialWrites           = getLong(ATTR_SEQUENTIAL_WRITES);
505    transactionsWaitingOnLocks = getLong(ATTR_NUM_WAITING_TXNS);
506    writeLocksHeld             = getLong(ATTR_NUM_WRITE_LOCKS);
507    backendID                  = getString(ATTR_BACKEND_ID);
508    dbDirectory                = getString(ATTR_DB_DIRECTORY);
509    jeVersion                  = getString(ATTR_JE_VERSION);
510
511    checkpointInProgress = getBoolean(ATTR_CHECKPOINT_IN_PROGRESS);
512    lastCheckpointStartTime = getDate(ATTR_LAST_CHECKPOINT_START_TIME);
513    lastCheckpointStopTime = getDate(ATTR_LAST_CHECKPOINT_STOP_TIME);
514    lastCheckpointTime = getDate(ATTR_LAST_CHECKPOINT_TIME);
515    averageCheckpointDurationMillis  =
516         getLong(ATTR_AVERAGE_CHECKPOINT_DURATION_MILLIS);
517    lastCheckpointDurationMillis =
518         getLong(ATTR_LAST_CHECKPOINT_DURATION_MILLIS);
519    millisSinceLastCheckpoint = getLong(ATTR_MILLIS_SINCE_LAST_CHECKPOINT);
520    numCheckpoints = getLong(ATTR_NUM_CHECKPOINTS);
521    totalCheckpointDurationMillis =
522         getLong(ATTR_TOTAL_CHECKPOINT_DURATION_MILLIS);
523
524    final LinkedHashMap<String,String> tmpEnvStats =
525         new LinkedHashMap<>(StaticUtils.computeMapCapacity(20));
526    final LinkedHashMap<String,String> tmpLockStats =
527         new LinkedHashMap<>(StaticUtils.computeMapCapacity(20));
528    final LinkedHashMap<String,String> tmpTxnStats =
529         new LinkedHashMap<>(StaticUtils.computeMapCapacity(20));
530    for (final Attribute a : entry.getAttributes())
531    {
532      final String name = StaticUtils.toLowerCase(a.getName());
533      if (name.startsWith(ATTR_PREFIX_ENV_STAT))
534      {
535        tmpEnvStats.put(
536             StaticUtils.toLowerCase(name.substring(
537                  ATTR_PREFIX_ENV_STAT.length())),
538             a.getValue());
539      }
540      else if (name.startsWith(ATTR_PREFIX_LOCK_STAT))
541      {
542        tmpLockStats.put(
543             StaticUtils.toLowerCase(name.substring(
544                  ATTR_PREFIX_LOCK_STAT.length())),
545             a.getValue());
546      }
547      else if (name.startsWith(ATTR_PREFIX_TXN_STAT))
548      {
549        tmpTxnStats.put(
550             StaticUtils.toLowerCase(name.substring(
551                  ATTR_PREFIX_TXN_STAT.length())),
552             a.getValue());
553      }
554    }
555
556    envStats  = Collections.unmodifiableMap(tmpEnvStats);
557    lockStats = Collections.unmodifiableMap(tmpLockStats);
558    txnStats  = Collections.unmodifiableMap(tmpTxnStats);
559  }
560
561
562
563  /**
564   * Retrieves the backend ID for the backend with which the Berkeley DB JE
565   * database is associated.
566   *
567   * @return  The backend ID for the backend with which the Berkeley DB JE
568   *          database is associated.
569   */
570  public String getBackendID()
571  {
572    return backendID;
573  }
574
575
576
577  /**
578   * Retrieves the Berkeley DB JE version string for the database environment
579   * of the associated backend.
580   *
581   * @return  The Berkeley DB JE version string for the database environment of
582   *          the associated backend, or {@code null} if it was not included in
583   *          the monitor entry.
584   */
585  public String getJEVersion()
586  {
587    return jeVersion;
588  }
589
590
591
592  /**
593   * Retrieves the path to the directory containing the database files.
594   *
595   * @return  The path to the directory containing the database files, or
596   *          {@code null} if it was not included in the monitor entry.
597   */
598  public String getDBDirectory()
599  {
600    return dbDirectory;
601  }
602
603
604
605  /**
606   * Retrieves the amount of disk space in bytes consumed by the database files.
607   *
608   * @return  The amount of disk space in bytes consumed by the database files,
609   *          or {@code null} if it was not included in the monitor entry.
610   */
611  public Long getDBOnDiskSize()
612  {
613    return dbOnDiskSize;
614  }
615
616
617
618  /**
619   * Retrieves the amount of memory in bytes currently consumed by the database
620   * cache.
621   *
622   * @return  The amount of memory in bytes currently consumed by the database
623   *          cache, or {@code null} if it was not included in the monitor
624   *          entry.
625   */
626  public Long getCurrentDBCacheSize()
627  {
628    return currentDBCacheSize;
629  }
630
631
632
633  /**
634   * Retrieves the maximum amount of memory in bytes that may be consumed by the
635   * database cache.
636   *
637   * @return  The maximum of memory in bytes that may be consumed by the
638   *          database cache, or {@code null} if it was not included in the
639   *          monitor entry.
640   */
641  public Long getMaxDBCacheSize()
642  {
643    return maxDBCacheSize;
644  }
645
646
647
648  /**
649   * Retrieves the percentage of the maximum database cache size that is
650   * currently in use.
651   *
652   * @return  The percentage of the maximum database cache size that is
653   *          currently in use, or {@code null} if it was not included in the
654   *          monitor entry.
655   */
656  public Long getDBCachePercentFull()
657  {
658    return dbCachePercentFull;
659  }
660
661
662
663  /**
664   * Indicates whether a checkpoint is currently in progress in the associated
665   * backend.
666   *
667   * @return  A {@code Boolean} value indicating whether a checkpoint is
668   *          currently in progress in the associated backend, or {@code null}
669   *          if it was not included in the monitor entry.
670   */
671  public Boolean checkpointInProgress()
672  {
673    return checkpointInProgress;
674  }
675
676
677
678  /**
679   * Retrieves the number of checkpoints completed in the associated backend.
680   *
681   * @return  The number of checkpoints completed in the associated backend, or
682   *          {@code null} if it was not included in the monitor entry.
683   */
684  public Long getNumCheckpoints()
685  {
686    return numCheckpoints;
687  }
688
689
690
691  /**
692   * Retrieves the total duration in milliseconds of all checkpoints completed
693   * in the associated backend.
694   *
695   * @return  The total duration in milliseconds of all checkpoints completed in
696   *          the associated backend, or {@code null} if it was not included in
697   *          the monitor entry.
698   */
699  public Long getTotalCheckpointDurationMillis()
700  {
701    return totalCheckpointDurationMillis;
702  }
703
704
705
706  /**
707   * Retrieves the average duration in milliseconds of all checkpoints completed
708   * in the associated backend.
709   *
710   * @return  The average duration in milliseconds of all checkpoints completed
711   *          in the associated backend, or {@code null} if it was not included
712   *          in the monitor entry.
713   */
714  public Long getAverageCheckpointDurationMillis()
715  {
716    return averageCheckpointDurationMillis;
717  }
718
719
720
721  /**
722   * Retrieves the duration in milliseconds of the last checkpoint completed in
723   * the associated backend.
724   *
725   * @return  The duration in milliseconds of the last checkpoint completed in
726   *          the associated backend, or {@code null} if it was not included
727   *          in the monitor entry.
728   */
729  public Long getLastCheckpointDurationMillis()
730  {
731    return lastCheckpointDurationMillis;
732  }
733
734
735
736  /**
737   * Retrieves the time that the last completed checkpoint began.
738   *
739   * @return  The time that the last completed checkpoint began, or {@code null}
740   *          if it was not included in the monitor entry.
741   */
742  public Date getLastCheckpointStartTime()
743  {
744    return lastCheckpointStartTime;
745  }
746
747
748
749  /**
750   * Retrieves the time that the last completed checkpoint ended.
751   *
752   * @return  The time that the last completed checkpoint ended, or {@code null}
753   *          if it was not included in the monitor entry.
754   */
755  public Date getLastCheckpointStopTime()
756  {
757    return lastCheckpointStopTime;
758  }
759
760
761
762  /**
763   * Retrieves the time that the last checkpoint occurred.
764   *
765   * @return  The time that the last checkpoint occurred, or {@code null} if it
766   *          was not included in the monitor entry.
767   *
768   * @deprecated  Use {@link #getLastCheckpointStopTime()} instead.
769   */
770  @Deprecated()
771  @SuppressWarnings("deprecation")
772  public Date getLastCheckpointTime()
773  {
774    return lastCheckpointTime;
775  }
776
777
778
779  /**
780   * Retrieves the length of time in milliseconds since the last completed
781   * checkpoint.
782   *
783   * @return  The length of time in milliseconds since the last completed
784   *          checkpoint, or {@code null} if it was not included in the monitor
785   *          entry.
786   */
787  public Long getMillisSinceLastCheckpoint()
788  {
789    return millisSinceLastCheckpoint;
790  }
791
792
793
794  /**
795   * Retrieves the number of log files that the cleaner needs to examine.
796   *
797   * @return  The number of log files that the cleaner needs to examine, or
798   *          {@code null} if it was not included in the monitor entry.
799   */
800  public Long getCleanerBacklog()
801  {
802    return cleanerBacklog;
803  }
804
805
806
807  /**
808   * Retrieves the number of nodes that have been evicted from the database
809   * cache since the backend was started.
810   *
811   * @return  The number of nodes that have been evicted from the database cache
812   *          since the backend was started, or {@code null} if it was not
813   *          included in the monitor entry.
814   */
815  public Long getNodesEvicted()
816  {
817    return nodesEvicted;
818  }
819
820
821
822  /**
823   * Retrieves the number of random-access disk reads performed since the
824   * backend was started.
825   *
826   * @return  The number of random-access disk reads performed since the backend
827   *          was started, or {@code null} if it was not included in the monitor
828   *          entry.
829   */
830  public Long getRandomReads()
831  {
832    return randomReads;
833  }
834
835
836
837  /**
838   * Retrieves the number of random-access disk writes performed since the
839   * backend was started.
840   *
841   * @return  The number of random-access disk writes performed since the
842   *          backend was started, or {@code null} if it was not included in the
843   *          monitor entry.
844   */
845  public Long getRandomWrites()
846  {
847    return randomWrites;
848  }
849
850
851
852  /**
853   * Retrieves the number of sequential disk reads performed since the backend
854   * was started.
855   *
856   * @return  The number of sequential disk reads performed since the backend
857   *          was started, or {@code null} if it was not included in the monitor
858   *          entry.
859   */
860  public Long getSequentialReads()
861  {
862    return sequentialReads;
863  }
864
865
866
867  /**
868   * Retrieves the number of sequential disk writes performed since the backend
869   * was started.
870   *
871   * @return  The number of sequential disk writes performed since the backend
872   *          was started, or {@code null} if it was not included in the monitor
873   *          entry.
874   */
875  public Long getSequentialWrites()
876  {
877    return sequentialWrites;
878  }
879
880
881
882  /**
883   * Retrieves the number of active transactions in the JE database environment.
884   *
885   * @return  The number of active transactions in the JE database environment,
886   *          or {@code null} if it was not included in the monitor entry.
887   */
888  public Long getActiveTransactionCount()
889  {
890    return activeTransactionCount;
891  }
892
893
894
895  /**
896   * Retrieves the number of read locks held in the JE database environment.
897   *
898   * @return  The number of read locks held in the JE database environment, or
899   *          {@code null} if it was not included in the monitor entry.
900   */
901  public Long getReadLocksHeld()
902  {
903    return readLocksHeld;
904  }
905
906
907
908  /**
909   * Retrieves the number of write locks held in the JE database environment.
910   *
911   * @return  The number of write locks held in the JE database environment, or
912   *          {@code null} if it was not included in the monitor entry.
913   */
914  public Long getWriteLocksHeld()
915  {
916    return writeLocksHeld;
917  }
918
919
920
921  /**
922   * Retrieves the number of transactions currently waiting on a lock in the
923   * database environment.
924   *
925   * @return  The number of transactions currently waiting on a lock in the
926   *          database environment, or {@code null} if it was not included in
927   *          the monitor entry.
928   */
929  public Long getTransactionsWaitingOnLocks()
930  {
931    return transactionsWaitingOnLocks;
932  }
933
934
935
936  /**
937   * Retrieves a set of general environment statistics for the database
938   * environment, mapped from the statistic name to the string representation of
939   * its value.  The statistic names will be formatted in all lowercase
940   * characters.
941   *
942   * @return  A set of general environment statistics for the database
943   *          environment, mapped from the statistic name to the string
944   *          representation of its value.
945   */
946  public Map<String,String> getEnvironmentStats()
947  {
948    return envStats;
949  }
950
951
952
953  /**
954   * Retrieves the string representation of the value for a database environment
955   * statistic.
956   *
957   * @param  statName  The name of the statistic to retrieve.  It will be
958   *                   treated in a case-insensitive manner.
959   *
960   * @return  The value of the requested database environment statistic, or
961   *          {@code null} if no such statistic was provided.
962   */
963  public String getEnvironmentStat(final String statName)
964  {
965    return envStats.get(StaticUtils.toLowerCase(statName));
966  }
967
968
969
970  /**
971   * Retrieves a set of lock statistics for the database environment, mapped
972   * from the statistic name to the string representation of its value.  The
973   * statistic names will be formatted in all lowercase characters.
974   *
975   * @return  A set of lock statistics for the database environment, mapped from
976   *          the statistic name to the string representation of its value.
977   */
978  public Map<String,String> getLockStats()
979  {
980    return lockStats;
981  }
982
983
984
985  /**
986   * Retrieves the string representation of the value for a database environment
987   * lock statistic.
988   *
989   * @param  statName  The name of the statistic to retrieve.  It will be
990   *                   treated in a case-insensitive manner.
991   *
992   * @return  The value of the requested database environment lock statistic, or
993   *          {@code null} if no such statistic was provided.
994   */
995  public String getLockStat(final String statName)
996  {
997    return lockStats.get(StaticUtils.toLowerCase(statName));
998  }
999
1000
1001
1002  /**
1003   * Retrieves a set of transaction statistics for the database environment,
1004   * mapped from the statistic name to the string representation of its value.
1005   * The statistic names will be formatted in all lowercase characters.
1006   *
1007   * @return  A set of transaction statistics for the database environment,
1008   *          mapped from the statistic name to the string representation of its
1009   *          value.
1010   */
1011  public Map<String,String> getTransactionStats()
1012  {
1013    return txnStats;
1014  }
1015
1016
1017
1018  /**
1019   * Retrieves the string representation of the value for a database environment
1020   * transaction statistic.
1021   *
1022   * @param  statName  The name of the statistic to retrieve.  It will be
1023   *                   treated in a case-insensitive manner.
1024   *
1025   * @return  The value of the requested database environment transaction
1026   *          statistic, or {@code null} if no such statistic was provided.
1027   */
1028  public String getTransactionStat(final String statName)
1029  {
1030    return txnStats.get(StaticUtils.toLowerCase(statName));
1031  }
1032
1033
1034
1035  /**
1036   * {@inheritDoc}
1037   */
1038  @Override()
1039  public String getMonitorDisplayName()
1040  {
1041    return INFO_JE_ENVIRONMENT_MONITOR_DISPNAME.get();
1042  }
1043
1044
1045
1046  /**
1047   * {@inheritDoc}
1048   */
1049  @Override()
1050  public String getMonitorDescription()
1051  {
1052    return INFO_JE_ENVIRONMENT_MONITOR_DESC.get();
1053  }
1054
1055
1056
1057  /**
1058   * {@inheritDoc}
1059   */
1060  @Override()
1061  public Map<String,MonitorAttribute> getMonitorAttributes()
1062  {
1063    final LinkedHashMap<String,MonitorAttribute> attrs =
1064         new LinkedHashMap<>(StaticUtils.computeMapCapacity(20));
1065
1066    if (backendID != null)
1067    {
1068      addMonitorAttribute(attrs,
1069           ATTR_BACKEND_ID,
1070           INFO_JE_ENVIRONMENT_DISPNAME_BACKEND_ID.get(),
1071           INFO_JE_ENVIRONMENT_DESC_BACKEND_ID.get(),
1072           backendID);
1073    }
1074
1075    if (jeVersion != null)
1076    {
1077      addMonitorAttribute(attrs,
1078           ATTR_JE_VERSION,
1079           INFO_JE_ENVIRONMENT_DISPNAME_JE_VERSION.get(),
1080           INFO_JE_ENVIRONMENT_DESC_JE_VERSION.get(),
1081           jeVersion);
1082    }
1083
1084    if (dbDirectory != null)
1085    {
1086      addMonitorAttribute(attrs,
1087           ATTR_DB_DIRECTORY,
1088           INFO_JE_ENVIRONMENT_DISPNAME_DB_DIRECTORY.get(),
1089           INFO_JE_ENVIRONMENT_DESC_DB_DIRECTORY.get(),
1090           dbDirectory);
1091    }
1092
1093    if (dbOnDiskSize != null)
1094    {
1095      addMonitorAttribute(attrs,
1096           ATTR_DB_ON_DISK_SIZE,
1097           INFO_JE_ENVIRONMENT_DISPNAME_DB_ON_DISK_SIZE.get(),
1098           INFO_JE_ENVIRONMENT_DESC_DB_ON_DISK_SIZE.get(),
1099           dbOnDiskSize);
1100    }
1101
1102    if (currentDBCacheSize != null)
1103    {
1104      addMonitorAttribute(attrs,
1105           ATTR_CURRENT_CACHE_SIZE,
1106           INFO_JE_ENVIRONMENT_DISPNAME_CURRENT_CACHE_SIZE.get(),
1107           INFO_JE_ENVIRONMENT_DESC_CURRENT_CACHE_SIZE.get(),
1108           currentDBCacheSize);
1109    }
1110
1111    if (maxDBCacheSize != null)
1112    {
1113      addMonitorAttribute(attrs,
1114           ATTR_MAX_CACHE_SIZE,
1115           INFO_JE_ENVIRONMENT_DISPNAME_MAX_CACHE_SIZE.get(),
1116           INFO_JE_ENVIRONMENT_DESC_MAX_CACHE_SIZE.get(),
1117           maxDBCacheSize);
1118    }
1119
1120    if (dbCachePercentFull != null)
1121    {
1122      addMonitorAttribute(attrs,
1123           ATTR_CACHE_PCT_FULL,
1124           INFO_JE_ENVIRONMENT_DISPNAME_CACHE_PCT_FULL.get(),
1125           INFO_JE_ENVIRONMENT_DESC_CACHE_PCT_FULL.get(),
1126           dbCachePercentFull);
1127    }
1128
1129    if (checkpointInProgress != null)
1130    {
1131      addMonitorAttribute(attrs,
1132           ATTR_CHECKPOINT_IN_PROGRESS,
1133           INFO_JE_ENVIRONMENT_DISPNAME_CP_IN_PROGRESS.get(),
1134           INFO_JE_ENVIRONMENT_DESC_CP_IN_PROGRESS.get(),
1135           checkpointInProgress);
1136    }
1137
1138    if (numCheckpoints != null)
1139    {
1140      addMonitorAttribute(attrs,
1141           ATTR_NUM_CHECKPOINTS,
1142           INFO_JE_ENVIRONMENT_DISPNAME_NUM_CP.get(),
1143           INFO_JE_ENVIRONMENT_DESC_NUM_CP.get(),
1144           numCheckpoints);
1145    }
1146
1147    if (totalCheckpointDurationMillis != null)
1148    {
1149      addMonitorAttribute(attrs,
1150           ATTR_TOTAL_CHECKPOINT_DURATION_MILLIS,
1151           INFO_JE_ENVIRONMENT_DISPNAME_TOTAL_CP_DURATION.get(),
1152           INFO_JE_ENVIRONMENT_DESC_TOTAL_CP_DURATION.get(),
1153           totalCheckpointDurationMillis);
1154    }
1155
1156    if (averageCheckpointDurationMillis != null)
1157    {
1158      addMonitorAttribute(attrs,
1159           ATTR_AVERAGE_CHECKPOINT_DURATION_MILLIS,
1160           INFO_JE_ENVIRONMENT_DISPNAME_AVG_CP_DURATION.get(),
1161           INFO_JE_ENVIRONMENT_DESC_AVG_CP_DURATION.get(),
1162           averageCheckpointDurationMillis);
1163    }
1164
1165    if (lastCheckpointDurationMillis != null)
1166    {
1167      addMonitorAttribute(attrs,
1168           ATTR_LAST_CHECKPOINT_DURATION_MILLIS,
1169           INFO_JE_ENVIRONMENT_DISPNAME_LAST_CP_DURATION.get(),
1170           INFO_JE_ENVIRONMENT_DESC_LAST_CP_DURATION.get(),
1171           lastCheckpointDurationMillis);
1172    }
1173
1174    if (lastCheckpointStartTime != null)
1175    {
1176      addMonitorAttribute(attrs,
1177           ATTR_LAST_CHECKPOINT_START_TIME,
1178           INFO_JE_ENVIRONMENT_DISPNAME_LAST_CP_START_TIME.get(),
1179           INFO_JE_ENVIRONMENT_DESC_LAST_CP_START_TIME.get(),
1180           lastCheckpointStartTime);
1181    }
1182
1183    if (lastCheckpointStopTime != null)
1184    {
1185      addMonitorAttribute(attrs,
1186           ATTR_LAST_CHECKPOINT_STOP_TIME,
1187           INFO_JE_ENVIRONMENT_DISPNAME_LAST_CP_STOP_TIME.get(),
1188           INFO_JE_ENVIRONMENT_DESC_LAST_CP_STOP_TIME.get(),
1189           lastCheckpointStopTime);
1190    }
1191
1192    if (millisSinceLastCheckpoint != null)
1193    {
1194      addMonitorAttribute(attrs,
1195           ATTR_MILLIS_SINCE_LAST_CHECKPOINT,
1196           INFO_JE_ENVIRONMENT_DISPNAME_MILLIS_SINCE_CP.get(),
1197           INFO_JE_ENVIRONMENT_DESC_MILLIS_SINCE_CP.get(),
1198           millisSinceLastCheckpoint);
1199    }
1200
1201    if (cleanerBacklog != null)
1202    {
1203      addMonitorAttribute(attrs,
1204           ATTR_CLEANER_BACKLOG,
1205           INFO_JE_ENVIRONMENT_DISPNAME_CLEANER_BACKLOG.get(),
1206           INFO_JE_ENVIRONMENT_DESC_CLEANER_BACKLOG.get(),
1207           cleanerBacklog);
1208    }
1209
1210    if (nodesEvicted != null)
1211    {
1212      addMonitorAttribute(attrs,
1213           ATTR_NODES_EVICTED,
1214           INFO_JE_ENVIRONMENT_DISPNAME_NODES_EVICTED.get(),
1215           INFO_JE_ENVIRONMENT_DESC_NODES_EVICTED.get(),
1216           nodesEvicted);
1217    }
1218
1219    if (randomReads != null)
1220    {
1221      addMonitorAttribute(attrs,
1222           ATTR_RANDOM_READS,
1223           INFO_JE_ENVIRONMENT_DISPNAME_RANDOM_READS.get(),
1224           INFO_JE_ENVIRONMENT_DESC_RANDOM_READS.get(),
1225           randomReads);
1226    }
1227
1228    if (randomWrites != null)
1229    {
1230      addMonitorAttribute(attrs,
1231           ATTR_RANDOM_WRITES,
1232           INFO_JE_ENVIRONMENT_DISPNAME_RANDOM_WRITES.get(),
1233           INFO_JE_ENVIRONMENT_DESC_RANDOM_WRITES.get(),
1234           randomWrites);
1235    }
1236
1237    if (sequentialReads != null)
1238    {
1239      addMonitorAttribute(attrs,
1240           ATTR_SEQUENTIAL_READS,
1241           INFO_JE_ENVIRONMENT_DISPNAME_SEQUENTIAL_READS.get(),
1242           INFO_JE_ENVIRONMENT_DESC_SEQUENTIAL_READS.get(),
1243           sequentialReads);
1244    }
1245
1246    if (sequentialWrites != null)
1247    {
1248      addMonitorAttribute(attrs,
1249           ATTR_SEQUENTIAL_WRITES,
1250           INFO_JE_ENVIRONMENT_DISPNAME_SEQUENTIAL_WRITES.get(),
1251           INFO_JE_ENVIRONMENT_DESC_SEQUENTIAL_WRITES.get(),
1252           sequentialWrites);
1253    }
1254
1255    if (activeTransactionCount != null)
1256    {
1257      addMonitorAttribute(attrs,
1258           ATTR_ACTIVE_TXNS,
1259           INFO_JE_ENVIRONMENT_DISPNAME_ACTIVE_TXNS.get(),
1260           INFO_JE_ENVIRONMENT_DESC_ACTIVE_TXNS.get(),
1261           activeTransactionCount);
1262    }
1263
1264    if (readLocksHeld != null)
1265    {
1266      addMonitorAttribute(attrs,
1267           ATTR_NUM_READ_LOCKS,
1268           INFO_JE_ENVIRONMENT_DISPNAME_READ_LOCKS.get(),
1269           INFO_JE_ENVIRONMENT_DESC_READ_LOCKS.get(),
1270           readLocksHeld);
1271    }
1272
1273    if (writeLocksHeld != null)
1274    {
1275      addMonitorAttribute(attrs,
1276           ATTR_NUM_WRITE_LOCKS,
1277           INFO_JE_ENVIRONMENT_DISPNAME_WRITE_LOCKS.get(),
1278           INFO_JE_ENVIRONMENT_DESC_WRITE_LOCKS.get(),
1279           writeLocksHeld);
1280    }
1281
1282    if (transactionsWaitingOnLocks != null)
1283    {
1284      addMonitorAttribute(attrs,
1285           ATTR_NUM_WAITING_TXNS,
1286           INFO_JE_ENVIRONMENT_DISPNAME_TXNS_WAITING_ON_LOCKS.get(),
1287           INFO_JE_ENVIRONMENT_DESC_TXNS_WAITING_ON_LOCKS.get(),
1288           transactionsWaitingOnLocks);
1289    }
1290
1291    if (! envStats.isEmpty())
1292    {
1293      final ArrayList<String> values = new ArrayList<>(envStats.size());
1294      for (final Map.Entry<String,String> e : envStats.entrySet())
1295      {
1296        values.add(e.getKey() + '=' + e.getValue());
1297      }
1298
1299      addMonitorAttribute(attrs,
1300           PROPERTY_ENV_STATS,
1301           INFO_JE_ENVIRONMENT_DISPNAME_ENV_STATS.get(),
1302           INFO_JE_ENVIRONMENT_DESC_ENV_STATS.get(),
1303           values);
1304    }
1305
1306    if (! lockStats.isEmpty())
1307    {
1308      final ArrayList<String> values = new ArrayList<>(lockStats.size());
1309      for (final Map.Entry<String,String> e : lockStats.entrySet())
1310      {
1311        values.add(e.getKey() + '=' + e.getValue());
1312      }
1313
1314      addMonitorAttribute(attrs,
1315           PROPERTY_LOCK_STATS,
1316           INFO_JE_ENVIRONMENT_DISPNAME_LOCK_STATS.get(),
1317           INFO_JE_ENVIRONMENT_DESC_LOCK_STATS.get(),
1318           values);
1319    }
1320
1321    if (! txnStats.isEmpty())
1322    {
1323      final ArrayList<String> values = new ArrayList<>(txnStats.size());
1324      for (final Map.Entry<String,String> e : txnStats.entrySet())
1325      {
1326        values.add(e.getKey() + '=' + e.getValue());
1327      }
1328
1329      addMonitorAttribute(attrs,
1330           PROPERTY_TXN_STATS,
1331           INFO_JE_ENVIRONMENT_DISPNAME_TXN_STATS.get(),
1332           INFO_JE_ENVIRONMENT_DESC_TXN_STATS.get(),
1333           values);
1334    }
1335
1336    return Collections.unmodifiableMap(attrs);
1337  }
1338}