Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(reports): sidecar container report generation #779

Merged
merged 24 commits into from
Jan 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a0c8bcd
feat(reports): implement/config sidecar container report generator
andrewazores Nov 19, 2021
db6286e
Add remote report status to health
andrewazores Nov 19, 2021
186d9e6
extract some env var names that are referenced in multiple places
andrewazores Nov 19, 2021
3197ff3
apply report generation locking only in subprocess mode
andrewazores Nov 19, 2021
664ab88
default to subprocess generation if env var unset
andrewazores Nov 19, 2021
a9bbcbd
apply limits to report generator
andrewazores Nov 19, 2021
6349165
error handling cleanup
andrewazores Nov 19, 2021
1b329ca
test(health): include reports status in expected output
andrewazores Dec 7, 2021
8c4cae3
fixup! default to subprocess generation if env var unset
andrewazores Dec 7, 2021
67790bd
apply spotless formatting
andrewazores Dec 7, 2021
9cd39ab
fix(reports): throw expected exception type when recording not found …
andrewazores Dec 7, 2021
cf7a60b
fix(reports): attempt to open local file stream before remote recordi…
andrewazores Dec 7, 2021
b6ee6b3
suppress spurious warning
andrewazores Dec 7, 2021
0ee531c
change cryostat-reports namespace after repo transfer
andrewazores Dec 8, 2021
6e1da1b
extract SslConfiguration variables
andrewazores Dec 8, 2021
f3337f5
remove unnecessary comment
andrewazores Dec 9, 2021
ca1f8f6
use xpath host var
andrewazores Dec 9, 2021
3eae455
fixup! change cryostat-reports namespace after repo transfer
andrewazores Dec 9, 2021
c991b65
remove unused class
andrewazores Dec 10, 2021
d054763
fix(reports): apply timeout when generating reports to avoid hanging …
andrewazores Dec 10, 2021
f242afd
fix(reports): reports handlers should be unordered
andrewazores Dec 10, 2021
e65d0e8
fix unit tests
andrewazores Dec 10, 2021
d9820d3
use latest cryostat-reports and configure for small footprint
andrewazores Dec 20, 2021
5c330fc
enable JDP and JMX on cryostat-reports sidecar
andrewazores Dec 21, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,11 @@ podman run \
--mount type=bind,source="$(dirname $0)/templates",destination=/opt/cryostat.d/templates.d,relabel=shared \
--mount type=bind,source="$(dirname $0)/truststore",destination=/truststore,relabel=shared \
--mount type=tmpfs,target=/opt/cryostat.d/probes.d \
-e CRYOSTAT_REPORT_GENERATOR=$CRYOSTAT_REPORT_GENERATOR \
-e CRYOSTAT_PLATFORM=$CRYOSTAT_PLATFORM \
-e CRYOSTAT_DISABLE_SSL=$CRYOSTAT_DISABLE_SSL \
-e CRYOSTAT_DISABLE_JMX_AUTH=$CRYOSTAT_DISABLE_JMX_AUTH \
-e CRYOSTAT_ALLOW_UNTRUSTED_SSL=$CRYOSTAT_ALLOW_UNTRUSTED_SSL \
-e CRYOSTAT_RJMX_USER=$CRYOSTAT_RJMX_USER \
-e CRYOSTAT_RJMX_PASS=$CRYOSTAT_RJMX_PASS \
-e CRYOSTAT_RJMX_PORT=$CRYOSTAT_RJMX_PORT \
Expand Down
24 changes: 22 additions & 2 deletions smoketest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ function runCryostat() {
GRAFANA_DASHBOARD_URL="http://${host}:${grafanaPort}" \
CRYOSTAT_RJMX_USER=smoketest \
CRYOSTAT_RJMX_PASS=smoketest \
CRYOSTAT_ALLOW_UNTRUSTED_SSL=true \
CRYOSTAT_REPORT_GENERATOR="http://${host}:10001" \
exec "$DIR/run.sh"
}

Expand Down Expand Up @@ -76,6 +78,19 @@ function runGrafana() {
--rm -d "${stream}:${tag}"
}

function runReportGenerator() {
local RJMX_PORT=10000
podman run \
--name reports \
--pod cryostat \
--cpus 1 \
--memory 512M \
--restart on-failure \
--env JAVA_OPTIONS="-XX:ActiveProcessorCount=1 -XX:+UseSerialGC -Dorg.openjdk.jmc.flightrecorder.parser.singlethreaded=true -Dcom.sun.management.jmxremote.autodiscovery=true -Dcom.sun.management.jmxremote.port=${RJMX_PORT} -Dcom.sun.management.jmxremote.rmi.port=${RJMX_PORT} -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" \
--env QUARKUS_HTTP_PORT=10001 \
--rm -d quay.io/cryostat/cryostat-reports:latest
}

function createPod() {
local jmxPort="$(xpath -q -e 'project/properties/cryostat.rjmxPort/text()' pom.xml)"
local webPort="$(xpath -q -e 'project/properties/cryostat.webPort/text()' pom.xml)"
Expand All @@ -97,7 +112,9 @@ function createPod() {
--publish 9999:9999 \
--publish 8082:8082 \
--publish 9990:9990 \
--publish 9991:9991
--publish 9991:9991 \
--publish 10000:10000 \
--publish 10001:10001
# 8081: vertx-fib-demo
# 9093: vertx-fib-demo-1 RJMX
# 9094: vertx-fib-demo-2 RJMX
Expand All @@ -106,7 +123,9 @@ function createPod() {
# 9999: quarkus-test HTTP
# 8082: Wildfly HTTP
# 9990: Wildfly Admin Console
# 9990: Wildfly RJMX
# 9991: Wildfly RJMX
# 10000: cryostat-reports RJMX
# 10001: cryostat-reports HTTP
}

function destroyPod() {
Expand All @@ -119,4 +138,5 @@ createPod
runDemoApps
runJfrDatasource
runGrafana
runReportGenerator
runCryostat
3 changes: 2 additions & 1 deletion src/main/java/io/cryostat/MainModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import javax.management.remote.JMXServiceURL;

import io.cryostat.configuration.ConfigurationModule;
import io.cryostat.configuration.Variables;
import io.cryostat.core.log.Logger;
import io.cryostat.core.sys.Environment;
import io.cryostat.core.tui.ClientWriter;
Expand Down Expand Up @@ -144,7 +145,7 @@ JMXServiceURL.class, new GsonJmxServiceUrlAdapter(logger))
@Singleton
@Named(RECORDINGS_PATH)
static Path provideSavedRecordingsPath(Logger logger, Environment env) {
String archivePath = env.getEnv("CRYOSTAT_ARCHIVE_PATH", "/flightrecordings");
String archivePath = env.getEnv(Variables.ARCHIVE_PATH, "/flightrecordings");
logger.info("Local save path for flight recordings set as {}", archivePath);
return Paths.get(archivePath);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public abstract class ConfigurationModule {
@Singleton
@Named(CONFIGURATION_PATH)
static Path provideConfigurationPath(Logger logger, Environment env) {
String path = env.getEnv("CRYOSTAT_CONFIG_PATH", "/opt/cryostat.d/conf.d");
String path = env.getEnv(Variables.CONFIG_PATH, "/opt/cryostat.d/conf.d");
logger.info(String.format("Local config path set as %s", path));
return Paths.get(path);
}
Expand Down
78 changes: 78 additions & 0 deletions src/main/java/io/cryostat/configuration/Variables.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright The Cryostat Authors
*
* The Universal Permissive License (UPL), Version 1.0
*
* Subject to the condition set forth below, permission is hereby granted to any
* person obtaining a copy of this software, associated documentation and/or data
* (collectively the "Software"), free of charge and under any and all copyright
* rights in the Software, and any and all patent rights owned or freely
* licensable by each licensor hereunder covering either (i) the unmodified
* Software as contributed to or provided by such licensor, or (ii) the Larger
* Works (as defined below), to deal in both
*
* (a) the Software, and
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
* one is included with the Software (each a "Larger Work" to which the Software
* is contributed by such licensors),
*
* without restriction, including without limitation the rights to copy, create
* derivative works of, display, perform, and distribute the Software and make,
* use, sell, offer for sale, import, export, have made, and have sold the
* Software and the Larger Work(s), and to sublicense the foregoing rights on
* either these or other terms.
*
* This license is subject to the following condition:
* The above copyright notice and either this complete permission notice or at
* a minimum a reference to the UPL must be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package io.cryostat.configuration;

public final class Variables {
private Variables() {}

// jfr-datasource, cryostat-grafana-dashboard
public static final String GRAFANA_DATASOURCE_ENV = "GRAFANA_DATASOURCE_URL";
public static final String GRAFANA_DASHBOARD_ENV = "GRAFANA_DASHBOARD_URL";

// report generation
public static final String REPORT_GENERATOR_ENV = "CRYOSTAT_REPORT_GENERATOR";
public static final String SUBPROCESS_MAX_HEAP_ENV = "CRYOSTAT_REPORT_GENERATION_MAX_HEAP";

// SSL configuration
public static final String DISABLE_SSL = "CRYOSTAT_DISABLE_SSL";
public static final String KEYSTORE_PATH_ENV = "KEYSTORE_PATH";
public static final String KEYSTORE_PASS_ENV = "KEYSTORE_PASS";
public static final String KEY_PATH_ENV = "KEY_PATH";
public static final String CERT_PATH_ENV = "CERT_PATH";

// platform configuration
public static final String PLATFORM_STRATEGY_ENV_VAR = "CRYOSTAT_PLATFORM";
public static final String AUTH_MANAGER_ENV_VAR = "CRYOSTAT_AUTH_MANAGER";

// webserver configuration
public static final String WEBSERVER_HOST = "CRYOSTAT_WEB_HOST";
public static final String WEBSERVER_PORT = "CRYOSTAT_WEB_PORT";
public static final String WEBSERVER_PORT_EXT = "CRYOSTAT_EXT_WEB_PORT";
public static final String WEBSERVER_SSL_PROXIED = "CRYOSTAT_SSL_PROXIED";
public static final String WEBSERVER_ALLOW_UNTRUSTED_SSL = "CRYOSTAT_ALLOW_UNTRUSTED_SSL";
public static final String MAX_CONNECTIONS_ENV_VAR = "CRYOSTAT_MAX_WS_CONNECTIONS";
public static final String ENABLE_CORS_ENV = "CRYOSTAT_CORS_ORIGIN";

// JMX connections configuration
public static final String TARGET_CACHE_SIZE = "CRYOSTAT_TARGET_CACHE_SIZE";
public static final String TARGET_CACHE_TTL = "CRYOSTAT_TARGET_CACHE_TTL";

// paths configuration
public static final String ARCHIVE_PATH = "CRYOSTAT_ARCHIVE_PATH";
public static final String CONFIG_PATH = "CRYOSTAT_CONFIG_PATH";
}
5 changes: 2 additions & 3 deletions src/main/java/io/cryostat/messaging/MessagingModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import javax.inject.Named;
import javax.inject.Singleton;

import io.cryostat.configuration.Variables;
import io.cryostat.core.log.Logger;
import io.cryostat.core.sys.Clock;
import io.cryostat.core.sys.Environment;
Expand All @@ -64,8 +65,6 @@ public abstract class MessagingModule {
static final String WS_MAX_CONNECTIONS = "WS_MAX_CONNECTIONS";
static final String LIMBO_PRUNER = "LIMBO_PRUNER";
static final String KEEPALIVE_PINGER = "KEEPALIVE_PINGER";

static final String MAX_CONNECTIONS_ENV_VAR = "CRYOSTAT_MAX_WS_CONNECTIONS";
static final int MIN_CONNECTIONS = 1;
static final int MAX_CONNECTIONS = 64;
static final int DEFAULT_MAX_CONNECTIONS = 2;
Expand Down Expand Up @@ -103,7 +102,7 @@ static int provideWebSocketMaxConnections(Environment env, Logger logger) {
int maxConn =
Integer.parseInt(
env.getEnv(
MAX_CONNECTIONS_ENV_VAR,
Variables.MAX_CONNECTIONS_ENV_VAR,
String.valueOf(DEFAULT_MAX_CONNECTIONS)));
if (maxConn > MAX_CONNECTIONS) {
logger.info("Requested maximum WebSocket connections {} is too large.", maxConn);
Expand Down
12 changes: 7 additions & 5 deletions src/main/java/io/cryostat/net/NetworkConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import java.net.SocketException;
import java.net.UnknownHostException;

import io.cryostat.configuration.Variables;
import io.cryostat.core.sys.Environment;

public class NetworkConfiguration {
Expand All @@ -53,7 +54,7 @@ public class NetworkConfiguration {
}

public String getWebServerHost() throws SocketException, UnknownHostException {
return env.getEnv("CRYOSTAT_WEB_HOST", resolver.getHostAddress());
return env.getEnv(Variables.WEBSERVER_HOST, resolver.getHostAddress());
}

public int getDefaultWebServerPort() {
Expand All @@ -62,19 +63,20 @@ public int getDefaultWebServerPort() {

public int getInternalWebServerPort() {
return Integer.parseInt(
env.getEnv("CRYOSTAT_WEB_PORT", String.valueOf(getDefaultWebServerPort())));
env.getEnv(Variables.WEBSERVER_PORT, String.valueOf(getDefaultWebServerPort())));
}

public int getExternalWebServerPort() {
return Integer.parseInt(
env.getEnv("CRYOSTAT_EXT_WEB_PORT", String.valueOf(getInternalWebServerPort())));
env.getEnv(
Variables.WEBSERVER_PORT_EXT, String.valueOf(getInternalWebServerPort())));
}

public boolean isSslProxied() {
return env.hasEnv("CRYOSTAT_SSL_PROXIED");
return env.hasEnv(Variables.WEBSERVER_SSL_PROXIED);
}

public boolean isUntrustedSslAllowed() {
return env.hasEnv("CRYOSTAT_ALLOW_UNTRUSTED_SSL");
return env.hasEnv(Variables.WEBSERVER_ALLOW_UNTRUSTED_SSL);
}
}
16 changes: 7 additions & 9 deletions src/main/java/io/cryostat/net/NetworkModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import javax.inject.Singleton;

import io.cryostat.configuration.ConfigurationModule;
import io.cryostat.configuration.Variables;
import io.cryostat.core.log.Logger;
import io.cryostat.core.net.JFRConnectionToolkit;
import io.cryostat.core.sys.Environment;
Expand Down Expand Up @@ -77,9 +78,6 @@
})
public abstract class NetworkModule {

static final String TARGET_CACHE_SIZE = "CRYOSTAT_TARGET_CACHE_SIZE";
static final String TARGET_CACHE_TTL = "CRYOSTAT_TARGET_CACHE_TTL";

@Provides
@Singleton
static HttpServer provideHttpServer(
Expand All @@ -101,24 +99,24 @@ static NetworkResolver provideNetworkResolver() {
}

@Provides
@Named(TARGET_CACHE_SIZE)
@Named(Variables.TARGET_CACHE_SIZE)
static int provideMaxTargetConnections(Environment env) {
return Integer.parseInt(env.getEnv(TARGET_CACHE_SIZE, "-1"));
return Integer.parseInt(env.getEnv(Variables.TARGET_CACHE_SIZE, "-1"));
}

@Provides
@Named(TARGET_CACHE_TTL)
@Named(Variables.TARGET_CACHE_TTL)
static Duration provideMaxTargetTTL(Environment env) {
return Duration.ofSeconds(Integer.parseInt(env.getEnv(TARGET_CACHE_TTL, "10")));
return Duration.ofSeconds(Integer.parseInt(env.getEnv(Variables.TARGET_CACHE_TTL, "10")));
}

@Provides
@Singleton
static TargetConnectionManager provideTargetConnectionManager(
Lazy<JFRConnectionToolkit> connectionToolkit,
PlatformClient platformClient,
@Named(TARGET_CACHE_TTL) Duration maxTargetTtl,
@Named(TARGET_CACHE_SIZE) int maxTargetConnections,
@Named(Variables.TARGET_CACHE_TTL) Duration maxTargetTtl,
@Named(Variables.TARGET_CACHE_SIZE) int maxTargetConnections,
Logger logger) {
return new TargetConnectionManager(
connectionToolkit,
Expand Down
24 changes: 10 additions & 14 deletions src/main/java/io/cryostat/net/SslConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

import java.nio.file.Path;

import io.cryostat.configuration.Variables;
import io.cryostat.core.log.Logger;
import io.cryostat.core.sys.Environment;
import io.cryostat.core.sys.FileSystem;
Expand All @@ -56,18 +57,13 @@ public class SslConfiguration {

private final SslConfigurationStrategy strategy;

private static final String KEYSTORE_PATH_ENV = "KEYSTORE_PATH";
private static final String KEYSTORE_PASS_ENV = "KEYSTORE_PASS";
private static final String KEY_PATH_ENV = "KEY_PATH";
private static final String CERT_PATH_ENV = "CERT_PATH";

SslConfiguration(Environment env, FileSystem fs, Logger logger)
throws SslConfigurationException {
this.env = env;
this.fs = fs;
this.logger = logger;

if (env.hasEnv("CRYOSTAT_DISABLE_SSL")) {
if (env.hasEnv(Variables.DISABLE_SSL)) {
strategy = new NoSslStrategy();
logger.info("Selected NoSSL strategy");
return;
Expand All @@ -76,7 +72,7 @@ public class SslConfiguration {
{
Path path = obtainKeyStorePathIfSpecified();
if (path != null) {
strategy = new KeyStoreStrategy(path, env.getEnv(KEYSTORE_PASS_ENV, ""));
strategy = new KeyStoreStrategy(path, env.getEnv(Variables.KEYSTORE_PASS_ENV, ""));
logger.info("Selected SSL KeyStore strategy with keystore {}", path.toString());
return;
}
Expand All @@ -99,7 +95,7 @@ public class SslConfiguration {
{
Path path = discoverKeyStorePathInDefaultLocations();
if (path != null) {
strategy = new KeyStoreStrategy(path, env.getEnv(KEYSTORE_PASS_ENV, ""));
strategy = new KeyStoreStrategy(path, env.getEnv(Variables.KEYSTORE_PASS_ENV, ""));
logger.info("Selected SSL KeyStore strategy in default location");
return;
}
Expand Down Expand Up @@ -128,11 +124,11 @@ public class SslConfiguration {
}

Path obtainKeyStorePathIfSpecified() throws SslConfigurationException {
if (!env.hasEnv(KEYSTORE_PATH_ENV)) {
if (!env.hasEnv(Variables.KEYSTORE_PATH_ENV)) {
return null;
}

Path path = fs.pathOf(env.getEnv(KEYSTORE_PATH_ENV)).normalize();
Path path = fs.pathOf(env.getEnv(Variables.KEYSTORE_PATH_ENV)).normalize();
if (!fs.exists(path)) {
throw new SslConfigurationException(
String.format(
Expand All @@ -144,16 +140,16 @@ Path obtainKeyStorePathIfSpecified() throws SslConfigurationException {
}

Pair<Path, Path> obtainKeyCertPathPairIfSpecified() throws SslConfigurationException {
if (!env.hasEnv(KEY_PATH_ENV) && !env.hasEnv(CERT_PATH_ENV)) {
if (!env.hasEnv(Variables.KEY_PATH_ENV) && !env.hasEnv(Variables.CERT_PATH_ENV)) {
return null;
}

if (env.hasEnv(KEY_PATH_ENV) ^ env.hasEnv(CERT_PATH_ENV)) {
if (env.hasEnv(Variables.KEY_PATH_ENV) ^ env.hasEnv(Variables.CERT_PATH_ENV)) {
throw new SslConfigurationException("both KEY_PATH and CERT_PATH must be specified");
}

Path key = fs.pathOf(env.getEnv(KEY_PATH_ENV)).normalize();
Path cert = fs.pathOf(env.getEnv(CERT_PATH_ENV)).normalize();
Path key = fs.pathOf(env.getEnv(Variables.KEY_PATH_ENV)).normalize();
Path cert = fs.pathOf(env.getEnv(Variables.CERT_PATH_ENV)).normalize();
if (!fs.exists(key)) {
throw new SslConfigurationException(
String.format(
Expand Down
Loading