|
5 | 5 | "io" |
6 | 6 | "mime" |
7 | 7 | "os" |
| 8 | + "os/exec" |
8 | 9 | "path/filepath" |
9 | 10 | "strings" |
10 | 11 |
|
@@ -93,11 +94,24 @@ func (w *worker) work(controller inputer, jobProvider *jobProvider, readBufferSi |
93 | 94 | } |
94 | 95 | } |
95 | 96 |
|
96 | | - mimeType := getMimeType(file.Name()) |
97 | 97 | var reader io.Reader |
98 | | - |
99 | | - if mimeType == "application/x-lz4" { |
| 98 | + if job.mimeType == "application/x-lz4" { |
| 99 | + if isNotFileBeingWritten(file.Name()) { |
| 100 | + logger.Error("cannot lock file", zap.String("filename", file.Name())) |
| 101 | + break |
| 102 | + } |
100 | 103 | lz4Reader := lz4.NewReader(file) |
| 104 | + if len(offsets) > 0 { |
| 105 | + for lastOffset+int64(readBufferSize) < offsets[0].Offset { |
| 106 | + n, err := lz4Reader.Read(readBuf) |
| 107 | + if err != nil { |
| 108 | + if err == io.EOF { |
| 109 | + break // End of file reached |
| 110 | + } |
| 111 | + } |
| 112 | + lastOffset += int64(n) |
| 113 | + } |
| 114 | + } |
101 | 115 | reader = lz4Reader |
102 | 116 | } else { |
103 | 117 | reader = file |
@@ -200,22 +214,49 @@ func getMimeType(filename string) string { |
200 | 214 | return mimeType |
201 | 215 | } |
202 | 216 |
|
| 217 | +func isNotFileBeingWritten(filePath string) bool { |
| 218 | + // Run the lsof command to check open file descriptors |
| 219 | + cmd := exec.Command("lsof", filePath) |
| 220 | + output, err := cmd.Output() |
| 221 | + if err != nil { |
| 222 | + return false // Error running lsof |
| 223 | + } |
| 224 | + |
| 225 | + // Check the output for write access |
| 226 | + lines := strings.Split(string(output), "\n") |
| 227 | + for _, line := range lines { |
| 228 | + // Check if the line contains 'w' indicating write access |
| 229 | + if strings.Contains(line, "w") { |
| 230 | + return true // File is being written to |
| 231 | + } |
| 232 | + } |
| 233 | + |
| 234 | + return false // File is not being written to |
| 235 | +} |
| 236 | + |
203 | 237 | func (w *worker) processEOF(file *os.File, job *Job, jobProvider *jobProvider, totalOffset int64) error { |
204 | 238 | stat, err := file.Stat() |
205 | 239 | if err != nil { |
206 | 240 | return err |
207 | 241 | } |
208 | 242 |
|
209 | | - // files truncated from time to time, after logs from file was processed. |
210 | | - // Position > stat.Size() means that data was truncated and |
211 | | - // caret pointer must be moved to start of file. |
212 | | - if totalOffset > stat.Size() { |
213 | | - jobProvider.truncateJob(job) |
| 243 | + if !job.isCompressed { |
| 244 | + // files truncated from time to time, after logs from file was processed. |
| 245 | + // Position > stat.Size() means that data was truncated and |
| 246 | + // caret pointer must be moved to start of file. |
| 247 | + if totalOffset > stat.Size() { |
| 248 | + jobProvider.truncateJob(job) |
| 249 | + } |
214 | 250 | } |
215 | | - |
216 | 251 | // Mark job as done till new lines has appeared. |
217 | 252 | jobProvider.doneJob(job) |
218 | 253 |
|
| 254 | + if job.isCompressed { |
| 255 | + job.mu.Lock() |
| 256 | + file.Close() |
| 257 | + jobProvider.deleteJobAndUnlock(job) |
| 258 | + } |
| 259 | + |
219 | 260 | return nil |
220 | 261 | } |
221 | 262 |
|
|
0 commit comments