github.com/openshift/installer@v1.4.17/pkg/metrics/timer/timer.go (about)

     1  package timer
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	"github.com/sirupsen/logrus"
     8  )
     9  
    10  // Timer is the struct that keeps track of each of the sections.
    11  type Timer struct {
    12  	listOfStages []string
    13  	stageTimes   map[string]time.Duration
    14  	startTimes   map[string]time.Time
    15  }
    16  
    17  const (
    18  
    19  	// TotalTimeElapsed is a constant string value to denote total time elapsed.
    20  	TotalTimeElapsed = "Total"
    21  )
    22  
    23  var timer = NewTimer()
    24  
    25  // StartTimer initiailzes the timer object with the current timestamp information.
    26  func StartTimer(key string) {
    27  	timer.StartTimer(key)
    28  }
    29  
    30  // StopTimer records the duration for the current stage sent as the key parameter and stores the information.
    31  func StopTimer(key string) {
    32  	timer.StopTimer(key)
    33  }
    34  
    35  // LogSummary prints the summary of all the times collected so far into the INFO section.
    36  func LogSummary() {
    37  	timer.LogSummary(logrus.StandardLogger())
    38  }
    39  
    40  // NewTimer returns a new timer that can be used to track sections and
    41  func NewTimer() Timer {
    42  	return Timer{
    43  		listOfStages: []string{},
    44  		stageTimes:   make(map[string]time.Duration),
    45  		startTimes:   make(map[string]time.Time),
    46  	}
    47  }
    48  
    49  // StartTimer initializes the timer object with the current timestamp information.
    50  func (t *Timer) StartTimer(key string) {
    51  	t.listOfStages = append(t.listOfStages, key)
    52  	t.startTimes[key] = time.Now().Round(time.Second)
    53  }
    54  
    55  // StopTimer records the duration for the current stage sent as the key parameter and stores the information.
    56  func (t *Timer) StopTimer(key string) time.Duration {
    57  	if item, found := t.startTimes[key]; found {
    58  		duration := time.Since(item).Round(time.Second)
    59  		t.stageTimes[key] = duration
    60  	}
    61  	return time.Since(time.Now())
    62  }
    63  
    64  // LogSummary prints the summary of all the times collected so far into the INFO section.
    65  // The format of printing will be the following:
    66  // If there are no stages except the total time stage, then it only prints the following
    67  // Time elapsed: <x>m<yy>s
    68  // If there are multiple stages, it prints the following:
    69  // Time elapsed for each section
    70  // Stage1: <x>m<yy>s
    71  // Stage2: <x>m<yy>s
    72  // .
    73  // .
    74  // .
    75  // StageN: <x>m<yy>s
    76  // Time elapsed: <x>m<yy>s
    77  // All durations printed are rounded up to the next second value and printed in the format mentioned above.
    78  func (t *Timer) LogSummary(logger *logrus.Logger) {
    79  	maxLen := 0
    80  	count := 0
    81  	for _, item := range t.listOfStages {
    82  		if len(item) > maxLen && item != TotalTimeElapsed {
    83  			maxLen = len(item)
    84  		}
    85  		if t.stageTimes[item] > 0 {
    86  			count++
    87  		}
    88  	}
    89  
    90  	if maxLen != 0 && count > 0 {
    91  		logger.Debugf("Time elapsed per stage:")
    92  	}
    93  
    94  	for _, item := range t.listOfStages {
    95  		if item != TotalTimeElapsed && t.stageTimes[item] > 0 {
    96  			logger.Debugf(fmt.Sprintf("%*s: %s", maxLen, item, t.stageTimes[item]))
    97  		}
    98  	}
    99  	logger.Infof("Time elapsed: %s", t.stageTimes[TotalTimeElapsed])
   100  }