Search in sources :

Example 1 with TraceContext

use of com.google.gerrit.server.logging.TraceContext in project gerrit by GerritCodeReview.

the class SshCommand method start.

@Override
public void start(ChannelSession channel, Environment env) throws IOException {
    startThread(() -> {
        try (DynamicOptions pluginOptions = new DynamicOptions(injector, dynamicBeans)) {
            parseCommandLine(pluginOptions);
            stdout = toPrintWriter(out);
            stderr = toPrintWriter(err);
            try (TraceContext traceContext = enableTracing();
                PerformanceLogContext performanceLogContext = new PerformanceLogContext(config, performanceLoggers)) {
                RequestInfo requestInfo = RequestInfo.builder(RequestInfo.RequestType.SSH, user, traceContext).build();
                try (RequestStateContext requestStateContext = RequestStateContext.open().addRequestStateProvider(deadlineCheckerFactory.create(requestInfo, deadline))) {
                    requestListeners.runEach(l -> l.onRequest(requestInfo));
                    SshCommand.this.run();
                } catch (InvalidDeadlineException e) {
                    stderr.println(e.getMessage());
                } catch (RuntimeException e) {
                    Optional<RequestCancelledException> requestCancelledException = RequestCancelledException.getFromCausalChain(e);
                    if (!requestCancelledException.isPresent()) {
                        Throwables.throwIfUnchecked(e);
                    }
                    cancellationMetrics.countCancelledRequest(requestInfo, requestCancelledException.get().getCancellationReason());
                    StringBuilder msg = new StringBuilder(requestCancelledException.get().formatCancellationReason());
                    if (requestCancelledException.get().getCancellationMessage().isPresent()) {
                        msg.append(String.format(" (%s)", requestCancelledException.get().getCancellationMessage().get()));
                    }
                    stderr.println(msg.toString());
                }
            } finally {
                stdout.flush();
                stderr.flush();
            }
        }
    }, AccessPath.SSH_COMMAND);
}
Also used : DynamicOptions(com.google.gerrit.server.DynamicOptions) RequestStateContext(com.google.gerrit.server.cancellation.RequestStateContext) InvalidDeadlineException(com.google.gerrit.server.InvalidDeadlineException) Optional(java.util.Optional) TraceContext(com.google.gerrit.server.logging.TraceContext) RequestInfo(com.google.gerrit.server.RequestInfo) PerformanceLogContext(com.google.gerrit.server.logging.PerformanceLogContext)

Example 2 with TraceContext

use of com.google.gerrit.server.logging.TraceContext in project gerrit by GerritCodeReview.

the class ReceiveCommits method sendMessages.

/**
 * Sends all messages which have been collected while processing the push to the client.
 *
 * <p><strong>Attention:</strong>{@link AsyncReceiveCommits} may call this method while {@link
 * #processCommands(Collection, MultiProgressMonitor)} is still running (if the execution of
 * processCommands takes too long and AsyncReceiveCommits gets a timeout). This means that local
 * variables that are accessed in this method must be thread-safe (otherwise we may hit a {@link
 * java.util.ConcurrentModificationException} if we read a variable here that at the same time is
 * updated by the background thread that still executes processCommands).
 */
void sendMessages() {
    try (TraceContext traceContext = TraceContext.newTrace(loggingTags.containsKey(RequestId.Type.TRACE_ID.name()), loggingTags.get(RequestId.Type.TRACE_ID.name()), (tagName, traceId) -> {
    })) {
        loggingTags.forEach((tagName, tagValue) -> traceContext.addTag(tagName, tagValue));
        for (ValidationMessage m : messages) {
            String msg = m.getType().getPrefix() + m.getMessage();
            logger.atFine().log("Sending message: %s", msg);
            // Avoid calling sendError which will add its own error: prefix.
            messageSender.sendMessage(msg);
        }
    }
}
Also used : ValidationMessage(com.google.gerrit.server.git.validators.ValidationMessage) CommitValidationMessage(com.google.gerrit.server.git.validators.CommitValidationMessage) TraceContext(com.google.gerrit.server.logging.TraceContext)

Example 3 with TraceContext

use of com.google.gerrit.server.logging.TraceContext in project gerrit by GerritCodeReview.

the class ReceiveCommits method processCommands.

ReceiveCommitsResult processCommands(Collection<ReceiveCommand> commands, MultiProgressMonitor progress) throws StorageException {
    checkState(!used, "Tried to re-use a ReceiveCommits objects that is single-use only");
    long start = TimeUtil.nowNanos();
    parsePushOptions();
    String clientProvidedDeadlineValue = Iterables.getLast(pushOptions.get("deadline"), /* defaultValue= */
    null);
    int commandCount = commands.size();
    try (TraceContext traceContext = TraceContext.newTrace(tracePushOption.isPresent(), tracePushOption.orElse(null), (tagName, traceId) -> addMessage(tagName + ": " + traceId));
        PerformanceLogContext performanceLogContext = new PerformanceLogContext(config, performanceLoggers);
        TraceTimer traceTimer = newTimer("processCommands", Metadata.builder().resourceCount(commandCount))) {
        RequestInfo requestInfo = RequestInfo.builder(RequestInfo.RequestType.GIT_RECEIVE, user, traceContext).project(project.getNameKey()).build();
        requestListeners.runEach(l -> l.onRequest(requestInfo));
        traceContext.addTag(RequestId.Type.RECEIVE_ID, new RequestId(project.getNameKey().get()));
        // Log the push options here, rather than in parsePushOptions(), so that they are included
        // into the trace if tracing is enabled.
        logger.atFine().log("push options: %s", receivePack.getPushOptions());
        Task commandProgress = progress.beginSubTask("refs", UNKNOWN);
        commands = commands.stream().map(c -> wrapReceiveCommand(c, commandProgress)).collect(toList());
        try (RequestStateContext requestStateContext = RequestStateContext.open().addRequestStateProvider(progress).addRequestStateProvider(deadlineCheckerFactory.create(start, requestInfo, clientProvidedDeadlineValue))) {
            processCommandsUnsafe(commands, progress);
            rejectRemaining(commands, INTERNAL_SERVER_ERROR);
        } catch (InvalidDeadlineException e) {
            rejectRemaining(commands, e.getMessage());
        } catch (RuntimeException e) {
            Optional<RequestCancelledException> requestCancelledException = RequestCancelledException.getFromCausalChain(e);
            if (!requestCancelledException.isPresent()) {
                Throwables.throwIfUnchecked(e);
            }
            cancellationMetrics.countCancelledRequest(requestInfo, requestCancelledException.get().getCancellationReason());
            StringBuilder msg = new StringBuilder(requestCancelledException.get().formatCancellationReason());
            if (requestCancelledException.get().getCancellationMessage().isPresent()) {
                msg.append(String.format(" (%s)", requestCancelledException.get().getCancellationMessage().get()));
            }
            rejectRemaining(commands, msg.toString());
        }
        // This sends error messages before the 'done' string of the progress monitor is sent.
        // Currently, the test framework relies on this ordering to understand if pushes completed
        // successfully.
        sendErrorMessages();
        commandProgress.end();
        loggingTags = traceContext.getTags();
        logger.atFine().log("Processing commands done.");
    }
    progress.end();
    return result.build();
}
Also used : Task(com.google.gerrit.server.git.MultiProgressMonitor.Task) RequestStateContext(com.google.gerrit.server.cancellation.RequestStateContext) RequestId(com.google.gerrit.server.logging.RequestId) Optional(java.util.Optional) RequestInfo(com.google.gerrit.server.RequestInfo) PerformanceLogContext(com.google.gerrit.server.logging.PerformanceLogContext) InvalidDeadlineException(com.google.gerrit.server.InvalidDeadlineException) TraceTimer(com.google.gerrit.server.logging.TraceContext.TraceTimer) TraceContext(com.google.gerrit.server.logging.TraceContext)

Example 4 with TraceContext

use of com.google.gerrit.server.logging.TraceContext in project gerrit by GerritCodeReview.

the class MergeOp method merge.

/**
 * Merges the given change.
 *
 * <p>Depending on the server configuration, more changes may be affected, e.g. by submission of a
 * topic or via superproject subscriptions. All affected changes are integrated using the projects
 * integration strategy.
 *
 * @param change the change to be merged.
 * @param caller the identity of the caller
 * @param checkSubmitRules whether the prolog submit rules should be evaluated
 * @param submitInput parameters regarding the merge
 * @throws RestApiException if an error occurred.
 * @throws PermissionBackendException if permissions can't be checked
 * @throws IOException an error occurred reading from NoteDb.
 * @return the merged change
 */
public Change merge(Change change, IdentifiedUser caller, boolean checkSubmitRules, SubmitInput submitInput, boolean dryrun) throws RestApiException, UpdateException, IOException, ConfigInvalidException, PermissionBackendException {
    this.submitInput = submitInput;
    this.notify = notifyResolver.resolve(firstNonNull(submitInput.notify, NotifyHandling.ALL), submitInput.notifyDetails);
    this.dryrun = dryrun;
    this.caller = caller;
    this.ts = TimeUtil.now();
    this.submissionId = new SubmissionId(change);
    try (TraceContext traceContext = TraceContext.open().addTag(RequestId.Type.SUBMISSION_ID, new RequestId(submissionId.toString()))) {
        openRepoManager();
        logger.atFine().log("Beginning integration of %s", change);
        try {
            ChangeSet indexBackedChangeSet = mergeSuperSet.setMergeOpRepoManager(orm).completeChangeSet(change, caller, /* includingTopicClosure= */
            false);
            if (!indexBackedChangeSet.ids().contains(change.getId())) {
                // indexBackedChangeSet contains only open changes, if the change is missing in this set
                // it might be that the change was concurrently submitted in the meantime.
                change = changeDataFactory.create(change).reloadChange();
                if (!change.isNew()) {
                    throw new ResourceConflictException("change is " + ChangeUtil.status(change));
                }
                throw new IllegalStateException(String.format("change %s missing from %s", change.getId(), indexBackedChangeSet));
            }
            if (indexBackedChangeSet.furtherHiddenChanges()) {
                throw new AuthException("A change to be submitted with " + change.getId() + " is not visible");
            }
            logger.atFine().log("Calculated to merge %s", indexBackedChangeSet);
            // Reload ChangeSet so that we don't rely on (potentially) stale index data for merging
            ChangeSet noteDbChangeSet = reloadChanges(indexBackedChangeSet);
            // At this point, any change that isn't new can be filtered out since they were only here
            // in the first place due to stale index.
            List<ChangeData> filteredChanges = new ArrayList<>();
            for (ChangeData changeData : noteDbChangeSet.changes()) {
                if (!changeData.change().getStatus().equals(Status.NEW)) {
                    logger.atFine().log("Change %s has status %s due to stale index, so it is skipped during submit", changeData.getId(), changeData.change().getStatus().name());
                    continue;
                }
                filteredChanges.add(changeData);
            }
            // There are no hidden changes (or else we would have thrown AuthException above).
            ChangeSet filteredNoteDbChangeSet = new ChangeSet(filteredChanges, /* hiddenChanges= */
            ImmutableList.of());
            // Count cross-project submissions outside of the retry loop. The chance of a single project
            // failing increases with the number of projects, so the failure count would be inflated if
            // this metric were incremented inside of integrateIntoHistory.
            int projects = filteredNoteDbChangeSet.projects().size();
            if (projects > 1) {
                topicMetrics.topicSubmissions.increment();
            }
            SubmissionExecutor submissionExecutor = new SubmissionExecutor(dryrun, superprojectUpdateSubmissionListeners);
            RetryTracker retryTracker = new RetryTracker();
            retryHelper.changeUpdate("integrateIntoHistory", updateFactory -> {
                long attempt = retryTracker.lastAttemptNumber + 1;
                boolean isRetry = attempt > 1;
                if (isRetry) {
                    logger.atFine().log("Retrying, attempt #%d; skipping merged changes", attempt);
                    this.ts = TimeUtil.now();
                    openRepoManager();
                }
                this.commitStatus = new CommitStatus(filteredNoteDbChangeSet, isRetry);
                if (checkSubmitRules) {
                    logger.atFine().log("Checking submit rules and state");
                    checkSubmitRulesAndState(filteredNoteDbChangeSet, isRetry);
                } else {
                    logger.atFine().log("Bypassing submit rules");
                    bypassSubmitRulesAndRequirements(filteredNoteDbChangeSet);
                }
                integrateIntoHistory(filteredNoteDbChangeSet, submissionExecutor);
                return null;
            }).listener(retryTracker).defaultTimeoutMultiplier(filteredNoteDbChangeSet.projects().size() * 2).retryOn(t -> t instanceof RuntimeException).call();
            submissionExecutor.afterExecutions(orm);
            if (projects > 1) {
                topicMetrics.topicSubmissionsCompleted.increment();
            }
            // (e.g. caller provided a change that was already merged).
            return updatedChanges.containsKey(change.getId()) ? updatedChanges.get(change.getId()) : change;
        } catch (IOException e) {
            // Anything before the merge attempt is an error
            throw new StorageException(e);
        }
    }
}
Also used : ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) SuperprojectUpdateOnSubmission(com.google.gerrit.server.update.SuperprojectUpdateOnSubmission) ListMultimap(com.google.common.collect.ListMultimap) MultimapBuilder(com.google.common.collect.MultimapBuilder) InternalUser(com.google.gerrit.server.InternalUser) Inject(com.google.inject.Inject) SubmissionId(com.google.gerrit.entities.SubmissionId) UpdateException(com.google.gerrit.server.update.UpdateException) SubmitRequirementResult(com.google.gerrit.entities.SubmitRequirementResult) MergeUpdateException(com.google.gerrit.exceptions.MergeUpdateException) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) SubmitInput(com.google.gerrit.extensions.api.changes.SubmitInput) Map(java.util.Map) AuthException(com.google.gerrit.extensions.restapi.AuthException) StoreSubmitRequirementsOp(com.google.gerrit.server.notedb.StoreSubmitRequirementsOp) RetryHelper(com.google.gerrit.server.update.RetryHelper) MergeTip(com.google.gerrit.server.git.MergeTip) Collectors.toSet(java.util.stream.Collectors.toSet) ImmutableSetMultimap(com.google.common.collect.ImmutableSetMultimap) ImmutableSet(com.google.common.collect.ImmutableSet) Status(com.google.gerrit.entities.Change.Status) ImmutableMap(com.google.common.collect.ImmutableMap) TraceContext(com.google.gerrit.server.logging.TraceContext) SubmitType(com.google.gerrit.extensions.client.SubmitType) Collection(java.util.Collection) Set(java.util.Set) Constants(org.eclipse.jgit.lib.Constants) CodeReviewCommit(com.google.gerrit.server.git.CodeReviewCommit) Instant(java.time.Instant) RetryListener(com.github.rholder.retry.RetryListener) SubmitRecord(com.google.gerrit.entities.SubmitRecord) Collectors(java.util.stream.Collectors) BranchNameKey(com.google.gerrit.entities.BranchNameKey) NotifyHandling(com.google.gerrit.extensions.api.changes.NotifyHandling) SubmitTypeRecord(com.google.gerrit.entities.SubmitTypeRecord) ChangeData(com.google.gerrit.server.query.change.ChangeData) List(java.util.List) Nullable(com.google.gerrit.common.Nullable) Ref(org.eclipse.jgit.lib.Ref) AutoValue(com.google.auto.value.AutoValue) InternalChangeQuery(com.google.gerrit.server.query.change.InternalChangeQuery) Optional(java.util.Optional) MoreObjects.firstNonNull(com.google.common.base.MoreObjects.firstNonNull) Counter0(com.google.gerrit.metrics.Counter0) MetricMaker(com.google.gerrit.metrics.MetricMaker) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp) FluentLogger(com.google.common.flogger.FluentLogger) Joiner(com.google.common.base.Joiner) ChangeMessagesUtil(com.google.gerrit.server.ChangeMessagesUtil) Singleton(com.google.inject.Singleton) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) RevCommit(org.eclipse.jgit.revwalk.RevCommit) OpenRepo(com.google.gerrit.server.submit.MergeOpRepoManager.OpenRepo) IncorrectObjectTypeException(org.eclipse.jgit.errors.IncorrectObjectTypeException) HashMap(java.util.HashMap) Function(java.util.function.Function) SubmissionListener(com.google.gerrit.server.update.SubmissionListener) MergeValidators(com.google.gerrit.server.git.validators.MergeValidators) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ImmutableList(com.google.common.collect.ImmutableList) SubmissionExecutor(com.google.gerrit.server.update.SubmissionExecutor) Description(com.google.gerrit.metrics.Description) Objects.requireNonNull(java.util.Objects.requireNonNull) Change(com.google.gerrit.entities.Change) PatchSet(com.google.gerrit.entities.PatchSet) Comparator.comparing(java.util.Comparator.comparing) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) ChangeUtil(com.google.gerrit.server.ChangeUtil) LockFailureException(com.google.gerrit.git.LockFailureException) ChangeContext(com.google.gerrit.server.update.ChangeContext) MergeValidationException(com.google.gerrit.server.git.validators.MergeValidationException) LinkedHashSet(java.util.LinkedHashSet) SubmitRequirement(com.google.gerrit.entities.SubmitRequirement) NotifyResolver(com.google.gerrit.server.change.NotifyResolver) OpenBranch(com.google.gerrit.server.submit.MergeOpRepoManager.OpenBranch) StorageException(com.google.gerrit.exceptions.StorageException) Attempt(com.github.rholder.retry.Attempt) NoSuchProjectException(com.google.gerrit.server.project.NoSuchProjectException) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) IOException(java.io.IOException) SubmitRuleOptions(com.google.gerrit.server.project.SubmitRuleOptions) SetMultimap(com.google.common.collect.SetMultimap) ObjectId(org.eclipse.jgit.lib.ObjectId) Provider(com.google.inject.Provider) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) Project(com.google.gerrit.entities.Project) TimeUtil(com.google.gerrit.server.util.time.TimeUtil) RequestId(com.google.gerrit.server.logging.RequestId) RequestId(com.google.gerrit.server.logging.RequestId) ArrayList(java.util.ArrayList) AuthException(com.google.gerrit.extensions.restapi.AuthException) IOException(java.io.IOException) ChangeData(com.google.gerrit.server.query.change.ChangeData) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) SubmissionId(com.google.gerrit.entities.SubmissionId) TraceContext(com.google.gerrit.server.logging.TraceContext) StorageException(com.google.gerrit.exceptions.StorageException) SubmissionExecutor(com.google.gerrit.server.update.SubmissionExecutor)

Example 5 with TraceContext

use of com.google.gerrit.server.logging.TraceContext in project gerrit by GerritCodeReview.

the class MergeSuperSet method completeChangeSetIncludingTopics.

private ChangeSet completeChangeSetIncludingTopics(ChangeSet changeSet, CurrentUser user) throws IOException, PermissionBackendException {
    Set<String> topicsSeen = new HashSet<>();
    Set<String> visibleTopicsSeen = new HashSet<>();
    int oldSeen;
    int seen;
    changeSet = topicClosure(changeSet, user, topicsSeen, visibleTopicsSeen);
    seen = topicsSeen.size() + visibleTopicsSeen.size();
    do {
        oldSeen = seen;
        try (TraceContext traceContext = PluginContext.newTrace(mergeSuperSetComputation)) {
            changeSet = mergeSuperSetComputation.get().completeWithoutTopic(orm, changeSet, user);
        }
        changeSet = topicClosure(changeSet, user, topicsSeen, visibleTopicsSeen);
        seen = topicsSeen.size() + visibleTopicsSeen.size();
    } while (seen != oldSeen);
    return changeSet;
}
Also used : TraceContext(com.google.gerrit.server.logging.TraceContext) HashSet(java.util.HashSet)

Aggregations

TraceContext (com.google.gerrit.server.logging.TraceContext)12 AuthException (com.google.gerrit.extensions.restapi.AuthException)5 RequestInfo (com.google.gerrit.server.RequestInfo)4 RequestId (com.google.gerrit.server.logging.RequestId)4 ImmutableSet (com.google.common.collect.ImmutableSet)3 Optional (java.util.Optional)3 Joiner (com.google.common.base.Joiner)2 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)2 ImmutableList (com.google.common.collect.ImmutableList)2 ListMultimap (com.google.common.collect.ListMultimap)2 FluentLogger (com.google.common.flogger.FluentLogger)2 BadRequestException (com.google.gerrit.extensions.restapi.BadRequestException)2 IdString (com.google.gerrit.extensions.restapi.IdString)2 InvalidDeadlineException (com.google.gerrit.server.InvalidDeadlineException)2 RequestStateContext (com.google.gerrit.server.cancellation.RequestStateContext)2 PerformanceLogContext (com.google.gerrit.server.logging.PerformanceLogContext)2 PermissionBackend (com.google.gerrit.server.permissions.PermissionBackend)2 PermissionBackendException (com.google.gerrit.server.permissions.PermissionBackendException)2 ChangeData (com.google.gerrit.server.query.change.ChangeData)2 HashSet (java.util.HashSet)2