diff --git a/app/server/appsmith-git/src/main/java/com/appsmith/git/handler/FSGitHandlerImpl.java b/app/server/appsmith-git/src/main/java/com/appsmith/git/handler/FSGitHandlerImpl.java index a36aa4947a..f22fec6f06 100644 --- a/app/server/appsmith-git/src/main/java/com/appsmith/git/handler/FSGitHandlerImpl.java +++ b/app/server/appsmith-git/src/main/java/com/appsmith/git/handler/FSGitHandlerImpl.java @@ -2,6 +2,7 @@ package com.appsmith.git.handler; import com.appsmith.external.configurations.git.GitConfig; import com.appsmith.external.git.handler.FSGitHandler; +import com.appsmith.external.helpers.ObservationHelper; import com.appsmith.git.configurations.GitServiceConfig; import com.appsmith.git.handler.ce.FSGitHandlerCEImpl; import io.micrometer.observation.ObservationRegistry; @@ -15,7 +16,10 @@ import org.springframework.stereotype.Component; public class FSGitHandlerImpl extends FSGitHandlerCEImpl implements FSGitHandler { public FSGitHandlerImpl( - GitServiceConfig gitServiceConfig, GitConfig gitConfig, ObservationRegistry observationRegistry) { - super(gitServiceConfig, gitConfig, observationRegistry); + GitServiceConfig gitServiceConfig, + GitConfig gitConfig, + ObservationRegistry observationRegistry, + ObservationHelper observationHelper) { + super(gitServiceConfig, gitConfig, observationRegistry, observationHelper); } } diff --git a/app/server/appsmith-git/src/main/java/com/appsmith/git/handler/ce/FSGitHandlerCEImpl.java b/app/server/appsmith-git/src/main/java/com/appsmith/git/handler/ce/FSGitHandlerCEImpl.java index 3dd0e4970e..b2a526ce45 100644 --- a/app/server/appsmith-git/src/main/java/com/appsmith/git/handler/ce/FSGitHandlerCEImpl.java +++ b/app/server/appsmith-git/src/main/java/com/appsmith/git/handler/ce/FSGitHandlerCEImpl.java @@ -12,6 +12,7 @@ import com.appsmith.external.git.constants.GitSpan; import com.appsmith.external.git.constants.ce.RefType; import com.appsmith.external.git.dtos.FetchRemoteDTO; import com.appsmith.external.git.handler.FSGitHandler; +import com.appsmith.external.helpers.ObservationHelper; import com.appsmith.external.helpers.Stopwatch; import com.appsmith.git.configurations.GitServiceConfig; import com.appsmith.git.constants.AppsmithBotAsset; @@ -22,6 +23,7 @@ import com.appsmith.git.helpers.RepositoryHelper; import com.appsmith.git.helpers.SshTransportConfigCallback; import com.appsmith.git.helpers.StopwatchHelpers; import io.micrometer.observation.ObservationRegistry; +import io.micrometer.tracing.Span; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.jgit.api.CreateBranchCommand; @@ -99,6 +101,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { private static final String TAG_REF = "refs/tags/"; private static final String SUCCESS_MERGE_STATUS = "This branch has no conflicts with the base branch."; + private final ObservationHelper observationHelper; /** * This method will handle the git-commit functionality. Under the hood it checks if the repo has already been @@ -128,6 +131,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { return Mono.using( () -> Git.open(repoPath.toFile()), git -> Mono.fromCallable(() -> { + Span jgitAddSpan = observationHelper.createSpan(GitSpan.JGIT_ADD); log.debug("Trying to commit to local repo path, {}", path); Stopwatch processStopwatch = StopwatchHelpers.startStopwatch( @@ -140,8 +144,10 @@ public class FSGitHandlerCEImpl implements FSGitHandler { .setUpdate(true) .addFilepattern(".") .call(); + jgitAddSpan.end(); // Commit the changes + Span jgitCommitSpan = observationHelper.createSpan(GitSpan.JGIT_COMMIT); git.commit() .setMessage(commitMessage) // Only make a commit if there are any updates @@ -150,6 +156,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { .setCommitter(finalAuthorName, finalAuthorEmail) .setAmend(doAmend) .call(); + jgitCommitSpan.end(); processStopwatch.stopAndLogTimeInMillis(); return "Committed successfully!"; }) @@ -236,6 +243,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { return Mono.using( () -> Git.open(baseRepoPath.toFile()), git -> Mono.fromCallable(() -> { + Span jgitPushSpan = observationHelper.createSpan(GitSpan.JGIT_PUSH); log.debug(Thread.currentThread().getName() + ": pushing changes to remote " + remoteUrl); // open the repo @@ -266,6 +274,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { // UsernamePasswordCredentialsProvider("username", // "password")); processStopwatch.stopAndLogTimeInMillis(); + jgitPushSpan.end(); return result.substring(0, result.length() - 1); }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) @@ -294,6 +303,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { Stopwatch processStopwatch = StopwatchHelpers.startStopwatch(repoSuffix, AnalyticsEvents.GIT_CLONE.getEventName()); return Mono.fromCallable(() -> { + Span jgitCloneRepoSpan = observationHelper.createSpan(GitSpan.JGIT_CLONE_REPO); log.debug(Thread.currentThread().getName() + ": Cloning the repo from the remote " + remoteUrl); final TransportConfigCallback transportConfigCallback = new SshTransportConfigCallback(privateKey, publicKey); @@ -314,6 +324,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { repositoryHelper.updateRemoteBranchTrackingConfig(branchName, git); } processStopwatch.stopAndLogTimeInMillis(); + jgitCloneRepoSpan.end(); return branchName; }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) @@ -331,6 +342,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler { return Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitCreateBranchSpan = + observationHelper.createSpan(GitSpan.JGIT_CREATE_BRANCH); log.debug(Thread.currentThread().getName() + ": Creating branch " + branchName + "for the repo " + repoSuffix); // open the repo @@ -343,7 +356,10 @@ public class FSGitHandlerCEImpl implements FSGitHandler { repositoryHelper.updateRemoteBranchTrackingConfig(branchName, git); processStopwatch.stopAndLogTimeInMillis(); - return git.getRepository().getBranch(); + String branch = git.getRepository().getBranch(); + jgitCreateBranchSpan.end(); + + return branch; }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .name(GitSpan.FS_CREATE_BRANCH) @@ -378,6 +394,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler { return Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitCreateBranchSpan = + observationHelper.createSpan(GitSpan.JGIT_CREATE_BRANCH); log.info( "{} : Creating reference of type {} and name {} for the repo {}", Thread.currentThread().getName(), @@ -388,8 +406,9 @@ public class FSGitHandlerCEImpl implements FSGitHandler { if (RefType.tag.equals(refType)) { return createTag(git, gitRefDTO); } - - return createAndCheckoutBranch(git, gitRefDTO); + String branch = createAndCheckoutBranch(git, gitRefDTO); + jgitCreateBranchSpan.end(); + return branch; }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .name(GitSpan.FS_CREATE_BRANCH) @@ -407,6 +426,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler { return Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitDeleteBranchSpan = + observationHelper.createSpan(GitSpan.JGIT_DELETE_BRANCH); log.debug(Thread.currentThread().getName() + ": Deleting branch " + branchName + "for the repo " + repoSuffix); // open the repo @@ -416,9 +437,11 @@ public class FSGitHandlerCEImpl implements FSGitHandler { .setForce(TRUE) .call(); processStopwatch.stopAndLogTimeInMillis(); + jgitDeleteBranchSpan.end(); if (deleteBranchList.isEmpty()) { return Boolean.FALSE; } + return TRUE; }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) @@ -436,6 +459,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler { return Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitCheckoutBranchSpan = + observationHelper.createSpan(GitSpan.JGIT_CHECKOUT_BRANCH); log.info( "{}: Switching to the branch {}", Thread.currentThread().getName(), @@ -455,6 +480,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { .call() .getName(); processStopwatch.stopAndLogTimeInMillis(); + jgitCheckoutBranchSpan.end(); return StringUtils.equalsIgnoreCase(checkedOutBranch, "refs/heads/" + branchName); }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) @@ -474,6 +500,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { return Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitPullSpan = observationHelper.createSpan(GitSpan.JGIT_PULL); log.info( "{} : Pull changes from remote {} for the branch {}.", Thread.currentThread().getName(), @@ -496,6 +523,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { if (mergeResult.getMergeStatus().isSuccessful()) { mergeStatus.setMergeAble(true); mergeStatus.setStatus(count + " commits merged from origin/" + branchName); + jgitPullSpan.end(); return mergeStatus; } else { // If there are conflicts add the conflicting file names to the response @@ -518,6 +546,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler { log.debug("Encountered error while aborting merge", e); throw new org.eclipse.jgit.errors.CheckoutConflictException( mergeConflictFiles.toString()); + } finally { + jgitPullSpan.end(); } } }) @@ -541,6 +571,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { return Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitPullSpan = observationHelper.createSpan(GitSpan.JGIT_PULL); log.debug(Thread.currentThread().getName() + ": Pull changes from remote " + remoteUrl + " for the branch " + branchName); // checkout the branch on which the merge command is run @@ -566,6 +597,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { mergeStatus.setMergeAble(true); mergeStatus.setStatus(count + " commits merged from origin/" + branchName); processStopwatch.stopAndLogTimeInMillis(); + jgitPullSpan.end(); return mergeStatus; } else { // If there are conflicts add the conflicting file names to the response @@ -590,6 +622,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { mergeConflictFiles.toString()); } finally { processStopwatch.stopAndLogTimeInMillis(); + jgitPullSpan.end(); } } }) @@ -676,6 +709,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { return Mono.using( () -> Git.open(repoPath.toFile()), git -> Mono.fromCallable(() -> { + Span jgitStatusSpan = observationHelper.createSpan(GitSpan.JGIT_STATUS); log.info( "{}: Get status for repo {}, {}", Thread.currentThread().getName(), @@ -728,10 +762,12 @@ public class FSGitHandlerCEImpl implements FSGitHandler { if (!status.isClean()) { return resetToLastCommit(git).map(ref -> { processStopwatch.stopAndLogTimeInMillis(); + jgitStatusSpan.end(); return response; }); } processStopwatch.stopAndLogTimeInMillis(); + jgitStatusSpan.end(); return Mono.just(response); }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) @@ -919,6 +955,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { return Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitMergeSpan = observationHelper.createSpan(GitSpan.JGIT_MERGE); Stopwatch processStopwatch = StopwatchHelpers.startStopwatch( repoSuffix, AnalyticsEvents.GIT_MERGE.getEventName()); @@ -941,6 +978,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler { git.getRepository().writeMergeHeads(null); processStopwatch.stopAndLogTimeInMillis(); throw new Exception(e); + } finally { + jgitMergeSpan.end(); } }) .onErrorResume(error -> { @@ -973,6 +1012,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { return Mono.using( () -> Git.open(repoPath.toFile()), git -> Mono.fromCallable(() -> { + Span jgitFetchRemoteSpan = observationHelper.createSpan(GitSpan.JGIT_FETCH_REMOTE); TransportConfigCallback config = new SshTransportConfigCallback(privateKey, publicKey); String fetchMessages; @@ -993,6 +1033,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { .getMessages(); } processStopwatch.stopAndLogTimeInMillis(); + jgitFetchRemoteSpan.end(); return fetchMessages; }) .onErrorResume(error -> { @@ -1013,15 +1054,18 @@ public class FSGitHandlerCEImpl implements FSGitHandler { return Mono.using( () -> Git.open(repoPath.toFile()), git -> Mono.fromCallable(() -> { + Span jgitFetchRemoteSpan = observationHelper.createSpan(GitSpan.JGIT_FETCH_REMOTE); TransportConfigCallback config = new SshTransportConfigCallback(privateKey, publicKey); if (TRUE.equals(fetchRemoteDTO.getIsFetchAll())) { - return git.fetch() + String fetchMessages = git.fetch() .setRemoveDeletedRefs(true) .setTransportConfigCallback(config) .call() .getMessages(); + jgitFetchRemoteSpan.end(); + return fetchMessages; } List refNames = fetchRemoteDTO.getRefNames(); @@ -1044,7 +1088,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { } } - return git.fetch() + String fetchMessages = git.fetch() .setRefSpecs(refSpecs.toArray(new RefSpec[0])) .setRemoveDeletedRefs(true) .setTagOpt(TagOpt.NO_TAGS) // no tags would mean that tags are fetched @@ -1052,6 +1096,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler { .setTransportConfigCallback(config) .call() .getMessages(); + jgitFetchRemoteSpan.end(); + return fetchMessages; }) .onErrorResume(error -> { log.error(error.getMessage()); @@ -1152,6 +1198,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler { return Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitCheckoutBranchSpan = + observationHelper.createSpan(GitSpan.JGIT_CHECKOUT_BRANCH); log.debug(Thread.currentThread().getName() + ": Checking out remote branch origin/" + branchName + " for the repo " + repoSuffix); // open the repo @@ -1168,7 +1216,9 @@ public class FSGitHandlerCEImpl implements FSGitHandler { config.setString("branch", branchName, "remote", "origin"); config.setString("branch", branchName, "merge", "refs/heads/" + branchName); config.save(); - return git.getRepository().getBranch(); + String branch = git.getRepository().getBranch(); + jgitCheckoutBranchSpan.end(); + return branch; }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .tag(CHECKOUT_REMOTE, TRUE.toString()) @@ -1199,10 +1249,14 @@ public class FSGitHandlerCEImpl implements FSGitHandler { Stopwatch processStopwatch = StopwatchHelpers.startStopwatch( git.getRepository().getDirectory().toPath().getParent(), AnalyticsEvents.GIT_RESET.getEventName()); return Mono.fromCallable(() -> { + Span jgitResetHardSpan = observationHelper.createSpan(GitSpan.JGIT_RESET_HARD); // Remove tracked files Ref ref = git.reset().setMode(ResetCommand.ResetType.HARD).call(); + jgitResetHardSpan.end(); // Remove untracked files + Span jgitCleanSpan = observationHelper.createSpan(GitSpan.JGIT_CLEAN); git.clean().setForce(true).setCleanDirectories(true).call(); + jgitCleanSpan.end(); processStopwatch.stopAndLogTimeInMillis(); return ref; }) @@ -1227,10 +1281,12 @@ public class FSGitHandlerCEImpl implements FSGitHandler { .flatMap(aBoolean -> Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitResetHardSpan = observationHelper.createSpan(GitSpan.JGIT_RESET_HARD); git.reset() .setMode(ResetCommand.ResetType.HARD) .setRef("HEAD~1") .call(); + jgitResetHardSpan.end(); return true; }) .onErrorResume(e -> { @@ -1249,10 +1305,12 @@ public class FSGitHandlerCEImpl implements FSGitHandler { return this.checkoutToBranch(repoSuffix, branchName).flatMap(isCheckedOut -> Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitRebaseSpan = observationHelper.createSpan(GitSpan.JGIT_REBASE); RebaseResult result = git.rebase() .setUpstream("origin/" + branchName) .call(); if (result.getStatus().isSuccessful()) { + jgitRebaseSpan.end(); return true; } else { log.error( @@ -1263,6 +1321,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler { .setUpstream("origin/" + branchName) .setOperation(RebaseCommand.Operation.ABORT) .call(); + jgitRebaseSpan.end(); throw new Exception("Error while rebasing the branch, " + result.getStatus().name()); } @@ -1282,7 +1341,14 @@ public class FSGitHandlerCEImpl implements FSGitHandler { public Mono getBranchTrackingStatus(Path repoPath, String branchName) { return Mono.using( () -> Git.open(repoPath.toFile()), - git -> Mono.fromCallable(() -> BranchTrackingStatus.of(git.getRepository(), branchName)) + git -> Mono.fromCallable(() -> { + Span jgitBranchTrackingSpan = + observationHelper.createSpan(GitSpan.JGIT_BRANCH_TRACK); + BranchTrackingStatus branchTrackingStatus = + BranchTrackingStatus.of(git.getRepository(), branchName); + jgitBranchTrackingSpan.end(); + return branchTrackingStatus; + }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .name(GitSpan.FS_BRANCH_TRACK) .tap(Micrometer.observation(observationRegistry)), diff --git a/app/server/appsmith-git/src/main/java/com/appsmith/git/service/GitExecutorImpl.java b/app/server/appsmith-git/src/main/java/com/appsmith/git/service/GitExecutorImpl.java index f0ad7bdb12..16177dea96 100644 --- a/app/server/appsmith-git/src/main/java/com/appsmith/git/service/GitExecutorImpl.java +++ b/app/server/appsmith-git/src/main/java/com/appsmith/git/service/GitExecutorImpl.java @@ -2,6 +2,7 @@ package com.appsmith.git.service; import com.appsmith.external.configurations.git.GitConfig; import com.appsmith.external.git.GitExecutor; +import com.appsmith.external.helpers.ObservationHelper; import com.appsmith.git.configurations.GitServiceConfig; import com.appsmith.git.service.ce.GitExecutorCEImpl; import io.micrometer.observation.ObservationRegistry; @@ -14,7 +15,10 @@ import org.springframework.stereotype.Component; @Slf4j public class GitExecutorImpl extends GitExecutorCEImpl implements GitExecutor { public GitExecutorImpl( - GitServiceConfig gitServiceConfig, GitConfig gitConfig, ObservationRegistry observationRegistry) { - super(gitServiceConfig, gitConfig, observationRegistry); + GitServiceConfig gitServiceConfig, + GitConfig gitConfig, + ObservationRegistry observationRegistry, + ObservationHelper observationHelper) { + super(gitServiceConfig, gitConfig, observationRegistry, observationHelper); } } diff --git a/app/server/appsmith-git/src/main/java/com/appsmith/git/service/ce/GitExecutorCEImpl.java b/app/server/appsmith-git/src/main/java/com/appsmith/git/service/ce/GitExecutorCEImpl.java index 228a9eb8cb..05c9d01f7d 100644 --- a/app/server/appsmith-git/src/main/java/com/appsmith/git/service/ce/GitExecutorCEImpl.java +++ b/app/server/appsmith-git/src/main/java/com/appsmith/git/service/ce/GitExecutorCEImpl.java @@ -9,6 +9,7 @@ import com.appsmith.external.dtos.GitStatusDTO; import com.appsmith.external.dtos.MergeStatusDTO; import com.appsmith.external.git.GitExecutor; import com.appsmith.external.git.constants.GitSpan; +import com.appsmith.external.helpers.ObservationHelper; import com.appsmith.external.helpers.Stopwatch; import com.appsmith.git.configurations.GitServiceConfig; import com.appsmith.git.constants.AppsmithBotAsset; @@ -19,6 +20,7 @@ import com.appsmith.git.helpers.RepositoryHelper; import com.appsmith.git.helpers.SshTransportConfigCallback; import com.appsmith.git.helpers.StopwatchHelpers; import io.micrometer.observation.ObservationRegistry; +import io.micrometer.tracing.Span; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.jgit.api.CreateBranchCommand; @@ -91,6 +93,7 @@ public class GitExecutorCEImpl implements GitExecutor { private final Scheduler scheduler = Schedulers.boundedElastic(); private static final String SUCCESS_MERGE_STATUS = "This branch has no conflicts with the base branch."; + private final ObservationHelper observationHelper; /** * This method will handle the git-commit functionality. Under the hood it checks if the repo has already been @@ -120,6 +123,7 @@ public class GitExecutorCEImpl implements GitExecutor { return Mono.using( () -> Git.open(repoPath.toFile()), git -> Mono.fromCallable(() -> { + Span jgitAddSpan = observationHelper.createSpan(GitSpan.JGIT_ADD); log.debug("Trying to commit to local repo path, {}", path); Stopwatch processStopwatch = StopwatchHelpers.startStopwatch( @@ -132,8 +136,10 @@ public class GitExecutorCEImpl implements GitExecutor { .setUpdate(true) .addFilepattern(".") .call(); + jgitAddSpan.end(); // Commit the changes + Span jgitCommitSpan = observationHelper.createSpan(GitSpan.JGIT_COMMIT); git.commit() .setMessage(commitMessage) // Only make a commit if there are any updates @@ -142,6 +148,7 @@ public class GitExecutorCEImpl implements GitExecutor { .setCommitter(finalAuthorName, finalAuthorEmail) .setAmend(doAmend) .call(); + jgitCommitSpan.end(); processStopwatch.stopAndLogTimeInMillis(); return "Committed successfully!"; }) @@ -228,6 +235,7 @@ public class GitExecutorCEImpl implements GitExecutor { return Mono.using( () -> Git.open(baseRepoPath.toFile()), git -> Mono.fromCallable(() -> { + Span jgitPushSpan = observationHelper.createSpan(GitSpan.JGIT_PUSH); log.debug(Thread.currentThread().getName() + ": pushing changes to remote " + remoteUrl); // open the repo @@ -258,6 +266,7 @@ public class GitExecutorCEImpl implements GitExecutor { // UsernamePasswordCredentialsProvider("username", // "password")); processStopwatch.stopAndLogTimeInMillis(); + jgitPushSpan.end(); return result.substring(0, result.length() - 1); }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) @@ -286,6 +295,7 @@ public class GitExecutorCEImpl implements GitExecutor { Stopwatch processStopwatch = StopwatchHelpers.startStopwatch(repoSuffix, AnalyticsEvents.GIT_CLONE.getEventName()); return Mono.fromCallable(() -> { + Span jgitCloneRepoSpan = observationHelper.createSpan(GitSpan.JGIT_CLONE_REPO); log.debug(Thread.currentThread().getName() + ": Cloning the repo from the remote " + remoteUrl); final TransportConfigCallback transportConfigCallback = new SshTransportConfigCallback(privateKey, publicKey); @@ -306,6 +316,7 @@ public class GitExecutorCEImpl implements GitExecutor { repositoryHelper.updateRemoteBranchTrackingConfig(branchName, git); } processStopwatch.stopAndLogTimeInMillis(); + jgitCloneRepoSpan.end(); return branchName; }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) @@ -323,6 +334,8 @@ public class GitExecutorCEImpl implements GitExecutor { return Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitCreateBranchSpan = + observationHelper.createSpan(GitSpan.JGIT_CREATE_BRANCH); log.debug(Thread.currentThread().getName() + ": Creating branch " + branchName + "for the repo " + repoSuffix); // open the repo @@ -335,7 +348,10 @@ public class GitExecutorCEImpl implements GitExecutor { repositoryHelper.updateRemoteBranchTrackingConfig(branchName, git); processStopwatch.stopAndLogTimeInMillis(); - return git.getRepository().getBranch(); + String branch = git.getRepository().getBranch(); + jgitCreateBranchSpan.end(); + + return branch; }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .name(GitSpan.FS_CREATE_BRANCH) @@ -353,6 +369,8 @@ public class GitExecutorCEImpl implements GitExecutor { return Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitDeleteBranchSpan = + observationHelper.createSpan(GitSpan.JGIT_DELETE_BRANCH); log.debug(Thread.currentThread().getName() + ": Deleting branch " + branchName + "for the repo " + repoSuffix); // open the repo @@ -362,6 +380,7 @@ public class GitExecutorCEImpl implements GitExecutor { .setForce(TRUE) .call(); processStopwatch.stopAndLogTimeInMillis(); + jgitDeleteBranchSpan.end(); if (deleteBranchList.isEmpty()) { return Boolean.FALSE; } @@ -382,6 +401,8 @@ public class GitExecutorCEImpl implements GitExecutor { return Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitCheckoutBranchSpan = + observationHelper.createSpan(GitSpan.JGIT_CHECKOUT_BRANCH); log.debug(Thread.currentThread().getName() + ": Switching to the branch " + branchName); // We can safely assume that repo has been already initialised either in commit or @@ -400,6 +421,7 @@ public class GitExecutorCEImpl implements GitExecutor { .call() .getName(); processStopwatch.stopAndLogTimeInMillis(); + jgitCheckoutBranchSpan.end(); return StringUtils.equalsIgnoreCase(checkedOutBranch, "refs/heads/" + branchName); }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) @@ -422,6 +444,7 @@ public class GitExecutorCEImpl implements GitExecutor { return Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitPullSpan = observationHelper.createSpan(GitSpan.JGIT_PULL); log.debug(Thread.currentThread().getName() + ": Pull changes from remote " + remoteUrl + " for the branch " + branchName); // checkout the branch on which the merge command is run @@ -447,6 +470,7 @@ public class GitExecutorCEImpl implements GitExecutor { mergeStatus.setMergeAble(true); mergeStatus.setStatus(count + " commits merged from origin/" + branchName); processStopwatch.stopAndLogTimeInMillis(); + jgitPullSpan.end(); return mergeStatus; } else { // If there are conflicts add the conflicting file names to the response @@ -471,6 +495,7 @@ public class GitExecutorCEImpl implements GitExecutor { mergeConflictFiles.toString()); } finally { processStopwatch.stopAndLogTimeInMillis(); + jgitPullSpan.end(); } } }) @@ -557,6 +582,7 @@ public class GitExecutorCEImpl implements GitExecutor { return Mono.using( () -> Git.open(repoPath.toFile()), git -> Mono.fromCallable(() -> { + Span jgitStatusSpan = observationHelper.createSpan(GitSpan.JGIT_STATUS); log.debug(Thread.currentThread().getName() + ": Get status for repo " + repoPath + ", branch " + branchName); Status status = git.status().call(); @@ -605,10 +631,12 @@ public class GitExecutorCEImpl implements GitExecutor { if (!status.isClean()) { return resetToLastCommit(git).map(ref -> { processStopwatch.stopAndLogTimeInMillis(); + jgitStatusSpan.end(); return response; }); } processStopwatch.stopAndLogTimeInMillis(); + jgitStatusSpan.end(); return Mono.just(response); }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) @@ -796,6 +824,7 @@ public class GitExecutorCEImpl implements GitExecutor { return Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitMergeSpan = observationHelper.createSpan(GitSpan.JGIT_MERGE); Stopwatch processStopwatch = StopwatchHelpers.startStopwatch( repoSuffix, AnalyticsEvents.GIT_MERGE.getEventName()); log.debug(Thread.currentThread().getName() + ": Merge branch " + sourceBranch @@ -819,6 +848,8 @@ public class GitExecutorCEImpl implements GitExecutor { git.getRepository().writeMergeHeads(null); processStopwatch.stopAndLogTimeInMillis(); throw new Exception(e); + } finally { + jgitMergeSpan.end(); } }) .onErrorResume(error -> { @@ -851,6 +882,7 @@ public class GitExecutorCEImpl implements GitExecutor { return Mono.using( () -> Git.open(repoPath.toFile()), git -> Mono.fromCallable(() -> { + Span jgitFetchRemoteSpan = observationHelper.createSpan(GitSpan.JGIT_FETCH_REMOTE); TransportConfigCallback config = new SshTransportConfigCallback(privateKey, publicKey); String fetchMessages; @@ -871,6 +903,7 @@ public class GitExecutorCEImpl implements GitExecutor { .getMessages(); } processStopwatch.stopAndLogTimeInMillis(); + jgitFetchRemoteSpan.end(); return fetchMessages; }) .onErrorResume(error -> { @@ -893,6 +926,7 @@ public class GitExecutorCEImpl implements GitExecutor { return Mono.using( () -> Git.open(repoPath.toFile()), git -> Mono.fromCallable(() -> { + Span jgitFetchRemoteSpan = observationHelper.createSpan(GitSpan.JGIT_FETCH_REMOTE); TransportConfigCallback config = new SshTransportConfigCallback(privateKey, publicKey); String fetchMessages; @@ -912,6 +946,7 @@ public class GitExecutorCEImpl implements GitExecutor { .getMessages(); processStopwatch.stopAndLogTimeInMillis(); + jgitFetchRemoteSpan.end(); return fetchMessages; }) .onErrorResume(error -> { @@ -1017,6 +1052,8 @@ public class GitExecutorCEImpl implements GitExecutor { return Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitCheckoutRemoteBranchSpan = + observationHelper.createSpan(GitSpan.JGIT_CHECKOUT_BRANCH); log.debug(Thread.currentThread().getName() + ": Checking out remote branch origin/" + branchName + " for the repo " + repoSuffix); // open the repo @@ -1033,7 +1070,9 @@ public class GitExecutorCEImpl implements GitExecutor { config.setString("branch", branchName, "remote", "origin"); config.setString("branch", branchName, "merge", "refs/heads/" + branchName); config.save(); - return git.getRepository().getBranch(); + String branch = git.getRepository().getBranch(); + jgitCheckoutRemoteBranchSpan.end(); + return branch; }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .tag(CHECKOUT_REMOTE, TRUE.toString()) @@ -1064,10 +1103,14 @@ public class GitExecutorCEImpl implements GitExecutor { Stopwatch processStopwatch = StopwatchHelpers.startStopwatch( git.getRepository().getDirectory().toPath().getParent(), AnalyticsEvents.GIT_RESET.getEventName()); return Mono.fromCallable(() -> { + Span jgitResetHardSpan = observationHelper.createSpan(GitSpan.JGIT_RESET_HARD); // Remove tracked files Ref ref = git.reset().setMode(ResetCommand.ResetType.HARD).call(); + jgitResetHardSpan.end(); // Remove untracked files + Span jgitCleanSpan = observationHelper.createSpan(GitSpan.JGIT_CLEAN); git.clean().setForce(true).setCleanDirectories(true).call(); + jgitCleanSpan.end(); processStopwatch.stopAndLogTimeInMillis(); return ref; }) @@ -1092,10 +1135,12 @@ public class GitExecutorCEImpl implements GitExecutor { .flatMap(aBoolean -> Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitResetHardSpan = observationHelper.createSpan(GitSpan.JGIT_RESET_HARD); git.reset() .setMode(ResetCommand.ResetType.HARD) .setRef("HEAD~1") .call(); + jgitResetHardSpan.end(); return true; }) .onErrorResume(e -> { @@ -1114,10 +1159,12 @@ public class GitExecutorCEImpl implements GitExecutor { return this.checkoutToBranch(repoSuffix, branchName).flatMap(isCheckedOut -> Mono.using( () -> Git.open(createRepoPath(repoSuffix).toFile()), git -> Mono.fromCallable(() -> { + Span jgitRebaseSpan = observationHelper.createSpan(GitSpan.JGIT_REBASE); RebaseResult result = git.rebase() .setUpstream("origin/" + branchName) .call(); if (result.getStatus().isSuccessful()) { + jgitRebaseSpan.end(); return true; } else { log.error( @@ -1128,6 +1175,7 @@ public class GitExecutorCEImpl implements GitExecutor { .setUpstream("origin/" + branchName) .setOperation(RebaseCommand.Operation.ABORT) .call(); + jgitRebaseSpan.end(); throw new Exception("Error while rebasing the branch, " + result.getStatus().name()); } @@ -1147,7 +1195,14 @@ public class GitExecutorCEImpl implements GitExecutor { public Mono getBranchTrackingStatus(Path repoPath, String branchName) { return Mono.using( () -> Git.open(repoPath.toFile()), - git -> Mono.fromCallable(() -> BranchTrackingStatus.of(git.getRepository(), branchName)) + git -> Mono.fromCallable(() -> { + Span jgitBranchTrackingSpan = + observationHelper.createSpan(GitSpan.JGIT_BRANCH_TRACK); + BranchTrackingStatus branchTrackingStatus = + BranchTrackingStatus.of(git.getRepository(), branchName); + jgitBranchTrackingSpan.end(); + return branchTrackingStatus; + }) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .name(GitSpan.FS_BRANCH_TRACK) .tap(Micrometer.observation(observationRegistry)), diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/constants/ce/GitSpanCE.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/constants/ce/GitSpanCE.java index cb4393e177..304ea6eab1 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/constants/ce/GitSpanCE.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/constants/ce/GitSpanCE.java @@ -6,21 +6,36 @@ import static com.appsmith.external.constants.spans.BaseSpan.GIT_SPAN_PREFIX; public class GitSpanCE { public static final String FS_CLONE_REPO = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_clone_repo"; + public static final String JGIT_CLONE_REPO = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_clone_repo"; public static final String FS_STATUS = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_status"; + public static final String JGIT_STATUS = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_status"; public static final String FS_PULL = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_pull"; + public static final String JGIT_PULL = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_pull"; public static final String FS_BRANCH_TRACK = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_branch_track"; public static final String ADD_FILE_LOCK = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "add_file_lock"; public static final String RELEASE_FILE_LOCK = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "release_file_lock"; public static final String FS_COMMIT = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_commit"; + public static final String JGIT_ADD = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_add"; + public static final String JGIT_COMMIT = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_commit"; public static final String FS_CHECKOUT_BRANCH = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_checkout_branch"; + public static final String JGIT_CHECKOUT_BRANCH = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_checkout_branch"; public static final String FS_CREATE_BRANCH = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_create_branch"; + public static final String JGIT_CREATE_BRANCH = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_create_branch"; public static final String FS_DELETE_BRANCH = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_delete_branch"; + public static final String JGIT_DELETE_BRANCH = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_delete_branch"; + public static final String JGIT_BRANCH_TRACK = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_branch_track"; public static final String FS_CREATE_REPO = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_create_repo"; public static final String FS_RESET = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_reset"; + public static final String JGIT_RESET_HARD = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_reset_hard"; + public static final String JGIT_CLEAN = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_clean"; public static final String FS_MERGE = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_merge"; + public static final String JGIT_MERGE = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_merge"; public static final String FS_REBASE = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_rebase"; + public static final String JGIT_REBASE = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_rebase"; public static final String FS_PUSH = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_push"; + public static final String JGIT_PUSH = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_push"; public static final String FS_FETCH_REMOTE = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_fetch_remote"; + public static final String JGIT_FETCH_REMOTE = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "jgit_fetch_remote"; public static final String OPS_STATUS = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "ops_status"; public static final String OPS_COMMIT = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "ops_commit"; public static final String OPS_PUSH = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "ops_push";