Merge "Fix per-file import if per-file rule ignores parent code owners"
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/AbstractFileBasedCodeOwnerBackend.java b/java/com/google/gerrit/plugins/codeowners/backend/AbstractFileBasedCodeOwnerBackend.java
index 2824246..20a44c2 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/AbstractFileBasedCodeOwnerBackend.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/AbstractFileBasedCodeOwnerBackend.java
@@ -52,6 +52,7 @@
private final MetaDataUpdate.InternalFactory metaDataUpdateInternalFactory;
private final RetryHelper retryHelper;
private final String defaultFileName;
+ private final CodeOwnerConfigFile.Factory codeOwnerConfigFileFactory;
private final CodeOwnerConfigParser codeOwnerConfigParser;
protected AbstractFileBasedCodeOwnerBackend(
@@ -61,6 +62,7 @@
MetaDataUpdate.InternalFactory metaDataUpdateInternalFactory,
RetryHelper retryHelper,
String defaultFileName,
+ CodeOwnerConfigFile.Factory codeOwnerConfigFileFactory,
CodeOwnerConfigParser codeOwnerConfigParser) {
this.codeOwnersPluginConfiguration = codeOwnersPluginConfiguration;
this.repoManager = repoManager;
@@ -68,6 +70,7 @@
this.metaDataUpdateInternalFactory = metaDataUpdateInternalFactory;
this.retryHelper = retryHelper;
this.defaultFileName = defaultFileName;
+ this.codeOwnerConfigFileFactory = codeOwnerConfigFileFactory;
this.codeOwnerConfigParser = codeOwnerConfigParser;
}
@@ -103,7 +106,7 @@
@Nullable ObjectId revision) {
try (Repository repository = repoManager.openRepository(codeOwnerConfigKey.project())) {
if (revision == null) {
- return CodeOwnerConfigFile.loadCurrent(
+ return codeOwnerConfigFileFactory.loadCurrent(
fileName, codeOwnerConfigParser, repository, codeOwnerConfigKey);
}
@@ -113,7 +116,7 @@
revWalk = new RevWalk(repository);
}
try {
- return CodeOwnerConfigFile.load(
+ return codeOwnerConfigFileFactory.load(
fileName, codeOwnerConfigParser, revWalk, revision, codeOwnerConfigKey);
} finally {
if (closeRevWalk) {
@@ -222,7 +225,8 @@
CodeOwnerConfigUpdate codeOwnerConfigUpdate) {
try (Repository repository = repoManager.openRepository(codeOwnerConfigKey.project())) {
CodeOwnerConfigFile codeOwnerConfigFile =
- CodeOwnerConfigFile.loadCurrent(
+ codeOwnerConfigFileFactory
+ .loadCurrent(
getFileName(codeOwnerConfigKey.project()),
codeOwnerConfigParser,
repository,
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/ChangedFiles.java b/java/com/google/gerrit/plugins/codeowners/backend/ChangedFiles.java
index cf88e62..4fdab65 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/ChangedFiles.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/ChangedFiles.java
@@ -146,14 +146,12 @@
logger.atFine().log(
"computing changed files for revision %s in project %s", revCommit.name(), project);
- try (Timer0.Context ctx = codeOwnerMetrics.computeChangedFiles.start()) {
- if (revCommit.getParentCount() > 1
- && MergeCommitStrategy.FILES_WITH_CONFLICT_RESOLUTION.equals(mergeCommitStrategy)) {
- return computeByComparingAgainstAutoMerge(project, revCommit);
- }
-
- return computeByComparingAgainstFirstParent(repoConfig, revWalk, revCommit);
+ if (revCommit.getParentCount() > 1
+ && MergeCommitStrategy.FILES_WITH_CONFLICT_RESOLUTION.equals(mergeCommitStrategy)) {
+ return computeByComparingAgainstAutoMerge(project, revCommit);
}
+
+ return computeByComparingAgainstFirstParent(repoConfig, revWalk, revCommit);
}
/**
@@ -171,16 +169,19 @@
checkState(
mergeCommit.getParentCount() > 1, "expected %s to be a merge commit", mergeCommit.name());
- // for merge commits the default base is the auto merge commit
- PatchListKey patchListKey =
- PatchListKey.againstDefaultBase(mergeCommit, Whitespace.IGNORE_NONE);
+ try (Timer0.Context ctx = codeOwnerMetrics.computeChangedFilesAgainstAutoMerge.start()) {
+ // for merge commits the default base is the auto merge commit
+ PatchListKey patchListKey =
+ PatchListKey.againstDefaultBase(mergeCommit, Whitespace.IGNORE_NONE);
- return patchListCache.get(patchListKey, project).getPatches().stream()
- .filter(
- patchListEntry ->
- patchListEntry.getNewName() == null || !Patch.isMagic(patchListEntry.getNewName()))
- .map(ChangedFile::create)
- .collect(toImmutableSet());
+ return patchListCache.get(patchListKey, project).getPatches().stream()
+ .filter(
+ patchListEntry ->
+ patchListEntry.getNewName() == null
+ || !Patch.isMagic(patchListEntry.getNewName()))
+ .map(ChangedFile::create)
+ .collect(toImmutableSet());
+ }
}
/**
@@ -195,25 +196,27 @@
*/
private ImmutableSet<ChangedFile> computeByComparingAgainstFirstParent(
Config repoConfig, RevWalk revWalk, RevCommit revCommit) throws IOException {
- RevCommit baseCommit = revCommit.getParentCount() > 0 ? revCommit.getParent(0) : null;
- logger.atFine().log("baseCommit = %s", baseCommit != null ? baseCommit.name() : "n/a");
+ try (Timer0.Context ctx = codeOwnerMetrics.computeChangedFilesAgainstFirstParent.start()) {
+ RevCommit baseCommit = revCommit.getParentCount() > 0 ? revCommit.getParent(0) : null;
+ logger.atFine().log("baseCommit = %s", baseCommit != null ? baseCommit.name() : "n/a");
- try (DiffFormatter diffFormatter = new DiffFormatter(DisabledOutputStream.INSTANCE)) {
- diffFormatter.setReader(revWalk.getObjectReader(), repoConfig);
- diffFormatter.setDiffComparator(RawTextComparator.DEFAULT);
- diffFormatter.setDetectRenames(true);
- List<DiffEntry> diffEntries = diffFormatter.scan(baseCommit, revCommit);
- ImmutableSet<ChangedFile> changedFiles =
- diffEntries.stream().map(ChangedFile::create).collect(toImmutableSet());
- if (changedFiles.size() <= MAX_CHANGED_FILES_TO_LOG) {
- logger.atFine().log("changed files = %s", changedFiles);
- } else {
- logger.atFine().log(
- "changed files = %s (and %d more)",
- changedFiles.asList().subList(0, MAX_CHANGED_FILES_TO_LOG),
- changedFiles.size() - MAX_CHANGED_FILES_TO_LOG);
+ try (DiffFormatter diffFormatter = new DiffFormatter(DisabledOutputStream.INSTANCE)) {
+ diffFormatter.setReader(revWalk.getObjectReader(), repoConfig);
+ diffFormatter.setDiffComparator(RawTextComparator.DEFAULT);
+ diffFormatter.setDetectRenames(true);
+ List<DiffEntry> diffEntries = diffFormatter.scan(baseCommit, revCommit);
+ ImmutableSet<ChangedFile> changedFiles =
+ diffEntries.stream().map(ChangedFile::create).collect(toImmutableSet());
+ if (changedFiles.size() <= MAX_CHANGED_FILES_TO_LOG) {
+ logger.atFine().log("changed files = %s", changedFiles);
+ } else {
+ logger.atFine().log(
+ "changed files = %s (and %d more)",
+ changedFiles.asList().subList(0, MAX_CHANGED_FILES_TO_LOG),
+ changedFiles.size() - MAX_CHANGED_FILES_TO_LOG);
+ }
+ return changedFiles;
}
- return changedFiles;
}
}
}
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigFile.java b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigFile.java
index 4cceb13..b704f2b 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigFile.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigFile.java
@@ -19,9 +19,13 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
+import com.google.gerrit.metrics.Timer0;
+import com.google.gerrit.metrics.Timer1;
+import com.google.gerrit.plugins.codeowners.metrics.CodeOwnerMetrics;
import com.google.gerrit.plugins.codeowners.util.JgitPath;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.git.meta.VersionedMetaData;
+import com.google.inject.Inject;
import java.io.IOException;
import java.util.Optional;
import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -36,9 +40,9 @@
* A representation of a code owner config that is stored as an {@code OWNERS} file in a source
* branch.
*
- * <p>For reading code owner configs or creating/updating them, refer to {@link #load(String,
- * CodeOwnerConfigParser, RevWalk, ObjectId, CodeOwnerConfig.Key)} and {@link #loadCurrent(String,
- * CodeOwnerConfigParser, Repository, CodeOwnerConfig.Key)}.
+ * <p>For reading code owner configs or creating/updating them, refer to {@link Factory#load(String,
+ * CodeOwnerConfigParser, RevWalk, ObjectId, CodeOwnerConfig.Key)} and {@link
+ * Factory#loadCurrent(String, CodeOwnerConfigParser, Repository, CodeOwnerConfig.Key)}.
*
* <p><strong>Note:</strong> Any modification (code owner config creation or update) only becomes
* permanent (and hence written to repository) if {@link
@@ -46,83 +50,95 @@
*/
@VisibleForTesting
public class CodeOwnerConfigFile extends VersionedMetaData {
- /**
- * Creates a {@link CodeOwnerConfigFile} for a code owner config.
- *
- * <p>The code owner config is automatically loaded within this method and can be accessed via
- * {@link #getLoadedCodeOwnerConfig()}.
- *
- * <p>It's safe to call this method for non-existing code owner configs. In that case, {@link
- * #getLoadedCodeOwnerConfig()} won't return any code owner config. Thus, the existence of a code
- * owner config can be easily tested.
- *
- * <p>The code owner config represented by the returned {@link CodeOwnerConfigFile} can be
- * created/updated by setting an {@link CodeOwnerConfigUpdate} via {@link
- * #setCodeOwnerConfigUpdate(CodeOwnerConfigUpdate)} and committing the {@link
- * CodeOwnerConfigUpdate} via {@link #commit(com.google.gerrit.server.git.meta.MetaDataUpdate)}.
- *
- * @param defaultFileName the name of the code owner configuration files that should be used if
- * none is specified in the code owner config key
- * @param codeOwnerConfigParser the parser that should be used to parse code owner config files
- * @param revWalk the revWalk that should be used to load the revision
- * @param revision the branch revision from which the code owner config file should be loaded
- * @param codeOwnerConfigKey the key of the code owner config
- * @return a {@link CodeOwnerConfigFile} for the code owner config with the specified key
- * @throws IOException if the repository can't be accessed for some reason
- * @throws ConfigInvalidException if the code owner config exists but can't be read due to an
- * invalid format
- */
- public static CodeOwnerConfigFile load(
- String defaultFileName,
- CodeOwnerConfigParser codeOwnerConfigParser,
- RevWalk revWalk,
- ObjectId revision,
- CodeOwnerConfig.Key codeOwnerConfigKey)
- throws IOException, ConfigInvalidException {
- requireNonNull(defaultFileName, "defaultFileName");
- requireNonNull(codeOwnerConfigParser, "codeOwnerConfigParser");
- requireNonNull(revWalk, "revWalk");
- requireNonNull(revision, "revision");
- requireNonNull(codeOwnerConfigKey, "codeOwnerConfigKey");
+ public static class Factory {
+ private final CodeOwnerMetrics codeOwnerMetrics;
- CodeOwnerConfigFile codeOwnerConfigFile =
- new CodeOwnerConfigFile(defaultFileName, codeOwnerConfigParser, codeOwnerConfigKey);
- codeOwnerConfigFile.load(codeOwnerConfigKey.project(), revWalk, revision);
- return codeOwnerConfigFile;
+ @Inject
+ Factory(CodeOwnerMetrics codeOwnerMetrics) {
+ this.codeOwnerMetrics = codeOwnerMetrics;
+ }
+
+ /**
+ * Creates a {@link CodeOwnerConfigFile} for a code owner config.
+ *
+ * <p>The code owner config is automatically loaded within this method and can be accessed via
+ * {@link #getLoadedCodeOwnerConfig()}.
+ *
+ * <p>It's safe to call this method for non-existing code owner configs. In that case, {@link
+ * #getLoadedCodeOwnerConfig()} won't return any code owner config. Thus, the existence of a
+ * code owner config can be easily tested.
+ *
+ * <p>The code owner config represented by the returned {@link CodeOwnerConfigFile} can be
+ * created/updated by setting an {@link CodeOwnerConfigUpdate} via {@link
+ * #setCodeOwnerConfigUpdate(CodeOwnerConfigUpdate)} and committing the {@link
+ * CodeOwnerConfigUpdate} via {@link #commit(com.google.gerrit.server.git.meta.MetaDataUpdate)}.
+ *
+ * @param defaultFileName the name of the code owner configuration files that should be used if
+ * none is specified in the code owner config key
+ * @param codeOwnerConfigParser the parser that should be used to parse code owner config files
+ * @param revWalk the revWalk that should be used to load the revision
+ * @param revision the branch revision from which the code owner config file should be loaded
+ * @param codeOwnerConfigKey the key of the code owner config
+ * @return a {@link CodeOwnerConfigFile} for the code owner config with the specified key
+ * @throws IOException if the repository can't be accessed for some reason
+ * @throws ConfigInvalidException if the code owner config exists but can't be read due to an
+ * invalid format
+ */
+ public CodeOwnerConfigFile load(
+ String defaultFileName,
+ CodeOwnerConfigParser codeOwnerConfigParser,
+ RevWalk revWalk,
+ ObjectId revision,
+ CodeOwnerConfig.Key codeOwnerConfigKey)
+ throws IOException, ConfigInvalidException {
+ requireNonNull(defaultFileName, "defaultFileName");
+ requireNonNull(codeOwnerConfigParser, "codeOwnerConfigParser");
+ requireNonNull(revWalk, "revWalk");
+ requireNonNull(revision, "revision");
+ requireNonNull(codeOwnerConfigKey, "codeOwnerConfigKey");
+
+ CodeOwnerConfigFile codeOwnerConfigFile =
+ new CodeOwnerConfigFile(
+ codeOwnerMetrics, defaultFileName, codeOwnerConfigParser, codeOwnerConfigKey);
+ codeOwnerConfigFile.load(codeOwnerConfigKey.project(), revWalk, revision);
+ return codeOwnerConfigFile;
+ }
+
+ /**
+ * Creates a {@link CodeOwnerConfigFile} for a code owner config from the current revision in
+ * the branch.
+ *
+ * @param defaultFileName the name of the code owner configuration files that should be used if
+ * none is specified in the code owner config key
+ * @param codeOwnerConfigParser the parser that should be used to parse code owner config files
+ * @param repository the repository in which the code owner config is stored
+ * @param codeOwnerConfigKey the key of the code owner config
+ * @return a {@link CodeOwnerConfigFile} for the code owner config with the specified key
+ * @throws IOException if the repository can't be accessed for some reason
+ * @throws ConfigInvalidException if the code owner config exists but can't be read due to an
+ * invalid format
+ * @see #load(String, CodeOwnerConfigParser, RevWalk, ObjectId, CodeOwnerConfig.Key)
+ */
+ public CodeOwnerConfigFile loadCurrent(
+ String defaultFileName,
+ CodeOwnerConfigParser codeOwnerConfigParser,
+ Repository repository,
+ CodeOwnerConfig.Key codeOwnerConfigKey)
+ throws IOException, ConfigInvalidException {
+ requireNonNull(defaultFileName, "defaultFileName");
+ requireNonNull(codeOwnerConfigParser, "codeOwnerConfigParser");
+ requireNonNull(repository, "repository");
+ requireNonNull(codeOwnerConfigKey, "codeOwnerConfigKey");
+
+ CodeOwnerConfigFile codeOwnerConfigFile =
+ new CodeOwnerConfigFile(
+ codeOwnerMetrics, defaultFileName, codeOwnerConfigParser, codeOwnerConfigKey);
+ codeOwnerConfigFile.load(codeOwnerConfigKey.project(), repository);
+ return codeOwnerConfigFile;
+ }
}
- /**
- * Creates a {@link CodeOwnerConfigFile} for a code owner config from the current revision in the
- * branch.
- *
- * @param defaultFileName the name of the code owner configuration files that should be used if
- * none is specified in the code owner config key
- * @param codeOwnerConfigParser the parser that should be used to parse code owner config files
- * @param repository the repository in which the code owner config is stored
- * @param codeOwnerConfigKey the key of the code owner config
- * @return a {@link CodeOwnerConfigFile} for the code owner config with the specified key
- * @throws IOException if the repository can't be accessed for some reason
- * @throws ConfigInvalidException if the code owner config exists but can't be read due to an
- * invalid format
- * @see #load(String, CodeOwnerConfigParser, RevWalk, ObjectId, CodeOwnerConfig.Key)
- */
- public static CodeOwnerConfigFile loadCurrent(
- String defaultFileName,
- CodeOwnerConfigParser codeOwnerConfigParser,
- Repository repository,
- CodeOwnerConfig.Key codeOwnerConfigKey)
- throws IOException, ConfigInvalidException {
- requireNonNull(defaultFileName, "defaultFileName");
- requireNonNull(codeOwnerConfigParser, "codeOwnerConfigParser");
- requireNonNull(repository, "repository");
- requireNonNull(codeOwnerConfigKey, "codeOwnerConfigKey");
-
- CodeOwnerConfigFile codeOwnerConfigFile =
- new CodeOwnerConfigFile(defaultFileName, codeOwnerConfigParser, codeOwnerConfigKey);
- codeOwnerConfigFile.load(codeOwnerConfigKey.project(), repository);
- return codeOwnerConfigFile;
- }
-
+ private final CodeOwnerMetrics codeOwnerMetrics;
private final String defaultFileName;
private final CodeOwnerConfigParser codeOwnerConfigParser;
private final CodeOwnerConfig.Key codeOwnerConfigKey;
@@ -132,9 +148,11 @@
private Optional<CodeOwnerConfigUpdate> codeOwnerConfigUpdate = Optional.empty();
private CodeOwnerConfigFile(
+ CodeOwnerMetrics codeOwnerMetrics,
String defaultFileName,
CodeOwnerConfigParser codeOwnerConfigParser,
CodeOwnerConfig.Key codeOwnerConfigKey) {
+ this.codeOwnerMetrics = codeOwnerMetrics;
this.defaultFileName = defaultFileName;
this.codeOwnerConfigParser = codeOwnerConfigParser;
this.codeOwnerConfigKey = codeOwnerConfigKey;
@@ -186,12 +204,21 @@
}
@Override
+ protected byte[] readFile(String fileName) throws IOException {
+ try (Timer0.Context ctx = codeOwnerMetrics.readCodeOwnerConfig.start()) {
+ return super.readFile(fileName);
+ }
+ }
+
+ @Override
protected void onLoad() throws IOException, ConfigInvalidException {
if (revision != null) {
Optional<String> codeOwnerConfigFileContent =
getFileIfItExists(JgitPath.of(codeOwnerConfigKey.filePath(defaultFileName)).get());
if (codeOwnerConfigFileContent.isPresent()) {
- try {
+ try (Timer1.Context<String> ctx =
+ codeOwnerMetrics.parseCodeOwnerConfig.start(
+ codeOwnerConfigParser.getClass().getSimpleName())) {
loadedCodeOwnersConfig =
Optional.of(
codeOwnerConfigParser.parse(
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerSubmitRule.java b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerSubmitRule.java
index 0683b25..1785a1d 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerSubmitRule.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerSubmitRule.java
@@ -78,6 +78,7 @@
}
try (Timer0.Context ctx = codeOwnerMetrics.runCodeOwnerSubmitRule.start()) {
+ codeOwnerMetrics.countCodeOwnerConfigReads.increment();
logger.atFine().log(
"run code owner submit rule (project = %s, change = %d)",
changeData.project().get(), changeData.getId().get());
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwners.java b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwners.java
index 4247849..32ad7b5 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwners.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwners.java
@@ -17,6 +17,7 @@
import static java.util.Objects.requireNonNull;
import com.google.common.base.Throwables;
+import com.google.gerrit.metrics.Timer1;
import com.google.gerrit.plugins.codeowners.backend.config.CodeOwnersPluginConfiguration;
import com.google.gerrit.plugins.codeowners.metrics.CodeOwnerMetrics;
import com.google.inject.Inject;
@@ -57,7 +58,10 @@
codeOwnersPluginConfiguration
.getProjectConfig(codeOwnerConfigKey.project())
.getBackend(codeOwnerConfigKey.branchNameKey().branch());
- return codeOwnerBackend.getCodeOwnerConfig(codeOwnerConfigKey, revision);
+ try (Timer1.Context<String> ctx =
+ codeOwnerMetrics.loadCodeOwnerConfig.start(codeOwnerBackend.getClass().getSimpleName())) {
+ return codeOwnerBackend.getCodeOwnerConfig(codeOwnerConfigKey, revision);
+ }
}
@Override
@@ -68,7 +72,10 @@
codeOwnersPluginConfiguration
.getProjectConfig(codeOwnerConfigKey.project())
.getBackend(codeOwnerConfigKey.branchNameKey().branch());
- return codeOwnerBackend.getCodeOwnerConfig(codeOwnerConfigKey, /* revision= */ null);
+ try (Timer1.Context<String> ctx =
+ codeOwnerMetrics.loadCodeOwnerConfig.start(codeOwnerBackend.getClass().getSimpleName())) {
+ return codeOwnerBackend.getCodeOwnerConfig(codeOwnerConfigKey, /* revision= */ null);
+ }
}
/**
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/findowners/FindOwnersBackend.java b/java/com/google/gerrit/plugins/codeowners/backend/findowners/FindOwnersBackend.java
index 257c1d4..0e923d7 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/findowners/FindOwnersBackend.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/findowners/FindOwnersBackend.java
@@ -17,6 +17,7 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.gerrit.plugins.codeowners.backend.AbstractFileBasedCodeOwnerBackend;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfig;
+import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfigFile;
import com.google.gerrit.plugins.codeowners.backend.FindOwnersGlobMatcher;
import com.google.gerrit.plugins.codeowners.backend.PathExpressionMatcher;
import com.google.gerrit.plugins.codeowners.backend.config.CodeOwnersPluginConfiguration;
@@ -44,6 +45,7 @@
@Inject
FindOwnersBackend(
CodeOwnersPluginConfiguration codeOwnersPluginConfiguration,
+ CodeOwnerConfigFile.Factory codeOwnerConfigFileFactory,
FindOwnersCodeOwnerConfigParser codeOwnerConfigParser,
GitRepositoryManager repoManager,
@GerritPersonIdent PersonIdent serverIdent,
@@ -56,6 +58,7 @@
metaDataUpdateInternalFactory,
retryHelper,
CODE_OWNER_CONFIG_FILE_NAME,
+ codeOwnerConfigFileFactory,
codeOwnerConfigParser);
}
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/proto/ProtoBackend.java b/java/com/google/gerrit/plugins/codeowners/backend/proto/ProtoBackend.java
index e8e0694..b273ab2 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/proto/ProtoBackend.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/proto/ProtoBackend.java
@@ -17,6 +17,7 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.gerrit.plugins.codeowners.backend.AbstractFileBasedCodeOwnerBackend;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfig;
+import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfigFile;
import com.google.gerrit.plugins.codeowners.backend.PathExpressionMatcher;
import com.google.gerrit.plugins.codeowners.backend.SimplePathExpressionMatcher;
import com.google.gerrit.plugins.codeowners.backend.config.CodeOwnersPluginConfiguration;
@@ -52,6 +53,7 @@
@GerritPersonIdent PersonIdent serverIdent,
MetaDataUpdate.InternalFactory metaDataUpdateInternalFactory,
RetryHelper retryHelper,
+ CodeOwnerConfigFile.Factory codeOwnerConfigFileFactory,
ProtoCodeOwnerConfigParser codeOwnerConfigParser) {
super(
codeOwnersPluginConfiguration,
@@ -60,6 +62,7 @@
metaDataUpdateInternalFactory,
retryHelper,
CODE_OWNER_CONFIG_FILE_NAME,
+ codeOwnerConfigFileFactory,
codeOwnerConfigParser);
}
diff --git a/java/com/google/gerrit/plugins/codeowners/metrics/CodeOwnerMetrics.java b/java/com/google/gerrit/plugins/codeowners/metrics/CodeOwnerMetrics.java
index e5a3c58..56aec3c 100644
--- a/java/com/google/gerrit/plugins/codeowners/metrics/CodeOwnerMetrics.java
+++ b/java/com/google/gerrit/plugins/codeowners/metrics/CodeOwnerMetrics.java
@@ -17,8 +17,10 @@
import com.google.gerrit.metrics.Counter0;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Description.Units;
+import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.Timer0;
+import com.google.gerrit.metrics.Timer1;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -26,7 +28,8 @@
@Singleton
public class CodeOwnerMetrics {
// latency metrics
- public final Timer0 computeChangedFiles;
+ public final Timer0 computeChangedFilesAgainstAutoMerge;
+ public final Timer0 computeChangedFilesAgainstFirstParent;
public final Timer0 computeFileStatus;
public final Timer0 computeFileStatuses;
public final Timer0 computeOwnedPaths;
@@ -38,9 +41,15 @@
public final Timer0 resolvePathCodeOwners;
public final Timer0 runCodeOwnerSubmitRule;
+ // code owner config latency metrics
+ public final Timer1<String> loadCodeOwnerConfig;
+ public final Timer0 readCodeOwnerConfig;
+ public final Timer1<String> parseCodeOwnerConfig;
+
// counter metrics
public final Counter0 countCodeOwnerConfigReads;
public final Counter0 countCodeOwnerConfigCacheReads;
+ public final Counter0 countCodeOwnerSubmitRuleRuns;
private final MetricMaker metricMaker;
@@ -49,8 +58,14 @@
this.metricMaker = metricMaker;
// latency metrics
- this.computeChangedFiles =
- createLatencyTimer("compute_changed_files", "Latency for computing changed files");
+ this.computeChangedFilesAgainstAutoMerge =
+ createLatencyTimer(
+ "compute_changed_files_against_auto_merge",
+ "Latency for computing changed files against auto merge");
+ this.computeChangedFilesAgainstFirstParent =
+ createLatencyTimer(
+ "compute_changed_files_against_first_parent",
+ "Latency for computing changed files against first parent");
this.computeFileStatus =
createLatencyTimer(
"compute_file_status", "Latency for computing the file status of one file");
@@ -87,6 +102,19 @@
createLatencyTimer(
"run_code_owner_submit_rule", "Latency for running the code owner submit rule");
+ // code owner config latency metrics
+ this.loadCodeOwnerConfig =
+ createTimerWithClassField(
+ "load_code_owner_config",
+ "Latency for loading a code owner config file (read + parse)",
+ "backend");
+ this.parseCodeOwnerConfig =
+ createTimerWithClassField(
+ "parse_code_owner_config", "Latency for parsing a code owner config file", "parser");
+ this.readCodeOwnerConfig =
+ createLatencyTimer(
+ "read_code_owner_config", "Latency for reading a code owner config file");
+
// counter metrics
this.countCodeOwnerConfigReads =
createCounter(
@@ -96,6 +124,9 @@
createCounter(
"count_code_owner_config_cache_reads",
"Total number of code owner config reads from cache");
+ this.countCodeOwnerSubmitRuleRuns =
+ createCounter(
+ "count_code_owner_submit_rule_runs", "Total number of code owner submit rule runs");
}
private Timer0 createLatencyTimer(String name, String description) {
@@ -104,6 +135,19 @@
new Description(description).setCumulative().setUnit(Units.MILLISECONDS));
}
+ private Timer1<String> createTimerWithClassField(
+ String name, String description, String fieldName) {
+ Field<String> CODE_OWNER_BACKEND_FIELD =
+ Field.ofString(
+ fieldName, (metadataBuilder, fieldValue) -> metadataBuilder.className(fieldValue))
+ .build();
+
+ return metricMaker.newTimer(
+ "code_owners/" + name,
+ new Description(description).setCumulative().setUnit(Description.Units.MILLISECONDS),
+ CODE_OWNER_BACKEND_FIELD);
+ }
+
private Counter0 createCounter(String name, String description) {
return metricMaker.newCounter("code_owners/" + name, new Description(description).setRate());
}
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigFileTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigFileTest.java
index 61bbdb7..e6b776d 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigFileTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigFileTest.java
@@ -47,10 +47,13 @@
@Inject private ProjectOperations projectOperations;
@Inject private MetaDataUpdate.Server metaDataUpdateServer;
+ private CodeOwnerConfigFile.Factory codeOwnerConfigFileFactory;
private TestCodeOwnerConfigStorage testCodeOwnerConfigStorage;
@Before
public void setUpCodeOwnersPlugin() throws Exception {
+ codeOwnerConfigFileFactory =
+ plugin.getSysInjector().getInstance(CodeOwnerConfigFile.Factory.class);
testCodeOwnerConfigStorage =
plugin
.getSysInjector()
@@ -534,7 +537,7 @@
private CodeOwnerConfigFile loadCodeOwnerConfig(CodeOwnerConfig.Key codeOwnerConfigKey)
throws IOException, ConfigInvalidException {
try (Repository repository = repoManager.openRepository(codeOwnerConfigKey.project())) {
- return CodeOwnerConfigFile.loadCurrent(
+ return codeOwnerConfigFileFactory.loadCurrent(
CODE_OWNER_CONFIG_FILE_NAME, CODE_OWNER_CONFIG_PARSER, repository, codeOwnerConfigKey);
}
}
@@ -544,7 +547,7 @@
throws IOException, ConfigInvalidException {
try (Repository repository = repoManager.openRepository(codeOwnerConfigKey.project());
RevWalk revWalk = new RevWalk(repository)) {
- return CodeOwnerConfigFile.load(
+ return codeOwnerConfigFileFactory.load(
CODE_OWNER_CONFIG_FILE_NAME,
CODE_OWNER_CONFIG_PARSER,
revWalk,
diff --git a/resources/Documentation/metrics.md b/resources/Documentation/metrics.md
index d236b3e..3abb6f8 100644
--- a/resources/Documentation/metrics.md
+++ b/resources/Documentation/metrics.md
@@ -5,8 +5,10 @@
## <a id="latencyMetrics"> Latency Metrics
-* `compute_changed_files`:
- Latency for computing changed files.
+* `compute_changed_files_against_auto_merge`:
+ Latency for computing changed files against auto merge.
+* `compute_changed_files_against_first_parent`:
+ Latency for computing changed files against first parent.
* `compute_file_status`:
Latency for computing the file status for one file.
* `compute_file_statuses`:
@@ -28,12 +30,23 @@
* `run_code_owner_submit_rule`:
Latency for running the code owner submit rule.
+### <a id="codeOwnerConfigLatencyMetrics"> Code Owner Config Latency Metrics
+
+* `load_code_owner_config`:
+ Latency for loading a code owner config file (read + parse).
+* `parse_code_owner_config`:
+ Latency for parsing a code owner config file.
+* `read_code_owner_config`:
+ Latency for reading a code owner config file.
+
## <a id="counterMetrics"> Counter Metrics
* `count_code_owner_config_reads`:
Total number of code owner config reads from backend.
* `count_code_owner_config_cache_reads`:
Total number of code owner config reads from cache.
+* `count_code_owner_submit_rule_runs`:
+ Total number of code owner submit rule runs.
---