diff --git a/Makefile b/Makefile
index 4cfb0063..7adb431c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION=1.7.1
+VERSION=1.8.0
default: compile
@@ -53,11 +53,14 @@ site:
tree:
./gradlew -q dependencies
+depends:
+ ./gradlew dependencies
+
versioncheck:
./gradlew dependencyUpdates
refresh:
./gradlew --refresh-dependencies
-depends:
- ./gradlew dependencies
\ No newline at end of file
+upgrade-wrapper:
+ ./gradlew wrapper --gradle-version=6.6.1 --distribution-type=bin
\ No newline at end of file
diff --git a/README.md b/README.md
index b89889a1..c56b40b8 100644
--- a/README.md
+++ b/README.md
@@ -97,8 +97,8 @@ scrape_configs:
The docker images are available via:
```bash
-docker pull pambrose/prometheus-proxy:1.7.1
-docker pull pambrose/prometheus-agent:1.7.1
+docker pull pambrose/prometheus-proxy:1.8.0
+docker pull pambrose/prometheus-agent:1.8.0
```
Start a proxy container with:
@@ -107,7 +107,7 @@ Start a proxy container with:
docker run --rm -p 8082:8082 -p 8092:8092 -p 50051:50051 -p 8080:8080 \
--env ADMIN_ENABLED=true \
--env METRICS_ENABLED=true \
- pambrose/prometheus-proxy:1.7.1
+ pambrose/prometheus-proxy:1.8.0
```
Start an agent container with:
@@ -115,7 +115,7 @@ Start an agent container with:
```bash
docker run --rm -p 8083:8083 -p 8093:8093 \
--env AGENT_CONFIG='https://raw.githubusercontent.com/pambrose/prometheus-proxy/master/examples/simple.conf' \
- pambrose/prometheus-agent:1.7.1
+ pambrose/prometheus-agent:1.8.0
```
Using the config file [simple.conf](https://raw.githubusercontent.com/pambrose/prometheus-proxy/master/examples/simple.conf),
@@ -131,7 +131,7 @@ is in your current directory, run an agent container with:
docker run --rm -p 8083:8083 -p 8093:8093 \
--mount type=bind,source="$(pwd)"/prom-agent.conf,target=/app/prom-agent.conf \
--env AGENT_CONFIG=prom-agent.conf \
- pambrose/prometheus-agent:1.7.1
+ pambrose/prometheus-agent:1.8.0
```
**Note:** The `WORKDIR` of the proxy and agent images is `/app`, so make sure
@@ -182,8 +182,9 @@ The only required argument is an agent config value, which should have an `agent
| --metrics, -e | METRICS_ENABLED
agent.metrics.enabled | false | Enable agent metrics |
| --metrics_port, -m | METRICS_PORT
agent.metrics.port | 8083 | Agent metrics listen port |
| --consolidated, -o | CONSOLIDATED
agent.consolidated | false | Enable multiple agents per registered path |
+| --timeout | REQUEST_TIMEOUT_SECS
agent.requestTimeoutSecs | 15 | Scrape request timeout time (seconds) |
| --chunk | CHUNK_CONTENT_SIZE_KBS
agent.chunkContentSizeKbs | 32 | Threshold for chunking data to Proxy and buffer size (KBs) |
-| --gzip | MIN_GZIP_SIZE_BYTES
agent.minGzipSizeBytes | 1024 | Minimum size for content to be gzipped (Bytes) |
+| --gzip | MIN_GZIP_SIZE_BYTES
agent.minGzipSizeBytes | 1024 | Minimum size for content to be gzipped (bytes) |
| --cert, -t | CERT_CHAIN_FILE_PATH
agent.tls.certChainFilePath | | Certificate chain file path |
| --key, -k | PRIVATE_KEY_FILE_PATH
agent.tls.privateKeyFilePath | | Private key file path |
| --trust, -s | TRUST_CERT_COLLECTION_FILE_PATH
agent.tls.trustCertCollectionFilePath | | Trust certificate collection file path |
@@ -251,7 +252,7 @@ docker run --rm -p 8082:8082 -p 8092:8092 -p 50440:50440 -p 8080:8080 \
--env PROXY_CONFIG=tls-no-mutual-auth.conf \
--env ADMIN_ENABLED=true \
--env METRICS_ENABLED=true \
- pambrose/prometheus-proxy:1.7.1
+ pambrose/prometheus-proxy:1.8.0
docker run --rm -p 8083:8083 -p 8093:8093 \
--mount type=bind,source="$(pwd)"/testing/certs,target=/app/testing/certs \
@@ -259,7 +260,7 @@ docker run --rm -p 8083:8083 -p 8093:8093 \
--env AGENT_CONFIG=tls-no-mutual-auth.conf \
--env PROXY_HOSTNAME=mymachine.lan:50440 \
--name docker-agent \
- pambrose/prometheus-agent:1.7.1
+ pambrose/prometheus-agent:1.8.0
```
**Note:** The `WORKDIR` of the proxy and agent images is `/app`, so make sure
diff --git a/bin/docker-agent.sh b/bin/docker-agent.sh
index 24cc3d5a..e4fca6fb 100755
--- a/bin/docker-agent.sh
+++ b/bin/docker-agent.sh
@@ -3,4 +3,4 @@
docker run --rm -p 8083:8083 -p 8093:8093 \
--env AGENT_CONFIG='https://raw.githubusercontent.com/pambrose/prometheus-proxy/master/examples/simple.conf' \
--env PROXY_HOSTNAME=mymachine.lan \
- pambrose/prometheus-agent:1.7.1
+ pambrose/prometheus-agent:1.8.0
diff --git a/bin/docker-proxy.sh b/bin/docker-proxy.sh
index 705d2441..59eb08ef 100755
--- a/bin/docker-proxy.sh
+++ b/bin/docker-proxy.sh
@@ -2,4 +2,4 @@
docker run --rm -p 8082:8082 -p 8092:8092 -p 50051:50051 -p 8080:8080 \
--env PROXY_CONFIG='https://raw.githubusercontent.com/pambrose/prometheus-proxy/master/examples/simple.conf' \
- pambrose/prometheus-proxy:1.7.1
+ pambrose/prometheus-proxy:1.8.0
diff --git a/build.gradle b/build.gradle
index b37e07a1..ef674ecf 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,8 +1,8 @@
plugins {
id 'idea'
id 'java'
- id 'org.jetbrains.kotlin.jvm' version '1.3.72'
- id 'org.jetbrains.kotlin.plugin.serialization' version '1.3.72'
+ id 'org.jetbrains.kotlin.jvm' version '1.4.0'
+ id 'org.jetbrains.kotlin.plugin.serialization' version '1.4.0'
id 'com.google.protobuf' version '0.8.12'
id "com.github.ben-manes.versions" version '0.29.0'
id 'com.github.johnrengelman.shadow' version '6.0.0'
@@ -11,14 +11,15 @@ plugins {
}
group = 'io.prometheus'
-version = '1.7.1'
+version = '1.8.0'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
- maven { url = "https://kotlin.bintray.com/kotlinx" }
- maven { url = 'https://maven-central.storage-download.googleapis.com/repos/central/data/' }
+ maven { url 'https://kotlin.bintray.com/ktor' }
+ maven { url 'https://kotlin.bintray.com/kotlinx' }
+ maven { url 'https://maven-central.storage-download.googleapis.com/repos/central/data/' }
jcenter()
maven { url = 'https://jitpack.io' }
}
@@ -27,10 +28,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation "org.jetbrains.kotlin:kotlin-reflect"
- implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$coroutines_version"
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:$coroutines_version"
//implementation "io.grpc:grpc-netty-shaded:${grpc_version}"
implementation "io.grpc:grpc-netty:${grpc_version}"
@@ -116,12 +114,10 @@ compileKotlin {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs += ['-Xuse-experimental=kotlin.time.ExperimentalTime',
- '-Xuse-experimental=kotlinx.serialization.UnstableDefault',
'-Xuse-experimental=kotlin.ExperimentalUnsignedTypes',
'-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi',
'-Xuse-experimental=kotlinx.coroutines.InternalCoroutinesApi',
- '-Xuse-experimental=io.ktor.util.KtorExperimentalAPI',
- '-Xuse-experimental=kotlinx.serialization.UnstableDefault']
+ '-Xuse-experimental=io.ktor.util.KtorExperimentalAPI']
}
}
@@ -129,12 +125,10 @@ compileTestKotlin {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs += ['-Xuse-experimental=kotlin.time.ExperimentalTime',
- '-Xuse-experimental=kotlinx.serialization.UnstableDefault',
'-Xuse-experimental=kotlin.ExperimentalUnsignedTypes',
'-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi',
'-Xuse-experimental=kotlinx.coroutines.InternalCoroutinesApi',
- '-Xuse-experimental=io.ktor.util.KtorExperimentalAPI',
- '-Xuse-experimental=kotlinx.serialization.UnstableDefault']
+ '-Xuse-experimental=io.ktor.util.KtorExperimentalAPI']
}
}
diff --git a/docs/release.md b/docs/release.md
index 68cc202e..08b90fb8 100644
--- a/docs/release.md
+++ b/docs/release.md
@@ -6,7 +6,7 @@
3) Modify code
-4) Update the release date in *package-info.java*
+4) Update the release date in Agent.kt and Proxy.kt
5) Verify tests run cleanly before merge with: `make tests`
diff --git a/etc/compose/proxy.yml b/etc/compose/proxy.yml
index 6829973f..430ab3a0 100644
--- a/etc/compose/proxy.yml
+++ b/etc/compose/proxy.yml
@@ -1,6 +1,6 @@
prometheus-proxy:
autoredeploy: true
- image: 'pambrose/prometheus-proxy:1.7.1'
+ image: 'pambrose/prometheus-proxy:1.8.0'
ports:
- '8080:8080'
- '8082:8082'
diff --git a/etc/config/config.conf b/etc/config/config.conf
index 35add358..eb8aff1f 100644
--- a/etc/config/config.conf
+++ b/etc/config/config.conf
@@ -8,6 +8,7 @@ proxy {
maxThreads = -1
minThreads = -1
idleTimeoutSecs = 45
+ requestLoggingEnabled = true // Log every proxy metrics request
}
admin {
@@ -47,11 +48,11 @@ proxy {
internal {
staleAgentCheckEnabled = true
- maxAgentInactivitySecs = 15 // Seconds of inactivity before agent is evicted
- staleAgentCheckPauseSecs = 10 // Pause interval for agent cleanup
+ maxAgentInactivitySecs = 15 // Seconds of inactivity before agent is evicted in seconds
+ staleAgentCheckPauseSecs = 10 // Pause interval for agent cleanup in seconds
- scrapeRequestTimeoutSecs = 5 // Timeout for scrape requests
- scrapeRequestCheckMillis = 500 // Pause time between checks for scrape request timeout
+ scrapeRequestTimeoutSecs = 60 // Timeout for scrape requests in seconds
+ scrapeRequestCheckMillis = 500 // Pause time between checks for scrape request timeout in millis
scrapeRequestBacklogUnhealthySize = 25 // Threshold for returning an unhealthy healthcheck
scrapeRequestMapUnhealthySize = 25 // Threshold for returning an unhealthy healthcheck
@@ -82,6 +83,8 @@ agent {
chunkContentSizeKbs = 32 // Threshold for chunking data to Proxy and buffer size
minGzipSizeBytes = 512 // Minimum size for content to be gzipped
+ scrapeTimeoutSecs = 15 // Scrape timeout in seconds
+
proxy {
hostname = "localhost" // Proxy hostname
port = 50051 // Proxy port
diff --git a/examples/simple.conf b/examples/simple.conf
index 9b0aabab..f45bb2d7 100644
--- a/examples/simple.conf
+++ b/examples/simple.conf
@@ -3,6 +3,8 @@ proxy {
admin.enabled: true
metrics.enabled: true
+
+ http.requestLoggingEnabled: true
}
agent {
diff --git a/gradle.properties b/gradle.properties
index 30783469..441779a5 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,21 +6,20 @@ org.gradle.parallel=true
org.gradle.caching=true
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
annotation_version=1.3.2
-coroutines_version=1.3.6
-dropwizard_version=4.1.11
-gengrpc_version=0.1.4
-grpc_version=1.31.0
+coroutines_version=1.3.9
+dropwizard_version=4.1.12.1
+gengrpc_version=0.1.5
+grpc_version=1.31.1
jcommander_version=1.78
-jetty_version=9.4.22.v20191022
+jetty_version=9.4.24.v20191120
junit_version=5.6.1
kluent_version=1.61
-ktor_version=1.3.2
+ktor_version=1.4.0
logback_version=1.2.3
logging_version=1.8.3
prometheus_version=0.9.0
-protoc_version=3.12.3
-serialization_version=0.20.0-1.3.70-eap-274-2
-slf4j_version=1.7.28
+protoc_version=3.12.4
+slf4j_version=1.7.30
typesafe_version=1.4.0
-utils_version=1.1.20
-zipkin_version=5.12.4
\ No newline at end of file
+utils_version=1.3.0
+zipkin_version=5.12.5
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 62d4c053..e708b1c0 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 6c9a2247..12d38de6 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index fbd7c515..4f906e0c 100755
--- a/gradlew
+++ b/gradlew
@@ -130,7 +130,7 @@ fi
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
+
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
diff --git a/gradlew.bat b/gradlew.bat
index 5093609d..107acd32 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
+if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -54,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-if exist "%JAVA_EXE%" goto init
+if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -64,21 +64,6 @@ echo location of your Java installation.
goto fail
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
:execute
@rem Setup the command line
@@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
diff --git a/src/main/java/io/prometheus/common/ConfigVals.java b/src/main/java/io/prometheus/common/ConfigVals.java
index 5ca4473b..4a583386 100644
--- a/src/main/java/io/prometheus/common/ConfigVals.java
+++ b/src/main/java/io/prometheus/common/ConfigVals.java
@@ -1,4 +1,4 @@
-// generated by tscfg 0.9.98 on Sun Aug 09 16:05:51 PDT 2020
+// generated by tscfg 0.9.98 on Fri Aug 28 11:59:55 PDT 2020
// source: etc/config/config.conf
package io.prometheus.common;
@@ -6,7 +6,6 @@
public class ConfigVals {
public final ConfigVals.Agent agent;
public final ConfigVals.Proxy2 proxy;
-
public ConfigVals(com.typesafe.config.Config c) {
final $TsCfgValidator $tsCfgValidator = new $TsCfgValidator();
final java.lang.String parentPath = "";
@@ -25,8 +24,8 @@ public static class Agent {
public final java.lang.String name;
public final java.util.List pathConfigs;
public final Agent.Proxy proxy;
+ public final int scrapeTimeoutSecs;
public final Agent.Tls tls;
-
public Agent(com.typesafe.config.Config c, java.lang.String parentPath, $TsCfgValidator $tsCfgValidator) {
this.admin = c.hasPathOrNull("admin") ? new Agent.Admin(c.getConfig("admin"), parentPath + "admin.", $tsCfgValidator) : new Agent.Admin(com.typesafe.config.ConfigFactory.parseString("admin{}"), parentPath + "admin.", $tsCfgValidator);
this.chunkContentSizeKbs = c.hasPathOrNull("chunkContentSizeKbs") ? c.getInt("chunkContentSizeKbs") : 32;
@@ -37,6 +36,7 @@ public Agent(com.typesafe.config.Config c, java.lang.String parentPath, $TsCfgVa
this.name = c.hasPathOrNull("name") ? c.getString("name") : "";
this.pathConfigs = $_LAgent_PathConfigs$Elm(c.getList("pathConfigs"), parentPath, $tsCfgValidator);
this.proxy = c.hasPathOrNull("proxy") ? new Agent.Proxy(c.getConfig("proxy"), parentPath + "proxy.", $tsCfgValidator) : new Agent.Proxy(com.typesafe.config.ConfigFactory.parseString("proxy{}"), parentPath + "proxy.", $tsCfgValidator);
+ this.scrapeTimeoutSecs = c.hasPathOrNull("scrapeTimeoutSecs") ? c.getInt("scrapeTimeoutSecs") : 15;
this.tls = c.hasPathOrNull("tls") ? new Agent.Tls(c.getConfig("tls"), parentPath + "tls.", $tsCfgValidator) : new Agent.Tls(com.typesafe.config.ConfigFactory.parseString("tls{}"), parentPath + "tls.", $tsCfgValidator);
}
@@ -75,7 +75,6 @@ public static class Internal {
public final int reconnectPauseSecs;
public final int scrapeRequestBacklogUnhealthySize;
public final Internal.Zipkin zipkin;
-
public Internal(com.typesafe.config.Config c, java.lang.String parentPath, $TsCfgValidator $tsCfgValidator) {
this.heartbeatCheckPauseMillis = c.hasPathOrNull("heartbeatCheckPauseMillis") ? c.getInt("heartbeatCheckPauseMillis") : 500;
this.heartbeatEnabled = !c.hasPathOrNull("heartbeatEnabled") || c.getBoolean("heartbeatEnabled");
@@ -115,6 +114,15 @@ public static class Metrics {
public final boolean standardExportsEnabled;
public final boolean threadExportsEnabled;
public final boolean versionInfoExportsEnabled;
+ public static class Grpc {
+ public final boolean allMetricsReported;
+ public final boolean metricsEnabled;
+
+ public Grpc(com.typesafe.config.Config c, java.lang.String parentPath, $TsCfgValidator $tsCfgValidator) {
+ this.allMetricsReported = c.hasPathOrNull("allMetricsReported") && c.getBoolean("allMetricsReported");
+ this.metricsEnabled = c.hasPathOrNull("metricsEnabled") && c.getBoolean("metricsEnabled");
+ }
+ }
public Metrics(com.typesafe.config.Config c, java.lang.String parentPath, $TsCfgValidator $tsCfgValidator) {
this.classLoadingExportsEnabled = c.hasPathOrNull("classLoadingExportsEnabled") && c.getBoolean("classLoadingExportsEnabled");
@@ -128,16 +136,6 @@ public Metrics(com.typesafe.config.Config c, java.lang.String parentPath, $TsCfg
this.threadExportsEnabled = c.hasPathOrNull("threadExportsEnabled") && c.getBoolean("threadExportsEnabled");
this.versionInfoExportsEnabled = c.hasPathOrNull("versionInfoExportsEnabled") && c.getBoolean("versionInfoExportsEnabled");
}
-
- public static class Grpc {
- public final boolean allMetricsReported;
- public final boolean metricsEnabled;
-
- public Grpc(com.typesafe.config.Config c, java.lang.String parentPath, $TsCfgValidator $tsCfgValidator) {
- this.allMetricsReported = c.hasPathOrNull("allMetricsReported") && c.getBoolean("allMetricsReported");
- this.metricsEnabled = c.hasPathOrNull("metricsEnabled") && c.getBoolean("metricsEnabled");
- }
- }
}
public static class PathConfigs$Elm {
@@ -150,7 +148,6 @@ public static class PathConfigs$Elm {
this.path = $_reqStr(parentPath, c, "path", $tsCfgValidator);
this.url = $_reqStr(parentPath, c, "url", $tsCfgValidator);
}
-
private static java.lang.String $_reqStr(java.lang.String parentPath, com.typesafe.config.Config c, java.lang.String path, $TsCfgValidator $tsCfgValidator) {
if (c == null) return null;
try {
@@ -195,7 +192,6 @@ public static class Proxy2 {
public final Proxy2.Internal2 internal;
public final Proxy2.Metrics2 metrics;
public final Proxy2.Tls2 tls;
-
public Proxy2(com.typesafe.config.Config c, java.lang.String parentPath, $TsCfgValidator $tsCfgValidator) {
this.admin = c.hasPathOrNull("admin") ? new Proxy2.Admin2(c.getConfig("admin"), parentPath + "admin.", $tsCfgValidator) : new Proxy2.Admin2(com.typesafe.config.ConfigFactory.parseString("admin{}"), parentPath + "admin.", $tsCfgValidator);
this.agent = c.hasPathOrNull("agent") ? new Proxy2.Agent2(c.getConfig("agent"), parentPath + "agent.", $tsCfgValidator) : new Proxy2.Agent2(com.typesafe.config.ConfigFactory.parseString("agent{}"), parentPath + "agent.", $tsCfgValidator);
@@ -240,12 +236,14 @@ public static class Http {
public final int maxThreads;
public final int minThreads;
public final int port;
+ public final boolean requestLoggingEnabled;
public Http(com.typesafe.config.Config c, java.lang.String parentPath, $TsCfgValidator $tsCfgValidator) {
this.idleTimeoutSecs = c.hasPathOrNull("idleTimeoutSecs") ? c.getInt("idleTimeoutSecs") : 45;
this.maxThreads = c.hasPathOrNull("maxThreads") ? c.getInt("maxThreads") : -1;
this.minThreads = c.hasPathOrNull("minThreads") ? c.getInt("minThreads") : -1;
this.port = c.hasPathOrNull("port") ? c.getInt("port") : 8080;
+ this.requestLoggingEnabled = !c.hasPathOrNull("requestLoggingEnabled") || c.getBoolean("requestLoggingEnabled");
}
}
@@ -260,7 +258,6 @@ public static class Internal2 {
public final boolean staleAgentCheckEnabled;
public final int staleAgentCheckPauseSecs;
public final Internal2.Zipkin2 zipkin;
-
public Internal2(com.typesafe.config.Config c, java.lang.String parentPath, $TsCfgValidator $tsCfgValidator) {
this.blitz = c.hasPathOrNull("blitz") ? new Internal2.Blitz(c.getConfig("blitz"), parentPath + "blitz.", $tsCfgValidator) : new Internal2.Blitz(com.typesafe.config.ConfigFactory.parseString("blitz{}"), parentPath + "blitz.", $tsCfgValidator);
this.chunkContextMapUnhealthySize = c.hasPathOrNull("chunkContextMapUnhealthySize") ? c.getInt("chunkContextMapUnhealthySize") : 25;
@@ -268,7 +265,7 @@ public Internal2(com.typesafe.config.Config c, java.lang.String parentPath, $TsC
this.scrapeRequestBacklogUnhealthySize = c.hasPathOrNull("scrapeRequestBacklogUnhealthySize") ? c.getInt("scrapeRequestBacklogUnhealthySize") : 25;
this.scrapeRequestCheckMillis = c.hasPathOrNull("scrapeRequestCheckMillis") ? c.getInt("scrapeRequestCheckMillis") : 500;
this.scrapeRequestMapUnhealthySize = c.hasPathOrNull("scrapeRequestMapUnhealthySize") ? c.getInt("scrapeRequestMapUnhealthySize") : 25;
- this.scrapeRequestTimeoutSecs = c.hasPathOrNull("scrapeRequestTimeoutSecs") ? c.getInt("scrapeRequestTimeoutSecs") : 5;
+ this.scrapeRequestTimeoutSecs = c.hasPathOrNull("scrapeRequestTimeoutSecs") ? c.getInt("scrapeRequestTimeoutSecs") : 60;
this.staleAgentCheckEnabled = !c.hasPathOrNull("staleAgentCheckEnabled") || c.getBoolean("staleAgentCheckEnabled");
this.staleAgentCheckPauseSecs = c.hasPathOrNull("staleAgentCheckPauseSecs") ? c.getInt("staleAgentCheckPauseSecs") : 10;
this.zipkin = c.hasPathOrNull("zipkin") ? new Internal2.Zipkin2(c.getConfig("zipkin"), parentPath + "zipkin.", $tsCfgValidator) : new Internal2.Zipkin2(com.typesafe.config.ConfigFactory.parseString("zipkin{}"), parentPath + "zipkin.", $tsCfgValidator);
@@ -314,6 +311,15 @@ public static class Metrics2 {
public final boolean standardExportsEnabled;
public final boolean threadExportsEnabled;
public final boolean versionInfoExportsEnabled;
+ public static class Grpc2 {
+ public final boolean allMetricsReported;
+ public final boolean metricsEnabled;
+
+ public Grpc2(com.typesafe.config.Config c, java.lang.String parentPath, $TsCfgValidator $tsCfgValidator) {
+ this.allMetricsReported = c.hasPathOrNull("allMetricsReported") && c.getBoolean("allMetricsReported");
+ this.metricsEnabled = c.hasPathOrNull("metricsEnabled") && c.getBoolean("metricsEnabled");
+ }
+ }
public Metrics2(com.typesafe.config.Config c, java.lang.String parentPath, $TsCfgValidator $tsCfgValidator) {
this.classLoadingExportsEnabled = c.hasPathOrNull("classLoadingExportsEnabled") && c.getBoolean("classLoadingExportsEnabled");
@@ -327,16 +333,6 @@ public Metrics2(com.typesafe.config.Config c, java.lang.String parentPath, $TsCf
this.threadExportsEnabled = c.hasPathOrNull("threadExportsEnabled") && c.getBoolean("threadExportsEnabled");
this.versionInfoExportsEnabled = c.hasPathOrNull("versionInfoExportsEnabled") && c.getBoolean("versionInfoExportsEnabled");
}
-
- public static class Grpc2 {
- public final boolean allMetricsReported;
- public final boolean metricsEnabled;
-
- public Grpc2(com.typesafe.config.Config c, java.lang.String parentPath, $TsCfgValidator $tsCfgValidator) {
- this.allMetricsReported = c.hasPathOrNull("allMetricsReported") && c.getBoolean("allMetricsReported");
- this.metricsEnabled = c.hasPathOrNull("metricsEnabled") && c.getBoolean("metricsEnabled");
- }
- }
}
public static class Tls2 {
diff --git a/src/main/kotlin/io/prometheus/Agent.kt b/src/main/kotlin/io/prometheus/Agent.kt
index 5ca00ee6..78fb5db3 100644
--- a/src/main/kotlin/io/prometheus/Agent.kt
+++ b/src/main/kotlin/io/prometheus/Agent.kt
@@ -24,11 +24,8 @@ import com.github.pambrose.common.dsl.GuavaDsl.toStringElements
import com.github.pambrose.common.service.GenericService
import com.github.pambrose.common.servlet.LambdaServlet
import com.github.pambrose.common.time.format
+import com.github.pambrose.common.util.*
import com.github.pambrose.common.util.MetricsUtils.newBacklogHealthCheck
-import com.github.pambrose.common.util.getBanner
-import com.github.pambrose.common.util.hostInfo
-import com.github.pambrose.common.util.randomId
-import com.github.pambrose.common.util.simpleClassName
import com.google.common.util.concurrent.RateLimiter
import io.grpc.Status
import io.grpc.StatusException
@@ -41,11 +38,11 @@ import io.prometheus.common.ConfigWrappers.newAdminConfig
import io.prometheus.common.ConfigWrappers.newMetricsConfig
import io.prometheus.common.ConfigWrappers.newZipkinConfig
import io.prometheus.common.getVersionDesc
-import kotlinx.atomicfu.atomic
import kotlinx.coroutines.*
import mu.KLogging
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit.MILLISECONDS
+import java.util.concurrent.atomic.AtomicInteger
import kotlin.math.roundToInt
import kotlin.time.Duration
import kotlin.time.TimeMark
@@ -53,6 +50,7 @@ import kotlin.time.TimeSource.Monotonic
import kotlin.time.milliseconds
import kotlin.time.seconds
+@Version(version = "1.8.0", date = "8/28/20")
class Agent(val options: AgentOptions,
inProcessServerName: String = "",
testMode: Boolean = false,
@@ -76,7 +74,7 @@ class Agent(val options: AgentOptions,
private var lastMsgSentMark: TimeMark by nonNullableReference(clock.markNow())
internal val agentName = if (options.agentName.isBlank()) "Unnamed-${hostInfo.hostName}" else options.agentName
- internal val scrapeRequestBacklogSize = atomic(0)
+ internal val scrapeRequestBacklogSize = AtomicInteger(0)
internal val pathManager = AgentPathManager(this)
internal val grpcService = AgentGrpcService(this, options, inProcessServerName)
internal var agentId: String by nonNullableReference("")
@@ -100,8 +98,9 @@ class Agent(val options: AgentOptions,
""".trimIndent()
- logger.info { "Assigned agent name: $agentName" }
- logger.info { "Assigned proxy reconnect pause time: ${agentConfigVals.reconnectPauseSecs.seconds}" }
+ logger.info { "Agent name: $agentName" }
+ logger.info { "Proxy reconnect pause time: ${agentConfigVals.reconnectPauseSecs.seconds}" }
+ logger.info { "Scrape timeout time: ${configVals.agent.scrapeTimeoutSecs.seconds}" }
initService {
if (options.debugEnabled) {
@@ -137,7 +136,7 @@ class Agent(val options: AgentOptions,
// Reset values for each connection attempt
pathManager.clear()
- scrapeRequestBacklogSize.value = 0
+ scrapeRequestBacklogSize.set(0)
lastMsgSentMark = clock.markNow()
if (grpcService.connectAgent()) {
@@ -209,7 +208,7 @@ class Agent(val options: AgentOptions,
healthCheckRegistry.register(
"scrape_request_backlog_check",
newBacklogHealthCheck(
- scrapeRequestBacklogSize.value,
+ scrapeRequestBacklogSize.get(),
agentConfigVals.scrapeRequestBacklogUnhealthySize
)
)
@@ -280,11 +279,14 @@ class Agent(val options: AgentOptions,
}
@JvmStatic
- fun startAsyncAgent(configFilename: String, exitOnMissingConfig: Boolean): EmbeddedAgentInfo {
- logger.apply {
- info { getBanner("banners/agent.txt", this) }
- info { getVersionDesc() }
- }
+ fun startAsyncAgent(configFilename: String,
+ exitOnMissingConfig: Boolean,
+ logBanner: Boolean = true): EmbeddedAgentInfo {
+ if (logBanner)
+ logger.apply {
+ info { getBanner("banners/agent.txt", this) }
+ info { getVersionDesc() }
+ }
val agent = Agent(options = AgentOptions(configFilename, exitOnMissingConfig)) { startAsync() }
return EmbeddedAgentInfo(agent.launchId, agent.agentName)
}
diff --git a/src/main/kotlin/io/prometheus/Proxy.kt b/src/main/kotlin/io/prometheus/Proxy.kt
index 4762129c..c22e332e 100644
--- a/src/main/kotlin/io/prometheus/Proxy.kt
+++ b/src/main/kotlin/io/prometheus/Proxy.kt
@@ -45,7 +45,7 @@ import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import kotlin.time.milliseconds
-@Version(version = "1.7.1", date = "8/12/20")
+@Version(version = "1.8.0", date = "8/28/20")
class Proxy(val options: ProxyOptions,
proxyHttpPort: Int = options.proxyHttpPort,
inProcessServerName: String = "",
@@ -63,7 +63,7 @@ class Proxy(val options: ProxyOptions,
isTestMode = testMode) {
private val proxyConfigVals: ConfigVals.Proxy2.Internal2 = configVals.proxy.internal
- private val httpService = ProxyHttpService(this, proxyHttpPort)
+ private val httpService = ProxyHttpService(this, proxyHttpPort, isTestMode)
private val recentActions: EvictingQueue =
EvictingQueue.create(configVals.proxy.admin.recentRequestsQueueSize)
private val grpcService =
diff --git a/src/main/kotlin/io/prometheus/agent/AgentGrpcService.kt b/src/main/kotlin/io/prometheus/agent/AgentGrpcService.kt
index 5083ce08..7de29569 100644
--- a/src/main/kotlin/io/prometheus/agent/AgentGrpcService.kt
+++ b/src/main/kotlin/io/prometheus/agent/AgentGrpcService.kt
@@ -206,20 +206,21 @@ internal class AgentGrpcService(internal val agent: Agent,
suspend fun sendHeartBeat() {
if (agent.agentId.isEmpty())
return
-
- try {
- val request = GrpcObjects.newHeartBeatRequest(agent.agentId)
- stub.sendHeartBeat(request)
- .apply {
- agent.markMsgSent()
- if (!valid) {
- logger.error { "AgentId ${agent.agentId} not found on proxy" }
- throw StatusRuntimeException(Status.NOT_FOUND)
+ else {
+ try {
+ val request = GrpcObjects.newHeartBeatRequest(agent.agentId)
+ stub.sendHeartBeat(request)
+ .apply {
+ agent.markMsgSent()
+ if (!valid) {
+ logger.error { "AgentId ${agent.agentId} not found on proxy" }
+ throw StatusRuntimeException(Status.NOT_FOUND)
+ }
}
- }
- }
- catch (e: StatusRuntimeException) {
- logger.error { "Hearbeat failed ${e.status}" }
+ }
+ catch (e: StatusRuntimeException) {
+ logger.error { "Hearbeat failed ${e.status}" }
+ }
}
}
@@ -227,13 +228,13 @@ internal class AgentGrpcService(internal val agent: Agent,
connectionContext
.use {
val agentInfo = newAgentInfo(agent.agentId)
- val replies = stub.readRequestsFromProxy(agentInfo)
- replies.collect { request: ScrapeRequest ->
- // The actual fetch happens at the other end of the channel, not here.
- logger.debug { "readRequestsFromProxy():\n$request" }
- connectionContext.scrapeRequestsChannel.send { agentHttpService.fetchScrapeUrl(request) }
- agent.scrapeRequestBacklogSize.incrementAndGet()
- }
+ stub.readRequestsFromProxy(agentInfo)
+ .collect { request: ScrapeRequest ->
+ // The actual fetch happens at the other end of the channel, not here.
+ logger.debug { "readRequestsFromProxy():\n$request" }
+ connectionContext.scrapeRequestsChannel.send { agentHttpService.fetchScrapeUrl(request) }
+ agent.scrapeRequestBacklogSize.incrementAndGet()
+ }
}
}
diff --git a/src/main/kotlin/io/prometheus/agent/AgentHttpService.kt b/src/main/kotlin/io/prometheus/agent/AgentHttpService.kt
index 409d657a..5fac1006 100644
--- a/src/main/kotlin/io/prometheus/agent/AgentHttpService.kt
+++ b/src/main/kotlin/io/prometheus/agent/AgentHttpService.kt
@@ -24,11 +24,10 @@ import com.github.pambrose.common.util.isNull
import com.github.pambrose.common.util.simpleClassName
import com.github.pambrose.common.util.zip
import com.google.common.net.HttpHeaders
-import io.ktor.client.request.HttpRequestBuilder
-import io.ktor.client.request.header
-import io.ktor.client.statement.HttpResponse
-import io.ktor.client.statement.readText
-import io.ktor.http.isSuccess
+import io.ktor.client.features.*
+import io.ktor.client.request.*
+import io.ktor.client.statement.*
+import io.ktor.http.*
import io.prometheus.Agent
import io.prometheus.common.ScrapeResults
import io.prometheus.grpc.ScrapeRequest
@@ -36,11 +35,13 @@ import mu.KLogging
import java.io.IOException
import java.net.URLDecoder
import java.util.concurrent.atomic.AtomicReference
+import kotlin.time.seconds
internal class AgentHttpService(val agent: Agent) {
suspend fun fetchScrapeUrl(request: ScrapeRequest): ScrapeResults =
- ScrapeResults(agentId = request.agentId, scrapeId = request.scrapeId).also { scrapeResults ->
+ ScrapeResults(agentId = request.agentId,
+ scrapeId = request.scrapeId).also { scrapeResults ->
val scrapeMsg = AtomicReference("")
val path = request.path
val encodedQueryParams = request.encodedQueryParams
@@ -64,19 +65,41 @@ internal class AgentHttpService(val agent: Agent) {
if (encodedQueryParams.isNotEmpty())
logger.debug { "URL: $url" }
+ val scrapeTimeout = agent.options.configVals.agent.scrapeTimeoutSecs.seconds
+
// Content is fetched here
try {
withHttpClient {
- get(url, setup(request), getBlock(url, scrapeResults, scrapeMsg, request.debugEnabled))
+ get(url,
+ {
+ val accept: String? = request.accept
+ if (accept?.isNotEmpty() == true) header(HttpHeaders.ACCEPT, accept)
+ timeout { requestTimeoutMillis = scrapeTimeout.toLongMilliseconds() }
+ },
+ getBlock(url, scrapeResults, scrapeMsg, request.debugEnabled))
}
}
+ catch (e: HttpRequestTimeoutException) {
+ logger.warn(e) { "fetchScrapeUrl() $e - $url" }
+ scrapeResults.statusCode = HttpStatusCode.RequestTimeout.value
+ scrapeResults.failureReason = e.message ?: e.simpleClassName
+
+ if (request.debugEnabled)
+ scrapeResults.setDebugInfo(url, "${e.simpleClassName} - ${e.message}")
+ }
catch (e: IOException) {
logger.info { "Failed HTTP request: $url [${e.simpleClassName}: ${e.message}]" }
+ scrapeResults.statusCode = HttpStatusCode.NotFound.value
+ scrapeResults.failureReason = e.message ?: e.simpleClassName
+
if (request.debugEnabled)
scrapeResults.setDebugInfo(url, "${e.simpleClassName} - ${e.message}")
}
catch (e: Throwable) {
logger.warn(e) { "fetchScrapeUrl() $e - $url" }
+ scrapeResults.failureReason = e.message ?: e.simpleClassName
+ scrapeResults.statusCode = HttpStatusCode.ServiceUnavailable.value
+
if (request.debugEnabled)
scrapeResults.setDebugInfo(url, "${e.simpleClassName} - ${e.message}")
}
@@ -88,12 +111,6 @@ internal class AgentHttpService(val agent: Agent) {
agent.updateScrapeCounter(agent, scrapeMsg.get())
}
- private fun setup(request: ScrapeRequest): HttpRequestBuilder.() -> Unit = {
- val accept: String? = request.accept
- if (accept?.isNotEmpty() == true)
- header(HttpHeaders.ACCEPT, accept)
- }
-
private fun getBlock(url: String,
responseArg: ScrapeResults,
scrapeCounterMsg: AtomicReference,
diff --git a/src/main/kotlin/io/prometheus/agent/AgentMetrics.kt b/src/main/kotlin/io/prometheus/agent/AgentMetrics.kt
index 09b23dd3..61ae693d 100644
--- a/src/main/kotlin/io/prometheus/agent/AgentMetrics.kt
+++ b/src/main/kotlin/io/prometheus/agent/AgentMetrics.kt
@@ -65,7 +65,7 @@ internal class AgentMetrics(agent: Agent) {
"Agent scrape backlog size",
labelNames = listOf(LAUNCH_ID),
labelValues = listOf(agent.launchId),
- data = { agent.scrapeRequestBacklogSize.value.toDouble() })
+ data = { agent.scrapeRequestBacklogSize.get().toDouble() })
}
companion object {
diff --git a/src/main/kotlin/io/prometheus/agent/AgentOptions.kt b/src/main/kotlin/io/prometheus/agent/AgentOptions.kt
index 0aa04cf2..c82301a9 100644
--- a/src/main/kotlin/io/prometheus/agent/AgentOptions.kt
+++ b/src/main/kotlin/io/prometheus/agent/AgentOptions.kt
@@ -23,6 +23,8 @@ import com.google.common.collect.Iterables
import io.prometheus.Agent
import io.prometheus.common.BaseOptions
import io.prometheus.common.EnvVars.*
+import mu.KLogging
+import kotlin.time.seconds
class AgentOptions(argv: Array, exitOnMissingConfig: Boolean) :
BaseOptions(Agent::class.java.name, argv, AGENT_CONFIG.name, exitOnMissingConfig) {
@@ -49,11 +51,15 @@ class AgentOptions(argv: Array, exitOnMissingConfig: Boolean) :
var overrideAuthority = ""
private set
+ @Parameter(names = ["--timeout"], description = "Scrape timeout time (seconds)")
+ var scrapeTimeoutSecs = -1
+ private set
+
@Parameter(names = ["--chunk"], description = "Threshold for chunking content to Proxy and buffer size (KBs)")
var chunkContentSizeKbs = -1
private set
- @Parameter(names = ["--gzip"], description = "Minimum size for content to be gzipped (Bytes)")
+ @Parameter(names = ["--gzip"], description = "Minimum size for content to be gzipped (bytes)")
var minGzipSizeBytes = -1
private set
@@ -64,6 +70,7 @@ class AgentOptions(argv: Array, exitOnMissingConfig: Boolean) :
override fun assignConfigVals() {
configVals.agent.also { agent ->
+
if (proxyHostname.isEmpty()) {
val configHostname = agent.proxy.hostname
proxyHostname = PROXY_HOSTNAME.getEnv(if (":" in configHostname)
@@ -71,23 +78,34 @@ class AgentOptions(argv: Array, exitOnMissingConfig: Boolean) :
else
"$configHostname:${agent.proxy.port}")
}
+ logger.info { "proxyHostname: $proxyHostname" }
+
if (agentName.isEmpty())
agentName = AGENT_NAME.getEnv(agent.name)
+ logger.info { "agentName: $agentName" }
- if (overrideAuthority.isEmpty())
- overrideAuthority = OVERRIDE_AUTHORITY.getEnv(agent.tls.overrideAuthority)
+ if (!consolidated)
+ consolidated = CONSOLIDATED.getEnv(agent.consolidated)
+ logger.info { "consolidated: $consolidated" }
+
+ if (scrapeTimeoutSecs == -1)
+ scrapeTimeoutSecs = SCRAPE_TIMEOUT_SECS.getEnv(agent.scrapeTimeoutSecs)
+ logger.info { "scrapeTimeoutSecs: ${scrapeTimeoutSecs.seconds}" }
if (chunkContentSizeKbs == -1)
chunkContentSizeKbs = CHUNK_CONTENT_SIZE_KBS.getEnv(agent.chunkContentSizeKbs)
// Multiply the value time KB
chunkContentSizeKbs *= 1024
+ logger.info { "chunkContentSizeKbs: $chunkContentSizeKbs" }
if (minGzipSizeBytes == -1)
minGzipSizeBytes = MIN_GZIP_SIZE_BYTES.getEnv(agent.minGzipSizeBytes)
+ logger.info { "minGzipSizeBytes: $minGzipSizeBytes" }
- if (!consolidated)
- consolidated = CONSOLIDATED.getEnv(agent.consolidated)
+ if (overrideAuthority.isEmpty())
+ overrideAuthority = OVERRIDE_AUTHORITY.getEnv(agent.tls.overrideAuthority)
+ logger.info { "overrideAuthority: $overrideAuthority" }
assignAdminEnabled(agent.admin.enabled)
assignAdminPort(agent.admin.port)
@@ -100,4 +118,6 @@ class AgentOptions(argv: Array, exitOnMissingConfig: Boolean) :
assignTrustCertCollectionFilePath(agent.tls.trustCertCollectionFilePath)
}
}
+
+ companion object : KLogging()
}
\ No newline at end of file
diff --git a/src/main/kotlin/io/prometheus/agent/AgentPathManager.kt b/src/main/kotlin/io/prometheus/agent/AgentPathManager.kt
index 9dfa4465..3f914c7c 100644
--- a/src/main/kotlin/io/prometheus/agent/AgentPathManager.kt
+++ b/src/main/kotlin/io/prometheus/agent/AgentPathManager.kt
@@ -81,8 +81,8 @@ internal class AgentPathManager(private val agent: Agent) {
}
fun toPlainText(): String {
- val maxName = pathConfigs.map { it[NAME]?.length ?: 0 }.max() ?: 0
- val maxPath = pathConfigs.map { it[PATH]?.length ?: 0 }.max() ?: 0
+ val maxName = pathConfigs.map { it[NAME]?.length ?: 0 }.maxOrNull() ?: 0
+ val maxPath = pathConfigs.map { it[PATH]?.length ?: 0 }.maxOrNull() ?: 0
return "Agent Path Configs:\n" + "Name".padEnd(maxName + 1) + "Path".padEnd(maxPath + 2) + "URL\n" +
pathConfigs.joinToString("\n") { c -> "${c[NAME]?.padEnd(maxName)} /${c[PATH]?.padEnd(maxPath)} ${c[URL]}" }
}
diff --git a/src/main/kotlin/io/prometheus/common/BaseOptions.kt b/src/main/kotlin/io/prometheus/common/BaseOptions.kt
index 75754ddd..a4657f6c 100644
--- a/src/main/kotlin/io/prometheus/common/BaseOptions.kt
+++ b/src/main/kotlin/io/prometheus/common/BaseOptions.kt
@@ -124,60 +124,70 @@ abstract class BaseOptions protected constructor(private val progName: String,
protected fun assignAdminEnabled(defaultVal: Boolean) {
if (!adminEnabled)
adminEnabled = ADMIN_ENABLED.getEnv(defaultVal)
+ logger.info { "adminEnabled: $adminEnabled" }
}
protected fun assignAdminPort(defaultVal: Int) {
if (adminPort == -1)
adminPort = ADMIN_PORT.getEnv(defaultVal)
+ logger.info { "adminPort: $adminPort" }
}
protected fun assignMetricsEnabled(defaultVal: Boolean) {
if (!metricsEnabled)
metricsEnabled = METRICS_ENABLED.getEnv(defaultVal)
+ logger.info { "metricsEnabled: $metricsEnabled" }
}
protected fun assignDebugEnabled(defaultVal: Boolean) {
if (!debugEnabled)
debugEnabled = DEBUG_ENABLED.getEnv(defaultVal)
+ logger.info { "debugEnabled: $debugEnabled" }
}
protected fun assignMetricsPort(defaultVal: Int) {
if (metricsPort == -1)
metricsPort = METRICS_PORT.getEnv(defaultVal)
+ logger.info { "metricsPort: $metricsPort" }
}
protected fun assignCertChainFilePath(defaultVal: String) {
if (certChainFilePath.isEmpty())
certChainFilePath = CERT_CHAIN_FILE_PATH.getEnv(defaultVal)
+ logger.info { "certChainFilePath: $certChainFilePath" }
}
protected fun assignPrivateKeyFilePath(defaultVal: String) {
if (privateKeyFilePath.isEmpty())
privateKeyFilePath = PRIVATE_KEY_FILE_PATH.getEnv(defaultVal)
+ logger.info { "privateKeyFilePath: $privateKeyFilePath" }
}
protected fun assignTrustCertCollectionFilePath(defaultVal: String) {
if (trustCertCollectionFilePath.isEmpty())
trustCertCollectionFilePath = TRUST_CERT_COLLECTION_FILE_PATH.getEnv(defaultVal)
+ logger.info { "trustCertCollectionFilePath: $trustCertCollectionFilePath" }
}
private fun readConfig(envConfig: String, exitOnMissingConfig: Boolean) {
- config = readConfig(if (configSource.isNotEmpty()) configSource else System.getenv(envConfig).orEmpty(),
- envConfig,
- ConfigParseOptions.defaults().setAllowMissing(false),
- ConfigFactory.load().resolve(),
- exitOnMissingConfig)
- .resolve(ConfigResolveOptions.defaults())
- .resolve()
-
- dynamicParams.forEach { (k, v) ->
- // Strip quotes
- val qval = if (v.startsWith("\"") && v.endsWith("\"")) v.substring(1, v.length - 1) else v
- val prop = "$k=$qval"
- System.setProperty(k, prop)
- val newConfig = ConfigFactory.parseString(prop, PROPS)
- config = newConfig.withFallback(config).resolve()
- }
+ config =
+ readConfig(if (configSource.isNotEmpty()) configSource else System.getenv(envConfig).orEmpty(),
+ envConfig,
+ ConfigParseOptions.defaults().setAllowMissing(false),
+ ConfigFactory.load().resolve(),
+ exitOnMissingConfig)
+ .resolve(ConfigResolveOptions.defaults())
+ .resolve()
+
+ dynamicParams
+ .forEach { (k, v) ->
+ // Strip quotes
+ val qval = if (v.startsWith("\"") && v.endsWith("\"")) v.substring(1, v.length - 1) else v
+ val prop = "$k=$qval"
+ System.setProperty(k, prop)
+ val newConfig = ConfigFactory.parseString(prop, PROPS)
+ config = newConfig.withFallback(config).resolve()
+ }
}
private fun readConfig(configName: String,
diff --git a/src/main/kotlin/io/prometheus/common/EnvVars.kt b/src/main/kotlin/io/prometheus/common/EnvVars.kt
index 001ca191..b80772aa 100644
--- a/src/main/kotlin/io/prometheus/common/EnvVars.kt
+++ b/src/main/kotlin/io/prometheus/common/EnvVars.kt
@@ -32,6 +32,7 @@ enum class EnvVars {
PROXY_HOSTNAME,
AGENT_NAME,
CONSOLIDATED,
+ SCRAPE_TIMEOUT_SECS,
CHUNK_CONTENT_SIZE_KBS,
MIN_GZIP_SIZE_BYTES,
diff --git a/src/main/kotlin/io/prometheus/proxy/AgentContext.kt b/src/main/kotlin/io/prometheus/proxy/AgentContext.kt
index 5bedfac8..44c5223b 100644
--- a/src/main/kotlin/io/prometheus/proxy/AgentContext.kt
+++ b/src/main/kotlin/io/prometheus/proxy/AgentContext.kt
@@ -22,9 +22,10 @@ import com.github.pambrose.common.delegate.AtomicDelegates.atomicBoolean
import com.github.pambrose.common.delegate.AtomicDelegates.nonNullableReference
import com.github.pambrose.common.dsl.GuavaDsl.toStringElements
import io.prometheus.grpc.RegisterAgentRequest
-import kotlinx.atomicfu.atomic
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.receiveOrNull
+import java.util.concurrent.atomic.AtomicInteger
+import java.util.concurrent.atomic.AtomicLong
import kotlin.time.TimeMark
import kotlin.time.TimeSource.Monotonic
@@ -33,7 +34,7 @@ internal class AgentContext(private val remoteAddr: String) {
val agentId = AGENT_ID_GENERATOR.incrementAndGet().toString()
private val scrapeRequestChannel = Channel(Channel.UNLIMITED)
- private val channelBacklogSize = atomic(0)
+ private val channelBacklogSize = AtomicInteger(0)
private val clock = Monotonic
private var lastActivityTimeMark: TimeMark by nonNullableReference(clock.markNow())
@@ -59,7 +60,7 @@ internal class AgentContext(private val remoteAddr: String) {
get() = lastActivityTimeMark.elapsedNow()
val scrapeRequestBacklogSize: Int
- get() = channelBacklogSize.value
+ get() = channelBacklogSize.get()
init {
markActivityTime(true)
@@ -123,6 +124,6 @@ internal class AgentContext(private val remoteAddr: String) {
override fun hashCode() = agentId.hashCode()
companion object {
- private val AGENT_ID_GENERATOR = atomic(0L)
+ private val AGENT_ID_GENERATOR = AtomicLong(0L)
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/io/prometheus/proxy/AgentContextManager.kt b/src/main/kotlin/io/prometheus/proxy/AgentContextManager.kt
index 1c60beeb..84f63abe 100644
--- a/src/main/kotlin/io/prometheus/proxy/AgentContextManager.kt
+++ b/src/main/kotlin/io/prometheus/proxy/AgentContextManager.kt
@@ -21,14 +21,15 @@ package io.prometheus.proxy
import com.github.pambrose.common.util.isNull
import com.google.common.collect.Maps.newConcurrentMap
import mu.KLogging
+import java.util.concurrent.ConcurrentMap
internal class AgentContextManager {
// Map agent_id to AgentContext
- val agentContextMap = newConcurrentMap()
+ val agentContextMap: ConcurrentMap = newConcurrentMap()
val agentContextSize: Int get() = agentContextMap.size
// Map scrape_id to ChunkedContext
- val chunkedContextMap = newConcurrentMap()
+ val chunkedContextMap: ConcurrentMap = newConcurrentMap()
val chunkedContextSize: Int get() = chunkedContextMap.size
val totalAgentScrapeRequestBacklogSize: Int get() = agentContextMap.values.map { it.scrapeRequestBacklogSize }.sum()
diff --git a/src/main/kotlin/io/prometheus/proxy/ProxyHttpConfig.kt b/src/main/kotlin/io/prometheus/proxy/ProxyHttpConfig.kt
index 97c21074..6f15fbfe 100644
--- a/src/main/kotlin/io/prometheus/proxy/ProxyHttpConfig.kt
+++ b/src/main/kotlin/io/prometheus/proxy/ProxyHttpConfig.kt
@@ -18,236 +18,256 @@ package io.prometheus.proxy
import com.github.pambrose.common.util.isNotNull
import com.github.pambrose.common.util.isNull
+import com.github.pambrose.common.util.simpleClassName
import com.github.pambrose.common.util.unzip
-import io.ktor.application.Application
-import io.ktor.application.ApplicationCall
-import io.ktor.application.call
-import io.ktor.application.install
+import io.ktor.application.*
import io.ktor.features.*
import io.ktor.http.*
import io.ktor.http.ContentType.Text.Plain
import io.ktor.http.HttpStatusCode.Companion.NotFound
import io.ktor.http.HttpStatusCode.Companion.OK
-import io.ktor.request.ApplicationRequest
-import io.ktor.request.header
-import io.ktor.request.path
-import io.ktor.response.ApplicationResponse
-import io.ktor.response.header
-import io.ktor.response.respondText
-import io.ktor.routing.get
-import io.ktor.routing.routing
+import io.ktor.http.content.*
+import io.ktor.request.*
+import io.ktor.response.*
+import io.ktor.routing.*
import io.prometheus.Proxy
import kotlinx.coroutines.async
+import mu.KLogging
+import org.slf4j.event.Level
import kotlin.time.Duration
import kotlin.time.milliseconds
import kotlin.time.seconds
-internal fun Application.configServer(proxy: Proxy) {
+internal object ProxyHttpConfig : KLogging() {
- install(DefaultHeaders)
+ fun Application.configServer(proxy: Proxy, isTestMode: Boolean) {
- /*
- install(CallLogging){
- level = Level.INFO
- filter { call -> call.request.path().startsWith("/") }
- }
- */
+ install(DefaultHeaders) {
+ header("X-Engine", "Ktor")
+ }
- install(Compression) {
- gzip {
- priority = 1.0
+ if (!isTestMode && proxy.options.configVals.proxy.http.requestLoggingEnabled) {
+ install(CallLogging) {
+ level = Level.INFO
+ filter { call -> call.request.path().startsWith("/") }
+ format { call ->
+ when (val status = call.response.status()) {
+ HttpStatusCode.Found -> {
+ "$status: ${call.request.toLogString()} -> ${call.response.headers[HttpHeaders.Location]} - ${call.request.origin.remoteHost}"
+ }
+ else -> "$status: ${call.request.toLogString()} - ${call.request.origin.remoteHost}"
+ }
+ }
+ }
}
- deflate {
- priority = 10.0
- minimumSize(1024) // condition
+
+ install(Compression) {
+ gzip {
+ priority = 1.0
+ }
+ deflate {
+ priority = 10.0
+ minimumSize(1024) // condition
+ }
}
- }
- routing {
- get("/*") {
- call.response.header(HttpHeaders.CacheControl, "must-revalidate,no-cache,no-store")
+ install(StatusPages) {
+ // Catch all
+ exception { cause ->
+ logger.info(cause) { " Throwable caught: ${cause.simpleClassName}" }
+ call.respond(NotFound)
+ }
- val proxyConfigVals = proxy.configVals.proxy
- val path = call.request.path().drop(1)
- val queryParams = call.request.queryParameters.formUrlEncode()
- val responseResults = ResponseResults()
- val logger = ProxyHttpService.logger
-
- logger.debug { "Servicing request for path: $path${if (queryParams.isNotEmpty()) " with query params $queryParams" else ""}" }
-
- when {
- !proxy.isRunning -> {
- logger.error { "Proxy stopped" }
- responseResults
- .apply {
- updateMsg = "proxy_stopped"
- statusCode = HttpStatusCode.ServiceUnavailable
- }
- }
+ status(NotFound) {
+ call.respond(TextContent("${it.value} ${it.description}", Plain.withCharset(Charsets.UTF_8), it))
+ }
+ }
- path.isEmpty() || path.isBlank() -> {
- val msg = "Request missing path"
- proxy.logActivity(msg)
- logger.info { msg }
- responseResults.apply { updateMsg = "missing_path"; statusCode = NotFound }
- }
+ routing {
+ get("/*") {
+ call.response.header(HttpHeaders.CacheControl, "must-revalidate,no-cache,no-store")
- path == "favicon.ico" -> {
- //logger.info { "Invalid path request /${path}" }
- responseResults.apply { updateMsg = "invalid_path"; statusCode = NotFound }
- }
+ val proxyConfigVals = proxy.configVals.proxy
+ val path = call.request.path().drop(1)
+ val queryParams = call.request.queryParameters.formUrlEncode()
+ val responseResults = ResponseResults()
+ val logger = ProxyHttpService.logger
- proxyConfigVals.internal.blitz.enabled && path == proxyConfigVals.internal.blitz.path ->
- responseResults.contentText = "42"
+ logger.debug { "Servicing request for path: $path${if (queryParams.isNotEmpty()) " with query params $queryParams" else ""}" }
+
+ when {
+ !proxy.isRunning -> {
+ logger.error { "Proxy stopped" }
+ responseResults
+ .apply {
+ updateMsg = "proxy_stopped"
+ statusCode = HttpStatusCode.ServiceUnavailable
+ }
+ }
- else -> {
- val agentContextInfo = proxy.pathManager.getAgentContextInfo(path)
- if (agentContextInfo.isNull()) {
- val msg = "Invalid path request /${path}"
+ path.isEmpty() || path.isBlank() -> {
+ val msg = "Request missing path"
proxy.logActivity(msg)
logger.info { msg }
+ responseResults.apply { updateMsg = "missing_path"; statusCode = NotFound }
+ }
+
+ path == "favicon.ico" -> {
responseResults.apply { updateMsg = "invalid_path"; statusCode = NotFound }
}
- else {
- if (!agentContextInfo.consolidated && agentContextInfo.agentContexts.get(0).isNotValid()) {
- val msg = "Invalid AgentContext for /${path}"
+
+ proxyConfigVals.internal.blitz.enabled && path == proxyConfigVals.internal.blitz.path ->
+ responseResults.contentText = "42"
+
+ else -> {
+ val agentContextInfo = proxy.pathManager.getAgentContextInfo(path)
+ if (agentContextInfo.isNull()) {
+ val msg = "Invalid path request /${path}"
proxy.logActivity(msg)
- logger.error { msg }
- responseResults.apply { updateMsg = "invalid_agent_context"; statusCode = NotFound }
+ logger.info { msg }
+ responseResults.apply { updateMsg = "invalid_path"; statusCode = NotFound }
}
else {
- val jobs =
- agentContextInfo.agentContexts
- .map { async { submitScrapeRequest(it, proxy, path, queryParams, call.request, call.response) } }
- .map { it.await() }
- .onEach { response ->
- var status = "/$path - ${response.updateMsg} - ${response.statusCode}"
- if (!response.statusCode.isSuccess())
- status += " reason: [${response.failureReason}]"
- status += " time: ${response.fetchDuration} url: ${response.url}"
-
- proxy.logActivity(status)
- }
+ if (!agentContextInfo.consolidated && agentContextInfo.agentContexts[0].isNotValid()) {
+ val msg = "Invalid AgentContext for /${path}"
+ proxy.logActivity(msg)
+ logger.error { msg }
+ responseResults.apply { updateMsg = "invalid_agent_context"; statusCode = NotFound }
+ }
+ else {
+ val jobs =
+ agentContextInfo.agentContexts
+ .map { async { submitScrapeRequest(it, proxy, path, queryParams, call.request, call.response) } }
+ .map { it.await() }
+ .onEach { response ->
+ var status = "/$path - ${response.updateMsg} - ${response.statusCode}"
+ if (!response.statusCode.isSuccess())
+ status += " reason: [${response.failureReason}]"
+ status += " time: ${response.fetchDuration} url: ${response.url}"
- val statusCodes = jobs.map { it.statusCode }.toSet().toList()
- val contentTypes = jobs.map { it.contentType }.toSet().toList()
- val updateMsgs = jobs.map { it.updateMsg }.joinToString("\n")
- // Grab the contentType of the first OK in the lit
- val okContentType = jobs.firstOrNull { it.statusCode == OK }?.contentType
-
- responseResults
- .apply {
- statusCode = if (statusCodes.contains(OK)) OK else statusCodes.get(0)
- contentType = if (okContentType.isNotNull()) okContentType else contentTypes.get(0)
- contentText = jobs.map { it.contentText }.joinToString("\n")
- updateMsg = updateMsgs
- }
+ proxy.logActivity(status)
+ }
+
+ val statusCodes = jobs.map { it.statusCode }.toSet().toList()
+ val contentTypes = jobs.map { it.contentType }.toSet().toList()
+ val updateMsgs = jobs.joinToString("\n") { it.updateMsg }
+ // Grab the contentType of the first OK in the lit
+ val okContentType = jobs.firstOrNull { it.statusCode == OK }?.contentType
+
+ responseResults
+ .apply {
+ statusCode = if (statusCodes.contains(OK)) OK else statusCodes[0]
+ contentType = if (okContentType.isNotNull()) okContentType else contentTypes[0]
+ contentText = jobs.joinToString("\n") { it.contentText }
+ updateMsg = updateMsgs
+ }
+ }
}
}
}
- }
- responseResults
- .apply {
- updateScrapeRequests(proxy, updateMsg)
- call.respondWith(contentText, contentType, statusCode)
- }
+ responseResults
+ .apply {
+ updateScrapeRequests(proxy, updateMsg)
+ call.respondWith(contentText, contentType, statusCode)
+ }
+ }
}
}
-}
-private fun updateScrapeRequests(proxy: Proxy, type: String) {
- if (type.isNotEmpty())
- proxy.metrics { scrapeRequestCount.labels(type).inc() }
-}
+ private fun updateScrapeRequests(proxy: Proxy, type: String) {
+ if (type.isNotEmpty())
+ proxy.metrics { scrapeRequestCount.labels(type).inc() }
+ }
-private suspend fun ApplicationCall.respondWith(text: String,
- contentType: ContentType = Plain,
- status: HttpStatusCode = OK) {
- response.header(HttpHeaders.CacheControl, "must-revalidate,no-cache,no-store")
- response.status(status)
- respondText(text, contentType, status)
-}
+ private suspend fun ApplicationCall.respondWith(text: String,
+ contentType: ContentType = Plain,
+ status: HttpStatusCode = OK) {
+ response.header(HttpHeaders.CacheControl, "must-revalidate,no-cache,no-store")
+ response.status(status)
+ respondText(text, contentType, status)
+ }
+
+ private suspend fun submitScrapeRequest(agentContext: AgentContext,
+ proxy: Proxy,
+ path: String,
+ encodedQueryParams: String,
+ request: ApplicationRequest,
+ response: ApplicationResponse): ScrapeRequestResponse {
+
+ val scrapeRequest = ScrapeRequestWrapper(agentContext,
+ proxy,
+ path,
+ encodedQueryParams,
+ request.header(HttpHeaders.Accept),
+ proxy.options.debugEnabled)
+ val logger = ProxyHttpService.logger
-private suspend fun submitScrapeRequest(agentContext: AgentContext,
- proxy: Proxy,
- path: String,
- encodedQueryParams: String,
- request: ApplicationRequest,
- response: ApplicationResponse): ScrapeRequestResponse {
-
- val scrapeRequest = ScrapeRequestWrapper(agentContext,
- proxy,
- path,
- encodedQueryParams,
- request.header(HttpHeaders.Accept),
- proxy.options.debugEnabled)
- val logger = ProxyHttpService.logger
-
- try {
- val proxyConfigVals = proxy.configVals.proxy
- val timeoutTime = proxyConfigVals.internal.scrapeRequestTimeoutSecs.seconds
- val checkTime = proxyConfigVals.internal.scrapeRequestCheckMillis.milliseconds
-
- proxy.scrapeRequestManager.addToScrapeRequestMap(scrapeRequest)
- agentContext.writeScrapeRequest(scrapeRequest)
-
- // Returns false if timed out
- while (!scrapeRequest.suspendUntilComplete(checkTime)) {
- // Check if agent is disconnected or agent is hung
- if (scrapeRequest.ageDuration() >= timeoutTime || !scrapeRequest.agentContext.isValid() || !proxy.isRunning)
- return ScrapeRequestResponse(statusCode = HttpStatusCode.ServiceUnavailable,
- updateMsg = "timed_out",
- fetchDuration = scrapeRequest.ageDuration())
+ try {
+ val proxyConfigVals = proxy.configVals.proxy
+ val timeoutTime = proxyConfigVals.internal.scrapeRequestTimeoutSecs.seconds
+ val checkTime = proxyConfigVals.internal.scrapeRequestCheckMillis.milliseconds
+
+ proxy.scrapeRequestManager.addToScrapeRequestMap(scrapeRequest)
+ agentContext.writeScrapeRequest(scrapeRequest)
+
+ // Returns false if timed out
+ while (!scrapeRequest.suspendUntilComplete(checkTime)) {
+ // Check if agent is disconnected or agent is hung
+ if (scrapeRequest.ageDuration() >= timeoutTime || !scrapeRequest.agentContext.isValid() || !proxy.isRunning)
+ return ScrapeRequestResponse(statusCode = HttpStatusCode.ServiceUnavailable,
+ updateMsg = "timed_out",
+ fetchDuration = scrapeRequest.ageDuration())
+ }
}
- }
- finally {
- val scrapeId = scrapeRequest.scrapeId
- proxy.scrapeRequestManager.removeFromScrapeRequestMap(scrapeId)
- ?: logger.error { "Scrape request $scrapeId missing in map" }
- }
+ finally {
+ val scrapeId = scrapeRequest.scrapeId
+ proxy.scrapeRequestManager.removeFromScrapeRequestMap(scrapeId)
+ ?: logger.error { "Scrape request $scrapeId missing in map" }
+ }
+
+ logger.debug { "Results returned from $agentContext for $scrapeRequest" }
- logger.debug { "Results returned from $agentContext for $scrapeRequest" }
-
- scrapeRequest.scrapeResults
- .also { scrapeResults ->
- HttpStatusCode.fromValue(scrapeResults.statusCode)
- .also { statusCode ->
- scrapeResults.contentType.split("/")
- .also { contentTypeElems ->
-
- val contentType =
- if (contentTypeElems.size == 2)
- ContentType(contentTypeElems[0], contentTypeElems[1])
- else
- Plain
-
- // Do not return content on error status codes
- return if (!statusCode.isSuccess()) {
- scrapeRequest.scrapeResults.run {
- ScrapeRequestResponse(statusCode = statusCode,
- contentType = contentType,
- failureReason = failureReason,
- url = url,
- updateMsg = "path_not_found",
- fetchDuration = scrapeRequest.ageDuration())
+ scrapeRequest.scrapeResults
+ .also { scrapeResults ->
+ HttpStatusCode.fromValue(scrapeResults.statusCode)
+ .also { statusCode ->
+ scrapeResults.contentType.split("/")
+ .also { contentTypeElems ->
+
+ val contentType =
+ if (contentTypeElems.size == 2)
+ ContentType(contentTypeElems[0], contentTypeElems[1])
+ else
+ Plain
+
+ // Do not return content on error status codes
+ return if (!statusCode.isSuccess()) {
+ scrapeRequest.scrapeResults.run {
+ ScrapeRequestResponse(statusCode = statusCode,
+ contentType = contentType,
+ failureReason = failureReason,
+ url = url,
+ updateMsg = "path_not_found",
+ fetchDuration = scrapeRequest.ageDuration())
+ }
}
- }
- else {
- scrapeRequest.scrapeResults.run {
- // Unzip content here
- ScrapeRequestResponse(statusCode = statusCode,
- contentType = contentType,
- contentText = if (zipped) contentAsZipped.unzip() else contentAsText,
- failureReason = failureReason,
- url = url,
- updateMsg = "success",
- fetchDuration = scrapeRequest.ageDuration())
+ else {
+ scrapeRequest.scrapeResults.run {
+ // Unzip content here
+ ScrapeRequestResponse(statusCode = statusCode,
+ contentType = contentType,
+ contentText = if (zipped) contentAsZipped.unzip() else contentAsText,
+ failureReason = failureReason,
+ url = url,
+ updateMsg = "success",
+ fetchDuration = scrapeRequest.ageDuration())
+ }
}
}
- }
- }
- }
+ }
+ }
+ }
}
private class ScrapeRequestResponse(val statusCode: HttpStatusCode,
diff --git a/src/main/kotlin/io/prometheus/proxy/ProxyHttpService.kt b/src/main/kotlin/io/prometheus/proxy/ProxyHttpService.kt
index 14180799..3923d0af 100644
--- a/src/main/kotlin/io/prometheus/proxy/ProxyHttpService.kt
+++ b/src/main/kotlin/io/prometheus/proxy/ProxyHttpService.kt
@@ -23,14 +23,15 @@ import com.github.pambrose.common.concurrent.genericServiceListener
import com.github.pambrose.common.dsl.GuavaDsl.toStringElements
import com.github.pambrose.common.util.sleep
import com.google.common.util.concurrent.MoreExecutors
-import io.ktor.server.cio.CIO
-import io.ktor.server.cio.CIOApplicationEngine
-import io.ktor.server.engine.embeddedServer
+import io.ktor.server.cio.*
+import io.ktor.server.engine.*
import io.prometheus.Proxy
+import io.prometheus.proxy.ProxyHttpConfig.configServer
import mu.KLogging
import kotlin.time.seconds
-internal class ProxyHttpService(private val proxy: Proxy, val httpPort: Int) : GenericIdleService() {
+internal class ProxyHttpService(private val proxy: Proxy, val httpPort: Int, isTestMode: Boolean) :
+ GenericIdleService() {
private val proxyConfigVals = proxy.configVals.proxy
private val idleTimeout =
if (proxyConfigVals.http.idleTimeoutSecs == -1) 45.seconds else proxyConfigVals.http.idleTimeoutSecs.seconds
@@ -39,7 +40,7 @@ internal class ProxyHttpService(private val proxy: Proxy, val httpPort: Int) : G
private val config: CIOApplicationEngine.Configuration.() -> Unit =
{ connectionIdleTimeoutSeconds = idleTimeout.inSeconds.toInt() }
- private val httpServer = embeddedServer(CIO, port = httpPort, configure = config) { configServer(proxy) }
+ private val httpServer = embeddedServer(CIO, port = httpPort, configure = config) { configServer(proxy, isTestMode) }
init {
addListener(genericServiceListener(logger), MoreExecutors.directExecutor())
diff --git a/src/main/kotlin/io/prometheus/proxy/ProxyOptions.kt b/src/main/kotlin/io/prometheus/proxy/ProxyOptions.kt
index ca4e020c..e353a038 100644
--- a/src/main/kotlin/io/prometheus/proxy/ProxyOptions.kt
+++ b/src/main/kotlin/io/prometheus/proxy/ProxyOptions.kt
@@ -41,12 +41,14 @@ class ProxyOptions(argv: Array) : BaseOptions(Proxy::class.java.simpleNa
}
override fun assignConfigVals() {
+
if (proxyHttpPort == -1)
proxyHttpPort = PROXY_PORT.getEnv(configVals.proxy.http.port)
+ logger.info { "proxyHttpPort: $proxyHttpPort" }
if (proxyAgentPort == -1)
proxyAgentPort = AGENT_PORT.getEnv(configVals.proxy.agent.port)
-
+ logger.info { "proxyAgentPort: $proxyAgentPort" }
configVals.proxy.also { proxy ->
assignAdminEnabled(proxy.admin.enabled)
diff --git a/src/main/kotlin/io/prometheus/proxy/ProxyPathManager.kt b/src/main/kotlin/io/prometheus/proxy/ProxyPathManager.kt
index 336828ae..4b440b72 100644
--- a/src/main/kotlin/io/prometheus/proxy/ProxyPathManager.kt
+++ b/src/main/kotlin/io/prometheus/proxy/ProxyPathManager.kt
@@ -60,7 +60,7 @@ internal class ProxyPathManager(private val proxy: Proxy, private val isTestMode
}
}
else {
- if (agentInfo.isNotNull()) logger.info { "Overwriting path /$path for ${agentInfo.agentContexts.get(0)}" }
+ if (agentInfo.isNotNull()) logger.info { "Overwriting path /$path for ${agentInfo.agentContexts[0]}" }
pathMap[path] = AgentContextInfo(false, mutableListOf(agentContext))
}
@@ -83,7 +83,7 @@ internal class ProxyPathManager(private val proxy: Proxy, private val isTestMode
else {
val agentContext = agentInfo.agentContexts.firstOrNull { it.agentId == agentId }
if (agentContext.isNull()) {
- val agentIds = agentInfo.agentContexts.map { it.agentId }.joinToString(", ")
+ val agentIds = agentInfo.agentContexts.joinToString(", ") { it.agentId }
val msg = "Unable to remove path /$path - invalid agentId: $agentId -- [$agentIds]"
logger.error { msg }
false to msg
@@ -121,7 +121,7 @@ internal class ProxyPathManager(private val proxy: Proxy, private val isTestMode
synchronized(pathMap) {
pathMap.forEach { (k, v) ->
if (v.agentContexts.size == 1) {
- if (v.agentContexts.get(0).agentId == agentId)
+ if (v.agentContexts[0].agentId == agentId)
pathMap.remove(k)?.also {
if (!isTestMode)
logger.info { "Removed path /$k for $it" }
@@ -144,7 +144,7 @@ internal class ProxyPathManager(private val proxy: Proxy, private val isTestMode
"No agents connected."
}
else {
- val maxPath = pathMap.keys.map { it.length }.max() ?: 0
+ val maxPath = pathMap.keys.map { it.length }.maxOrNull() ?: 0
"Proxy Path Map:\n" + "Path".padEnd(maxPath + 2) + "Agent Context\n" +
pathMap
.toSortedMap()
diff --git a/src/main/kotlin/io/prometheus/proxy/ProxyServiceImpl.kt b/src/main/kotlin/io/prometheus/proxy/ProxyServiceImpl.kt
index 04014f55..9e860536 100644
--- a/src/main/kotlin/io/prometheus/proxy/ProxyServiceImpl.kt
+++ b/src/main/kotlin/io/prometheus/proxy/ProxyServiceImpl.kt
@@ -30,12 +30,12 @@ import io.prometheus.common.GrpcObjects.newRegisterPathResponse
import io.prometheus.common.GrpcObjects.toScrapeResults
import io.prometheus.common.GrpcObjects.unregisterPathResponse
import io.prometheus.grpc.*
-import kotlinx.atomicfu.atomic
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import mu.KLogging
import java.util.concurrent.CancellationException
+import java.util.concurrent.atomic.AtomicLong
internal class ProxyServiceImpl(private val proxy: Proxy) : ProxyServiceGrpcKt.ProxyServiceCoroutineImplBase() {
@@ -177,6 +177,6 @@ internal class ProxyServiceImpl(private val proxy: Proxy) : ProxyServiceGrpcKt.P
}
companion object : KLogging() {
- private val PATH_ID_GENERATOR = atomic(0L)
+ private val PATH_ID_GENERATOR = AtomicLong(0L)
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/io/prometheus/proxy/ScrapeRequestManager.kt b/src/main/kotlin/io/prometheus/proxy/ScrapeRequestManager.kt
index 9c7191a3..ab8ce31c 100644
--- a/src/main/kotlin/io/prometheus/proxy/ScrapeRequestManager.kt
+++ b/src/main/kotlin/io/prometheus/proxy/ScrapeRequestManager.kt
@@ -21,10 +21,11 @@ package io.prometheus.proxy
import com.google.common.collect.Maps.newConcurrentMap
import io.prometheus.common.ScrapeResults
import mu.KLogging
+import java.util.concurrent.ConcurrentMap
internal class ScrapeRequestManager {
// Map scrape_id to agent_id
- val scrapeRequestMap = newConcurrentMap()
+ val scrapeRequestMap: ConcurrentMap = newConcurrentMap()
val scrapeMapSize: Int
get() = scrapeRequestMap.size
diff --git a/src/main/kotlin/io/prometheus/proxy/ScrapeRequestWrapper.kt b/src/main/kotlin/io/prometheus/proxy/ScrapeRequestWrapper.kt
index 1d504089..3c6c3e7e 100644
--- a/src/main/kotlin/io/prometheus/proxy/ScrapeRequestWrapper.kt
+++ b/src/main/kotlin/io/prometheus/proxy/ScrapeRequestWrapper.kt
@@ -24,10 +24,10 @@ import com.github.pambrose.common.util.isNotNull
import io.prometheus.Proxy
import io.prometheus.common.GrpcObjects.newScrapeRequest
import io.prometheus.common.ScrapeResults
-import kotlinx.atomicfu.atomic
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ClosedReceiveChannelException
import kotlinx.coroutines.withTimeoutOrNull
+import java.util.concurrent.atomic.AtomicLong
import kotlin.time.Duration
import kotlin.time.TimeSource.Monotonic
@@ -81,6 +81,6 @@ internal class ScrapeRequestWrapper(val agentContext: AgentContext,
}
companion object {
- private val SCRAPE_ID_GENERATOR = atomic(0L)
+ private val SCRAPE_ID_GENERATOR = AtomicLong(0L)
}
}
\ No newline at end of file
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
index da289073..15e2009b 100644
--- a/src/main/resources/logback.xml
+++ b/src/main/resources/logback.xml
@@ -25,9 +25,9 @@
-
-
+
+
diff --git a/src/test/kotlin/io/prometheus/AdminDefaultPathTest.kt b/src/test/kotlin/io/prometheus/AdminDefaultPathTest.kt
index d22698f5..a00be68b 100644
--- a/src/test/kotlin/io/prometheus/AdminDefaultPathTest.kt
+++ b/src/test/kotlin/io/prometheus/AdminDefaultPathTest.kt
@@ -19,8 +19,8 @@
package io.prometheus
import com.github.pambrose.common.dsl.KtorDsl.blockingGet
-import io.ktor.client.statement.readText
-import io.ktor.http.HttpStatusCode
+import io.ktor.client.statement.*
+import io.ktor.http.*
import io.prometheus.TestUtils.startAgent
import io.prometheus.TestUtils.startProxy
import org.amshove.kluent.shouldBeEqualTo
@@ -122,7 +122,11 @@ class AdminDefaultPathTest {
@JvmStatic
@BeforeAll
- fun setUp() = setItUp({ startProxy(adminEnabled = true) }, { startAgent(adminEnabled = true) })
+ fun setUp() =
+ setItUp(
+ { startProxy(adminEnabled = true) },
+ { startAgent(adminEnabled = true) }
+ )
@JvmStatic
@AfterAll
diff --git a/src/test/kotlin/io/prometheus/AdminEmptyPathTest.kt b/src/test/kotlin/io/prometheus/AdminEmptyPathTest.kt
index 581dfa81..084519b5 100644
--- a/src/test/kotlin/io/prometheus/AdminEmptyPathTest.kt
+++ b/src/test/kotlin/io/prometheus/AdminEmptyPathTest.kt
@@ -19,7 +19,7 @@
package io.prometheus
import com.github.pambrose.common.dsl.KtorDsl.blockingGet
-import io.ktor.http.HttpStatusCode
+import io.ktor.http.*
import io.prometheus.TestUtils.startAgent
import io.prometheus.TestUtils.startProxy
import io.prometheus.common.ConfigVals
@@ -86,14 +86,17 @@ class AdminEmptyPathTest {
@JvmStatic
@BeforeAll
- fun setUp() = setItUp({
- startProxy(adminEnabled = true, argv = listOf("-Dproxy.admin.port=8098",
- "-Dproxy.admin.pingPath=\"\"",
- "-Dproxy.admin.versionPath=\"\"",
- "-Dproxy.admin.healthCheckPath=\"\"",
- "-Dproxy.admin.threadDumpPath=\"\""))
- },
- { startAgent(adminEnabled = true) })
+ fun setUp() =
+ setItUp(
+ {
+ startProxy(adminEnabled = true, argv = listOf("-Dproxy.admin.port=8098",
+ "-Dproxy.admin.pingPath=\"\"",
+ "-Dproxy.admin.versionPath=\"\"",
+ "-Dproxy.admin.healthCheckPath=\"\"",
+ "-Dproxy.admin.threadDumpPath=\"\""))
+ },
+ { startAgent(adminEnabled = true) }
+ )
@JvmStatic
@AfterAll
diff --git a/src/test/kotlin/io/prometheus/AdminNonDefaultPathTest.kt b/src/test/kotlin/io/prometheus/AdminNonDefaultPathTest.kt
index 735efd08..795d5267 100644
--- a/src/test/kotlin/io/prometheus/AdminNonDefaultPathTest.kt
+++ b/src/test/kotlin/io/prometheus/AdminNonDefaultPathTest.kt
@@ -19,8 +19,8 @@
package io.prometheus
import com.github.pambrose.common.dsl.KtorDsl.blockingGet
-import io.ktor.client.statement.readText
-import io.ktor.http.HttpStatusCode
+import io.ktor.client.statement.*
+import io.ktor.http.*
import io.prometheus.TestUtils.startAgent
import io.prometheus.TestUtils.startProxy
import io.prometheus.common.ConfigVals
@@ -93,14 +93,17 @@ class AdminNonDefaultPathTest {
@JvmStatic
@BeforeAll
- fun setUp() = setItUp({
- startProxy(adminEnabled = true, argv = listOf("-Dproxy.admin.port=8099",
- "-Dproxy.admin.pingPath=pingPath2",
- "-Dproxy.admin.versionPath=versionPath2",
- "-Dproxy.admin.healthCheckPath=healthCheckPath2",
- "-Dproxy.admin.threadDumpPath=threadDumpPath2"))
- },
- { startAgent(adminEnabled = true) })
+ fun setUp() =
+ setItUp(
+ {
+ startProxy(adminEnabled = true, argv = listOf("-Dproxy.admin.port=8099",
+ "-Dproxy.admin.pingPath=pingPath2",
+ "-Dproxy.admin.versionPath=versionPath2",
+ "-Dproxy.admin.healthCheckPath=healthCheckPath2",
+ "-Dproxy.admin.threadDumpPath=threadDumpPath2"))
+ },
+ { startAgent(adminEnabled = true) }
+ )
@JvmStatic
@AfterAll
diff --git a/src/test/kotlin/io/prometheus/InProcessTestNoAdminMetricsTest.kt b/src/test/kotlin/io/prometheus/InProcessTestNoAdminMetricsTest.kt
index fabab7f8..e2b855b1 100644
--- a/src/test/kotlin/io/prometheus/InProcessTestNoAdminMetricsTest.kt
+++ b/src/test/kotlin/io/prometheus/InProcessTestNoAdminMetricsTest.kt
@@ -19,6 +19,8 @@
package io.prometheus
import com.github.pambrose.common.util.simpleClassName
+import io.prometheus.TestConstants.DEFAULT_CHUNK_SIZE
+import io.prometheus.TestConstants.DEFAULT_TIMEOUT
import io.prometheus.TestUtils.startAgent
import io.prometheus.TestUtils.startProxy
import org.junit.jupiter.api.AfterAll
@@ -34,7 +36,12 @@ class InProcessTestNoAdminMetricsTest : CommonTests(ProxyCallTestArgs(agent = ag
fun setUp() =
setItUp(
{ startProxy("nometrics") },
- { startAgent(serverName = "nometrics", chunkContentSizeKbs = 5) })
+ {
+ startAgent(serverName = "nometrics",
+ scrapeTimeoutSecs = DEFAULT_TIMEOUT,
+ chunkContentSizeKbs = DEFAULT_CHUNK_SIZE)
+ }
+ )
@JvmStatic
@AfterAll
diff --git a/src/test/kotlin/io/prometheus/InProcessTestWithAdminMetricsTest.kt b/src/test/kotlin/io/prometheus/InProcessTestWithAdminMetricsTest.kt
index d2de691d..7a8e15ec 100644
--- a/src/test/kotlin/io/prometheus/InProcessTestWithAdminMetricsTest.kt
+++ b/src/test/kotlin/io/prometheus/InProcessTestWithAdminMetricsTest.kt
@@ -19,6 +19,8 @@
package io.prometheus
import com.github.pambrose.common.util.simpleClassName
+import io.prometheus.TestConstants.DEFAULT_CHUNK_SIZE
+import io.prometheus.TestConstants.DEFAULT_TIMEOUT
import io.prometheus.TestUtils.startAgent
import io.prometheus.TestUtils.startProxy
import org.junit.jupiter.api.AfterAll
@@ -37,7 +39,8 @@ class InProcessTestWithAdminMetricsTest :
startAgent(serverName = "withmetrics",
adminEnabled = true,
metricsEnabled = true,
- chunkContentSizeKbs = 5)
+ scrapeTimeoutSecs = DEFAULT_TIMEOUT,
+ chunkContentSizeKbs = DEFAULT_CHUNK_SIZE)
})
@JvmStatic
diff --git a/src/test/kotlin/io/prometheus/NettyTestNoAdminMetricsTest.kt b/src/test/kotlin/io/prometheus/NettyTestNoAdminMetricsTest.kt
index 03b1644c..8a7fd3eb 100644
--- a/src/test/kotlin/io/prometheus/NettyTestNoAdminMetricsTest.kt
+++ b/src/test/kotlin/io/prometheus/NettyTestNoAdminMetricsTest.kt
@@ -19,6 +19,8 @@
package io.prometheus
import com.github.pambrose.common.util.simpleClassName
+import io.prometheus.TestConstants.DEFAULT_CHUNK_SIZE
+import io.prometheus.TestConstants.DEFAULT_TIMEOUT
import io.prometheus.TestUtils.startAgent
import io.prometheus.TestUtils.startProxy
import org.junit.jupiter.api.AfterAll
@@ -32,7 +34,14 @@ class NettyTestNoAdminMetricsTest : CommonTests(ProxyCallTestArgs(agent = agent,
@JvmStatic
@BeforeAll
- fun setUp() = setItUp({ startProxy() }, { startAgent(chunkContentSizeKbs = 5) })
+ fun setUp() =
+ setItUp(
+ { startProxy() },
+ {
+ startAgent(scrapeTimeoutSecs = DEFAULT_TIMEOUT,
+ chunkContentSizeKbs = DEFAULT_CHUNK_SIZE)
+ }
+ )
@JvmStatic
@AfterAll
diff --git a/src/test/kotlin/io/prometheus/NettyTestWithAdminMetricsTest.kt b/src/test/kotlin/io/prometheus/NettyTestWithAdminMetricsTest.kt
index 31720ad2..2ecfd12d 100644
--- a/src/test/kotlin/io/prometheus/NettyTestWithAdminMetricsTest.kt
+++ b/src/test/kotlin/io/prometheus/NettyTestWithAdminMetricsTest.kt
@@ -22,8 +22,10 @@ import com.github.pambrose.common.dsl.KtorDsl.get
import com.github.pambrose.common.dsl.KtorDsl.withHttpClient
import com.github.pambrose.common.util.simpleClassName
import com.github.pambrose.common.util.sleep
-import io.ktor.client.statement.readText
-import io.ktor.http.HttpStatusCode
+import io.ktor.client.statement.*
+import io.ktor.http.*
+import io.prometheus.TestConstants.DEFAULT_CHUNK_SIZE
+import io.prometheus.TestConstants.DEFAULT_TIMEOUT
import io.prometheus.TestUtils.startAgent
import io.prometheus.TestUtils.startProxy
import kotlinx.coroutines.runBlocking
@@ -63,21 +65,24 @@ class NettyTestWithAdminMetricsTest : CommonTests(ProxyCallTestArgs(agent = agen
@JvmStatic
@BeforeAll
- fun setUp() = setItUp({
- startProxy(adminEnabled = true,
- debugEnabled = true,
- metricsEnabled = true)
- },
- {
- startAgent(adminEnabled = true,
- debugEnabled = true,
- metricsEnabled = true,
- chunkContentSizeKbs = 5)
- },
- {
- // Wait long enough to trigger heartbeat for code coverage
- sleep(15.seconds)
- })
+ fun setUp() =
+ setItUp(
+ {
+ startProxy(adminEnabled = true,
+ debugEnabled = true,
+ metricsEnabled = true)
+ },
+ {
+ startAgent(adminEnabled = true,
+ debugEnabled = true,
+ metricsEnabled = true,
+ scrapeTimeoutSecs = DEFAULT_TIMEOUT,
+ chunkContentSizeKbs = DEFAULT_CHUNK_SIZE)
+ },
+ {
+ // Wait long enough to trigger heartbeat for code coverage
+ sleep(15.seconds)
+ })
@JvmStatic
@AfterAll
diff --git a/src/test/kotlin/io/prometheus/ProxyTests.kt b/src/test/kotlin/io/prometheus/ProxyTests.kt
index feb01a0c..a50ed8c3 100644
--- a/src/test/kotlin/io/prometheus/ProxyTests.kt
+++ b/src/test/kotlin/io/prometheus/ProxyTests.kt
@@ -25,17 +25,15 @@ import com.github.pambrose.common.dsl.KtorDsl.httpClient
import com.github.pambrose.common.dsl.KtorDsl.withHttpClient
import com.github.pambrose.common.util.random
import com.google.common.collect.Maps.newConcurrentMap
-import io.ktor.application.call
-import io.ktor.client.HttpClient
-import io.ktor.client.statement.readText
-import io.ktor.http.ContentType.Text
-import io.ktor.http.HttpStatusCode
-import io.ktor.response.respondText
-import io.ktor.routing.get
-import io.ktor.routing.routing
-import io.ktor.server.cio.CIO
-import io.ktor.server.cio.CIOApplicationEngine
-import io.ktor.server.engine.embeddedServer
+import io.ktor.application.*
+import io.ktor.client.*
+import io.ktor.client.statement.*
+import io.ktor.http.*
+import io.ktor.http.ContentType.*
+import io.ktor.response.*
+import io.ktor.routing.*
+import io.ktor.server.cio.*
+import io.ktor.server.engine.*
import io.prometheus.CommonTests.Companion.HTTP_SERVER_COUNT
import io.prometheus.CommonTests.Companion.MAX_DELAY_MILLIS
import io.prometheus.CommonTests.Companion.MIN_DELAY_MILLIS
@@ -45,13 +43,13 @@ import io.prometheus.CommonTests.Companion.SEQUENTIAL_QUERY_COUNT
import io.prometheus.TestConstants.PROXY_PORT
import io.prometheus.agent.AgentPathManager
import io.prometheus.agent.RequestFailureException
-import kotlinx.atomicfu.atomic
import kotlinx.coroutines.*
import mu.KLogging
import org.amshove.kluent.shouldBeEqualTo
import org.amshove.kluent.shouldBeNull
import org.amshove.kluent.shouldNotBeNull
import java.util.concurrent.Executors
+import java.util.concurrent.atomic.AtomicInteger
import kotlin.collections.set
import kotlin.time.milliseconds
import kotlin.time.minutes
@@ -78,7 +76,7 @@ internal object ProxyTests : KLogging() {
embeddedServer(CIO, port = agentPort) {
routing {
get("/$agentPath") {
- delay(10.seconds)
+ delay(60.seconds)
call.respondText("This is never reached", Text.Plain)
}
}
@@ -88,14 +86,15 @@ internal object ProxyTests : KLogging() {
launch(Dispatchers.Default + exceptionHandler(logger)) {
logger.info { "Starting httpServer" }
httpServer.start()
- delay(5.seconds)
+ //delay(5.seconds)
}
}
+ delay(2.seconds) // Give http server a chance to start
pathManager.registerPath("/$proxyPath", "$agentPort/$agentPath".addPrefix())
blockingGet("$PROXY_PORT/$proxyPath".addPrefix()) { response ->
- response.status shouldBeEqualTo HttpStatusCode.ServiceUnavailable
+ response.status shouldBeEqualTo HttpStatusCode.RequestTimeout
}
pathManager.unregisterPath("/$proxyPath")
@@ -179,7 +178,7 @@ internal object ProxyTests : KLogging() {
.use { dispatcher ->
withTimeoutOrNull(1.minutes.toLongMilliseconds()) {
httpClient { client ->
- val counter = atomic(0)
+ val counter = AtomicInteger(0)
repeat(args.sequentialQueryCount) { cnt ->
val job =
launch(dispatcher + exceptionHandler(logger)) {
@@ -191,7 +190,7 @@ internal object ProxyTests : KLogging() {
job.getCancellationException().cause.shouldBeNull()
}
- counter.value shouldBeEqualTo args.sequentialQueryCount
+ counter.get() shouldBeEqualTo args.sequentialQueryCount
}
}
}
@@ -202,7 +201,7 @@ internal object ProxyTests : KLogging() {
.use { dispatcher ->
withTimeoutOrNull(1.minutes.toLongMilliseconds()) {
httpClient { client ->
- val counter = atomic(0)
+ val counter = AtomicInteger(0)
val jobs =
List(args.parallelQueryCount) { cnt ->
launch(dispatcher + exceptionHandler(logger)) {
@@ -217,14 +216,14 @@ internal object ProxyTests : KLogging() {
job.getCancellationException().cause.shouldBeNull()
}
- counter.value shouldBeEqualTo args.parallelQueryCount
+ counter.get() shouldBeEqualTo args.parallelQueryCount
}
}
}
logger.debug { "Unregistering paths" }
- val counter = atomic(0)
- val errorCnt = atomic(0)
+ val counter = AtomicInteger(0)
+ val errorCnt = AtomicInteger(0)
pathMap.forEach { path ->
try {
args.agent.pathManager.unregisterPath("proxy-${path.key}")
@@ -235,8 +234,8 @@ internal object ProxyTests : KLogging() {
}
}
- counter.value shouldBeEqualTo pathMap.size
- errorCnt.value shouldBeEqualTo 0
+ counter.get() shouldBeEqualTo pathMap.size
+ errorCnt.get() shouldBeEqualTo 0
args.agent.grpcService.pathMapSize() shouldBeEqualTo originalSize
logger.info { "Shutting down ${httpServers.size} httpServers" }
diff --git a/src/test/kotlin/io/prometheus/TestConstants.kt b/src/test/kotlin/io/prometheus/TestConstants.kt
index 86c1d9f9..7c1a7c39 100644
--- a/src/test/kotlin/io/prometheus/TestConstants.kt
+++ b/src/test/kotlin/io/prometheus/TestConstants.kt
@@ -23,6 +23,8 @@ import java.io.File
object TestConstants {
const val REPS = 1000
const val PROXY_PORT = 9505
+ const val DEFAULT_TIMEOUT = 3
+ const val DEFAULT_CHUNK_SIZE = 5
private const val travisFile = "etc/test-configs/travis.conf"
private const val junitFile = "etc/test-configs/junit-test.conf"
diff --git a/src/test/kotlin/io/prometheus/TestUtils.kt b/src/test/kotlin/io/prometheus/TestUtils.kt
index 3ea1c3f0..5ba268f3 100644
--- a/src/test/kotlin/io/prometheus/TestUtils.kt
+++ b/src/test/kotlin/io/prometheus/TestUtils.kt
@@ -58,6 +58,7 @@ object TestUtils : KLogging() {
adminEnabled: Boolean = false,
debugEnabled: Boolean = false,
metricsEnabled: Boolean = false,
+ scrapeTimeoutSecs: Int = -1,
chunkContentSizeKbs: Int = -1,
argv: List = emptyList()): Agent {
@@ -73,6 +74,8 @@ object TestUtils : KLogging() {
add("-Dagent.admin.enabled=$adminEnabled")
add("-Dagent.admin.debugEnabled=$debugEnabled")
add("-Dagent.metrics.enabled=$metricsEnabled")
+ if (scrapeTimeoutSecs != -1)
+ add("-Dagent.scrapeTimeoutSecs=$scrapeTimeoutSecs")
if (chunkContentSizeKbs != -1)
add("-Dagent.chunkContentSizeKbs=$chunkContentSizeKbs")
},
diff --git a/src/test/kotlin/io/prometheus/TlsNoMutualAuthTest.kt b/src/test/kotlin/io/prometheus/TlsNoMutualAuthTest.kt
index af3d337a..17506862 100644
--- a/src/test/kotlin/io/prometheus/TlsNoMutualAuthTest.kt
+++ b/src/test/kotlin/io/prometheus/TlsNoMutualAuthTest.kt
@@ -19,6 +19,8 @@
package io.prometheus
import com.github.pambrose.common.util.simpleClassName
+import io.prometheus.TestConstants.DEFAULT_CHUNK_SIZE
+import io.prometheus.TestConstants.DEFAULT_TIMEOUT
import io.prometheus.TestUtils.startAgent
import io.prometheus.TestUtils.startProxy
import org.junit.jupiter.api.AfterAll
@@ -32,19 +34,23 @@ class TlsNoMutualAuthTest : CommonTests(ProxyCallTestArgs(agent = agent,
@JvmStatic
@BeforeAll
- fun setUp() = setItUp({
- startProxy(serverName = "nomutualauth",
- argv = listOf("--agent_port", "50440",
- "--cert", "testing/certs/server1.pem",
- "--key", "testing/certs/server1.key"))
- },
- {
- startAgent(serverName = "nomutualauth",
- chunkContentSizeKbs = 5,
- argv = listOf("--proxy", "localhost:50440",
- "--trust", "testing/certs/ca.pem",
- "--override", "foo.test.google.fr"))
- })
+ fun setUp() =
+ setItUp(
+ {
+ startProxy(serverName = "nomutualauth",
+ argv = listOf("--agent_port", "50440",
+ "--cert", "testing/certs/server1.pem",
+ "--key", "testing/certs/server1.key"))
+ },
+ {
+ startAgent(serverName = "nomutualauth",
+ scrapeTimeoutSecs = DEFAULT_TIMEOUT,
+ chunkContentSizeKbs = DEFAULT_CHUNK_SIZE,
+ argv = listOf("--proxy", "localhost:50440",
+ "--trust", "testing/certs/ca.pem",
+ "--override", "foo.test.google.fr"))
+ }
+ )
@JvmStatic
@AfterAll
diff --git a/src/test/kotlin/io/prometheus/TlsWithMutualAuthTest.kt b/src/test/kotlin/io/prometheus/TlsWithMutualAuthTest.kt
index dff6739e..b7ea89ab 100644
--- a/src/test/kotlin/io/prometheus/TlsWithMutualAuthTest.kt
+++ b/src/test/kotlin/io/prometheus/TlsWithMutualAuthTest.kt
@@ -19,6 +19,8 @@
package io.prometheus
import com.github.pambrose.common.util.simpleClassName
+import io.prometheus.TestConstants.DEFAULT_CHUNK_SIZE
+import io.prometheus.TestConstants.DEFAULT_TIMEOUT
import io.prometheus.TestUtils.startAgent
import io.prometheus.TestUtils.startProxy
import org.junit.jupiter.api.AfterAll
@@ -32,22 +34,26 @@ class TlsWithMutualAuthTest : CommonTests(ProxyCallTestArgs(agent = agent,
@JvmStatic
@BeforeAll
- fun setUp() = setItUp({
- startProxy(serverName = "withmutualauth",
- argv = listOf("--agent_port", "50440",
- "--cert", "testing/certs/server1.pem",
- "--key", "testing/certs/server1.key",
- "--trust", "testing/certs/ca.pem"))
- },
- {
- startAgent(serverName = "withmutualauth",
- chunkContentSizeKbs = 5,
- argv = listOf("--proxy", "localhost:50440",
- "--cert", "testing/certs/client.pem",
- "--key", "testing/certs/client.key",
- "--trust", "testing/certs/ca.pem",
- "--override", "foo.test.google.fr"))
- })
+ fun setUp() =
+ setItUp(
+ {
+ startProxy(serverName = "withmutualauth",
+ argv = listOf("--agent_port", "50440",
+ "--cert", "testing/certs/server1.pem",
+ "--key", "testing/certs/server1.key",
+ "--trust", "testing/certs/ca.pem"))
+ },
+ {
+ startAgent(serverName = "withmutualauth",
+ scrapeTimeoutSecs = DEFAULT_TIMEOUT,
+ chunkContentSizeKbs = DEFAULT_CHUNK_SIZE,
+ argv = listOf("--proxy", "localhost:50440",
+ "--cert", "testing/certs/client.pem",
+ "--key", "testing/certs/client.key",
+ "--trust", "testing/certs/ca.pem",
+ "--override", "foo.test.google.fr"))
+ }
+ )
@JvmStatic
@AfterAll