From 9f79a6ce37aa82b644b1b6fbacc1d2a201b800f6 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Tue, 21 Dec 2021 15:41:53 +0000 Subject: [PATCH 01/15] Update for next development version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1482033..3ecb638 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ de.skuzzle.ghpromexporter gh-prom-exporter - 0.0.4 + 0.0.5-SNAPSHOT gh-prom-exporter Export GitHub repository metrics in prometheus format From eb283b824da6659125b2eda3d148661b185d1ad6 Mon Sep 17 00:00:00 2001 From: Simon Taddiken Date: Tue, 21 Dec 2021 16:49:36 +0100 Subject: [PATCH 02/15] Adjust readme --- README.md | 12 +++++++----- RELEASE_NOTES.md | 2 +- readme/README.md | 8 +++++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 1eeeddb..b1f0fb5 100644 --- a/README.md +++ b/README.md @@ -8,21 +8,23 @@ Export your favorite GitHub repositories to Prometheus -Use it _as a service_: https://gh.skuzzle.de +Use it _as a service_: See https://gh.skuzzle.de for instructions +or +Use it _on-premise_: `docker pull ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5-SNAPSHOT` ## On-Premise deployment with docker This application can easily be run as a docker container in whatever environment you like: ``` docker run -p 8080:8080 \ - -e WEB_ALLOWANONYMOUSSCRAPE=true - ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.4 + -e WEB_ALLOWANONYMOUSSCRAPE=true \ + ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5-SNAPSHOT ``` With _anonymous scraping_ allowed, you can now easily view the scrape results directly in the browser by navigating to `https://your.docker.host:8080/YOUR-GITHUB-USERNAME/YOUR-REPOSITORY`. -The scraped repository can just as easiy be added as static scrape target to your prometheus' scrape configs: +The scraped repository can just as easy be added as static scrape target to your prometheus' scrape configs: ``` scrape_configs: @@ -36,7 +38,7 @@ scrape_configs: In case you want to enforce authenticated scrapes only, use this configuration instead: ``` docker run -p 8080:8080 \ - ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.4 + ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5-SNAPSHOT ``` And diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 43b71f8..b80e472 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -7,5 +7,5 @@ * Minimal documentation for on-premise setup ``` -docker pull ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.4 +docker pull ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5-SNAPSHOT ``` \ No newline at end of file diff --git a/readme/README.md b/readme/README.md index 9a2c609..2f3eb15 100644 --- a/readme/README.md +++ b/readme/README.md @@ -8,21 +8,23 @@ Export your favorite GitHub repositories to Prometheus -Use it _as a service_: https://gh.skuzzle.de +Use it _as a service_: See https://gh.skuzzle.de for instructions +or +Use it _on-premise_: `docker pull ${docker.image.name}:${project.version}` ## On-Premise deployment with docker This application can easily be run as a docker container in whatever environment you like: ``` docker run -p 8080:8080 \ - -e WEB_ALLOWANONYMOUSSCRAPE=true + -e WEB_ALLOWANONYMOUSSCRAPE=true \ ${docker.image.name}:${project.version} ``` With _anonymous scraping_ allowed, you can now easily view the scrape results directly in the browser by navigating to `https://your.docker.host:8080/YOUR-GITHUB-USERNAME/YOUR-REPOSITORY`. -The scraped repository can just as easiy be added as static scrape target to your prometheus' scrape configs: +The scraped repository can just as easy be added as static scrape target to your prometheus' scrape configs: ``` scrape_configs: From 2584716aba2440a25a8c78da7474aeb603a894a6 Mon Sep 17 00:00:00 2001 From: Simon Taddiken Date: Tue, 21 Dec 2021 16:49:59 +0100 Subject: [PATCH 03/15] Improve formatting --- README.md | 2 ++ readme/README.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index b1f0fb5..50adb99 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ Export your favorite GitHub repositories to Prometheus Use it _as a service_: See https://gh.skuzzle.de for instructions + or + Use it _on-premise_: `docker pull ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5-SNAPSHOT` ## On-Premise deployment with docker diff --git a/readme/README.md b/readme/README.md index 2f3eb15..37b77c0 100644 --- a/readme/README.md +++ b/readme/README.md @@ -9,7 +9,9 @@ Export your favorite GitHub repositories to Prometheus Use it _as a service_: See https://gh.skuzzle.de for instructions + or + Use it _on-premise_: `docker pull ${docker.image.name}:${project.version}` ## On-Premise deployment with docker From bdd76a29e636970bf5db5fe640746d2bba142a46 Mon Sep 17 00:00:00 2001 From: Simon Taddiken Date: Tue, 21 Dec 2021 16:52:14 +0100 Subject: [PATCH 04/15] Readme --- README.md | 7 ++----- readme/README.md | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 50adb99..7df4063 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,8 @@ Export your favorite GitHub repositories to Prometheus -Use it _as a service_: See https://gh.skuzzle.de for instructions - -or - -Use it _on-premise_: `docker pull ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5-SNAPSHOT` +* Use it _as a service_: See https://gh.skuzzle.de for instructions +* Deploy it _on-premise_: `docker pull ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5-SNAPSHOT` ## On-Premise deployment with docker This application can easily be run as a docker container in whatever environment you like: diff --git a/readme/README.md b/readme/README.md index 37b77c0..79b42d9 100644 --- a/readme/README.md +++ b/readme/README.md @@ -8,11 +8,8 @@ Export your favorite GitHub repositories to Prometheus -Use it _as a service_: See https://gh.skuzzle.de for instructions - -or - -Use it _on-premise_: `docker pull ${docker.image.name}:${project.version}` +* Use it _as a service_: See https://gh.skuzzle.de for instructions +* Deploy it _on-premise_: `docker pull ${docker.image.name}:${project.version}` ## On-Premise deployment with docker This application can easily be run as a docker container in whatever environment you like: From 189721f43061677fa1f3107ef533600a274093f1 Mon Sep 17 00:00:00 2001 From: Simon Taddiken Date: Tue, 21 Dec 2021 17:04:32 +0100 Subject: [PATCH 05/15] Formatting --- RELEASE_NOTES.md | 3 +-- readme/RELEASE_NOTES.md | 3 +-- .../java/de/skuzzle/ghpromexporter/web/RegistrySerializer.java | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index b80e472..1362a26 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,7 +1,6 @@ -[![Coverage Status](https://coveralls.io/repos/github/skuzzle/gh-prom-exporter/badge.svg?branch=master)](https://coveralls.io/github/skuzzle/gh-prom-exporter?branch=master) -[![Twitter Follow](https://img.shields.io/twitter/follow/skuzzleOSS.svg?style=social)](https://twitter.com/skuzzleOSS) +[![Coverage Status](https://coveralls.io/repos/github/skuzzle/gh-prom-exporter/badge.svg?branch=master)](https://coveralls.io/github/skuzzle/gh-prom-exporter?branch=master)[![Twitter Follow](https://img.shields.io/twitter/follow/skuzzleOSS.svg?style=social)](https://twitter.com/skuzzleOSS) * Configuration option to allow anonymous scraping * Minimal documentation for on-premise setup diff --git a/readme/RELEASE_NOTES.md b/readme/RELEASE_NOTES.md index 0b63843..72b0d07 100644 --- a/readme/RELEASE_NOTES.md +++ b/readme/RELEASE_NOTES.md @@ -1,7 +1,6 @@ -[![Coverage Status](https://coveralls.io/repos/github/${github.user}/${github.name}/badge.svg?branch=${github.main-branch})](https://coveralls.io/github/${github.user}/${github.name}?branch=${github.main-branch}) -[![Twitter Follow](https://img.shields.io/twitter/follow/skuzzleOSS.svg?style=social)](https://twitter.com/skuzzleOSS) +[![Coverage Status](https://coveralls.io/repos/github/${github.user}/${github.name}/badge.svg?branch=${github.main-branch})](https://coveralls.io/github/${github.user}/${github.name}?branch=${github.main-branch})[![Twitter Follow](https://img.shields.io/twitter/follow/skuzzleOSS.svg?style=social)](https://twitter.com/skuzzleOSS) * Configuration option to allow anonymous scraping * Minimal documentation for on-premise setup diff --git a/src/main/java/de/skuzzle/ghpromexporter/web/RegistrySerializer.java b/src/main/java/de/skuzzle/ghpromexporter/web/RegistrySerializer.java index db3921b..6dd9e21 100644 --- a/src/main/java/de/skuzzle/ghpromexporter/web/RegistrySerializer.java +++ b/src/main/java/de/skuzzle/ghpromexporter/web/RegistrySerializer.java @@ -17,7 +17,7 @@ class RegistrySerializer { public String serializeRegistry(CollectorRegistry registry, MediaType mediaType) { try (final var stringWriter = new StringWriter()) { - if (mediaType.equals(OPEN_METRICS)) { + if (mediaType.isCompatibleWith(OPEN_METRICS)) { TextFormat.writeOpenMetrics100(stringWriter, registry.metricFamilySamples()); } else { TextFormat.write004(stringWriter, registry.metricFamilySamples()); From 335775a7ff026c58d0e2b7fbc9a7c2812bd00e94 Mon Sep 17 00:00:00 2001 From: Simon Taddiken Date: Tue, 21 Dec 2021 17:05:07 +0100 Subject: [PATCH 06/15] Formatting --- RELEASE_NOTES.md | 5 ++--- readme/RELEASE_NOTES.md | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 1362a26..f05c76e 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,9 +1,8 @@ -[![Coverage Status](https://coveralls.io/repos/github/skuzzle/gh-prom-exporter/badge.svg?branch=master)](https://coveralls.io/github/skuzzle/gh-prom-exporter?branch=master)[![Twitter Follow](https://img.shields.io/twitter/follow/skuzzleOSS.svg?style=social)](https://twitter.com/skuzzleOSS) +[![Coverage Status](https://coveralls.io/repos/github/skuzzle/gh-prom-exporter/badge.svg?branch=master)](https://coveralls.io/github/skuzzle/gh-prom-exporter?branch=master) [![Twitter Follow](https://img.shields.io/twitter/follow/skuzzleOSS.svg?style=social)](https://twitter.com/skuzzleOSS) -* Configuration option to allow anonymous scraping -* Minimal documentation for on-premise setup +* ``` docker pull ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5-SNAPSHOT diff --git a/readme/RELEASE_NOTES.md b/readme/RELEASE_NOTES.md index 72b0d07..3b7d622 100644 --- a/readme/RELEASE_NOTES.md +++ b/readme/RELEASE_NOTES.md @@ -1,9 +1,8 @@ -[![Coverage Status](https://coveralls.io/repos/github/${github.user}/${github.name}/badge.svg?branch=${github.main-branch})](https://coveralls.io/github/${github.user}/${github.name}?branch=${github.main-branch})[![Twitter Follow](https://img.shields.io/twitter/follow/skuzzleOSS.svg?style=social)](https://twitter.com/skuzzleOSS) +[![Coverage Status](https://coveralls.io/repos/github/${github.user}/${github.name}/badge.svg?branch=${github.main-branch})](https://coveralls.io/github/${github.user}/${github.name}?branch=${github.main-branch}) [![Twitter Follow](https://img.shields.io/twitter/follow/skuzzleOSS.svg?style=social)](https://twitter.com/skuzzleOSS) -* Configuration option to allow anonymous scraping -* Minimal documentation for on-premise setup +* ``` docker pull ${docker.image.name}:${project.version} From a7b3e798928e623fba4c8f434f37ea777556de2e Mon Sep 17 00:00:00 2001 From: Simon Taddiken Date: Wed, 22 Dec 2021 07:51:12 +0100 Subject: [PATCH 07/15] Update to Spring-Boot 2.6.2 --- RELEASE_NOTES.md | 2 +- pom.xml | 2 +- readme/RELEASE_NOTES.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f05c76e..8ff167c 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -2,7 +2,7 @@ [![Coverage Status](https://coveralls.io/repos/github/skuzzle/gh-prom-exporter/badge.svg?branch=master)](https://coveralls.io/github/skuzzle/gh-prom-exporter?branch=master) [![Twitter Follow](https://img.shields.io/twitter/follow/skuzzleOSS.svg?style=social)](https://twitter.com/skuzzleOSS) -* +* Update to Spring-Boot 2.6.2 ``` docker pull ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5-SNAPSHOT diff --git a/pom.xml b/pom.xml index 3ecb638..84f7c6d 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ ghcr.io ${docker.registry.name}/${github.user}/${github.name}/${project.artifactId} - 2.6.1 + 2.6.2 2021.0.0-RC1 31.0.1-jre 1.135 diff --git a/readme/RELEASE_NOTES.md b/readme/RELEASE_NOTES.md index 3b7d622..8d40056 100644 --- a/readme/RELEASE_NOTES.md +++ b/readme/RELEASE_NOTES.md @@ -2,7 +2,7 @@ [![Coverage Status](https://coveralls.io/repos/github/${github.user}/${github.name}/badge.svg?branch=${github.main-branch})](https://coveralls.io/github/${github.user}/${github.name}?branch=${github.main-branch}) [![Twitter Follow](https://img.shields.io/twitter/follow/skuzzleOSS.svg?style=social)](https://twitter.com/skuzzleOSS) -* +* Update to Spring-Boot 2.6.2 ``` docker pull ${docker.image.name}:${project.version} From a77fed0df75356230555fb2999cd49c3943bbad7 Mon Sep 17 00:00:00 2001 From: Simon Taddiken Date: Wed, 22 Dec 2021 08:00:28 +0100 Subject: [PATCH 08/15] Remove unused classes --- .../clock/ApplicationClock.java | 11 ---- .../clock/ClockConfiguration.java | 13 ----- .../clock/StaticApplicationClock.java | 51 ------------------- 3 files changed, 75 deletions(-) delete mode 100644 src/main/java/de/skuzzle/ghpromexporter/clock/ApplicationClock.java delete mode 100644 src/main/java/de/skuzzle/ghpromexporter/clock/ClockConfiguration.java delete mode 100644 src/main/java/de/skuzzle/ghpromexporter/clock/StaticApplicationClock.java diff --git a/src/main/java/de/skuzzle/ghpromexporter/clock/ApplicationClock.java b/src/main/java/de/skuzzle/ghpromexporter/clock/ApplicationClock.java deleted file mode 100644 index 37f9196..0000000 --- a/src/main/java/de/skuzzle/ghpromexporter/clock/ApplicationClock.java +++ /dev/null @@ -1,11 +0,0 @@ -package de.skuzzle.ghpromexporter.clock; - -import java.time.Clock; - -@FunctionalInterface -public interface ApplicationClock { - - static final ApplicationClock DEFAULT = StaticApplicationClock::get; - - Clock get(); -} diff --git a/src/main/java/de/skuzzle/ghpromexporter/clock/ClockConfiguration.java b/src/main/java/de/skuzzle/ghpromexporter/clock/ClockConfiguration.java deleted file mode 100644 index a913a7f..0000000 --- a/src/main/java/de/skuzzle/ghpromexporter/clock/ClockConfiguration.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.skuzzle.ghpromexporter.clock; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration(proxyBeanMethods = false) -public class ClockConfiguration { - - @Bean - ApplicationClock applicationClock() { - return ApplicationClock.DEFAULT; - } -} diff --git a/src/main/java/de/skuzzle/ghpromexporter/clock/StaticApplicationClock.java b/src/main/java/de/skuzzle/ghpromexporter/clock/StaticApplicationClock.java deleted file mode 100644 index 8a79e1a..0000000 --- a/src/main/java/de/skuzzle/ghpromexporter/clock/StaticApplicationClock.java +++ /dev/null @@ -1,51 +0,0 @@ -package de.skuzzle.ghpromexporter.clock; - -import java.time.Clock; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Preconditions; - -public final class StaticApplicationClock { - - private static final Logger logger = LoggerFactory.getLogger(StaticApplicationClock.class); - - private StaticApplicationClock() { - // hidden - } - - private static volatile Clock APPLICATION_CLOCK = Clock.systemUTC(); - - public static Clock get() { - if (logger.isDebugEnabled()) { - final boolean clockChanged = !APPLICATION_CLOCK.equals(Clock.systemUTC()); - if (clockChanged) { - logger.debug("Accessed global application clock which has been changed from UTC to {}", - APPLICATION_CLOCK); - } - } - return APPLICATION_CLOCK; - } - - public static void resetToDefaultClock() { - final boolean clockChanged = !APPLICATION_CLOCK.equals(Clock.systemUTC()); - if (clockChanged) { - APPLICATION_CLOCK = Clock.systemUTC(); - logger.info("Reset Application clock to UTC"); - } - } - - public static void changeTo(Clock clock) { - Preconditions.checkArgument(clock != null, "global StaticApplicationClock can not be null"); - if (clock.equals(APPLICATION_CLOCK)) { - // early return to avoid warning log message - return; - } - APPLICATION_CLOCK = clock; - final boolean clockChanged = !APPLICATION_CLOCK.equals(Clock.systemUTC()); - if (clockChanged) { - logger.warn("Application clock has been changed globally to {}", clock); - } - } -} From 926e5c51e24aa63b2e951daf34b659f85a3b130a Mon Sep 17 00:00:00 2001 From: Simon Taddiken Date: Wed, 22 Dec 2021 09:27:37 +0100 Subject: [PATCH 09/15] Allow to scrape multiple repository with single call closes #1 --- README.md | 2 +- RELEASE_NOTES.md | 1 + readme/README.md | 2 +- readme/RELEASE_NOTES.md | 1 + .../scrape/RepositoryMeters.java | 66 ++++++++++++ .../scrape/RepositoryMetrics.java | 63 +---------- .../web/MultipleRepositories.java | 28 +++++ .../ghpromexporter/web/PromController.java | 30 ++++-- .../web/PromControllerTest.java | 102 +++++++++++------- .../scrape_multiple_repositories_0.snapshot | 54 ++++++++++ 10 files changed, 237 insertions(+), 112 deletions(-) create mode 100644 src/main/java/de/skuzzle/ghpromexporter/scrape/RepositoryMeters.java create mode 100644 src/main/java/de/skuzzle/ghpromexporter/web/MultipleRepositories.java create mode 100644 src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/scrape_multiple_repositories_0.snapshot diff --git a/README.md b/README.md index 7df4063..d23ffa4 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ The scraped repository can just as easy be added as static scrape target to your scrape_configs: - job_name: CHANGE_ME scrape_interval: 2m - metrics_path: /YOUR-GITHUB-USERNAME/YOUR-REPOSITORY + metrics_path: /YOUR-GITHUB-USERNAME/YOUR-REPOSITORY1,YOUR-REPOSITORY2 static_configs: - targets: ['your.docker.host:8080'] ``` diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 8ff167c..01e510f 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -3,6 +3,7 @@ [![Coverage Status](https://coveralls.io/repos/github/skuzzle/gh-prom-exporter/badge.svg?branch=master)](https://coveralls.io/github/skuzzle/gh-prom-exporter?branch=master) [![Twitter Follow](https://img.shields.io/twitter/follow/skuzzleOSS.svg?style=social)](https://twitter.com/skuzzleOSS) * Update to Spring-Boot 2.6.2 +* [#1](https://github.com/skuzzle/gh-prom-exporter/issues/1) Allow to scrape multiple repository with single call ``` docker pull ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5-SNAPSHOT diff --git a/readme/README.md b/readme/README.md index 79b42d9..531feeb 100644 --- a/readme/README.md +++ b/readme/README.md @@ -29,7 +29,7 @@ The scraped repository can just as easy be added as static scrape target to your scrape_configs: - job_name: CHANGE_ME scrape_interval: 2m - metrics_path: /YOUR-GITHUB-USERNAME/YOUR-REPOSITORY + metrics_path: /YOUR-GITHUB-USERNAME/YOUR-REPOSITORY1,YOUR-REPOSITORY2 static_configs: - targets: ['your.docker.host:8080'] ``` diff --git a/readme/RELEASE_NOTES.md b/readme/RELEASE_NOTES.md index 8d40056..a029a0d 100644 --- a/readme/RELEASE_NOTES.md +++ b/readme/RELEASE_NOTES.md @@ -3,6 +3,7 @@ [![Coverage Status](https://coveralls.io/repos/github/${github.user}/${github.name}/badge.svg?branch=${github.main-branch})](https://coveralls.io/github/${github.user}/${github.name}?branch=${github.main-branch}) [![Twitter Follow](https://img.shields.io/twitter/follow/skuzzleOSS.svg?style=social)](https://twitter.com/skuzzleOSS) * Update to Spring-Boot 2.6.2 +* [#1](https://github.com/skuzzle/gh-prom-exporter/issues/1) Allow to scrape multiple repository with single call ``` docker pull ${docker.image.name}:${project.version} diff --git a/src/main/java/de/skuzzle/ghpromexporter/scrape/RepositoryMeters.java b/src/main/java/de/skuzzle/ghpromexporter/scrape/RepositoryMeters.java new file mode 100644 index 0000000..6114a00 --- /dev/null +++ b/src/main/java/de/skuzzle/ghpromexporter/scrape/RepositoryMeters.java @@ -0,0 +1,66 @@ +package de.skuzzle.ghpromexporter.scrape; + +import io.prometheus.client.CollectorRegistry; +import io.prometheus.client.Counter; +import io.prometheus.client.Summary; + +public final class RepositoryMeters { + + private static final String LABEL_REPOSITORY = "repository"; + private static final String LABEL_OWNER = "owner"; + private static final String NAMESPACE = "github"; + + private final CollectorRegistry registry; + private final Counter additions; + private final Counter deletions; + private final Counter stargazers; + private final Counter forks; + private final Counter open_issues; + private final Counter subscribers; + private final Counter watchers; + private final Counter size; + private final Summary scrapeDuration; + + public static RepositoryMeters newRegistry() { + return new RepositoryMeters(new CollectorRegistry()); + } + + private RepositoryMeters(CollectorRegistry registry) { + this.registry = registry; + this.additions = Counter.build("additions", "Sum of additions over the last 52 weeks") + .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); + this.deletions = Counter.build("deletions", "Negative sum of deletions over the last 52 weeks") + .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); + this.stargazers = Counter.build("stargazers", "The repository's stargazer count") + .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); + this.forks = Counter.build("forks", "The repository's fork count") + .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); + this.open_issues = Counter.build("open_issues", "The repository's open issue count") + .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); + this.subscribers = Counter.build("subscribers", "The repository's subscriber count") + .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); + this.watchers = Counter.build("watchers", "The repository's watcher count") + .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); + this.size = Counter.build("size", "The repository's size in KB") + .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); + this.scrapeDuration = Summary.build("scrape_duration", "Duration of a single scrape") + .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); + } + + public RepositoryMeters addRepositoryScrapeResults(ScrapeRepositoryRequest repository, RepositoryMetrics metrics) { + additions.labels(repository.owner(), repository.name()).inc(metrics.totalAdditions()); + deletions.labels(repository.owner(), repository.name()).inc(metrics.totalDeletions()); + stargazers.labels(repository.owner(), repository.name()).inc(metrics.stargazersCount()); + forks.labels(repository.owner(), repository.name()).inc(metrics.forkCount()); + open_issues.labels(repository.owner(), repository.name()).inc(metrics.openIssueCount()); + subscribers.labels(repository.owner(), repository.name()).inc(metrics.subscriberCount()); + watchers.labels(repository.owner(), repository.name()).inc(metrics.watchersCount()); + size.labels(repository.owner(), repository.name()).inc(metrics.sizeInKb()); + scrapeDuration.labels(repository.owner(), repository.name()).observe(metrics.scrapeDuration()); + return this; + } + + public CollectorRegistry registry() { + return this.registry; + } +} diff --git a/src/main/java/de/skuzzle/ghpromexporter/scrape/RepositoryMetrics.java b/src/main/java/de/skuzzle/ghpromexporter/scrape/RepositoryMetrics.java index a4a8b1a..e8f51cb 100644 --- a/src/main/java/de/skuzzle/ghpromexporter/scrape/RepositoryMetrics.java +++ b/src/main/java/de/skuzzle/ghpromexporter/scrape/RepositoryMetrics.java @@ -1,9 +1,5 @@ package de.skuzzle.ghpromexporter.scrape; -import io.prometheus.client.CollectorRegistry; -import io.prometheus.client.Counter; -import io.prometheus.client.Summary; - public record RepositoryMetrics( long totalAdditions, long totalDeletions, @@ -13,61 +9,4 @@ public record RepositoryMetrics( int subscriberCount, int watchersCount, int sizeInKb, - long scrapeDuration) { - - public CollectorRegistry toRegistry(ScrapeRepositoryRequest repository) { - final Meters meters = new Meters(); - meters.additions.labels(repository.owner(), repository.name()) - .inc(totalAdditions()); - meters.deletions.labels(repository.owner(), repository.name()) - .inc(totalDeletions()); - meters.stargazers.labels(repository.owner(), repository.name()).inc(stargazersCount()); - meters.forks.labels(repository.owner(), repository.name()).inc(forkCount()); - meters.open_issues.labels(repository.owner(), repository.name()).inc(openIssueCount()); - meters.subscribers.labels(repository.owner(), repository.name()).inc(subscriberCount()); - meters.watchers.labels(repository.owner(), repository.name()).inc(watchersCount()); - meters.size.labels(repository.owner(), repository.name()).inc(sizeInKb()); - meters.scrapeDuration.labels(repository.owner(), repository.name()).observe(scrapeDuration()); - return meters.registry; - } - - private static class Meters { - private static final String LABEL_REPOSITORY = "repository"; - private static final String LABEL_OWNER = "owner"; - private static final String NAMESPACE = "github"; - - private final CollectorRegistry registry; - private final Counter additions; - private final Counter deletions; - private final Counter stargazers; - private final Counter forks; - private final Counter open_issues; - private final Counter subscribers; - private final Counter watchers; - private final Counter size; - private final Summary scrapeDuration; - - public Meters() { - this.registry = new CollectorRegistry(); - this.additions = Counter.build("additions", "TBD") - .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); - this.deletions = Counter.build("deletions", "TBD") - .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); - this.stargazers = Counter.build("stargazers", "The repository's stargazer count") - .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); - this.forks = Counter.build("forks", "The repository's fork count") - .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); - this.open_issues = Counter.build("open_issues", "The repository's open issue count") - .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); - this.subscribers = Counter.build("subscribers", "The repository's subscriber count") - .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); - this.watchers = Counter.build("watchers", "The repository's watcher count") - .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); - this.size = Counter.build("size", "The repository's size in KB") - .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); - this.scrapeDuration = Summary.build("scrape_duration", "Duration of a single scrape") - .namespace(NAMESPACE).labelNames(LABEL_OWNER, LABEL_REPOSITORY).register(registry); - } - - } -} + long scrapeDuration) {} diff --git a/src/main/java/de/skuzzle/ghpromexporter/web/MultipleRepositories.java b/src/main/java/de/skuzzle/ghpromexporter/web/MultipleRepositories.java new file mode 100644 index 0000000..97b5c61 --- /dev/null +++ b/src/main/java/de/skuzzle/ghpromexporter/web/MultipleRepositories.java @@ -0,0 +1,28 @@ +package de.skuzzle.ghpromexporter.web; + +import java.util.Arrays; +import java.util.List; + +import de.skuzzle.ghpromexporter.scrape.ScrapeRepositoryRequest; +import reactor.core.publisher.Flux; + +final class MultipleRepositories { + + private final String owner; + private final List repositories; + + private MultipleRepositories(String owner, List repositories) { + this.owner = owner; + this.repositories = repositories; + } + + public static MultipleRepositories parse(String owner, String repositoriesString) { + final String[] repositories = repositoriesString.split(","); + return new MultipleRepositories(owner, Arrays.asList(repositories)); + } + + Flux requests() { + return Flux.fromStream(repositories.stream() + .map(repository -> ScrapeRepositoryRequest.of(owner, repository))); + } +} diff --git a/src/main/java/de/skuzzle/ghpromexporter/web/PromController.java b/src/main/java/de/skuzzle/ghpromexporter/web/PromController.java index ca8633d..910ce92 100644 --- a/src/main/java/de/skuzzle/ghpromexporter/web/PromController.java +++ b/src/main/java/de/skuzzle/ghpromexporter/web/PromController.java @@ -13,7 +13,8 @@ import de.skuzzle.ghpromexporter.github.AuthenticationProvider; import de.skuzzle.ghpromexporter.github.GitHubAuthentication; import de.skuzzle.ghpromexporter.scrape.AsynchronousScrapeService; -import de.skuzzle.ghpromexporter.scrape.ScrapeRepositoryRequest; +import de.skuzzle.ghpromexporter.scrape.RepositoryMeters; +import io.prometheus.client.CollectorRegistry; import reactor.core.publisher.Mono; @RestController @@ -24,10 +25,10 @@ record PromController( AbuseLimiter abuseLimiter, WebProperties properties) { - @GetMapping(path = "{user}/{repo}") + @GetMapping(path = "{owner}/{repositories}") public Mono> createStats( - @PathVariable String user, - @PathVariable String repo, + @PathVariable String owner, + @PathVariable String repositories, ServerHttpRequest request) { final GitHubAuthentication gitHubAuthentication = authenticationProvider.authenticateRequest(request); @@ -39,10 +40,11 @@ public Mono> createStats( final InetAddress origin = request.getRemoteAddress().getAddress(); final MediaType contentType = MediaType.TEXT_PLAIN;// determineContentType(request); - final ScrapeRepositoryRequest scrapeRepositoryRequest = ScrapeRepositoryRequest.of(user, repo); + + final MultipleRepositories multipleRepositories = MultipleRepositories.parse(owner, repositories); return abuseLimiter.blockAbusers(origin) - .flatMap(__ -> freshResponse(gitHubAuthentication, scrapeRepositoryRequest, contentType)) + .flatMap(__ -> freshResponse(gitHubAuthentication, multipleRepositories, contentType)) .doOnError(e -> abuseLimiter.recordCall(e, origin)) .onErrorResume(e -> Mono.just(ResponseEntity.badRequest().body(e.getMessage()))) .switchIfEmpty( @@ -52,11 +54,21 @@ public Mono> createStats( } private Mono> freshResponse(GitHubAuthentication authentication, - ScrapeRepositoryRequest request, MediaType contentType) { - return scrapeService.scrapeReactive(authentication, request) - .map(result -> serializer.serializeRegistry(result.toRegistry(request), contentType)) + MultipleRepositories repositories, MediaType contentType) { + + return scrapeAll(authentication, repositories) + .map(registry -> serializer.serializeRegistry(registry, contentType)) .map(serializedMetrics -> ResponseEntity.ok() .contentType(contentType) .body(serializedMetrics)); } + + private Mono scrapeAll(GitHubAuthentication authentication, MultipleRepositories repositories) { + final RepositoryMeters meters = RepositoryMeters.newRegistry(); + + return repositories.requests() + .flatMap(req -> scrapeService.scrapeReactive(authentication, req) + .doOnNext(scrapeResult -> meters.addRepositoryScrapeResults(req, scrapeResult))) + .then(Mono.just(meters.registry())); + } } diff --git a/src/test/java/de/skuzzle/ghpromexporter/web/PromControllerTest.java b/src/test/java/de/skuzzle/ghpromexporter/web/PromControllerTest.java index 4aae4a1..cc40dc0 100644 --- a/src/test/java/de/skuzzle/ghpromexporter/web/PromControllerTest.java +++ b/src/test/java/de/skuzzle/ghpromexporter/web/PromControllerTest.java @@ -16,6 +16,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.reactive.function.client.WebClient; +import de.skuzzle.ghpromexporter.github.GitHubAuthentication; import de.skuzzle.test.snapshots.SnapshotAssertions; import de.skuzzle.test.snapshots.SnapshotDsl.Snapshot; import reactor.core.publisher.Mono; @@ -56,60 +57,83 @@ private Mono> getStatsFor(String owner, String repository @Test void scrape_anonymously_forbidden() throws Exception { final var serviceCall = getStatsFor("skuzzle", "test-repo"); + final GitHubAuthentication gitHubAuthentication = successfulAuthenticationForRepository( + withName("skuzzle", "test-repo") + .withStargazerCount(1337)) + .setAnonymous(true); - authentication.with(successfulAuthenticationForRepository(withName("skuzzle", "test-repo") - .withStargazerCount(1337)).setAnonymous(true), () -> { + authentication.with(gitHubAuthentication, () -> { + StepVerifier.create(serviceCall) + .assertNext( + response -> assertThat(response.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED)) + .verifyComplete(); + }); + } - StepVerifier.create(serviceCall) - .assertNext( - response -> assertThat(response.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED)) - .verifyComplete(); - }); + @Test + void scrape_multiple_repositories(Snapshot snapshot) throws Exception { + final var serviceCall = getStatsFor("skuzzle", "test-repo1,test-repo2"); + final var gitHubAuthentication = successfulAuthenticationForRepository( + withName("skuzzle", "test-repo1") + .withForkCount(5)); + + gitHubAuthentication.modify().withRepository(withName("skuzzle", "test-repo2").withStargazerCount(1337)); + authentication.with(gitHubAuthentication, () -> { + StepVerifier.create(serviceCall) + .assertNext(response -> snapshot.assertThat(response.getBody()) + .as(canonicalPrometheusRegistry()) + .matchesSnapshotText()) + .verifyComplete(); + }); } @Test void test_successful_initial_scrape(Snapshot snapshot) throws Exception { final var serviceCall = getStatsFor("skuzzle", "test-repo"); + final GitHubAuthentication gitHubAuthentication = successfulAuthenticationForRepository( + withName("skuzzle", "test-repo") + .withStargazerCount(1337) + .withForkCount(5) + .withOpenIssueCount(2) + .withWatchersCount(1) + .withSubscriberCount(4) + .withAdditions(50) + .withDeletions(-20) + .withSizeInKb(127)); + + authentication.with(gitHubAuthentication, () -> { - authentication.with(successfulAuthenticationForRepository(withName("skuzzle", "test-repo") - .withStargazerCount(1337) - .withForkCount(5) - .withOpenIssueCount(2) - .withWatchersCount(1) - .withSubscriberCount(4) - .withAdditions(50) - .withDeletions(-20) - .withSizeInKb(127)), () -> { - - StepVerifier.create(serviceCall) - .assertNext(response -> snapshot.assertThat(response.getBody()) - .as(canonicalPrometheusRegistry()) - .matchesSnapshotText()) - .verifyComplete(); - }); + StepVerifier.create(serviceCall) + .assertNext(response -> snapshot.assertThat(response.getBody()) + .as(canonicalPrometheusRegistry()) + .matchesSnapshotText()) + .verifyComplete(); + }); } @Test void test_successful_anonymous_scrape(Snapshot snapshot) throws Exception { final var serviceCall = getStatsFor("skuzzle", "test-repo"); webProperties.setAllowAnonymousScrape(true); + final GitHubAuthentication gitHubAuthentication = successfulAuthenticationForRepository( + withName("skuzzle", "test-repo") + .withStargazerCount(1337) + .withForkCount(5) + .withOpenIssueCount(2) + .withWatchersCount(1) + .withSubscriberCount(4) + .withAdditions(50) + .withDeletions(-20) + .withSizeInKb(127)).setAnonymous(true); + + authentication.with(gitHubAuthentication, () -> { - authentication.with(successfulAuthenticationForRepository(withName("skuzzle", "test-repo") - .withStargazerCount(1337) - .withForkCount(5) - .withOpenIssueCount(2) - .withWatchersCount(1) - .withSubscriberCount(4) - .withAdditions(50) - .withDeletions(-20) - .withSizeInKb(127)).setAnonymous(true), () -> { - - StepVerifier.create(serviceCall) - .assertNext(response -> snapshot.assertThat(response.getBody()) - .as(canonicalPrometheusRegistry()) - .matchesSnapshotText()) - .verifyComplete(); - }); + StepVerifier.create(serviceCall) + .assertNext(response -> snapshot.assertThat(response.getBody()) + .as(canonicalPrometheusRegistry()) + .matchesSnapshotText()) + .verifyComplete(); + }); } @Test diff --git a/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/scrape_multiple_repositories_0.snapshot b/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/scrape_multiple_repositories_0.snapshot new file mode 100644 index 0000000..d1ec6dd --- /dev/null +++ b/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/scrape_multiple_repositories_0.snapshot @@ -0,0 +1,54 @@ +# HELP github_additions_created TBD +# HELP github_additions_total TBD +# HELP github_deletions_created TBD +# HELP github_deletions_total TBD +# HELP github_forks_created The repository's fork count +# HELP github_forks_total The repository's fork count +# HELP github_open_issues_created The repository's open issue count +# HELP github_open_issues_total The repository's open issue count +# HELP github_scrape_duration Duration of a single scrape +# HELP github_scrape_duration_created Duration of a single scrape +# HELP github_size_created The repository's size in KB +# HELP github_size_total The repository's size in KB +# HELP github_stargazers_created The repository's stargazer count +# HELP github_stargazers_total The repository's stargazer count +# HELP github_subscribers_created The repository's subscriber count +# HELP github_subscribers_total The repository's subscriber count +# HELP github_watchers_created The repository's watcher count +# HELP github_watchers_total The repository's watcher count +# TYPE github_additions_created gauge +# TYPE github_additions_total counter +# TYPE github_deletions_created gauge +# TYPE github_deletions_total counter +# TYPE github_forks_created gauge +# TYPE github_forks_total counter +# TYPE github_open_issues_created gauge +# TYPE github_open_issues_total counter +# TYPE github_scrape_duration summary +# TYPE github_scrape_duration_created gauge +# TYPE github_size_created gauge +# TYPE github_size_total counter +# TYPE github_stargazers_created gauge +# TYPE github_stargazers_total counter +# TYPE github_subscribers_created gauge +# TYPE github_subscribers_total counter +# TYPE github_watchers_created gauge +# TYPE github_watchers_total counter +github_additions_total{owner="skuzzle",repository="test-repo1",} 0.0 +github_additions_total{owner="skuzzle",repository="test-repo2",} 0.0 +github_deletions_total{owner="skuzzle",repository="test-repo1",} 0.0 +github_deletions_total{owner="skuzzle",repository="test-repo2",} 0.0 +github_forks_total{owner="skuzzle",repository="test-repo1",} 5.0 +github_forks_total{owner="skuzzle",repository="test-repo2",} 0.0 +github_open_issues_total{owner="skuzzle",repository="test-repo1",} 0.0 +github_open_issues_total{owner="skuzzle",repository="test-repo2",} 0.0 +github_scrape_duration_count{owner="skuzzle",repository="test-repo1",} 1.0 +github_scrape_duration_count{owner="skuzzle",repository="test-repo2",} 1.0 +github_size_total{owner="skuzzle",repository="test-repo1",} 0.0 +github_size_total{owner="skuzzle",repository="test-repo2",} 0.0 +github_stargazers_total{owner="skuzzle",repository="test-repo1",} 0.0 +github_stargazers_total{owner="skuzzle",repository="test-repo2",} 1337.0 +github_subscribers_total{owner="skuzzle",repository="test-repo1",} 0.0 +github_subscribers_total{owner="skuzzle",repository="test-repo2",} 0.0 +github_watchers_total{owner="skuzzle",repository="test-repo1",} 0.0 +github_watchers_total{owner="skuzzle",repository="test-repo2",} 0.0 \ No newline at end of file From a7fd9021328045ddc64b43b7a64daf7d1d5c3cb1 Mon Sep 17 00:00:00 2001 From: Simon Taddiken Date: Wed, 22 Dec 2021 09:29:51 +0100 Subject: [PATCH 10/15] Adjust static page --- src/main/resources/templates/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index 704499b..da68bed 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -105,8 +105,8 @@

FAQ

  • I don't want to use the public service. Can I host this on-premise?

    - Not yet, but technically everything is prepared so that you can run this application yourself in a - environment that supports docker containers. + Yes, you can run this exact application yourself using Docker. You can find a detailed explanation on + GitHub.

  • From 160aa2e0c275fd5144bf5e27819a02c42641b209 Mon Sep 17 00:00:00 2001 From: Simon Taddiken Date: Wed, 22 Dec 2021 09:46:22 +0100 Subject: [PATCH 11/15] Attempt to display app version --- src/main/resources/templates/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index da68bed..3db1e58 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -171,6 +171,7 @@

    FAQ

    \ No newline at end of file From e773052b13715c6dcd347a53890c3a40d42e3e8e Mon Sep 17 00:00:00 2001 From: Simon Taddiken Date: Wed, 22 Dec 2021 09:50:02 +0100 Subject: [PATCH 12/15] Remove snapshot --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 84f7c6d..7bf371d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ de.skuzzle skuzzle-parent - 3.0.2-SNAPSHOT + 3.0.2 From 0a6a5a85d91d9bd3f3b7566359f1e39876ed84de Mon Sep 17 00:00:00 2001 From: Simon Taddiken Date: Wed, 22 Dec 2021 09:54:28 +0100 Subject: [PATCH 13/15] Update snapshots --- .../scrape_multiple_repositories_0.snapshot | 8 ++++---- .../test_successful_anonymous_scrape_0.snapshot | 8 ++++---- .../test_successful_initial_scrape_0.snapshot | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/scrape_multiple_repositories_0.snapshot b/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/scrape_multiple_repositories_0.snapshot index d1ec6dd..0c80036 100644 --- a/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/scrape_multiple_repositories_0.snapshot +++ b/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/scrape_multiple_repositories_0.snapshot @@ -1,7 +1,7 @@ -# HELP github_additions_created TBD -# HELP github_additions_total TBD -# HELP github_deletions_created TBD -# HELP github_deletions_total TBD +# HELP github_additions_created Sum of additions over the last 52 weeks +# HELP github_additions_total Sum of additions over the last 52 weeks +# HELP github_deletions_created Negative sum of deletions over the last 52 weeks +# HELP github_deletions_total Negative sum of deletions over the last 52 weeks # HELP github_forks_created The repository's fork count # HELP github_forks_total The repository's fork count # HELP github_open_issues_created The repository's open issue count diff --git a/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/test_successful_anonymous_scrape_0.snapshot b/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/test_successful_anonymous_scrape_0.snapshot index c230075..7669068 100644 --- a/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/test_successful_anonymous_scrape_0.snapshot +++ b/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/test_successful_anonymous_scrape_0.snapshot @@ -1,7 +1,7 @@ -# HELP github_additions_created TBD -# HELP github_additions_total TBD -# HELP github_deletions_created TBD -# HELP github_deletions_total TBD +# HELP github_additions_created Sum of additions over the last 52 weeks +# HELP github_additions_total Sum of additions over the last 52 weeks +# HELP github_deletions_created Negative sum of deletions over the last 52 weeks +# HELP github_deletions_total Negative sum of deletions over the last 52 weeks # HELP github_forks_created The repository's fork count # HELP github_forks_total The repository's fork count # HELP github_open_issues_created The repository's open issue count diff --git a/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/test_successful_initial_scrape_0.snapshot b/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/test_successful_initial_scrape_0.snapshot index c230075..7669068 100644 --- a/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/test_successful_initial_scrape_0.snapshot +++ b/src/test/resources/de/skuzzle/ghpromexporter/web/PromControllerTest_snapshots/test_successful_initial_scrape_0.snapshot @@ -1,7 +1,7 @@ -# HELP github_additions_created TBD -# HELP github_additions_total TBD -# HELP github_deletions_created TBD -# HELP github_deletions_total TBD +# HELP github_additions_created Sum of additions over the last 52 weeks +# HELP github_additions_total Sum of additions over the last 52 weeks +# HELP github_deletions_created Negative sum of deletions over the last 52 weeks +# HELP github_deletions_total Negative sum of deletions over the last 52 weeks # HELP github_forks_created The repository's fork count # HELP github_forks_total The repository's fork count # HELP github_open_issues_created The repository's open issue count From cc889a9da681b3a9f6697dc807ac7d617967060a Mon Sep 17 00:00:00 2001 From: Jenkins Date: Wed, 22 Dec 2021 09:01:44 +0000 Subject: [PATCH 14/15] Update versions for release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7bf371d..bb5fd72 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ de.skuzzle.ghpromexporter gh-prom-exporter - 0.0.5-SNAPSHOT + 0.0.5 gh-prom-exporter Export GitHub repository metrics in prometheus format From cfca257efb90d272fb0649bdd5ac52a14c079aec Mon Sep 17 00:00:00 2001 From: Jenkins Date: Wed, 22 Dec 2021 09:03:25 +0000 Subject: [PATCH 15/15] Update README and RELEASE_NOTES --- README.md | 6 +++--- RELEASE_NOTES.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d23ffa4..4c0569f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Export your favorite GitHub repositories to Prometheus * Use it _as a service_: See https://gh.skuzzle.de for instructions -* Deploy it _on-premise_: `docker pull ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5-SNAPSHOT` +* Deploy it _on-premise_: `docker pull ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5` ## On-Premise deployment with docker This application can easily be run as a docker container in whatever environment you like: @@ -17,7 +17,7 @@ This application can easily be run as a docker container in whatever environment ``` docker run -p 8080:8080 \ -e WEB_ALLOWANONYMOUSSCRAPE=true \ - ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5-SNAPSHOT + ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5 ``` With _anonymous scraping_ allowed, you can now easily view the scrape results directly in the browser by navigating to @@ -37,7 +37,7 @@ scrape_configs: In case you want to enforce authenticated scrapes only, use this configuration instead: ``` docker run -p 8080:8080 \ - ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5-SNAPSHOT + ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5 ``` And diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 01e510f..a5e7aae 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -6,5 +6,5 @@ * [#1](https://github.com/skuzzle/gh-prom-exporter/issues/1) Allow to scrape multiple repository with single call ``` -docker pull ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5-SNAPSHOT +docker pull ghcr.io/skuzzle/gh-prom-exporter/gh-prom-exporter:0.0.5 ``` \ No newline at end of file