mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-30 02:46:30 +02:00
* Initial envoy cgroup resource monitor implementation * Add cgroupv1 support; add metrics instrumentation * Slight refactor for more efficient memory limit detection Instead of reading memory.max/limit_in_bytes on every tick, we read it once, then again only when it is modified. To support this change, logic for computing the saturation was moved out of the cgroup driver and into the resource monitor, and the driver interface now has separate methods for reading memory usage and limit. * Code cleanup/lint fixes * Add platform build tags * Add unit tests * Fix lint issues * Add runtime flag to allow disabling resource monitor * Clamp saturation values to the range [0.0, 1.0] * Switch to x/sys/unix; handle inotify IN_IGNORED events
104 lines
2.8 KiB
Go
104 lines
2.8 KiB
Go
package metrics
|
|
|
|
import (
|
|
"context"
|
|
|
|
"go.opencensus.io/stats"
|
|
"go.opencensus.io/stats/view"
|
|
"go.opencensus.io/tag"
|
|
|
|
"github.com/pomerium/pomerium/internal/log"
|
|
"github.com/pomerium/pomerium/pkg/metrics"
|
|
)
|
|
|
|
var (
|
|
EnvoyViews = []*view.View{
|
|
EnvoyOverloadActionStateView,
|
|
EnvoyOverloadActionThresholdView,
|
|
EnvoyCgroupMemorySaturationView,
|
|
}
|
|
|
|
EnvoyOverloadActionState = stats.Int64(
|
|
metrics.EnvoyOverloadActionState,
|
|
"Current state of envoy overload actions by cgroup",
|
|
stats.UnitDimensionless,
|
|
)
|
|
|
|
EnvoyOverloadActionThreshold = stats.Float64(
|
|
metrics.EnvoyOverloadActionThreshold,
|
|
"Injected memory usage minimum thresholds for envoy overload actions",
|
|
stats.UnitDimensionless,
|
|
)
|
|
|
|
EnvoyCgroupMemorySaturation = stats.Float64(
|
|
metrics.EnvoyCgroupMemorySaturation,
|
|
"Memory usage percent (0.0-1.0) of the cgroup in which envoy is running",
|
|
stats.UnitDimensionless,
|
|
)
|
|
|
|
EnvoyOverloadActionStateView = &view.View{
|
|
Name: EnvoyOverloadActionState.Name(),
|
|
Description: EnvoyOverloadActionState.Description(),
|
|
TagKeys: []tag.Key{TagKeyCgroup, TagKeyActionName},
|
|
Measure: EnvoyOverloadActionState,
|
|
Aggregation: view.LastValue(),
|
|
}
|
|
|
|
EnvoyOverloadActionThresholdView = &view.View{
|
|
Name: EnvoyOverloadActionThreshold.Name(),
|
|
Description: EnvoyOverloadActionThreshold.Description(),
|
|
TagKeys: []tag.Key{TagKeyActionName},
|
|
Measure: EnvoyOverloadActionThreshold,
|
|
Aggregation: view.LastValue(),
|
|
}
|
|
|
|
EnvoyCgroupMemorySaturationView = &view.View{
|
|
Name: EnvoyCgroupMemorySaturation.Name(),
|
|
Description: EnvoyCgroupMemorySaturation.Description(),
|
|
TagKeys: []tag.Key{TagKeyCgroup},
|
|
Measure: EnvoyCgroupMemorySaturation,
|
|
Aggregation: view.LastValue(),
|
|
}
|
|
)
|
|
|
|
type EnvoyOverloadActionStateTags struct {
|
|
Cgroup string
|
|
ActionName string
|
|
}
|
|
|
|
func RecordEnvoyOverloadActionState(ctx context.Context, tags EnvoyOverloadActionStateTags, state int64) {
|
|
err := stats.RecordWithTags(ctx,
|
|
[]tag.Mutator{
|
|
tag.Upsert(TagKeyCgroup, tags.Cgroup),
|
|
tag.Upsert(TagKeyActionName, tags.ActionName),
|
|
},
|
|
EnvoyOverloadActionState.M(state),
|
|
)
|
|
if err != nil {
|
|
log.Warn(ctx).Err(err).Msg("internal/telemetry/metrics: failed to record")
|
|
}
|
|
}
|
|
|
|
func RecordEnvoyOverloadActionThreshold(ctx context.Context, actionName string, threshold float64) {
|
|
err := stats.RecordWithTags(ctx,
|
|
[]tag.Mutator{
|
|
tag.Upsert(TagKeyActionName, actionName),
|
|
},
|
|
EnvoyOverloadActionThreshold.M(threshold),
|
|
)
|
|
if err != nil {
|
|
log.Warn(ctx).Err(err).Msg("internal/telemetry/metrics: failed to record")
|
|
}
|
|
}
|
|
|
|
func RecordEnvoyCgroupMemorySaturation(ctx context.Context, cgroup string, percent float64) {
|
|
err := stats.RecordWithTags(ctx,
|
|
[]tag.Mutator{
|
|
tag.Upsert(TagKeyCgroup, cgroup),
|
|
},
|
|
EnvoyCgroupMemorySaturation.M(percent),
|
|
)
|
|
if err != nil {
|
|
log.Warn(ctx).Err(err).Msg("internal/telemetry/metrics: failed to record")
|
|
}
|
|
}
|