chore: add jgit spans inside resourceClosure (#39737)

## Description
Add jgit spans inside resourceClosure to verify if it is same as the
parent span.


Fixes #`Issue Number`  
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags="@tag.Git"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/13892637993>
> Commit: 923c9ab89af7d6d1ee86a0b5b8b0147eb32cafe6
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=13892637993&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Git`
> Spec:
> <hr>Mon, 17 Mar 2025 06:50:49 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Enhanced monitoring and observability for Git operations now provide
improved performance insights and reliability.
- Expanded tracking across version control activities delivers more
precise diagnostics and smoother troubleshooting, resulting in a more
stable and efficient Git experience for users.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Diljit 2025-03-17 14:17:38 +05:30 committed by GitHub
parent 1d9384b452
commit 2420f901c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 158 additions and 14 deletions

View File

@ -2,6 +2,7 @@ package com.appsmith.git.handler;
import com.appsmith.external.configurations.git.GitConfig; import com.appsmith.external.configurations.git.GitConfig;
import com.appsmith.external.git.handler.FSGitHandler; import com.appsmith.external.git.handler.FSGitHandler;
import com.appsmith.external.helpers.ObservationHelper;
import com.appsmith.git.configurations.GitServiceConfig; import com.appsmith.git.configurations.GitServiceConfig;
import com.appsmith.git.handler.ce.FSGitHandlerCEImpl; import com.appsmith.git.handler.ce.FSGitHandlerCEImpl;
import io.micrometer.observation.ObservationRegistry; import io.micrometer.observation.ObservationRegistry;
@ -15,7 +16,10 @@ import org.springframework.stereotype.Component;
public class FSGitHandlerImpl extends FSGitHandlerCEImpl implements FSGitHandler { public class FSGitHandlerImpl extends FSGitHandlerCEImpl implements FSGitHandler {
public FSGitHandlerImpl( public FSGitHandlerImpl(
GitServiceConfig gitServiceConfig, GitConfig gitConfig, ObservationRegistry observationRegistry) { GitServiceConfig gitServiceConfig,
super(gitServiceConfig, gitConfig, observationRegistry); GitConfig gitConfig,
ObservationRegistry observationRegistry,
ObservationHelper observationHelper) {
super(gitServiceConfig, gitConfig, observationRegistry, observationHelper);
} }
} }

View File

@ -12,6 +12,7 @@ import com.appsmith.external.git.constants.GitSpan;
import com.appsmith.external.git.constants.ce.RefType; import com.appsmith.external.git.constants.ce.RefType;
import com.appsmith.external.git.dtos.FetchRemoteDTO; import com.appsmith.external.git.dtos.FetchRemoteDTO;
import com.appsmith.external.git.handler.FSGitHandler; import com.appsmith.external.git.handler.FSGitHandler;
import com.appsmith.external.helpers.ObservationHelper;
import com.appsmith.external.helpers.Stopwatch; import com.appsmith.external.helpers.Stopwatch;
import com.appsmith.git.configurations.GitServiceConfig; import com.appsmith.git.configurations.GitServiceConfig;
import com.appsmith.git.constants.AppsmithBotAsset; 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.SshTransportConfigCallback;
import com.appsmith.git.helpers.StopwatchHelpers; import com.appsmith.git.helpers.StopwatchHelpers;
import io.micrometer.observation.ObservationRegistry; import io.micrometer.observation.ObservationRegistry;
import io.micrometer.tracing.Span;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.CreateBranchCommand; 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 TAG_REF = "refs/tags/";
private static final String SUCCESS_MERGE_STATUS = "This branch has no conflicts with the base branch."; 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 * 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( return Mono.using(
() -> Git.open(repoPath.toFile()), () -> Git.open(repoPath.toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitAddSpan = observationHelper.createSpan(GitSpan.JGIT_ADD);
log.debug("Trying to commit to local repo path, {}", path); log.debug("Trying to commit to local repo path, {}", path);
Stopwatch processStopwatch = StopwatchHelpers.startStopwatch( Stopwatch processStopwatch = StopwatchHelpers.startStopwatch(
@ -140,8 +144,10 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
.setUpdate(true) .setUpdate(true)
.addFilepattern(".") .addFilepattern(".")
.call(); .call();
jgitAddSpan.end();
// Commit the changes // Commit the changes
Span jgitCommitSpan = observationHelper.createSpan(GitSpan.JGIT_COMMIT);
git.commit() git.commit()
.setMessage(commitMessage) .setMessage(commitMessage)
// Only make a commit if there are any updates // Only make a commit if there are any updates
@ -150,6 +156,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
.setCommitter(finalAuthorName, finalAuthorEmail) .setCommitter(finalAuthorName, finalAuthorEmail)
.setAmend(doAmend) .setAmend(doAmend)
.call(); .call();
jgitCommitSpan.end();
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
return "Committed successfully!"; return "Committed successfully!";
}) })
@ -236,6 +243,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
return Mono.using( return Mono.using(
() -> Git.open(baseRepoPath.toFile()), () -> Git.open(baseRepoPath.toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitPushSpan = observationHelper.createSpan(GitSpan.JGIT_PUSH);
log.debug(Thread.currentThread().getName() + ": pushing changes to remote " log.debug(Thread.currentThread().getName() + ": pushing changes to remote "
+ remoteUrl); + remoteUrl);
// open the repo // open the repo
@ -266,6 +274,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
// UsernamePasswordCredentialsProvider("username", // UsernamePasswordCredentialsProvider("username",
// "password")); // "password"));
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitPushSpan.end();
return result.substring(0, result.length() - 1); return result.substring(0, result.length() - 1);
}) })
.timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
@ -294,6 +303,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
Stopwatch processStopwatch = Stopwatch processStopwatch =
StopwatchHelpers.startStopwatch(repoSuffix, AnalyticsEvents.GIT_CLONE.getEventName()); StopwatchHelpers.startStopwatch(repoSuffix, AnalyticsEvents.GIT_CLONE.getEventName());
return Mono.fromCallable(() -> { return Mono.fromCallable(() -> {
Span jgitCloneRepoSpan = observationHelper.createSpan(GitSpan.JGIT_CLONE_REPO);
log.debug(Thread.currentThread().getName() + ": Cloning the repo from the remote " + remoteUrl); log.debug(Thread.currentThread().getName() + ": Cloning the repo from the remote " + remoteUrl);
final TransportConfigCallback transportConfigCallback = final TransportConfigCallback transportConfigCallback =
new SshTransportConfigCallback(privateKey, publicKey); new SshTransportConfigCallback(privateKey, publicKey);
@ -314,6 +324,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
repositoryHelper.updateRemoteBranchTrackingConfig(branchName, git); repositoryHelper.updateRemoteBranchTrackingConfig(branchName, git);
} }
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitCloneRepoSpan.end();
return branchName; return branchName;
}) })
.timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
@ -331,6 +342,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
return Mono.using( return Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitCreateBranchSpan =
observationHelper.createSpan(GitSpan.JGIT_CREATE_BRANCH);
log.debug(Thread.currentThread().getName() + ": Creating branch " + branchName log.debug(Thread.currentThread().getName() + ": Creating branch " + branchName
+ "for the repo " + repoSuffix); + "for the repo " + repoSuffix);
// open the repo // open the repo
@ -343,7 +356,10 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
repositoryHelper.updateRemoteBranchTrackingConfig(branchName, git); repositoryHelper.updateRemoteBranchTrackingConfig(branchName, git);
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
return git.getRepository().getBranch(); String branch = git.getRepository().getBranch();
jgitCreateBranchSpan.end();
return branch;
}) })
.timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
.name(GitSpan.FS_CREATE_BRANCH) .name(GitSpan.FS_CREATE_BRANCH)
@ -378,6 +394,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
return Mono.using( return Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitCreateBranchSpan =
observationHelper.createSpan(GitSpan.JGIT_CREATE_BRANCH);
log.info( log.info(
"{} : Creating reference of type {} and name {} for the repo {}", "{} : Creating reference of type {} and name {} for the repo {}",
Thread.currentThread().getName(), Thread.currentThread().getName(),
@ -388,8 +406,9 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
if (RefType.tag.equals(refType)) { if (RefType.tag.equals(refType)) {
return createTag(git, gitRefDTO); return createTag(git, gitRefDTO);
} }
String branch = createAndCheckoutBranch(git, gitRefDTO);
return createAndCheckoutBranch(git, gitRefDTO); jgitCreateBranchSpan.end();
return branch;
}) })
.timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
.name(GitSpan.FS_CREATE_BRANCH) .name(GitSpan.FS_CREATE_BRANCH)
@ -407,6 +426,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
return Mono.using( return Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitDeleteBranchSpan =
observationHelper.createSpan(GitSpan.JGIT_DELETE_BRANCH);
log.debug(Thread.currentThread().getName() + ": Deleting branch " + branchName log.debug(Thread.currentThread().getName() + ": Deleting branch " + branchName
+ "for the repo " + repoSuffix); + "for the repo " + repoSuffix);
// open the repo // open the repo
@ -416,9 +437,11 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
.setForce(TRUE) .setForce(TRUE)
.call(); .call();
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitDeleteBranchSpan.end();
if (deleteBranchList.isEmpty()) { if (deleteBranchList.isEmpty()) {
return Boolean.FALSE; return Boolean.FALSE;
} }
return TRUE; return TRUE;
}) })
.timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
@ -436,6 +459,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
return Mono.using( return Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitCheckoutBranchSpan =
observationHelper.createSpan(GitSpan.JGIT_CHECKOUT_BRANCH);
log.info( log.info(
"{}: Switching to the branch {}", "{}: Switching to the branch {}",
Thread.currentThread().getName(), Thread.currentThread().getName(),
@ -455,6 +480,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
.call() .call()
.getName(); .getName();
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitCheckoutBranchSpan.end();
return StringUtils.equalsIgnoreCase(checkedOutBranch, "refs/heads/" + branchName); return StringUtils.equalsIgnoreCase(checkedOutBranch, "refs/heads/" + branchName);
}) })
.timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
@ -474,6 +500,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
return Mono.using( return Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitPullSpan = observationHelper.createSpan(GitSpan.JGIT_PULL);
log.info( log.info(
"{} : Pull changes from remote {} for the branch {}.", "{} : Pull changes from remote {} for the branch {}.",
Thread.currentThread().getName(), Thread.currentThread().getName(),
@ -496,6 +523,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
if (mergeResult.getMergeStatus().isSuccessful()) { if (mergeResult.getMergeStatus().isSuccessful()) {
mergeStatus.setMergeAble(true); mergeStatus.setMergeAble(true);
mergeStatus.setStatus(count + " commits merged from origin/" + branchName); mergeStatus.setStatus(count + " commits merged from origin/" + branchName);
jgitPullSpan.end();
return mergeStatus; return mergeStatus;
} else { } else {
// If there are conflicts add the conflicting file names to the response // 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); log.debug("Encountered error while aborting merge", e);
throw new org.eclipse.jgit.errors.CheckoutConflictException( throw new org.eclipse.jgit.errors.CheckoutConflictException(
mergeConflictFiles.toString()); mergeConflictFiles.toString());
} finally {
jgitPullSpan.end();
} }
} }
}) })
@ -541,6 +571,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
return Mono.using( return Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitPullSpan = observationHelper.createSpan(GitSpan.JGIT_PULL);
log.debug(Thread.currentThread().getName() + ": Pull changes from remote " log.debug(Thread.currentThread().getName() + ": Pull changes from remote "
+ remoteUrl + " for the branch " + branchName); + remoteUrl + " for the branch " + branchName);
// checkout the branch on which the merge command is run // checkout the branch on which the merge command is run
@ -566,6 +597,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
mergeStatus.setMergeAble(true); mergeStatus.setMergeAble(true);
mergeStatus.setStatus(count + " commits merged from origin/" + branchName); mergeStatus.setStatus(count + " commits merged from origin/" + branchName);
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitPullSpan.end();
return mergeStatus; return mergeStatus;
} else { } else {
// If there are conflicts add the conflicting file names to the response // If there are conflicts add the conflicting file names to the response
@ -590,6 +622,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
mergeConflictFiles.toString()); mergeConflictFiles.toString());
} finally { } finally {
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitPullSpan.end();
} }
} }
}) })
@ -676,6 +709,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
return Mono.using( return Mono.using(
() -> Git.open(repoPath.toFile()), () -> Git.open(repoPath.toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitStatusSpan = observationHelper.createSpan(GitSpan.JGIT_STATUS);
log.info( log.info(
"{}: Get status for repo {}, {}", "{}: Get status for repo {}, {}",
Thread.currentThread().getName(), Thread.currentThread().getName(),
@ -728,10 +762,12 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
if (!status.isClean()) { if (!status.isClean()) {
return resetToLastCommit(git).map(ref -> { return resetToLastCommit(git).map(ref -> {
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitStatusSpan.end();
return response; return response;
}); });
} }
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitStatusSpan.end();
return Mono.just(response); return Mono.just(response);
}) })
.timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
@ -919,6 +955,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
return Mono.using( return Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitMergeSpan = observationHelper.createSpan(GitSpan.JGIT_MERGE);
Stopwatch processStopwatch = StopwatchHelpers.startStopwatch( Stopwatch processStopwatch = StopwatchHelpers.startStopwatch(
repoSuffix, AnalyticsEvents.GIT_MERGE.getEventName()); repoSuffix, AnalyticsEvents.GIT_MERGE.getEventName());
@ -941,6 +978,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
git.getRepository().writeMergeHeads(null); git.getRepository().writeMergeHeads(null);
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
throw new Exception(e); throw new Exception(e);
} finally {
jgitMergeSpan.end();
} }
}) })
.onErrorResume(error -> { .onErrorResume(error -> {
@ -973,6 +1012,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
return Mono.using( return Mono.using(
() -> Git.open(repoPath.toFile()), () -> Git.open(repoPath.toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitFetchRemoteSpan = observationHelper.createSpan(GitSpan.JGIT_FETCH_REMOTE);
TransportConfigCallback config = TransportConfigCallback config =
new SshTransportConfigCallback(privateKey, publicKey); new SshTransportConfigCallback(privateKey, publicKey);
String fetchMessages; String fetchMessages;
@ -993,6 +1033,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
.getMessages(); .getMessages();
} }
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitFetchRemoteSpan.end();
return fetchMessages; return fetchMessages;
}) })
.onErrorResume(error -> { .onErrorResume(error -> {
@ -1013,15 +1054,18 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
return Mono.using( return Mono.using(
() -> Git.open(repoPath.toFile()), () -> Git.open(repoPath.toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitFetchRemoteSpan = observationHelper.createSpan(GitSpan.JGIT_FETCH_REMOTE);
TransportConfigCallback config = TransportConfigCallback config =
new SshTransportConfigCallback(privateKey, publicKey); new SshTransportConfigCallback(privateKey, publicKey);
if (TRUE.equals(fetchRemoteDTO.getIsFetchAll())) { if (TRUE.equals(fetchRemoteDTO.getIsFetchAll())) {
return git.fetch() String fetchMessages = git.fetch()
.setRemoveDeletedRefs(true) .setRemoveDeletedRefs(true)
.setTransportConfigCallback(config) .setTransportConfigCallback(config)
.call() .call()
.getMessages(); .getMessages();
jgitFetchRemoteSpan.end();
return fetchMessages;
} }
List<String> refNames = fetchRemoteDTO.getRefNames(); List<String> 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])) .setRefSpecs(refSpecs.toArray(new RefSpec[0]))
.setRemoveDeletedRefs(true) .setRemoveDeletedRefs(true)
.setTagOpt(TagOpt.NO_TAGS) // no tags would mean that tags are fetched .setTagOpt(TagOpt.NO_TAGS) // no tags would mean that tags are fetched
@ -1052,6 +1096,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
.setTransportConfigCallback(config) .setTransportConfigCallback(config)
.call() .call()
.getMessages(); .getMessages();
jgitFetchRemoteSpan.end();
return fetchMessages;
}) })
.onErrorResume(error -> { .onErrorResume(error -> {
log.error(error.getMessage()); log.error(error.getMessage());
@ -1152,6 +1198,8 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
return Mono.using( return Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitCheckoutBranchSpan =
observationHelper.createSpan(GitSpan.JGIT_CHECKOUT_BRANCH);
log.debug(Thread.currentThread().getName() + ": Checking out remote branch origin/" log.debug(Thread.currentThread().getName() + ": Checking out remote branch origin/"
+ branchName + " for the repo " + repoSuffix); + branchName + " for the repo " + repoSuffix);
// open the repo // open the repo
@ -1168,7 +1216,9 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
config.setString("branch", branchName, "remote", "origin"); config.setString("branch", branchName, "remote", "origin");
config.setString("branch", branchName, "merge", "refs/heads/" + branchName); config.setString("branch", branchName, "merge", "refs/heads/" + branchName);
config.save(); config.save();
return git.getRepository().getBranch(); String branch = git.getRepository().getBranch();
jgitCheckoutBranchSpan.end();
return branch;
}) })
.timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
.tag(CHECKOUT_REMOTE, TRUE.toString()) .tag(CHECKOUT_REMOTE, TRUE.toString())
@ -1199,10 +1249,14 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
Stopwatch processStopwatch = StopwatchHelpers.startStopwatch( Stopwatch processStopwatch = StopwatchHelpers.startStopwatch(
git.getRepository().getDirectory().toPath().getParent(), AnalyticsEvents.GIT_RESET.getEventName()); git.getRepository().getDirectory().toPath().getParent(), AnalyticsEvents.GIT_RESET.getEventName());
return Mono.fromCallable(() -> { return Mono.fromCallable(() -> {
Span jgitResetHardSpan = observationHelper.createSpan(GitSpan.JGIT_RESET_HARD);
// Remove tracked files // Remove tracked files
Ref ref = git.reset().setMode(ResetCommand.ResetType.HARD).call(); Ref ref = git.reset().setMode(ResetCommand.ResetType.HARD).call();
jgitResetHardSpan.end();
// Remove untracked files // Remove untracked files
Span jgitCleanSpan = observationHelper.createSpan(GitSpan.JGIT_CLEAN);
git.clean().setForce(true).setCleanDirectories(true).call(); git.clean().setForce(true).setCleanDirectories(true).call();
jgitCleanSpan.end();
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
return ref; return ref;
}) })
@ -1227,10 +1281,12 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
.flatMap(aBoolean -> Mono.using( .flatMap(aBoolean -> Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitResetHardSpan = observationHelper.createSpan(GitSpan.JGIT_RESET_HARD);
git.reset() git.reset()
.setMode(ResetCommand.ResetType.HARD) .setMode(ResetCommand.ResetType.HARD)
.setRef("HEAD~1") .setRef("HEAD~1")
.call(); .call();
jgitResetHardSpan.end();
return true; return true;
}) })
.onErrorResume(e -> { .onErrorResume(e -> {
@ -1249,10 +1305,12 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
return this.checkoutToBranch(repoSuffix, branchName).flatMap(isCheckedOut -> Mono.using( return this.checkoutToBranch(repoSuffix, branchName).flatMap(isCheckedOut -> Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitRebaseSpan = observationHelper.createSpan(GitSpan.JGIT_REBASE);
RebaseResult result = git.rebase() RebaseResult result = git.rebase()
.setUpstream("origin/" + branchName) .setUpstream("origin/" + branchName)
.call(); .call();
if (result.getStatus().isSuccessful()) { if (result.getStatus().isSuccessful()) {
jgitRebaseSpan.end();
return true; return true;
} else { } else {
log.error( log.error(
@ -1263,6 +1321,7 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
.setUpstream("origin/" + branchName) .setUpstream("origin/" + branchName)
.setOperation(RebaseCommand.Operation.ABORT) .setOperation(RebaseCommand.Operation.ABORT)
.call(); .call();
jgitRebaseSpan.end();
throw new Exception("Error while rebasing the branch, " throw new Exception("Error while rebasing the branch, "
+ result.getStatus().name()); + result.getStatus().name());
} }
@ -1282,7 +1341,14 @@ public class FSGitHandlerCEImpl implements FSGitHandler {
public Mono<BranchTrackingStatus> getBranchTrackingStatus(Path repoPath, String branchName) { public Mono<BranchTrackingStatus> getBranchTrackingStatus(Path repoPath, String branchName) {
return Mono.using( return Mono.using(
() -> Git.open(repoPath.toFile()), () -> 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)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
.name(GitSpan.FS_BRANCH_TRACK) .name(GitSpan.FS_BRANCH_TRACK)
.tap(Micrometer.observation(observationRegistry)), .tap(Micrometer.observation(observationRegistry)),

View File

@ -2,6 +2,7 @@ package com.appsmith.git.service;
import com.appsmith.external.configurations.git.GitConfig; import com.appsmith.external.configurations.git.GitConfig;
import com.appsmith.external.git.GitExecutor; import com.appsmith.external.git.GitExecutor;
import com.appsmith.external.helpers.ObservationHelper;
import com.appsmith.git.configurations.GitServiceConfig; import com.appsmith.git.configurations.GitServiceConfig;
import com.appsmith.git.service.ce.GitExecutorCEImpl; import com.appsmith.git.service.ce.GitExecutorCEImpl;
import io.micrometer.observation.ObservationRegistry; import io.micrometer.observation.ObservationRegistry;
@ -14,7 +15,10 @@ import org.springframework.stereotype.Component;
@Slf4j @Slf4j
public class GitExecutorImpl extends GitExecutorCEImpl implements GitExecutor { public class GitExecutorImpl extends GitExecutorCEImpl implements GitExecutor {
public GitExecutorImpl( public GitExecutorImpl(
GitServiceConfig gitServiceConfig, GitConfig gitConfig, ObservationRegistry observationRegistry) { GitServiceConfig gitServiceConfig,
super(gitServiceConfig, gitConfig, observationRegistry); GitConfig gitConfig,
ObservationRegistry observationRegistry,
ObservationHelper observationHelper) {
super(gitServiceConfig, gitConfig, observationRegistry, observationHelper);
} }
} }

View File

@ -9,6 +9,7 @@ import com.appsmith.external.dtos.GitStatusDTO;
import com.appsmith.external.dtos.MergeStatusDTO; import com.appsmith.external.dtos.MergeStatusDTO;
import com.appsmith.external.git.GitExecutor; import com.appsmith.external.git.GitExecutor;
import com.appsmith.external.git.constants.GitSpan; import com.appsmith.external.git.constants.GitSpan;
import com.appsmith.external.helpers.ObservationHelper;
import com.appsmith.external.helpers.Stopwatch; import com.appsmith.external.helpers.Stopwatch;
import com.appsmith.git.configurations.GitServiceConfig; import com.appsmith.git.configurations.GitServiceConfig;
import com.appsmith.git.constants.AppsmithBotAsset; 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.SshTransportConfigCallback;
import com.appsmith.git.helpers.StopwatchHelpers; import com.appsmith.git.helpers.StopwatchHelpers;
import io.micrometer.observation.ObservationRegistry; import io.micrometer.observation.ObservationRegistry;
import io.micrometer.tracing.Span;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.CreateBranchCommand; import org.eclipse.jgit.api.CreateBranchCommand;
@ -91,6 +93,7 @@ public class GitExecutorCEImpl implements GitExecutor {
private final Scheduler scheduler = Schedulers.boundedElastic(); private final Scheduler scheduler = Schedulers.boundedElastic();
private static final String SUCCESS_MERGE_STATUS = "This branch has no conflicts with the base branch."; 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 * 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( return Mono.using(
() -> Git.open(repoPath.toFile()), () -> Git.open(repoPath.toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitAddSpan = observationHelper.createSpan(GitSpan.JGIT_ADD);
log.debug("Trying to commit to local repo path, {}", path); log.debug("Trying to commit to local repo path, {}", path);
Stopwatch processStopwatch = StopwatchHelpers.startStopwatch( Stopwatch processStopwatch = StopwatchHelpers.startStopwatch(
@ -132,8 +136,10 @@ public class GitExecutorCEImpl implements GitExecutor {
.setUpdate(true) .setUpdate(true)
.addFilepattern(".") .addFilepattern(".")
.call(); .call();
jgitAddSpan.end();
// Commit the changes // Commit the changes
Span jgitCommitSpan = observationHelper.createSpan(GitSpan.JGIT_COMMIT);
git.commit() git.commit()
.setMessage(commitMessage) .setMessage(commitMessage)
// Only make a commit if there are any updates // Only make a commit if there are any updates
@ -142,6 +148,7 @@ public class GitExecutorCEImpl implements GitExecutor {
.setCommitter(finalAuthorName, finalAuthorEmail) .setCommitter(finalAuthorName, finalAuthorEmail)
.setAmend(doAmend) .setAmend(doAmend)
.call(); .call();
jgitCommitSpan.end();
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
return "Committed successfully!"; return "Committed successfully!";
}) })
@ -228,6 +235,7 @@ public class GitExecutorCEImpl implements GitExecutor {
return Mono.using( return Mono.using(
() -> Git.open(baseRepoPath.toFile()), () -> Git.open(baseRepoPath.toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitPushSpan = observationHelper.createSpan(GitSpan.JGIT_PUSH);
log.debug(Thread.currentThread().getName() + ": pushing changes to remote " log.debug(Thread.currentThread().getName() + ": pushing changes to remote "
+ remoteUrl); + remoteUrl);
// open the repo // open the repo
@ -258,6 +266,7 @@ public class GitExecutorCEImpl implements GitExecutor {
// UsernamePasswordCredentialsProvider("username", // UsernamePasswordCredentialsProvider("username",
// "password")); // "password"));
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitPushSpan.end();
return result.substring(0, result.length() - 1); return result.substring(0, result.length() - 1);
}) })
.timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
@ -286,6 +295,7 @@ public class GitExecutorCEImpl implements GitExecutor {
Stopwatch processStopwatch = Stopwatch processStopwatch =
StopwatchHelpers.startStopwatch(repoSuffix, AnalyticsEvents.GIT_CLONE.getEventName()); StopwatchHelpers.startStopwatch(repoSuffix, AnalyticsEvents.GIT_CLONE.getEventName());
return Mono.fromCallable(() -> { return Mono.fromCallable(() -> {
Span jgitCloneRepoSpan = observationHelper.createSpan(GitSpan.JGIT_CLONE_REPO);
log.debug(Thread.currentThread().getName() + ": Cloning the repo from the remote " + remoteUrl); log.debug(Thread.currentThread().getName() + ": Cloning the repo from the remote " + remoteUrl);
final TransportConfigCallback transportConfigCallback = final TransportConfigCallback transportConfigCallback =
new SshTransportConfigCallback(privateKey, publicKey); new SshTransportConfigCallback(privateKey, publicKey);
@ -306,6 +316,7 @@ public class GitExecutorCEImpl implements GitExecutor {
repositoryHelper.updateRemoteBranchTrackingConfig(branchName, git); repositoryHelper.updateRemoteBranchTrackingConfig(branchName, git);
} }
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitCloneRepoSpan.end();
return branchName; return branchName;
}) })
.timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
@ -323,6 +334,8 @@ public class GitExecutorCEImpl implements GitExecutor {
return Mono.using( return Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitCreateBranchSpan =
observationHelper.createSpan(GitSpan.JGIT_CREATE_BRANCH);
log.debug(Thread.currentThread().getName() + ": Creating branch " + branchName log.debug(Thread.currentThread().getName() + ": Creating branch " + branchName
+ "for the repo " + repoSuffix); + "for the repo " + repoSuffix);
// open the repo // open the repo
@ -335,7 +348,10 @@ public class GitExecutorCEImpl implements GitExecutor {
repositoryHelper.updateRemoteBranchTrackingConfig(branchName, git); repositoryHelper.updateRemoteBranchTrackingConfig(branchName, git);
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
return git.getRepository().getBranch(); String branch = git.getRepository().getBranch();
jgitCreateBranchSpan.end();
return branch;
}) })
.timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
.name(GitSpan.FS_CREATE_BRANCH) .name(GitSpan.FS_CREATE_BRANCH)
@ -353,6 +369,8 @@ public class GitExecutorCEImpl implements GitExecutor {
return Mono.using( return Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitDeleteBranchSpan =
observationHelper.createSpan(GitSpan.JGIT_DELETE_BRANCH);
log.debug(Thread.currentThread().getName() + ": Deleting branch " + branchName log.debug(Thread.currentThread().getName() + ": Deleting branch " + branchName
+ "for the repo " + repoSuffix); + "for the repo " + repoSuffix);
// open the repo // open the repo
@ -362,6 +380,7 @@ public class GitExecutorCEImpl implements GitExecutor {
.setForce(TRUE) .setForce(TRUE)
.call(); .call();
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitDeleteBranchSpan.end();
if (deleteBranchList.isEmpty()) { if (deleteBranchList.isEmpty()) {
return Boolean.FALSE; return Boolean.FALSE;
} }
@ -382,6 +401,8 @@ public class GitExecutorCEImpl implements GitExecutor {
return Mono.using( return Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitCheckoutBranchSpan =
observationHelper.createSpan(GitSpan.JGIT_CHECKOUT_BRANCH);
log.debug(Thread.currentThread().getName() + ": Switching to the branch " log.debug(Thread.currentThread().getName() + ": Switching to the branch "
+ branchName); + branchName);
// We can safely assume that repo has been already initialised either in commit or // We can safely assume that repo has been already initialised either in commit or
@ -400,6 +421,7 @@ public class GitExecutorCEImpl implements GitExecutor {
.call() .call()
.getName(); .getName();
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitCheckoutBranchSpan.end();
return StringUtils.equalsIgnoreCase(checkedOutBranch, "refs/heads/" + branchName); return StringUtils.equalsIgnoreCase(checkedOutBranch, "refs/heads/" + branchName);
}) })
.timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
@ -422,6 +444,7 @@ public class GitExecutorCEImpl implements GitExecutor {
return Mono.using( return Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitPullSpan = observationHelper.createSpan(GitSpan.JGIT_PULL);
log.debug(Thread.currentThread().getName() + ": Pull changes from remote " log.debug(Thread.currentThread().getName() + ": Pull changes from remote "
+ remoteUrl + " for the branch " + branchName); + remoteUrl + " for the branch " + branchName);
// checkout the branch on which the merge command is run // checkout the branch on which the merge command is run
@ -447,6 +470,7 @@ public class GitExecutorCEImpl implements GitExecutor {
mergeStatus.setMergeAble(true); mergeStatus.setMergeAble(true);
mergeStatus.setStatus(count + " commits merged from origin/" + branchName); mergeStatus.setStatus(count + " commits merged from origin/" + branchName);
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitPullSpan.end();
return mergeStatus; return mergeStatus;
} else { } else {
// If there are conflicts add the conflicting file names to the response // If there are conflicts add the conflicting file names to the response
@ -471,6 +495,7 @@ public class GitExecutorCEImpl implements GitExecutor {
mergeConflictFiles.toString()); mergeConflictFiles.toString());
} finally { } finally {
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitPullSpan.end();
} }
} }
}) })
@ -557,6 +582,7 @@ public class GitExecutorCEImpl implements GitExecutor {
return Mono.using( return Mono.using(
() -> Git.open(repoPath.toFile()), () -> Git.open(repoPath.toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitStatusSpan = observationHelper.createSpan(GitSpan.JGIT_STATUS);
log.debug(Thread.currentThread().getName() + ": Get status for repo " + repoPath log.debug(Thread.currentThread().getName() + ": Get status for repo " + repoPath
+ ", branch " + branchName); + ", branch " + branchName);
Status status = git.status().call(); Status status = git.status().call();
@ -605,10 +631,12 @@ public class GitExecutorCEImpl implements GitExecutor {
if (!status.isClean()) { if (!status.isClean()) {
return resetToLastCommit(git).map(ref -> { return resetToLastCommit(git).map(ref -> {
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitStatusSpan.end();
return response; return response;
}); });
} }
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitStatusSpan.end();
return Mono.just(response); return Mono.just(response);
}) })
.timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
@ -796,6 +824,7 @@ public class GitExecutorCEImpl implements GitExecutor {
return Mono.using( return Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitMergeSpan = observationHelper.createSpan(GitSpan.JGIT_MERGE);
Stopwatch processStopwatch = StopwatchHelpers.startStopwatch( Stopwatch processStopwatch = StopwatchHelpers.startStopwatch(
repoSuffix, AnalyticsEvents.GIT_MERGE.getEventName()); repoSuffix, AnalyticsEvents.GIT_MERGE.getEventName());
log.debug(Thread.currentThread().getName() + ": Merge branch " + sourceBranch log.debug(Thread.currentThread().getName() + ": Merge branch " + sourceBranch
@ -819,6 +848,8 @@ public class GitExecutorCEImpl implements GitExecutor {
git.getRepository().writeMergeHeads(null); git.getRepository().writeMergeHeads(null);
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
throw new Exception(e); throw new Exception(e);
} finally {
jgitMergeSpan.end();
} }
}) })
.onErrorResume(error -> { .onErrorResume(error -> {
@ -851,6 +882,7 @@ public class GitExecutorCEImpl implements GitExecutor {
return Mono.using( return Mono.using(
() -> Git.open(repoPath.toFile()), () -> Git.open(repoPath.toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitFetchRemoteSpan = observationHelper.createSpan(GitSpan.JGIT_FETCH_REMOTE);
TransportConfigCallback config = TransportConfigCallback config =
new SshTransportConfigCallback(privateKey, publicKey); new SshTransportConfigCallback(privateKey, publicKey);
String fetchMessages; String fetchMessages;
@ -871,6 +903,7 @@ public class GitExecutorCEImpl implements GitExecutor {
.getMessages(); .getMessages();
} }
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitFetchRemoteSpan.end();
return fetchMessages; return fetchMessages;
}) })
.onErrorResume(error -> { .onErrorResume(error -> {
@ -893,6 +926,7 @@ public class GitExecutorCEImpl implements GitExecutor {
return Mono.using( return Mono.using(
() -> Git.open(repoPath.toFile()), () -> Git.open(repoPath.toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitFetchRemoteSpan = observationHelper.createSpan(GitSpan.JGIT_FETCH_REMOTE);
TransportConfigCallback config = TransportConfigCallback config =
new SshTransportConfigCallback(privateKey, publicKey); new SshTransportConfigCallback(privateKey, publicKey);
String fetchMessages; String fetchMessages;
@ -912,6 +946,7 @@ public class GitExecutorCEImpl implements GitExecutor {
.getMessages(); .getMessages();
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
jgitFetchRemoteSpan.end();
return fetchMessages; return fetchMessages;
}) })
.onErrorResume(error -> { .onErrorResume(error -> {
@ -1017,6 +1052,8 @@ public class GitExecutorCEImpl implements GitExecutor {
return Mono.using( return Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitCheckoutRemoteBranchSpan =
observationHelper.createSpan(GitSpan.JGIT_CHECKOUT_BRANCH);
log.debug(Thread.currentThread().getName() + ": Checking out remote branch origin/" log.debug(Thread.currentThread().getName() + ": Checking out remote branch origin/"
+ branchName + " for the repo " + repoSuffix); + branchName + " for the repo " + repoSuffix);
// open the repo // open the repo
@ -1033,7 +1070,9 @@ public class GitExecutorCEImpl implements GitExecutor {
config.setString("branch", branchName, "remote", "origin"); config.setString("branch", branchName, "remote", "origin");
config.setString("branch", branchName, "merge", "refs/heads/" + branchName); config.setString("branch", branchName, "merge", "refs/heads/" + branchName);
config.save(); config.save();
return git.getRepository().getBranch(); String branch = git.getRepository().getBranch();
jgitCheckoutRemoteBranchSpan.end();
return branch;
}) })
.timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
.tag(CHECKOUT_REMOTE, TRUE.toString()) .tag(CHECKOUT_REMOTE, TRUE.toString())
@ -1064,10 +1103,14 @@ public class GitExecutorCEImpl implements GitExecutor {
Stopwatch processStopwatch = StopwatchHelpers.startStopwatch( Stopwatch processStopwatch = StopwatchHelpers.startStopwatch(
git.getRepository().getDirectory().toPath().getParent(), AnalyticsEvents.GIT_RESET.getEventName()); git.getRepository().getDirectory().toPath().getParent(), AnalyticsEvents.GIT_RESET.getEventName());
return Mono.fromCallable(() -> { return Mono.fromCallable(() -> {
Span jgitResetHardSpan = observationHelper.createSpan(GitSpan.JGIT_RESET_HARD);
// Remove tracked files // Remove tracked files
Ref ref = git.reset().setMode(ResetCommand.ResetType.HARD).call(); Ref ref = git.reset().setMode(ResetCommand.ResetType.HARD).call();
jgitResetHardSpan.end();
// Remove untracked files // Remove untracked files
Span jgitCleanSpan = observationHelper.createSpan(GitSpan.JGIT_CLEAN);
git.clean().setForce(true).setCleanDirectories(true).call(); git.clean().setForce(true).setCleanDirectories(true).call();
jgitCleanSpan.end();
processStopwatch.stopAndLogTimeInMillis(); processStopwatch.stopAndLogTimeInMillis();
return ref; return ref;
}) })
@ -1092,10 +1135,12 @@ public class GitExecutorCEImpl implements GitExecutor {
.flatMap(aBoolean -> Mono.using( .flatMap(aBoolean -> Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitResetHardSpan = observationHelper.createSpan(GitSpan.JGIT_RESET_HARD);
git.reset() git.reset()
.setMode(ResetCommand.ResetType.HARD) .setMode(ResetCommand.ResetType.HARD)
.setRef("HEAD~1") .setRef("HEAD~1")
.call(); .call();
jgitResetHardSpan.end();
return true; return true;
}) })
.onErrorResume(e -> { .onErrorResume(e -> {
@ -1114,10 +1159,12 @@ public class GitExecutorCEImpl implements GitExecutor {
return this.checkoutToBranch(repoSuffix, branchName).flatMap(isCheckedOut -> Mono.using( return this.checkoutToBranch(repoSuffix, branchName).flatMap(isCheckedOut -> Mono.using(
() -> Git.open(createRepoPath(repoSuffix).toFile()), () -> Git.open(createRepoPath(repoSuffix).toFile()),
git -> Mono.fromCallable(() -> { git -> Mono.fromCallable(() -> {
Span jgitRebaseSpan = observationHelper.createSpan(GitSpan.JGIT_REBASE);
RebaseResult result = git.rebase() RebaseResult result = git.rebase()
.setUpstream("origin/" + branchName) .setUpstream("origin/" + branchName)
.call(); .call();
if (result.getStatus().isSuccessful()) { if (result.getStatus().isSuccessful()) {
jgitRebaseSpan.end();
return true; return true;
} else { } else {
log.error( log.error(
@ -1128,6 +1175,7 @@ public class GitExecutorCEImpl implements GitExecutor {
.setUpstream("origin/" + branchName) .setUpstream("origin/" + branchName)
.setOperation(RebaseCommand.Operation.ABORT) .setOperation(RebaseCommand.Operation.ABORT)
.call(); .call();
jgitRebaseSpan.end();
throw new Exception("Error while rebasing the branch, " throw new Exception("Error while rebasing the branch, "
+ result.getStatus().name()); + result.getStatus().name());
} }
@ -1147,7 +1195,14 @@ public class GitExecutorCEImpl implements GitExecutor {
public Mono<BranchTrackingStatus> getBranchTrackingStatus(Path repoPath, String branchName) { public Mono<BranchTrackingStatus> getBranchTrackingStatus(Path repoPath, String branchName) {
return Mono.using( return Mono.using(
() -> Git.open(repoPath.toFile()), () -> 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)) .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS))
.name(GitSpan.FS_BRANCH_TRACK) .name(GitSpan.FS_BRANCH_TRACK)
.tap(Micrometer.observation(observationRegistry)), .tap(Micrometer.observation(observationRegistry)),

View File

@ -6,21 +6,36 @@ import static com.appsmith.external.constants.spans.BaseSpan.GIT_SPAN_PREFIX;
public class GitSpanCE { public class GitSpanCE {
public static final String FS_CLONE_REPO = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "fs_clone_repo"; 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 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 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 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 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 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 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 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 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 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_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 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 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 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 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 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_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_COMMIT = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "ops_commit";
public static final String OPS_PUSH = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "ops_push"; public static final String OPS_PUSH = APPSMITH_SPAN_PREFIX + GIT_SPAN_PREFIX + "ops_push";