github.com/grafana/pyroscope@v1.18.0/cmd/profilecli/blocks.go (about) 1 package main 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "path/filepath" 8 "time" 9 10 "github.com/dustin/go-humanize" 11 "github.com/go-kit/log/level" 12 "github.com/olekukonko/tablewriter" 13 14 "github.com/grafana/pyroscope/pkg/objstore/providers/filesystem" 15 "github.com/grafana/pyroscope/pkg/phlaredb" 16 "github.com/grafana/pyroscope/pkg/phlaredb/block" 17 ) 18 19 func fileInfo(f *block.File) string { 20 if f != nil && f.Parquet != nil { 21 return fmt.Sprintf("%d (%s in %d RGs)", f.Parquet.NumRows, humanize.Bytes(f.SizeBytes), f.Parquet.NumRowGroups) 22 } 23 if f != nil && f.TSDB != nil { 24 return fmt.Sprintf("%d series", f.TSDB.NumSeries) 25 } 26 return "" 27 } 28 29 func blocksList(ctx context.Context) error { 30 bucket, err := filesystem.NewBucket(cfg.blocks.path) 31 if err != nil { 32 return err 33 } 34 35 metas, err := phlaredb.NewBlockQuerier(ctx, bucket).BlockMetas(ctx) 36 if err != nil { 37 return err 38 } 39 40 table := tablewriter.NewWriter(output(ctx)) 41 table.SetHeader([]string{"Block ID", "MinTime", "MaxTime", "Duration", "Index", "Profiles", "Stacktraces", "Locations", "Functions", "Strings"}) 42 for _, blockInfo := range metas { 43 table.Append([]string{ 44 blockInfo.ULID.String(), 45 blockInfo.MinTime.Time().Format(time.RFC3339), 46 blockInfo.MaxTime.Time().Format(time.RFC3339), 47 blockInfo.MaxTime.Time().Sub(blockInfo.MinTime.Time()).String(), 48 fileInfo(blockInfo.FileByRelPath("index.tsdb")), 49 fileInfo(blockInfo.FileByRelPath("profiles.parquet")), 50 fileInfo(blockInfo.FileByRelPath("stacktraces.parquet")), 51 fileInfo(blockInfo.FileByRelPath("locations.parquet")), 52 fileInfo(blockInfo.FileByRelPath("functions.parquet")), 53 fileInfo(blockInfo.FileByRelPath("strings.parquet")), 54 }) 55 56 if cfg.blocks.restoreMissingMeta { 57 blockPath := filepath.Join(cfg.blocks.path, blockInfo.ULID.String()) 58 blockMetaPath := filepath.Join(blockPath, block.MetaFilename) 59 60 if _, err := os.Stat(blockMetaPath); err == nil { 61 continue 62 } else if !os.IsNotExist(err) { 63 level.Error(logger).Log("msg", "unable to check for existing "+block.MetaFilename+" file", "path", blockMetaPath, "err", err) 64 continue 65 } 66 67 if _, err := blockInfo.WriteToFile(logger, blockPath); err != nil { 68 level.Error(logger).Log("msg", "unable to write regenerated "+block.MetaFilename, "path", blockMetaPath, "err", err) 69 continue 70 } 71 } 72 } 73 table.Render() 74 75 return nil 76 }