/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.toolkitbridge.transitional; import java.util.List; import java.util.Map; import de.rcenvironment.core.toolkitbridge.api.StaticToolkitHolder; import de.rcenvironment.toolkit.modules.statistics.api.StatisticsTrackerService; /** * Provides a central mechanism for key/counter statistics. The key space is two-layered: on the top layer, arbitrary string keys define * categories; below that, each category holds a key-value map with string keys and a value holder. This holder can either be a "counter", * which represents a simple numeric (Java "long") value, or a "value event tracker", which registers events as numerical values, and * collects statistics about these values (for example, minimum, average, and maximum). * * All methods are safe for concurrent usage, in the sense that no values or events will ever be lost in the case of concurrent calls. Note * that, however, the generated reports are not strictly serialized with regards to concurrent counter events. This has the effect that it * is undefined whether a counter call that is made <b>during</b> report creation will still be reflected in that report or not. In the use * cases this statistics service is used for, this distinction is irrelevant, and was therefore designed for minimizing overhead instead. * * Note that this static class is a backwards compatibility wrapper for {@link StatisticsTrackerService}; new code should inject and use * this service directly. This static class will probably be deprecated in the future. * * @author Robert Mischke */ public final class StatsCounter { // Note: If there is a need to disable statistics gathering in the future, the actual service could simply be substituted with a // NOP service private static final StatisticsTrackerService sharedServiceInstance = initializeInstance(); // prevent instantiation private StatsCounter() {} /** * Checks whether statistics are enabled; should be used to prevent unneeded string concatenations for {@link #count(String, String)} * calls when statistics are disabled. * * @return true if statistics collection is enabled */ public static boolean isEnabled() { return true; // always enabled for now; to disable, provide a NOP StatisticsTrackerService implementation and return "false" here } /** * Increments the given counter by one. * * @param category the category identifier * @param key the counter key within the category */ public static void count(String category, String key) { sharedServiceInstance.getCounterCategory(category).count(key); } /** * Increments the given counter by an arbitrary value. * * @param category the category identifier * @param key the counter key within the category * @param delta the number to add to the counter; negative values and zero are allowed */ public static void count(String category, String key, long delta) { sharedServiceInstance.getCounterCategory(category).count(key, delta); } /** * Convenience method for the common case where occurrences of classes should be counted, with proper handling of null objects. The * counter key is the name of the object's class acquired using {@link Class#getName()}; for null objects, "<null>" is used as the * counter key. * * @param category the category identifier * @param object the object to count */ public static void countClass(String category, Object object) { sharedServiceInstance.getCounterCategory(category).countClass(object); } /** * Registers an event's value, for example an task's duration. * * @param category the category identifier * @param key the key within the category * @param value the value associated with an event */ public static void registerValue(String category, String key, long value) { sharedServiceInstance.getValueEventCategory(category).registerEvent(key, value); } /** * Gets a map of all counter maps; the outer map holds the categories, while the inner maps hold each categories' counter entries. * * @return the map of counter maps */ public static Map<String, Map<String, String>> getFullReport() { return sharedServiceInstance.getFullReport(); } /** * Gets the counter map for a single category. * * @param category the category id * @return the counter map */ public static Map<String, String> getReportForCategory(String category) { return sharedServiceInstance.getReportForCategory(category); } /** * Fetches all data via {@link #getFullReport()} and renders it into a standard representation. * * @return the rendered text lines */ public static List<String> getFullReportAsStandardTextRepresentation() { return sharedServiceInstance.getFullReportAsStandardTextRepresentation(); } private static StatisticsTrackerService initializeInstance() { return StaticToolkitHolder.getServiceWithUnitTestFallback(StatisticsTrackerService.class); } }