mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-29 04:12:08 -05:00
d3681f51c0
Highest first.
117 lines
3 KiB
Go
117 lines
3 KiB
Go
// Copyright 2017 The Hugo Authors. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
// Package metrics provides simple metrics tracking features.
|
|
package metrics
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"sort"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// The Provider interface defines an interface for measuring metrics.
|
|
type Provider interface {
|
|
// MeasureSince adds a measurement for key to the metric store.
|
|
// Used with defer and time.Now().
|
|
MeasureSince(key string, start time.Time)
|
|
|
|
// WriteMetrics will write a summary of the metrics to w.
|
|
WriteMetrics(w io.Writer)
|
|
|
|
// Reset clears the metric store.
|
|
Reset()
|
|
}
|
|
|
|
// Store provides storage for a set of metrics.
|
|
type Store struct {
|
|
metrics map[string][]time.Duration
|
|
mu *sync.Mutex
|
|
}
|
|
|
|
// NewProvider returns a new instance of a metric store.
|
|
func NewProvider() Provider {
|
|
return &Store{
|
|
metrics: make(map[string][]time.Duration),
|
|
mu: &sync.Mutex{},
|
|
}
|
|
}
|
|
|
|
// Reset clears the metrics store.
|
|
func (s *Store) Reset() {
|
|
s.mu.Lock()
|
|
s.metrics = make(map[string][]time.Duration)
|
|
s.mu.Unlock()
|
|
}
|
|
|
|
// MeasureSince adds a measurement for key to the metric store.
|
|
func (s *Store) MeasureSince(key string, start time.Time) {
|
|
s.mu.Lock()
|
|
s.metrics[key] = append(s.metrics[key], time.Since(start))
|
|
s.mu.Unlock()
|
|
}
|
|
|
|
// WriteMetrics writes a summary of the metrics to w.
|
|
func (s *Store) WriteMetrics(w io.Writer) {
|
|
s.mu.Lock()
|
|
|
|
results := make([]result, len(s.metrics))
|
|
|
|
var i int
|
|
for k, v := range s.metrics {
|
|
var sum time.Duration
|
|
var max time.Duration
|
|
|
|
for _, d := range v {
|
|
sum += d
|
|
if d > max {
|
|
max = d
|
|
}
|
|
}
|
|
|
|
avg := time.Duration(int(sum) / len(v))
|
|
|
|
results[i] = result{key: k, count: len(v), max: max, sum: sum, avg: avg}
|
|
i++
|
|
}
|
|
|
|
s.mu.Unlock()
|
|
|
|
// sort and print results
|
|
fmt.Fprintf(w, " %13s %12s %12s %5s %s\n", "cumulative", "average", "maximum", "", "")
|
|
fmt.Fprintf(w, " %13s %12s %12s %5s %s\n", "duration", "duration", "duration", "count", "template")
|
|
fmt.Fprintf(w, " %13s %12s %12s %5s %s\n", "----------", "--------", "--------", "-----", "--------")
|
|
|
|
sort.Sort(bySum(results))
|
|
for _, v := range results {
|
|
fmt.Fprintf(w, " %13s %12s %12s %5d %s\n", v.sum, v.avg, v.max, v.count, v.key)
|
|
}
|
|
|
|
}
|
|
|
|
// A result represents the calculated results for a given metric.
|
|
type result struct {
|
|
key string
|
|
count int
|
|
sum time.Duration
|
|
max time.Duration
|
|
avg time.Duration
|
|
}
|
|
|
|
type bySum []result
|
|
|
|
func (b bySum) Len() int { return len(b) }
|
|
func (b bySum) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
|
|
func (b bySum) Less(i, j int) bool { return b[i].sum > b[j].sum }
|