diff options
author | Cameron Moore <[email protected]> | 2017-09-26 13:03:04 -0500 |
---|---|---|
committer | Bjørn Erik Pedersen <[email protected]> | 2017-09-26 20:03:04 +0200 |
commit | b4a14c25fe85c41b79497be27ead128502a4dd7b (patch) | |
tree | 99cdbb0d9ab7a7adf137ce492773750aeec8e431 /metrics | |
parent | cb8eb472602754b310eaf7a10271149d1e1f5d75 (diff) | |
download | hugo-b4a14c25fe85c41b79497be27ead128502a4dd7b.tar.gz hugo-b4a14c25fe85c41b79497be27ead128502a4dd7b.zip |
metrics: Add simple template metrics feature
Diffstat (limited to 'metrics')
-rw-r--r-- | metrics/metrics.go | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/metrics/metrics.go b/metrics/metrics.go new file mode 100644 index 000000000..cabf52131 --- /dev/null +++ b/metrics/metrics.go @@ -0,0 +1,117 @@ +// 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 } |