Skip to content

Commit

Permalink
feat: add multi-paths flag
Browse files Browse the repository at this point in the history
  • Loading branch information
dundee committed Dec 15, 2023
1 parent e456532 commit 0c76dd3
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 19 deletions.
25 changes: 22 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package cmd
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strconv"

"github.com/dundee/disk_usage_exporter/build"
"github.com/dundee/disk_usage_exporter/exporter"
Expand All @@ -26,9 +28,13 @@ and reporting which directories consume what space.`,
Run: func(cmd *cobra.Command, args []string) {
printHeader()

paths := transformMultipaths(viper.GetStringMapString("multi-paths"))
if len(paths) == 0 {
paths[filepath.Clean(viper.GetString("analyzed-path"))] = viper.GetInt("dir-level")
}

e := exporter.NewExporter(
viper.GetInt("dir-level"),
viper.GetString("analyzed-path"),
(paths),
viper.GetBool("follow-symlinks"),
)
e.SetIgnoreDirPaths(viper.GetStringSlice("ignore-dirs"))
Expand All @@ -54,7 +60,7 @@ func init() {
cobra.OnInitialize(initConfig)
flags := rootCmd.PersistentFlags()
flags.StringVarP(&cfgFile, "config", "c", "", "config file (default is $HOME/.disk_usage_exporter.yaml)")
flags.StringP("mode", "m", "http", "Exposition method - either 'file' or 'http'")
flags.StringP("mode", "m", "http", "Expose method - either 'file' or 'http'")
flags.StringP("bind-address", "b", "0.0.0.0:9995", "Address to bind to")
flags.StringP("output-file", "f", "./disk-usage-exporter.prom", "Target file to store metrics in")
flags.StringP("analyzed-path", "p", "/", "Path where to analyze disk usage")
Expand All @@ -64,6 +70,7 @@ func init() {
"follow-symlinks", "L", false,
"Follow symlinks for files, i.e. show the size of the file to which symlink points to (symlinks to directories are not followed)",
)
flags.StringToString("multi-paths", map[string]string{}, "Multiple paths where to analyze disk usage, in format /path1=level1,/path2=level2,...")

viper.BindPFlags(flags)
}
Expand Down Expand Up @@ -104,3 +111,15 @@ func printHeader() {
runtime.GOARCH,
)
}

func transformMultipaths(multiPaths map[string]string) map[string]int {
paths := make(map[string]int, len(multiPaths))
for path, level := range multiPaths {
l, err := strconv.Atoi(level)
if err != nil {
log.Fatalf("Invalid level for path %s: %s", path, level)
}
paths[filepath.Clean(path)] = l
}
return paths
}
31 changes: 16 additions & 15 deletions exporter/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package exporter
import (
"fmt"
"net/http"
"path/filepath"
"runtime/debug"

"github.com/dundee/gdu/v5/pkg/analyze"
Expand Down Expand Up @@ -37,28 +36,30 @@ func init() {

// Exporter is the type to be used to start HTTP server and run the analysis
type Exporter struct {
paths map[string]int
ignoreDirPaths map[string]struct{}
maxLevel int
path string
followSymlinks bool
}

// NewExporter creates new Exporter
func NewExporter(maxLevel int, path string, followSymlinks bool) *Exporter {
func NewExporter(paths map[string]int, followSymlinks bool) *Exporter {
return &Exporter{
maxLevel: maxLevel,
path: filepath.Clean(path),
followSymlinks: followSymlinks,
paths: paths,
}
}

func (e *Exporter) runAnalysis() {
defer debug.FreeOSMemory()
analyzer := analyze.CreateAnalyzer()
analyzer.SetFollowSymlinks(e.followSymlinks)
dir := analyzer.AnalyzeDir(e.path, e.shouldDirBeIgnored, false)
dir.UpdateStats(fs.HardLinkedItems{})
e.reportItem(dir, 0)

for path, level := range e.paths {
analyzer := analyze.CreateAnalyzer()
analyzer.SetFollowSymlinks(e.followSymlinks)
dir := analyzer.AnalyzeDir(path, e.shouldDirBeIgnored, false)
dir.UpdateStats(fs.HardLinkedItems{})
e.reportItem(dir, 0, level)
}

log.Info("Analysis done")
}

Expand All @@ -75,16 +76,16 @@ func (e *Exporter) shouldDirBeIgnored(name, path string) bool {
return ok
}

func (e *Exporter) reportItem(item fs.Item, level int) {
if level == e.maxLevel {
func (e *Exporter) reportItem(item fs.Item, level, maxLevel int) {
if level == maxLevel {
diskUsage.WithLabelValues(item.GetPath()).Set(float64(item.GetUsage()))
} else if level == 1 {
diskUsageLevel1.WithLabelValues(item.GetPath()).Set(float64(item.GetUsage()))
}

if item.IsDir() && level+1 <= e.maxLevel {
if item.IsDir() && level+1 <= maxLevel {
for _, entry := range item.GetFiles() {
e.reportItem(entry, level+1)
e.reportItem(entry, level+1, maxLevel)
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion exporter/exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ func TestRunAnalysis(t *testing.T) {

w := &mockedResponseWriter{}

e := exporter.NewExporter(2, "test_dir", false)
paths := map[string]int{"test_dir": 2}
e := exporter.NewExporter(paths, false)
e.SetIgnoreDirPaths([]string{"/proc"})
e.ServeHTTP(w, &http.Request{
Header: make(http.Header),
Expand Down

0 comments on commit 0c76dd3

Please sign in to comment.