@@ -122,6 +122,43 @@ type FirewallAnalysis struct {
122122 RequestsByDomain map [string ]DomainRequestStats
123123}
124124
125+ // GetAllowedDomains returns the list of allowed domains
126+ func (f * FirewallAnalysis ) GetAllowedDomains () []string {
127+ return f .AllowedDomains
128+ }
129+
130+ // GetDeniedDomains returns the list of denied domains
131+ func (f * FirewallAnalysis ) GetDeniedDomains () []string {
132+ return f .DeniedDomains
133+ }
134+
135+ // SetAllowedDomains sets the list of allowed domains
136+ func (f * FirewallAnalysis ) SetAllowedDomains (domains []string ) {
137+ f .AllowedDomains = domains
138+ }
139+
140+ // SetDeniedDomains sets the list of denied domains
141+ func (f * FirewallAnalysis ) SetDeniedDomains (domains []string ) {
142+ f .DeniedDomains = domains
143+ }
144+
145+ // AddMetrics adds metrics from another analysis
146+ func (f * FirewallAnalysis ) AddMetrics (other LogAnalysis ) {
147+ if otherFirewall , ok := other .(* FirewallAnalysis ); ok {
148+ f .TotalRequests += otherFirewall .TotalRequests
149+ f .AllowedRequests += otherFirewall .AllowedRequests
150+ f .DeniedRequests += otherFirewall .DeniedRequests
151+
152+ // Merge request stats by domain
153+ for domain , stats := range otherFirewall .RequestsByDomain {
154+ existing := f .RequestsByDomain [domain ]
155+ existing .Allowed += stats .Allowed
156+ existing .Denied += stats .Denied
157+ f .RequestsByDomain [domain ] = existing
158+ }
159+ }
160+ }
161+
125162// DomainRequestStats tracks request statistics per domain
126163type DomainRequestStats struct {
127164 Allowed int
@@ -374,77 +411,17 @@ func analyzeFirewallLogs(runDir string, verbose bool) (*FirewallAnalysis, error)
374411
375412// analyzeMultipleFirewallLogs analyzes multiple firewall log files in a directory
376413func analyzeMultipleFirewallLogs (logsDir string , verbose bool ) (* FirewallAnalysis , error ) {
377- files , err := filepath .Glob (filepath .Join (logsDir , "*.log" ))
378- if err != nil {
379- return nil , fmt .Errorf ("failed to find firewall log files: %w" , err )
380- }
381-
382- if len (files ) == 0 {
383- if verbose {
384- fmt .Fprintln (os .Stderr , console .FormatInfoMessage (fmt .Sprintf ("No firewall log files found in %s" , logsDir )))
385- }
386- return nil , nil
387- }
388-
389- if verbose {
390- fmt .Fprintln (os .Stderr , console .FormatInfoMessage (fmt .Sprintf ("Analyzing %d firewall log files from %s" , len (files ), logsDir )))
391- }
392-
393- // Aggregate analysis from all files
394- aggregated := & FirewallAnalysis {
395- AllowedDomains : []string {},
396- DeniedDomains : []string {},
397- RequestsByDomain : make (map [string ]DomainRequestStats ),
398- }
399-
400- allAllowedDomains := make (map [string ]bool )
401- allDeniedDomains := make (map [string ]bool )
402-
403- for _ , file := range files {
404- if verbose {
405- fmt .Fprintln (os .Stderr , console .FormatInfoMessage (fmt .Sprintf ("Parsing %s" , filepath .Base (file ))))
406- }
407-
408- analysis , err := parseFirewallLog (file , verbose )
409- if err != nil {
410- if verbose {
411- fmt .Fprintln (os .Stderr , console .FormatWarningMessage (fmt .Sprintf ("Failed to parse %s: %v" , filepath .Base (file ), err )))
414+ return aggregateLogFiles (
415+ logsDir ,
416+ "*.log" ,
417+ verbose ,
418+ parseFirewallLog ,
419+ func () * FirewallAnalysis {
420+ return & FirewallAnalysis {
421+ AllowedDomains : []string {},
422+ DeniedDomains : []string {},
423+ RequestsByDomain : make (map [string ]DomainRequestStats ),
412424 }
413- continue
414- }
415-
416- // Aggregate metrics
417- aggregated .TotalRequests += analysis .TotalRequests
418- aggregated .AllowedRequests += analysis .AllowedRequests
419- aggregated .DeniedRequests += analysis .DeniedRequests
420-
421- // Collect unique domains
422- for _ , domain := range analysis .AllowedDomains {
423- allAllowedDomains [domain ] = true
424- }
425- for _ , domain := range analysis .DeniedDomains {
426- allDeniedDomains [domain ] = true
427- }
428-
429- // Merge request stats by domain
430- for domain , stats := range analysis .RequestsByDomain {
431- existing := aggregated .RequestsByDomain [domain ]
432- existing .Allowed += stats .Allowed
433- existing .Denied += stats .Denied
434- aggregated .RequestsByDomain [domain ] = existing
435- }
436- }
437-
438- // Convert sets to sorted slices
439- for domain := range allAllowedDomains {
440- aggregated .AllowedDomains = append (aggregated .AllowedDomains , domain )
441- }
442- for domain := range allDeniedDomains {
443- aggregated .DeniedDomains = append (aggregated .DeniedDomains , domain )
444- }
445-
446- sort .Strings (aggregated .AllowedDomains )
447- sort .Strings (aggregated .DeniedDomains )
448-
449- return aggregated , nil
425+ },
426+ )
450427}
0 commit comments