youtubebeat/vendor/github.com/elastic/beats/metricbeat/module/kubernetes/util/metrics_cache.go

123 lines
2.9 KiB
Go

// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you 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 util
import (
"sync"
"time"
)
// PerfMetrics stores known metrics from Kubernetes nodes and containers
var PerfMetrics = NewPerfMetricsCache()
const defaultTimeout = 120 * time.Second
var now = time.Now
var sleep = time.Sleep
// NewPerfMetricsCache initializes and returns a new PerfMetricsCache
func NewPerfMetricsCache() *PerfMetricsCache {
return &PerfMetricsCache{
NodeMemAllocatable: newValueMap(defaultTimeout),
NodeCoresAllocatable: newValueMap(defaultTimeout),
ContainerMemLimit: newValueMap(defaultTimeout),
ContainerCoresLimit: newValueMap(defaultTimeout),
}
}
// PerfMetricsCache stores known metrics from Kubernetes nodes and containers
type PerfMetricsCache struct {
mutex sync.RWMutex
NodeMemAllocatable *valueMap
NodeCoresAllocatable *valueMap
ContainerMemLimit *valueMap
ContainerCoresLimit *valueMap
}
func newValueMap(timeout time.Duration) *valueMap {
return &valueMap{
values: map[string]value{},
timeout: timeout,
}
}
type valueMap struct {
sync.RWMutex
running bool
timeout time.Duration
values map[string]value
}
type value struct {
value float64
expires int64
}
// ContainerUID creates an unique ID for from namespace, pod name and container name
func ContainerUID(namespace, pod, container string) string {
return namespace + "-" + pod + "-" + container
}
// Get value
func (m *valueMap) Get(name string) float64 {
m.RLock()
defer m.RUnlock()
return m.values[name].value
}
// Get value
func (m *valueMap) GetWithDefault(name string, def float64) float64 {
m.RLock()
defer m.RUnlock()
val, ok := m.values[name]
if ok {
return val.value
}
return def
}
// Set value
func (m *valueMap) Set(name string, val float64) {
m.Lock()
defer m.Unlock()
m.ensureCleanupWorker()
m.values[name] = value{val, now().Add(m.timeout).Unix()}
}
func (m *valueMap) ensureCleanupWorker() {
if !m.running {
// Run worker to cleanup expired entries
m.running = true
go func() {
for {
sleep(m.timeout)
m.Lock()
now := now().Unix()
for name, val := range m.values {
if now > val.expires {
delete(m.values, name)
}
}
m.Unlock()
}
}()
}
}