Skip to content

Commit

Permalink
Merge 02ff2a8 into 0a1bb19
Browse files Browse the repository at this point in the history
  • Loading branch information
decebals committed Jul 16, 2018
2 parents 0a1bb19 + 02ff2a8 commit 26a588a
Show file tree
Hide file tree
Showing 6 changed files with 306 additions and 0 deletions.
31 changes: 31 additions & 0 deletions pippo-core/src/main/java/ro/pippo/core/route/PingHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ro.pippo.core.route;

/**
* Returns "pong" text as response.
* The handler can be used to check the connection to the server.
*
* @author Decebal Suiu
*/
public class PingHandler implements RouteHandler {

@Override
public void handle(RouteContext routeContext) {
routeContext.getResponse().noCache().text().send("pong");
}

}
73 changes: 73 additions & 0 deletions pippo-core/src/main/java/ro/pippo/core/route/SettingsHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (C) 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ro.pippo.core.route;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ro.pippo.core.PippoSettings;
import ro.pippo.core.Response;

import java.io.BufferedWriter;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

/**
* Displays settings.
* See {@link PippoSettings}.
*
* @author Decebal Suiu
*/
public class SettingsHandler implements RouteHandler {

private static final Logger log = LoggerFactory.getLogger(SettingsHandler.class);

@Override
public void handle(RouteContext routeContext) {
Map<String, String> settingsMap = settingsToMap(routeContext.getSettings());

Response response = routeContext.getResponse().noCache().text();

try (BufferedWriter writer = new BufferedWriter(response.getWriter())) {
writeSettings(settingsMap, writer);
writer.flush();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}

protected Map<String, String> settingsToMap(PippoSettings settings) {
List<String> settingNames = settings.getSettingNames();
Map<String, String> settingsMap = new TreeMap<>();
for (String settingName : settingNames) {
settingsMap.put(settingName, settings.getRequiredString(settingName));
}

return settingsMap;
}

protected void writeSettings(Map<String, String> settings, BufferedWriter writer) throws IOException {
Set<String> names = new TreeSet<>(settings.keySet());
for (String name : names) {
writer.write(name + " = " + settings.get(name));
writer.newLine();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (C) 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ro.pippo.core.route;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ro.pippo.core.Response;

import java.io.BufferedWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

/**
* Display information about system:
* <ul>
* <li>system properties</li>
* <li>system environment</li>
* </ul>
* .
* See {@link System#getenv()}.
*
* @author Decebal Suiu
*/
public class SystemInfoHandler implements RouteHandler {

private static final Logger log = LoggerFactory.getLogger(SystemInfoHandler.class);

@Override
public void handle(RouteContext routeContext) {
Map<String, String> props = new HashMap<>();
for (String name : System.getProperties().stringPropertyNames()) {
props.put(name, System.getProperty(name));
}

Map<String, String> env = System.getenv();

Response response = routeContext.getResponse().noCache().text();

try (BufferedWriter writer = new BufferedWriter(response.getWriter())) {
writeProperties(props, writer);
writer.newLine();
writeProperties(env, writer);

writer.flush();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}

protected void writeProperties(Map<String, String> map, BufferedWriter writer) throws IOException {
Set<String> keys = new TreeSet<>(map.keySet());
for (String key : keys) {
writer.write(key + " = " + map.get(key));
writer.newLine();
}
}

}
6 changes: 6 additions & 0 deletions pippo-metrics-parent/pippo-metrics/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@
<version>${metrics.version}</version>
</dependency>

<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-healthchecks</artifactId>
<version>${metrics.version}</version>
</dependency>

<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-jmx</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ro.pippo.metrics;

import com.codahale.metrics.health.HealthCheck;
import com.codahale.metrics.health.HealthCheckRegistry;
import ro.pippo.core.Response;
import ro.pippo.core.route.RouteContext;
import ro.pippo.core.route.RouteHandler;

import java.util.SortedMap;

/**
* Returns a response with following status code:
* <ul>
* <li>501 (not implemented) if the registry is empty (no health checks)</li>
* <li>200 (ok) if all the health checks are healthy</li>
* <li>500 (internal error) otherwise</li>
* </ul>
*
* @author Decebal Suiu
*/
public class HealthCheckHandler implements RouteHandler {

final HealthCheckRegistry healthCheckRegistry;

public HealthCheckHandler(HealthCheckRegistry healthCheckRegistry) {
this.healthCheckRegistry = healthCheckRegistry;
}

@Override
public void handle(RouteContext routeContext) {
Response response = routeContext.getResponse().noCache().text();

SortedMap<String, HealthCheck.Result> healthChecks = healthCheckRegistry.runHealthChecks();
if (healthChecks.isEmpty()) {
response.notImplemented().send("The health checks are empty");
} else {
boolean notHealthy = healthChecks.values().stream().anyMatch(hc -> !hc.isHealthy());
if (notHealthy) {
response.internalError().send("The health is bad");
} else {
response.ok().send("The health is good");
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ro.pippo.metrics;

import com.codahale.metrics.jvm.ThreadDump;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ro.pippo.core.Response;
import ro.pippo.core.route.RouteContext;
import ro.pippo.core.route.RouteHandler;

import java.io.OutputStream;
import java.lang.management.ManagementFactory;

/**
* Returns a thread dump (thread states) as response.
* If the thread dump is not supported then the status code returned is 501 (not implemented).
*
* @author Decebal Suiu
*/
public class ThreadDumpHandler implements RouteHandler {

private static final Logger log = LoggerFactory.getLogger(ThreadDumpHandler.class);

private ThreadDump threadDump;

public ThreadDumpHandler() {
try {
// some PaaS like Google App Engine blacklist "java.lang.management" package
threadDump = new ThreadDump(ManagementFactory.getThreadMXBean());
} catch (NoClassDefFoundError e) {
log.warn("Thread dump isn't available", e);
}
}

@Override
public void handle(RouteContext routeContext) {
Response response = routeContext.getResponse().noCache().text();

if (threadDump != null) {
OutputStream output = response.getOutputStream();
threadDump.dump(output);
} else {
response.internalError().send("Sorry your runtime environment does not allow to dump threads");
}
}

}

0 comments on commit 26a588a

Please sign in to comment.