diff --git a/.gitignore b/.gitignore index aaadf73..2b49a0b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore # # Binaries for programs and plugins +/cloud_pcap *.exe *.exe~ *.dll diff --git a/callback.go b/callback.go index e6178fd..29e07e5 100644 --- a/callback.go +++ b/callback.go @@ -21,7 +21,8 @@ func compressAndUpload(cfg *Config, pcapPath string) error { log.Printf("Processing %s", pcapPath) - if _, err := os.Stat(pcapPath); err != nil { + originalInfo, err := os.Stat(pcapPath) + if err != nil { return fmt.Errorf("pcap file not found: %w", err) } @@ -32,6 +33,17 @@ func compressAndUpload(cfg *Config, pcapPath string) error { return fmt.Errorf("bzip2 failed: %s: %w", string(out), err) } compressedPath := pcapPath + ".bz2" + compressedInfo, err := os.Stat(compressedPath) + if err != nil { + return fmt.Errorf("stat compressed file: %w", err) + } + compressionStats := formatCompressionStats( + filepath.Base(pcapPath), + filepath.Base(compressedPath), + originalInfo.Size(), + compressedInfo.Size(), + ) + log.Printf("Compression complete: %s", compressionStats) // Upload to S3 with year/month/day folder structure now := time.Now().UTC() @@ -54,6 +66,20 @@ func compressAndUpload(cfg *Config, pcapPath string) error { return nil } +func formatCompressionStats(originalName, compressedName string, originalSize, compressedSize int64) string { + ratioText := "ratio unavailable" + + if originalSize == 0 { + ratioText = "ratio unavailable: empty input file" + } else if compressedSize == 0 { + ratioText = "ratio unavailable: empty compressed file" + } else { + ratioText = fmt.Sprintf("ratio %.2f:1", float64(originalSize)/float64(compressedSize)) + } + + return fmt.Sprintf("%s -> %s (%d bytes -> %d bytes, %s)", originalName, compressedName, originalSize, compressedSize, ratioText) +} + func uploadToS3(cfg *Config, filePath, key string) error { ctx := context.Background() diff --git a/callback_test.go b/callback_test.go new file mode 100644 index 0000000..50f611c --- /dev/null +++ b/callback_test.go @@ -0,0 +1,29 @@ +package main + +import "testing" + +func TestFormatCompressionStats(t *testing.T) { + t.Run("includes compression ratio", func(t *testing.T) { + got := formatCompressionStats("capture.pcap", "capture.pcap.bz2", 1024, 256) + want := "capture.pcap -> capture.pcap.bz2 (1024 bytes -> 256 bytes, ratio 4.00:1)" + if got != want { + t.Fatalf("formatCompressionStats() = %q, want %q", got, want) + } + }) + + t.Run("handles zero compressed size", func(t *testing.T) { + got := formatCompressionStats("capture.pcap", "capture.pcap.bz2", 1024, 0) + want := "capture.pcap -> capture.pcap.bz2 (1024 bytes -> 0 bytes, ratio unavailable: empty compressed file)" + if got != want { + t.Fatalf("formatCompressionStats() = %q, want %q", got, want) + } + }) + + t.Run("handles zero original size", func(t *testing.T) { + got := formatCompressionStats("capture.pcap", "capture.pcap.bz2", 0, 128) + want := "capture.pcap -> capture.pcap.bz2 (0 bytes -> 128 bytes, ratio unavailable: empty input file)" + if got != want { + t.Fatalf("formatCompressionStats() = %q, want %q", got, want) + } + }) +}