Add `is_gc_running_per_project_<repo_name>` metric
Introduce a Gerrit metric to track if a GC process is running
for specific projects. The metric checks for the presence of a
`gc.pid` file in the repository and ensures the file is not older
than the configured staleness period.
By default, the staleness period is 12 hours and can be customized
using the configuration:
`plugins.repo-repack-tracker.considerGcStaleAfter`.
Change-Id: Ib19541280a913eece34b96975412673c932a7370
diff --git a/admin/repo-repack-tracker-1.0.groovy b/admin/repo-repack-tracker-1.0.groovy
index 6a4553a..4743a01 100644
--- a/admin/repo-repack-tracker-1.0.groovy
+++ b/admin/repo-repack-tracker-1.0.groovy
@@ -33,8 +33,11 @@
class RepoRepackTracker implements LifecycleListener {
private static final FluentLogger logger = FluentLogger.forEnclosingClass()
- private static final NAME = "is_repack_running_per_project"
- private static final DESCRIPTION = "Check repack running for the project"
+ private static final DESCRIPTION_GC = "Check gc running for the project"
+ private static final DESCRIPTION_REPACK = "Check repack running for the project"
+ private static final NAME_GC = "is_gc_running_per_project"
+ private static final NAME_REPACK = "is_repack_running_per_project"
+ private static final GC_PID_FILE = "gc.pid"
private static final GIT_PACK_FOLDER = "objects/pack"
private static final TMP_PREFIX = "tmp_"
private static final TMP_SUFFIX = ".tmp"
@@ -50,26 +53,37 @@
LocalDiskRepositoryManager repoMgr
private def tmpFilter = ~/^(${TMP_PREFIX}.*|.*${TMP_SUFFIX})$/
- private long considerStaleAfterMs
- CallbackMetric1<String, Long> projectsAndGcMetric
+ private long repackStalenessAfterMs
+ private long gcStalenessAfterMs
+ CallbackMetric1<String, Long> callbackMetricGc
+ CallbackMetric1<String, Long> callbackMetricRepack
List<String> projects
@Override
void start() {
PluginConfig pluginConfig = configFactory.getFromGerritConfig(pluginName)
- long considerStaleAfter = ConfigUtil.getTimeUnit(
- pluginConfig.getString("considerStaleAfter", "60 minutes"),
+ long repackStalenessAfter = ConfigUtil.getTimeUnit(
+ pluginConfig.getString("considerRepackStaleAfter", "60 minutes"),
60L,
TimeUnit.MINUTES)
- considerStaleAfterMs = TimeUnit.MILLISECONDS.convert(considerStaleAfter, TimeUnit.MINUTES)
+ long gcStalenessAfter = ConfigUtil.getTimeUnit(
+ pluginConfig.getString("considerGcStaleAfter", "720 minutes"),
+ 720L,
+ TimeUnit.MINUTES)
+ repackStalenessAfterMs = TimeUnit.MILLISECONDS.convert(repackStalenessAfter, TimeUnit.MINUTES)
+ gcStalenessAfterMs = TimeUnit.MILLISECONDS.convert(gcStalenessAfter, TimeUnit.MINUTES)
projects = pluginConfig.getStringList("project")
- projectsAndGcMetric = createCallbackMetric(NAME, DESCRIPTION)
- addMetricsTrigger(projectsAndGcMetric, projects)
- logger.atInfo().log("Plugin %s started (staleAfter %d minutes)",
+ callbackMetricGc = createCallbackMetric(NAME_GC, DESCRIPTION_GC)
+ callbackMetricRepack = createCallbackMetric(NAME_REPACK, DESCRIPTION_REPACK)
+ addMetricsTriggers()
+
+ logger.atInfo().log("Plugin %s started for %d projects (considering gc stale after %d minutes, repack after %d minutes)",
pluginName,
- considerStaleAfter)
+ projects.size(),
+ gcStalenessAfter,
+ repackStalenessAfter)
}
CallbackMetric1<String, Long> createCallbackMetric(String name, String description) {
@@ -83,18 +97,41 @@
)
}
- void addMetricsTrigger(CallbackMetric1<String, Long> projectsAndGcMetric, List<String> projects) {
+ void addMetricsTriggers() {
metrics.newTrigger(
- projectsAndGcMetric, {
+ callbackMetricRepack, {
if (projects.isEmpty()) {
- projectsAndGcMetric.forceCreate("")
+ callbackMetricRepack.forceCreate("")
} else {
projects.each { e ->
- projectsAndGcMetric.set(e, checkRepackingRunningForProject(e))
+ callbackMetricRepack.set(e, checkRepackingRunningForProject(e))
}
- projectsAndGcMetric.prune()
+ callbackMetricRepack.prune()
}
})
+ metrics.newTrigger(
+ callbackMetricGc, {
+ if (projects.isEmpty()) {
+ callbackMetricGc.forceCreate("")
+ } else {
+ projects.each { e ->
+ callbackMetricGc.set(e, checkGCRunningForProject(e))
+ }
+ callbackMetricGc.prune()
+ }
+ })
+ }
+
+ long checkGCRunningForProject(String projectName) {
+ def isGcRunning = 0L
+ try {
+ def repoDir = getRepoDir(projectName)
+ def gcPid = new File(repoDir, GC_PID_FILE)
+ isGcRunning = (gcPid.exists() && !isFileStale(gcPid))? 1L : 0L
+ } catch (Exception e) {
+ logger.atSevere().withCause(e).log("Could not check project %s", projectName)
+ }
+ isGcRunning
}
long checkRepackingRunningForProject(String projectName) {
@@ -118,7 +155,7 @@
}
boolean hasRepackTmpFiles(folder) {
- def modifiedCutoffTime = System.currentTimeMillis() - considerStaleAfterMs
+ def modifiedCutoffTime = System.currentTimeMillis() - repackStalenessAfterMs
def tmpFileFound = false
folder.traverse(type: FILES, nameFilter: tmpFilter) { file ->
@@ -129,6 +166,11 @@
return tmpFileFound
}
+ boolean isFileStale(File f) {
+ def fileExpiry = f.lastModified() + gcStalenessAfterMs
+ return System.currentTimeMillis() > fileExpiry
+ }
+
@Override
void stop() {}
}
diff --git a/admin/repo-repack-tracker.md b/admin/repo-repack-tracker.md
index 00f4b96..cdb0506 100644
--- a/admin/repo-repack-tracker.md
+++ b/admin/repo-repack-tracker.md
@@ -3,7 +3,7 @@
DESCRIPTION
-----------
-Check for each project configured if a repack process is running.
+Check for each project configured if a gc or a repack process is running.
Configuration
=========================
@@ -13,7 +13,8 @@
```text
[plugins "repo-repack-tracker"]
- considerStaleAfter = 1h
+ considerGcStaleAfter = 1h
+ considerRepackStaleAfter = 12h
project = test
```
@@ -21,12 +22,18 @@
---------------------
=======
-```plugins.repo-repack-tracker.considerStaleAfter```
+```plugins.repo-repack-tracker.considerRepackStaleAfter```
: If any of the files checked for determining if the repack is running has the modified date older than this value, then
the repack is considered stale (not running). If a time unit suffix is not specified, `minutes` is assumed.
Default: 1 hour.
+```plugins.repo-repack-tracker.considerGcStaleAfter```
+: If any of the files checked for determining if the gc is running has the modified date older than this value, then
+the GC is considered stale (not running). If a time unit suffix is not specified, `minutes` is assumed.
+
+Default: 12 hours.
+
```plugins.repo-repack-tracker.project```
: The name of the repository to check.
May be specified more than once to specify multiple projects, for example:
@@ -45,3 +52,9 @@
The <repo_name> is sanitised to prevent the introduction of invalid characters for a metric name and to remove
the risk of collisions (between the sanitized metric names).
Repack is considered running when its value is greater than 0 .
+
+```groovy_repo_gc_tracker_is_gc_running_per_project_<repo_name>```
+: Indicates if the gc is currently running for the <repo_name>.
+The <repo_name> is sanitised to prevent the introduction of invalid characters for a metric name and to remove
+the risk of collisions (between the sanitized metric names).
+GC is considered as running when its value is greater than 0 .