<commit_before>package com.yammer.metrics.core;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static com.yammer.metrics.core.VirtualMachineMetrics.*;

import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerator;

public class ReporterServlet extends HttpServlet {
	private final Map<MetricName, Metric> metrics;
	private final JsonFactory factory = new JsonFactory();

	/*package*/ ReporterServlet(Map<MetricName, Metric> metrics) {
		this.metrics = metrics;
	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		final String uri = req.getPathInfo();
		if (uri.equals("/metrics")) {
			handleStats(resp);
		} else if (uri.equals("/ping")) {
			handlePing(resp);
		} else if (uri.equals("/thread-dump")) {
			handleThreadDump(resp);
		} else {
			// TODO: 1/11/11 <coda> -- healthcheck
			resp.sendError(HttpServletResponse.SC_NOT_FOUND);
		}
	}

	private void handleThreadDump(HttpServletResponse resp) throws IOException {
		resp.setStatus(HttpServletResponse.SC_OK);
		resp.setContentType("text/plain");
		final PrintWriter writer = resp.getWriter();

		Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
		for (Entry<Thread, StackTraceElement[]> entry : traces.entrySet()) {
			Thread t = entry.getKey();
			writer.format("Thread: %s  %s\n", t.getName(), t.isDaemon() ? "daemon" : "non-daemon");
			if (!t.isDaemon()) {
				for (StackTraceElement frame : entry.getValue()) {
					writer.format("\t%s.%s[%s:%d]\n", frame.getClassName(), frame.getMethodName(),
							frame.getFileName(), frame.getLineNumber());
				}
			}
		}
		writer.close();
	}

	private void handlePing(HttpServletResponse resp) throws IOException {
		resp.setStatus(HttpServletResponse.SC_OK);
		resp.setContentType("text/plain");
		final PrintWriter writer = resp.getWriter();
		writer.println("pong");<commit_msg>Added HTTP reporting of health checks.<commit_after>package com.yammer.metrics.core;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static com.yammer.metrics.core.VirtualMachineMetrics.*;

import com.yammer.metrics.core.HealthCheck.Result;
import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerator;

public class ReporterServlet extends HttpServlet {
	private final Map<MetricName, Metric> metrics;
	private final Map<String, HealthCheck> healthChecks;
	private final JsonFactory factory = new JsonFactory();

	/*package*/ ReporterServlet(Map<MetricName, Metric> metrics, Map<String, HealthCheck> healthChecks) {
		this.metrics = metrics;
		this.healthChecks = healthChecks;
	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		final String uri = req.getPathInfo();
		if (uri.equals("/metrics")) {
			handleStats(resp);
		} else if (uri.equals("/ping")) {
			handlePing(resp);
		} else if (uri.equals("/thread-dump")) {
			handleThreadDump(resp);
		} else if (uri.equals("/healthcheck")) {
			handleHealthCheck(resp);
		} else {
			resp.sendError(HttpServletResponse.SC_NOT_FOUND);
		}
	}

	private void handleHealthCheck(HttpServletResponse resp) throws IOException {
		boolean allHealthy = true;
		final Map<String, Result> results = new TreeMap<String, Result>();
		for (Entry<String, HealthCheck> entry : healthChecks.entrySet()) {
			final Result result = entry.getValue().execute();
			allHealthy &= result.isHealthy();
			results.put(entry.getKey(), result);
		}

		PrintWriter writer;
		if (allHealthy) {
			resp.setStatus(HttpServletResponse.SC_OK);
			resp.setContentType("text/plain");
			writer = resp.getWriter();


		} else {
			resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
			resp.setContentType("text/plain");
			writer = resp.getWriter();
		}

		for (Entry<String, Result> entry : results.entrySet()) {
			final Result result = entry.getValue();
			if (result.isHealthy()) {
				writer.format("* %s: OK\n", entry.getKey());
			} else {
				if (result.getMessage() != null) {
					writer.format("! %s: ERROR\n!  %s\n", entry.getKey(), result.getMessage());
				}

				if (result.getError() != null) {
					writer.println();
					result.getError().printStackTrace(writer);
					writer.println();
				}
			}
		}

	}

	private void handleThreadDump(HttpServletResponse resp) throws IOException {
		resp.setStatus(HttpServletResponse.SC_OK);
		resp.setContentType("text/plain");
		final PrintWriter writer = resp.getWriter();

		Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
		for (Entry<Thread, StackTraceElement[]> entry : traces.entrySet()) {
			Thread t = entry.getKey();
			writer.format("Thread: %s  %s\n", t.getName(), t.isDaemon() ? "daemon" : "non-daemon");
			if (!t.isDaemon()) {
				for (StackTraceElement frame : entry.getValue()) {
					writer.format("\t%s.%s[%s:%d]\n", frame.getClassName(), frame.getMethodName(),
							frame.getFileName(), frame.getLineNumber());
				}
			}
		}
		writer.close();
	}

	private void handlePing(HttpServletResponse resp) throws IOException {
		resp.setStatus(HttpServletResponse.SC_OK);
		resp.setContentType("text/plain");
		final PrintWriter writer = resp.getWriter();
		writer.println("pong");
{'fraction_non_alphanumeric': 0.13811965811965812, 'fraction_numerical': 0.0008547008547008547, 'mean_word_length': 4.845154845154845, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6437545', 'n_tokens_mistral': 1958, 'n_tokens_neox': 1781, 'n_words': 367}