(dir, pattern string, retainCount int)
| 131 | } |
| 132 | |
| 133 | func retainMostRecentFilesByPattern(dir, pattern string, retainCount int) error { |
| 134 | matches, err := filepath.Glob(filepath.Join(dir, pattern)) |
| 135 | if err != nil { |
| 136 | return err |
| 137 | } |
| 138 | |
| 139 | type fileInfo struct { |
| 140 | path string |
| 141 | timestamp int64 |
| 142 | } |
| 143 | |
| 144 | files := make([]fileInfo, 0, len(matches)) |
| 145 | for _, path := range matches { |
| 146 | // Extract timestamp from filename |
| 147 | base := filepath.Base(path) |
| 148 | // Find the last underscore and extract everything after it until .prof |
| 149 | if idx := strings.LastIndex(base, "_"); idx != -1 { |
| 150 | timestampStr := strings.TrimSuffix(base[idx+1:], ".prof") |
| 151 | timestamp, err := strconv.ParseInt(timestampStr, 10, 64) |
| 152 | if err != nil { |
| 153 | slog.Info("memory monitor: failed to parse timestamp from filename", "file", base, log.BBError(err)) |
| 154 | continue |
| 155 | } |
| 156 | files = append(files, fileInfo{path: path, timestamp: timestamp}) |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | // Sort files by timestamp in descending order (most recent first) |
| 161 | slices.SortFunc(files, func(a, b fileInfo) int { |
| 162 | if a.timestamp > b.timestamp { |
| 163 | return -1 |
| 164 | } else if a.timestamp < b.timestamp { |
| 165 | return 1 |
| 166 | } |
| 167 | return 0 |
| 168 | }) |
| 169 | |
| 170 | // Remove older files beyond retention count |
| 171 | for i := retainCount; i < len(files); i++ { |
| 172 | slog.Info("memory monitor: removing old dump file", "file", files[i].path) |
| 173 | if err := os.Remove(files[i].path); err != nil { |
| 174 | slog.Info("memory monitor: failed to remove old dump file", "file", files[i].path, log.BBError(err)) |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | return nil |
| 179 | } |
no test coverage detected