Class ProgressLogger


  • public final class ProgressLogger
    extends java.lang.Object
    Tunable progress logger.

    This class provides a simple way to log progress information about long-lasting activities. While originally based on Log4J 1.2, it is currently based on SLF4J.

    To use this class, you first create a new instance by passing an SLF4J logger, a time interval and a name for the items that are being logged. Information will be logged about the current state of affairs no more often than the given time interval. Note that the name of the logged items can be changed at any time.

    To log the progress of an activity, you call start(CharSequence) at the beginning, which will display the given string. Then, each time you want to mark progress, you call usually update() or lightUpdate(). The latter methods increase the item counter, and will log progress information if enough time has passed since the last log (and if the counter is a multiple of LIGHT_UPDATE_MASK + 1, in the case of lightUpdate()). Other update methods (e.g., update(long), updateAndDisplay(), …) make the update and display process very flexible. When the activity is over, you call stop(). At that point, the method toString() returns information about the internal state of the logger (elapsed time, number of items per second) that can be printed or otherwise processed. If update() has never been called, you will just get the elapsed time. By calling done() instead of stop, this information will be logged for you.

    Additionally:

    • by setting the expected amount of updates before calling start() you can get some estimations on the completion time;
    • by setting displayFreeMemory you can display information about the memory usage;
    • by setting displayLocalSpeed you can display, beside the average speed since the start of the activity, the speed since the last log;
    • by setting info you can display arbitrary additional information.
    • by setting speedTimeUnit and itemTimeUnit you can fix the time unit used to measure the speed and the time per item.

    After you finished a run of the progress logger, you can change its attributes and call start() again to measure another activity.

    A typical call sequence to a progress logger is as follows:

     ProgressLogger pl = new ProgressLogger(logger, 1, TimeUnit.MINUTES);
     pl.start("Smashing pumpkins...");
     ... activity on pumpkins that calls update() on each pumpkin ...
     pl.done();
     

    A more flexible behaviour can be obtained at the end of the process by calling stop():

     ProgressLogger pl = new ProgressLogger(logger, 1, TimeUnit.MINUTES, "pumpkins");
     pl.start("Smashing pumpkins...");
     ... activity on pumpkins that calls update() on each pumpkin ...
     pl.stop("Really done!");
     pl.logger.info(pl.toString());
     

    An instance of this class can also be used as a handy timer:

     ProgressLogger pl = new ProgressLogger();
     pl.start("Smashing pumpkins...");
     ... activity on pumpkins (no update() calls) ...
     pl.done(howManyPumpkins);
     

    Should you need to display additional information, you can set the field info to any object: it will be printed just after the timing (and possibly memory) information.

    Since:
    0.9.3
    Author:
    Sebastiano Vigna
    • Field Summary

      Fields 
      Modifier and Type Field Description
      long count
      The number of calls to update() since the last start() (but it be changed also with update(long) and set(long)).
      static long DEFAULT_LOG_INTERVAL  
      boolean displayFreeMemory
      Whether to display the free memory at each progress log (default: false).
      boolean displayLocalSpeed
      Whether to display additionally the local speed, that is, the detected speed between two consecutive logs, as opposed to the average speed since start() (default: false).
      long expectedUpdates
      The number of expected calls to update() (used to compute the percentages, ignored if negative).
      java.lang.Object info
      If non-null, this object will be printed after the timing information.
      java.lang.String itemsName
      The name of several counted items.
      java.util.concurrent.TimeUnit itemTimeUnit
      A fixed time unit for printing the timing of an item.
      int LIGHT_UPDATE_MASK
      Calls to lightUpdate() will cause a call to System.currentTimeMillis() only if the current value of count is a multiple of this mask plus one.
      org.slf4j.Logger logger
      The SLF4J logger used by this progress logger.
      long logInterval
      The time interval for a new log in milliseconds.
      static long ONE_HOUR  
      static long ONE_MINUTE  
      static long ONE_SECOND  
      java.util.concurrent.TimeUnit speedTimeUnit
      A fixed time unit for printing the speed.
      static long TEN_MINUTES  
      static long TEN_SECONDS  
    • Constructor Summary

      Constructors 
      Constructor Description
      ProgressLogger()
      Creates a new progress logger using items as items name and logging every 10000L milliseconds to the root logger.
      ProgressLogger​(java.lang.String itemsName)
      Creates a new progress logger logging every 10000L milliseconds to the root logger.
      ProgressLogger​(org.slf4j.Logger logger)
      Creates a new progress logger using items as items name and logging every 10000L milliseconds.
      ProgressLogger​(org.slf4j.Logger logger, long logInterval, java.util.concurrent.TimeUnit timeUnit)
      Creates a new progress logger using items as items name.
      ProgressLogger​(org.slf4j.Logger logger, long logInterval, java.util.concurrent.TimeUnit timeUnit, java.lang.String itemsName)
      Creates a new progress logger.
      ProgressLogger​(org.slf4j.Logger logger, java.lang.String itemsName)
      Creates a new progress logger logging every 10000L milliseconds.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void done()
      Completes a run of this progress logger, logging “Completed.” and the logger itself.
      void done​(long count)
      Completes a run of this progress logger and sets the internal counter, logging “Completed.” and the logger itself.
      void lightUpdate()
      Updates the internal count of this progress logger by adding one in a lightweight fashion.
      org.slf4j.Logger logger()
      The SLF4J logger used by this progress logger; it just returns the content of the field logger.
      long millis()
      Returns the number of milliseconds between present time and the last call to start(), if this progress logger is running, or between the last call to stop() and the last call to start(), if this progress logger is stopped.
      void set​(long count)
      Sets the internal count of this progress logger to a specified value; if enough time has passed since the last log, information will be logged.
      void setAndDisplay​(long count)
      Sets the internal count of this progress logger to a specified value, forcing a display.
      void start()
      Starts the progress logger, resetting the count.
      void start​(long alreadyElapsed)
      Starts the progress logger, resetting the count and assuming that a given amount of time has already passed.
      void start​(java.lang.CharSequence message)
      Starts the progress logger, displaying a message and resetting the count.
      void start​(java.lang.CharSequence message, long alreadyElapsed)
      Starts the progress logger, displaying a message, resetting the count and assuming that a given amount of time has already passed.
      void stop()
      Stops the progress logger.
      void stop​(java.lang.CharSequence message)
      Stops the progress logger, displaying a message.
      java.lang.String toString()
      Converts the data currently stored in this progress logger to a string.
      void update()
      Updates the internal count of this progress logger by adding one; if enough time has passed since the last log, information will be logged.
      void update​(long count)
      Updates the internal count of this progress logger by adding a specified value; if enough time has passed since the last log, information will be logged.
      void updateAndDisplay()
      Updates the internal count of this progress logger by adding one, forcing a display.
      void updateAndDisplay​(long count)
      Updates the internal count of this progress logger by adding a specified value, forcing a display.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Field Detail

      • LIGHT_UPDATE_MASK

        public final int LIGHT_UPDATE_MASK
        Calls to lightUpdate() will cause a call to System.currentTimeMillis() only if the current value of count is a multiple of this mask plus one.
        See Also:
        Constant Field Values
      • logger

        public final org.slf4j.Logger logger
        The SLF4J logger used by this progress logger.
      • logInterval

        public long logInterval
        The time interval for a new log in milliseconds. Can be set at any time (e.g., using TimeUnit.toMillis(long)).
      • info

        public java.lang.Object info
        If non-null, this object will be printed after the timing information.
      • expectedUpdates

        public long expectedUpdates
        The number of expected calls to update() (used to compute the percentages, ignored if negative).
      • itemsName

        public java.lang.String itemsName
        The name of several counted items.
      • displayFreeMemory

        public boolean displayFreeMemory
        Whether to display the free memory at each progress log (default: false).
      • displayLocalSpeed

        public boolean displayLocalSpeed
        Whether to display additionally the local speed, that is, the detected speed between two consecutive logs, as opposed to the average speed since start() (default: false).
      • speedTimeUnit

        public java.util.concurrent.TimeUnit speedTimeUnit
        A fixed time unit for printing the speed. If null, ProgressLogger will choose a time unit that is easy to understand. In some cases (e.g., machine-parsed logs) you might want to have always the speed in items per seconds, minues, hours or days.
      • itemTimeUnit

        public java.util.concurrent.TimeUnit itemTimeUnit
        A fixed time unit for printing the timing of an item. If null, ProgressLogger chooses a unit that is easy to understand. In some cases (e.g., machine-parsed logs) you might want to have always have the time for an item in nanoseconds, milliseconds, milliseconds, seconds, minutes or hours.
    • Constructor Detail

      • ProgressLogger

        public ProgressLogger()
        Creates a new progress logger using items as items name and logging every 10000L milliseconds to the root logger.
      • ProgressLogger

        public ProgressLogger​(java.lang.String itemsName)
        Creates a new progress logger logging every 10000L milliseconds to the root logger.
        Parameters:
        itemsName - a plural name denoting the counted items.
      • ProgressLogger

        public ProgressLogger​(org.slf4j.Logger logger)
        Creates a new progress logger using items as items name and logging every 10000L milliseconds.
        Parameters:
        logger - the logger to which messages will be sent.
      • ProgressLogger

        public ProgressLogger​(org.slf4j.Logger logger,
                              java.lang.String itemsName)
        Creates a new progress logger logging every 10000L milliseconds.
        Parameters:
        logger - the logger to which messages will be sent.
        itemsName - a plural name denoting the counted items.
      • ProgressLogger

        public ProgressLogger​(org.slf4j.Logger logger,
                              long logInterval,
                              java.util.concurrent.TimeUnit timeUnit)
        Creates a new progress logger using items as items name.
        Parameters:
        logger - the logger to which messages will be sent.
        logInterval - the logging interval.
        timeUnit - the unit of time of logInterval.
      • ProgressLogger

        public ProgressLogger​(org.slf4j.Logger logger,
                              long logInterval,
                              java.util.concurrent.TimeUnit timeUnit,
                              java.lang.String itemsName)
        Creates a new progress logger.
        Parameters:
        logger - the logger to which messages will be sent.
        logInterval - the logging interval.
        timeUnit - the unit of time of logInterval.
        itemsName - a plural name denoting the counted items.
    • Method Detail

      • logger

        public org.slf4j.Logger logger()
        The SLF4J logger used by this progress logger; it just returns the content of the field logger.
      • update

        public void update()
        Updates the internal count of this progress logger by adding one; if enough time has passed since the last log, information will be logged.

        This method is kept intentionally short (it delegates most of the work to an internal private method) so to suggest inlining. However, it performs a call to System.currentTimeMillis() that takes microseconds (not nanoseconds). If you plan on calling this method more than a few thousands times per second, you should use lightUpdate().

      • update

        public void update​(long count)
        Updates the internal count of this progress logger by adding a specified value; if enough time has passed since the last log, information will be logged.
        See Also:
        update()
      • updateAndDisplay

        public void updateAndDisplay()
        Updates the internal count of this progress logger by adding one, forcing a display.
        See Also:
        update()
      • set

        public void set​(long count)
        Sets the internal count of this progress logger to a specified value; if enough time has passed since the last log, information will be logged.
        See Also:
        update()
      • setAndDisplay

        public void setAndDisplay​(long count)
        Sets the internal count of this progress logger to a specified value, forcing a display.
        See Also:
        update()
      • updateAndDisplay

        public void updateAndDisplay​(long count)
        Updates the internal count of this progress logger by adding a specified value, forcing a display.
        See Also:
        update()
      • lightUpdate

        public final void lightUpdate()
        Updates the internal count of this progress logger by adding one in a lightweight fashion.

        This call updates the progress logger internal counter as update(). However, it will actually call System.currentTimeMillis() only if the new count is a multiple of LIGHT_UPDATE_MASK + 1. This mechanism makes it possible to reduce the number of calls to System.currentTimeMillis() significantly.

        This method is useful when the operations being counted take less than a few microseconds.

        See Also:
        update()
      • start

        public void start()
        Starts the progress logger, resetting the count.
      • start

        public void start​(java.lang.CharSequence message)
        Starts the progress logger, displaying a message and resetting the count.
        Parameters:
        message - the message to display.
      • start

        public void start​(long alreadyElapsed)
        Starts the progress logger, resetting the count and assuming that a given amount of time has already passed.
        Parameters:
        alreadyElapsed - the number of milliseconds already elapsed.
        See Also:
        start(CharSequence, long)
      • start

        public void start​(java.lang.CharSequence message,
                          long alreadyElapsed)
        Starts the progress logger, displaying a message, resetting the count and assuming that a given amount of time has already passed.

        The effect of the alreadyElapsed parameter is that the start time of this ProgressLogger will be set to System.currentTimeMillis() minus alreadyElapsed.

        Parameters:
        message - the message to display.
        alreadyElapsed - the number of milliseconds already elapsed.
      • stop

        public void stop​(java.lang.CharSequence message)
        Stops the progress logger, displaying a message.

        This method will also mark expectedUpdates as invalid, to avoid erroneous reuses of previous values.

        Parameters:
        message - the message to display.
      • stop

        public void stop()
        Stops the progress logger.
      • done

        public void done()
        Completes a run of this progress logger, logging “Completed.” and the logger itself.
      • done

        public void done​(long count)
        Completes a run of this progress logger and sets the internal counter, logging “Completed.” and the logger itself.

        This method is particularly useful in two circumstances:

        • you have updated the logger with some approximate values (e.g., in a multicore computation) but before printing the final statistics you want the internal counter to contain an exact value;
        • you have used the logger as a handy timer, calling just start() and this method.
        Parameters:
        count - will replace the internal counter value.
      • millis

        public long millis()
        Returns the number of milliseconds between present time and the last call to start(), if this progress logger is running, or between the last call to stop() and the last call to start(), if this progress logger is stopped.
        Returns:
        the number of milliseconds between present time and the last call to start(), if this progress logger is running, or between the last call to stop() and the last call to start(), if this progress logger is stopped.
      • toString

        public java.lang.String toString()
        Converts the data currently stored in this progress logger to a string.

        If this progress logger has been stopped, statistics are computed using the stop time. Otherwise, they are computed using the current time (i.e., the method call time).

        Overrides:
        toString in class java.lang.Object
        Returns:
        the current data in this progress logger in a printable form.