Skip to content

Commit e559916

Browse files
authored
Windows: add path filtering option for profile command (#6641)
1 parent 6405057 commit e559916

File tree

1 file changed

+39
-4
lines changed

1 file changed

+39
-4
lines changed

cmd/profile.go

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ Details: https://juicefs.com/docs/community/fault_diagnosis_and_analysis#profile
7171
Aliases: []string{"p"},
7272
Usage: "track only specified PIDs(separated by comma ,)",
7373
},
74+
&cli.StringFlag{
75+
Name: "paths",
76+
Aliases: []string{"filter-by-path"},
77+
Usage: "track only specified paths (separated by comma , Only for Windows FUSE log)",
78+
Hidden: true,
79+
},
7480
&cli.Int64Flag{
7581
Name: "interval",
7682
Value: 2,
@@ -90,6 +96,7 @@ type profiler struct {
9096
uids []string
9197
gids []string
9298
pids []string
99+
paths []string
93100
entryChan chan *logEntry // one line
94101
statsChan chan map[string]*stat
95102
pause chan bool
@@ -112,10 +119,11 @@ type logEntry struct {
112119
ts time.Time
113120
uid, gid, pid string
114121
op string
115-
latency int // us
122+
latency int // us
123+
path string // only for Windows FUSE log
116124
}
117125

118-
func parseLine(line string) *logEntry {
126+
func parseLine(line string, winFuseLog bool) *logEntry {
119127
if len(line) < 3 { // dummy line: "#"
120128
return nil
121129
}
@@ -140,20 +148,42 @@ func parseLine(line string) *logEntry {
140148
logger.Warnf("Failed to parse log line: %s: %s", line, err)
141149
return nil
142150
}
151+
152+
filePath := ""
153+
if winFuseLog {
154+
// Find the path in Windows log, should after the "{op} (/xxxx/bb bb/cc cc.*)"
155+
// the windows path may contain space or "(", ")"
156+
restPart := strings.Join(fields[4:len(fields)-1], " ")
157+
if strings.HasPrefix(restPart, "(") && strings.Contains(restPart, ")") {
158+
lastIndex := strings.LastIndex(restPart, ")")
159+
if lastIndex > 1 {
160+
paths := strings.SplitN(restPart[1:lastIndex], ",", 2)
161+
if len(paths) > 0 {
162+
filePath = paths[0]
163+
}
164+
}
165+
}
166+
167+
if filePath == "" {
168+
logger.Warnf("log line is invalid, cannot find path: %s", line)
169+
}
170+
}
171+
143172
return &logEntry{
144173
ts: ts,
145174
uid: ids[0],
146175
gid: ids[1],
147176
pid: ids[2],
148177
op: fields[3],
149178
latency: int(latFloat * 1000000.0),
179+
path: filePath,
150180
}
151181
}
152182

153183
func (p *profiler) reader() {
154184
scanner := bufio.NewScanner(p.file)
155185
for scanner.Scan() {
156-
p.entryChan <- parseLine(scanner.Text())
186+
p.entryChan <- parseLine(scanner.Text(), p.isWinFuseLog())
157187
}
158188
if err := scanner.Err(); err != nil {
159189
logger.Fatalf("Reading log file failed with error: %s", err)
@@ -164,6 +194,10 @@ func (p *profiler) reader() {
164194
}
165195
}
166196

197+
func (p *profiler) isWinFuseLog() bool {
198+
return len(p.paths) > 0
199+
}
200+
167201
func (p *profiler) isValid(entry *logEntry) bool {
168202
valid := func(f []string, e string) bool {
169203
if len(f) == 1 && f[0] == "" {
@@ -176,7 +210,7 @@ func (p *profiler) isValid(entry *logEntry) bool {
176210
}
177211
return false
178212
}
179-
return valid(p.uids, entry.uid) && valid(p.gids, entry.gid) && valid(p.pids, entry.pid)
213+
return valid(p.uids, entry.uid) && valid(p.gids, entry.gid) && valid(p.pids, entry.pid) && valid(p.paths, entry.path)
180214
}
181215

182216
func (p *profiler) counter() {
@@ -376,6 +410,7 @@ func profile(ctx *cli.Context) error {
376410
uids: strings.Split(ctx.String("uid"), ","),
377411
gids: strings.Split(ctx.String("gid"), ","),
378412
pids: strings.Split(ctx.String("pid"), ","),
413+
paths: strings.Split(ctx.String("paths"), ","),
379414
entryChan: make(chan *logEntry, 16),
380415
statsChan: make(chan map[string]*stat),
381416
pause: make(chan bool),

0 commit comments

Comments
 (0)