github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/health/disk_pressure.go (about)

     1  package health
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/pyroscope-io/pyroscope/pkg/util/bytesize"
     8  	"github.com/pyroscope-io/pyroscope/pkg/util/disk"
     9  )
    10  
    11  var (
    12  	errZeroTotalSize          = errors.New("total disk size is zero")
    13  	errTotalLessThanAvailable = errors.New("total disk size is less than available space")
    14  )
    15  
    16  const minAvailSpace = bytesize.GB
    17  
    18  type DiskPressure struct {
    19  	Threshold float64
    20  	Path      string
    21  }
    22  
    23  func (d DiskPressure) Probe() (StatusMessage, error) {
    24  	if d.Threshold == 0 {
    25  		return StatusMessage{Status: Healthy}, nil
    26  	}
    27  	u, err := disk.Usage(d.Path)
    28  	if err != nil {
    29  		return StatusMessage{}, err
    30  	}
    31  	return d.makeProbe(u)
    32  }
    33  
    34  func (d DiskPressure) makeProbe(u disk.UsageStats) (StatusMessage, error) {
    35  	var m StatusMessage
    36  	if u.Total == 0 {
    37  		return m, errZeroTotalSize
    38  	}
    39  	if u.Available > u.Total {
    40  		return m, errTotalLessThanAvailable
    41  	}
    42  	m.Status = Healthy
    43  	if u.Available < d.minRequired(u) {
    44  		availPercent := 100 * float64(u.Available) / float64(u.Total)
    45  		m.Message = fmt.Sprintf("Disk space is running low: %v available (%.1f%%)", u.Available, availPercent)
    46  		m.Status = Critical
    47  	}
    48  	return m, nil
    49  }
    50  
    51  func (d DiskPressure) minRequired(u disk.UsageStats) bytesize.ByteSize {
    52  	t := bytesize.ByteSize(float64(u.Total) / 100 * d.Threshold)
    53  	if t > minAvailSpace {
    54  		return t
    55  	}
    56  	return minAvailSpace
    57  }