This repository has been archived by the owner on Jul 19, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 73
/
main.go
113 lines (92 loc) 路 3.14 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package main
import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/common/version"
"gopkg.in/alecthomas/kingpin.v2"
phlarecontext "github.com/grafana/phlare/pkg/phlare/context"
_ "github.com/grafana/phlare/pkg/util/build"
)
var cfg struct {
verbose bool
blocks struct {
path string
restoreMissingMeta bool
}
}
var (
consoleOutput = os.Stderr
logger = log.NewLogfmtLogger(consoleOutput)
)
func main() {
ctx := phlarecontext.WithLogger(context.Background(), logger)
ctx = withOutput(ctx, os.Stdout)
app := kingpin.New(filepath.Base(os.Args[0]), "Tooling for Grafana Phlare, the continuous profiling aggregation system.").UsageWriter(os.Stdout)
app.Version(version.Print("phlaretool"))
app.HelpFlag.Short('h')
app.Flag("verbose", "Enable verbose logging.").Short('v').Default("0").BoolVar(&cfg.verbose)
blocksCmd := app.Command("blocks", "Operate on Grafana Phlare's blocks.")
blocksCmd.Flag("path", "Path to blocks directory").Default("./data/local").StringVar(&cfg.blocks.path)
blocksListCmd := blocksCmd.Command("list", "List blocks.")
blocksListCmd.Flag("restore-missing-meta", "").Default("false").BoolVar(&cfg.blocks.restoreMissingMeta)
parquetCmd := app.Command("parquet", "Operate on a Parquet file.")
parquetInspectCmd := parquetCmd.Command("inspect", "Inspect a parquet file's structure.")
parquetInspectFiles := parquetInspectCmd.Arg("file", "parquet file path").Required().ExistingFiles()
queryCmd := app.Command("query", "Query profile store.")
queryParams := addQueryParams(queryCmd)
queryOutput := queryCmd.Flag("output", "How to output the result, examples: console, raw, pprof=./my.pprof").Default("console").String()
queryMergeCmd := queryCmd.Command("merge", "Request merged profile.")
uploadCmd := app.Command("upload", "Upload profile(s).")
uploadParams := addUploadParams(uploadCmd)
// parse command line arguments
parsedCmd := kingpin.MustParse(app.Parse(os.Args[1:]))
// enable verbose logging if requested
if !cfg.verbose {
logger = level.NewFilter(logger, level.AllowInfo())
}
switch parsedCmd {
case blocksListCmd.FullCommand():
os.Exit(checkError(blocksList(ctx)))
case parquetInspectCmd.FullCommand():
for _, file := range *parquetInspectFiles {
if err := parquetInspect(ctx, file); err != nil {
os.Exit(checkError(err))
}
}
case queryMergeCmd.FullCommand():
if err := queryMerge(ctx, queryParams, *queryOutput); err != nil {
os.Exit(checkError(err))
}
case uploadCmd.FullCommand():
if err := upload(ctx, uploadParams); err != nil {
os.Exit(checkError(err))
}
default:
level.Error(logger).Log("msg", "unknown command", "cmd", parsedCmd)
}
}
func checkError(err error) int {
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
return 1
}
return 0
}
type contextKey uint8
const (
contextKeyOutput contextKey = iota
)
func withOutput(ctx context.Context, w io.Writer) context.Context {
return context.WithValue(ctx, contextKeyOutput, w)
}
func output(ctx context.Context) io.Writer {
if w, ok := ctx.Value(contextKeyOutput).(io.Writer); ok {
return w
}
return os.Stdout
}