@@ -64,18 +64,15 @@ type Git struct {
64
64
jobID sources.JobID
65
65
sourceMetadataFunc func (file , email , commit , timestamp , repository string , line int64 ) * source_metadatapb.MetaData
66
66
verify bool
67
- metrics metrics
67
+ metrics metricsCollector
68
68
concurrency * semaphore.Weighted
69
69
skipBinaries bool
70
70
skipArchives bool
71
+ repoCommitsScanned uint64 // Atomic counter for commits scanned in the current repo
71
72
72
73
parser * gitparse.Parser
73
74
}
74
75
75
- type metrics struct {
76
- commitsScanned uint64
77
- }
78
-
79
76
// Config for a Git source.
80
77
type Config struct {
81
78
Concurrency int
@@ -114,6 +111,7 @@ func NewGit(config *Config) *Git {
114
111
jobID : config .JobID ,
115
112
sourceMetadataFunc : config .SourceMetadataFunc ,
116
113
verify : config .Verify ,
114
+ metrics : metricsInstance ,
117
115
concurrency : semaphore .NewWeighted (int64 (config .Concurrency )),
118
116
skipBinaries : config .SkipBinaries ,
119
117
skipArchives : config .SkipArchives ,
@@ -404,6 +402,9 @@ func CloneRepo(ctx context.Context, userInfo *url.Userinfo, gitURL string, authI
404
402
// DO NOT FORGET TO CLEAN UP THE CLONE PATH HERE!!
405
403
// If we don't, we'll end up with a bunch of orphaned directories in the temp dir.
406
404
CleanOnError (& err , clonePath )
405
+
406
+ // Note: We don't need to record the clone failure here as it's already
407
+ // recorded in executeClone when the error occurs
407
408
return "" , nil , err
408
409
}
409
410
@@ -483,6 +484,10 @@ func executeClone(ctx context.Context, params cloneParams) (*git.Repository, err
483
484
return nil , fmt .Errorf ("clone command exited with no output" )
484
485
} else if cloneCmd .ProcessState .ExitCode () != 0 {
485
486
logger .V (1 ).Info ("git clone failed" , "error" , err )
487
+ // Record the clone failure with the appropriate reason and exit code
488
+ failureReason := ClassifyCloneError (output )
489
+ exitCode := cloneCmd .ProcessState .ExitCode ()
490
+ metricsInstance .RecordCloneOperation (statusFailure , failureReason , exitCode )
486
491
return nil , fmt .Errorf ("could not clone repo: %s, %w" , safeURL , err )
487
492
}
488
493
@@ -493,6 +498,9 @@ func executeClone(ctx context.Context, params cloneParams) (*git.Repository, err
493
498
}
494
499
logger .V (1 ).Info ("successfully cloned repo" )
495
500
501
+ // Record the successful clone operation
502
+ metricsInstance .RecordCloneOperation (statusSuccess , cloneSuccess , 0 )
503
+
496
504
return repo , nil
497
505
}
498
506
@@ -518,7 +526,18 @@ func PingRepoUsingToken(ctx context.Context, token, gitUrl, user string) error {
518
526
fakeRef := "TRUFFLEHOG_CHECK_GIT_REMOTE_URL_REACHABILITY"
519
527
gitArgs := []string {"ls-remote" , lsUrl .String (), "--quiet" , fakeRef }
520
528
cmd := exec .Command ("git" , gitArgs ... )
521
- _ , err = cmd .CombinedOutput ()
529
+ output , err := cmd .CombinedOutput ()
530
+
531
+ if err != nil {
532
+ // Record the ping failure with the appropriate reason and exit code
533
+ failureReason := ClassifyCloneError (string (output ))
534
+ exitCode := 0
535
+ if cmd .ProcessState != nil {
536
+ exitCode = cmd .ProcessState .ExitCode ()
537
+ }
538
+ metricsInstance .RecordCloneOperation (statusFailure , failureReason , exitCode )
539
+ }
540
+
522
541
return err
523
542
}
524
543
@@ -546,8 +565,9 @@ var codeCommitRE = regexp.MustCompile(`ssh://git-codecommit\.[\w-]+\.amazonaws\.
546
565
547
566
func isCodeCommitURL (gitURL string ) bool { return codeCommitRE .MatchString (gitURL ) }
548
567
568
+ // CommitsScanned returns the number of commits scanned
549
569
func (s * Git ) CommitsScanned () uint64 {
550
- return atomic .LoadUint64 (& s .metrics . commitsScanned )
570
+ return atomic .LoadUint64 (& s .repoCommitsScanned )
551
571
}
552
572
553
573
const gitDirName = ".git"
@@ -627,7 +647,9 @@ func (s *Git) ScanCommits(ctx context.Context, repo *git.Repository, path string
627
647
if fullHash != lastCommitHash {
628
648
depth ++
629
649
lastCommitHash = fullHash
630
- atomic .AddUint64 (& s .metrics .commitsScanned , 1 )
650
+ s .metrics .RecordCommitScanned ()
651
+ // Increment repo-specific commit counter
652
+ atomic .AddUint64 (& s .repoCommitsScanned , 1 )
631
653
logger .V (5 ).Info ("scanning commit" , "commit" , fullHash )
632
654
633
655
// Scan the commit metadata.
@@ -869,7 +891,9 @@ func (s *Git) ScanStaged(ctx context.Context, repo *git.Repository, path string,
869
891
if fullHash != lastCommitHash {
870
892
depth ++
871
893
lastCommitHash = fullHash
872
- atomic .AddUint64 (& s .metrics .commitsScanned , 1 )
894
+ s .metrics .RecordCommitScanned ()
895
+ // Increment repo-specific commit counter
896
+ atomic .AddUint64 (& s .repoCommitsScanned , 1 )
873
897
}
874
898
875
899
if reachedBase && fullHash != scanOptions .BaseHash {
@@ -961,7 +985,12 @@ func (s *Git) ScanRepo(ctx context.Context, repo *git.Repository, repoPath strin
961
985
}
962
986
start := time .Now ().Unix ()
963
987
988
+ // Reset the repo-specific commit counter
989
+ atomic .StoreUint64 (& s .repoCommitsScanned , 0 )
990
+
964
991
if err := s .ScanCommits (ctx , repo , repoPath , scanOptions , reporter ); err != nil {
992
+ // Record that we've failed to scan this repo
993
+ s .metrics .RecordRepoScanned (statusFailure )
965
994
return err
966
995
}
967
996
if ! scanOptions .Bare {
@@ -970,6 +999,9 @@ func (s *Git) ScanRepo(ctx context.Context, repo *git.Repository, repoPath strin
970
999
}
971
1000
}
972
1001
1002
+ // Get the number of commits scanned in this repo
1003
+ commitsScannedInRepo := atomic .LoadUint64 (& s .repoCommitsScanned )
1004
+
973
1005
logger := ctx .Logger ()
974
1006
// We're logging time, but the repoPath is usually a dynamically generated folder in /tmp.
975
1007
// To make this duration logging useful, we need to log the remote as well.
@@ -988,8 +1020,11 @@ func (s *Git) ScanRepo(ctx context.Context, repo *git.Repository, repoPath strin
988
1020
"scanning git repo complete" ,
989
1021
"path" , repoPath ,
990
1022
"time_seconds" , scanTime ,
991
- "commits_scanned" , atomic . LoadUint64 ( & s . metrics . commitsScanned ) ,
1023
+ "commits_scanned" , commitsScannedInRepo ,
992
1024
)
1025
+
1026
+ // Record that we've scanned a repo successfully
1027
+ s .metrics .RecordRepoScanned (statusSuccess )
993
1028
return nil
994
1029
}
995
1030
0 commit comments