internal/disk_stats/disk_stats.go (93 lines of code) (raw):

package disk_stats //nolint:staticcheck import ( "log/slog" "os" "path/filepath" "golang.org/x/sys/unix" ) type DiskStats struct { All uint64 `json:"all"` Free uint64 `json:"free"` Indexed int64 `json:"indexed"` Used uint64 `json:"used"` } type RepoStats struct { IndexFileCount uint16 `json:"index_file_count"` SizeInBytes uint64 `json:"size_in_bytes"` } func (r RepoStats) ToMap() map[string]interface{} { return map[string]interface{}{ "index_file_count": r.IndexFileCount, "size_in_bytes": r.SizeInBytes, } } func DiskUsage(path string) (DiskStats, error) { fs := unix.Statfs_t{} err := unix.Statfs(path, &fs) if err != nil { return DiskStats{}, err } all := fs.Blocks * uint64(fs.Bsize) //nolint:gosec free := fs.Bfree * uint64(fs.Bsize) //nolint:gosec used := all - free indexed, err := getIndexSize(path) if indexed < 0 || err != nil { slog.Error("can not get the index size", "path", path, "error", err) indexed = -1 } diskStats := DiskStats{ All: all, Free: free, Indexed: indexed, Used: used, } return diskStats, nil } func GetIndexFiles(indexDir string, globs ...string) ([]string, error) { var files []string for _, g := range globs { path := filepath.Join(indexDir, g) f, err := filepath.Glob(path) if err != nil { return nil, err } files = append(files, f...) } return files, nil } func GetFileSizeAndCount(indexDir string, globs ...string) RepoStats { files, err := GetIndexFiles(indexDir, globs...) repoStats := RepoStats{} if err != nil { return repoStats } var sizeInBytes uint64 numFiles := len(files) for i := 0; i < numFiles; i++ { fileInfo, err := os.Stat(files[i]) if err != nil { return repoStats } sizeInBytes += uint64(fileInfo.Size()) //nolint:gosec } repoStats.IndexFileCount = uint16(numFiles) //nolint:gosec repoStats.SizeInBytes = sizeInBytes return repoStats } func getIndexSize(path string) (int64, error) { var size int64 err := filepath.WalkDir(path, func(_ string, d os.DirEntry, err error) error { if err != nil { return err } if !d.IsDir() { info, err := d.Info() if err != nil { return err } size += int64(info.Size()) } return nil }) return size, err }