-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
133 lines (110 loc) · 4.46 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package main
import (
"flag"
"fmt"
"os"
"phpScope/config"
"phpScope/processor"
"phpScope/sender"
"strings"
)
func printWelcomeBanner(pyroscopeURL, appName string, rateHz int, interval float64, batchLimit int, concurrentLimit int, tags map[string]string, excludePattern string, debug bool) {
bannerLines := []string{
" ____ __ ______ _____ ",
" / __ \\/ / / / __ \\/ ___/________ ____ ___ ",
" / /_/ / /_/ / /_/ /\\__ \\/ ___/ _ \\/ __ \\/ _ \\",
" / ____/ __ / ____/___/ / /__/ __/ /_/ / __/",
"/_/ /_/ /_/_/ /____/\\___/\\___/ .___/\\___/ ",
" /_/ ",
}
// Print banner in orange color
for _, line := range bannerLines {
fmt.Println("\033[0;33m" + line + "\033[0m")
}
fmt.Print("https://github.com/everythings-gonna-be-alright\n\n")
fmt.Println("🚀 Starting phpScope with configuration:")
fmt.Printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n")
fmt.Printf("📡 Pyroscope URL: %s\n", pyroscopeURL)
fmt.Printf("📝 Application Name: %s\n", appName)
fmt.Printf("⚡ Sample Rate: %d Hz\n", rateHz)
fmt.Printf("⏱️ Update Interval: %.2f sec\n", interval)
fmt.Printf("📦 Batch Limit: %d\n", batchLimit)
fmt.Printf("🔄 Concurrent Limit: %d\n", concurrentLimit)
if excludePattern != "" {
fmt.Printf("🚫 Exclude Pattern: %s\n", excludePattern)
}
if len(tags) > 0 {
fmt.Printf("🏷️ Tags:\n")
for k, v := range tags {
fmt.Printf(" ├─ %s: %s\n", k, v)
}
}
fmt.Printf("🐛 Debug Mode: %v\n", debug)
fmt.Printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n")
}
func main() {
cfg := config.NewDefault()
// Command line flags configuration
flag.StringVar(&cfg.PyroscopeURL, "pyroscopeUrl", "", "URL of the Pyroscope server")
flag.StringVar(&cfg.AuthToken, "auth", "", "Authentication token for Pyroscope")
flag.StringVar(&cfg.AppName, "appName", "", "Application name for profiling data")
flag.StringVar(&cfg.ExcludePattern, "exclude", "", "Regex pattern to exclude functions")
var tags multiFlag
flag.Var(&tags, "tags", "Tags in format key=value")
// Profiling settings
flag.IntVar(&cfg.RateHz, "rateHz", cfg.RateHz, "Sampling rate in Hz")
flag.Float64Var(&cfg.Interval, "interval", cfg.Interval, "Time between data sends (seconds)")
flag.IntVar(&cfg.BatchLimit, "batch", cfg.BatchLimit, "Maximum traces per batch")
flag.IntVar(&cfg.ConcurrentLimit, "concurrent", cfg.ConcurrentLimit, "Maximum concurrent requests")
// PHP-specific settings
flag.IntVar(&cfg.PhpspyBufferSize, "phpspyBufferSize", cfg.PhpspyBufferSize, "Size of phpspy's internal buffer")
flag.IntVar(&cfg.PhpspyMaxDepth, "phpspyMaxDepth", cfg.PhpspyMaxDepth, "Maximum stack trace depth")
flag.IntVar(&cfg.PhpspyThreads, "phpspyThreads", cfg.PhpspyThreads, "Number of phpspy worker threads")
flag.StringVar(&cfg.PhpspyRequestInfo, "phpspyRequestInfo", cfg.PhpspyRequestInfo, "Request info to include in traces")
flag.BoolVar(&cfg.Debug, "debug", false, "Enable debug logging")
flag.Parse()
// Validate required fields
if cfg.PyroscopeURL == "" {
fmt.Println("Error: pyroscope URL is required")
os.Exit(1)
}
if cfg.AppName == "" {
fmt.Println("Error: app name is required")
os.Exit(1)
}
// Parse tags
cfg.Tags = make(map[string]string)
for _, tag := range tags {
key, value := parseTag(tag)
cfg.Tags[key] = value
}
// Print welcome banner
printWelcomeBanner(cfg.PyroscopeURL, cfg.AppName, cfg.RateHz, cfg.Interval, cfg.BatchLimit, cfg.ConcurrentLimit, cfg.Tags, cfg.ExcludePattern, cfg.Debug)
// Initialize components
s := sender.New(cfg)
p := processor.New(cfg, s)
// Start processing
if err := p.Process(); err != nil {
fmt.Printf("Error processing: %v\n", err)
os.Exit(1)
}
}
// multiFlag implements flag.Value interface to support multiple flag values
// for the same flag (e.g., multiple -tags flags)
type multiFlag []string
func (f *multiFlag) String() string {
return fmt.Sprint(*f)
}
func (f *multiFlag) Set(value string) error {
*f = append(*f, value)
return nil
}
// parseTag splits a "key=value" string into separate key and value.
// Returns empty strings if the format is invalid.
func parseTag(tag string) (string, string) {
parts := strings.Split(tag, "=")
if len(parts) != 2 {
return "", ""
}
return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1])
}