All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.welen.jmole.protocols.munin.MuninSocketHandler Maven / Gradle / Ivy
package net.welen.jmole.protocols.munin;
/*
* #%L
* JMole, https://bitbucket.org/awelen/jmole
* %%
* Copyright (C) 2015 - 2019 Anders Welén, [email protected]
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Locale;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import net.welen.jmole.Configuration;
import net.welen.jmole.collector.MBeanCollector;
import net.welen.jmole.finder.MBeanFinder;
import net.welen.jmole.presentation.PresentationInformation;
import net.welen.jmole.threshold.Threshold;
import net.welen.jmole.threshold.ThresholdValues;
public class MuninSocketHandler extends Thread {
private final static Logger LOG = Logger.getLogger(MuninSocketHandler.class.getName());
private Socket socket;
private Munin setup;
public MuninSocketHandler(Socket socket, Munin setup) {
this.socket = socket;
this.setup = setup;
this.setName("JMole Munin protocol thread #" + setup.currentThreads);
}
public void run() {
try {
setup.currentThreads++;
socket.setSoTimeout(setup.getTcpReadTimeOut());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"), true);
boolean multigraph = false;
// Send greeting
out.println("# munin node at "
+ socket.getLocalAddress().getHostAddress() + ":"
+ socket.getLocalPort());
int maxThreads = setup.getMaxThreads();
if (setup.currentThreads > maxThreads) {
out.println("# Max number of clients reached: " + maxThreads + ". Hanging up.");
throw new IOException("Max number of clients reached: " + maxThreads);
}
while (true) {
String command = reader.readLine();
if (command == null) {
break;
}
// Strip/cleanup command
command = command.replaceAll("\\b\\s{2,}\\b", " ").trim().toLowerCase(Locale.ENGLISH);
// Parse command
if (command.startsWith("quit")) { // quit
socket.close();
return;
} else if (command.startsWith("version")) { // version
// TODO Version number. Is this used for anything?
out.println("Munin JMole node version: 1.4.5");
} else if (command.startsWith("list")) { // list
if (multigraph) {
out.println("jmole");
} else {
LOG.log(Level.SEVERE, "cap multigraph not executed. Returning nothing.");
out.println("");
}
} else if (command.startsWith("cap ") // cap
&& command.contains("multigraph")) {
multigraph = true;
out.println("cap multigraph");
} else if (command.startsWith("config")) { // config
if (command.equals("config jmole")) {
out.println(executeConfig());
} else {
out.println("# Unknown service\n.");
}
} else if (command.startsWith("fetch")) { // fetch
if (command.equals("fetch jmole")) {
out.println(executeFetch());
} else {
out.println("# Unknown service\n.");
}
} else {
out.println("# Unknown command");
}
}
} catch (SocketTimeoutException e) {
LOG.log(Level.WARNING, e.getMessage(), e);
} catch (Exception e) {
LOG.log(Level.SEVERE, e.getMessage(), e);
} finally {
setup.currentThreads--;
try {
socket.close();
} catch (IOException e) {
LOG.log(Level.SEVERE, e.getMessage(), e);
}
}
}
private String executeConfig() throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException {
StringBuilder answer = new StringBuilder();
for (Configuration configuration : setup.jmole.getConfiguration()) {
MBeanFinder finder = configuration.getMBeanFinder();
if (finder.getMatchingObjectNames().isEmpty()) {
continue;
}
MBeanCollector collector = configuration.getMBeanCollector();
PresentationInformation presentationInformation = configuration.getPresentationInformation();
for (ObjectName objectName : finder.getMatchingObjectNames()) {
answer.append("multigraph " + fixForMunin(collector.getConstructedName(objectName)) + "\n");
if (presentationInformation.getCategory() != null) {
answer.append("graph_category " + presentationInformation.getCategory() + "\n");
}
answer.append("graph_title " + collector.getConstructedName(objectName) + "\n");
if (presentationInformation.getUnit() != null) {
answer.append("graph_vlabel " + presentationInformation.getUnit() + "\n");
}
if (presentationInformation.getDescription() != null) {
answer.append("graph_info " + presentationInformation.getDescription() + "\n");
}
// Hardcoded layout
answer.append("graph_printf %.0lf\n");
for (String attribute : collector.getAttributes()) {
String fixedAttribute = fixForMunin(attribute);
answer.append(fixedAttribute + ".label " + presentationInformation.translateAttributeLabel(attribute) + "\n");
String description = presentationInformation.getAttributeDescription(attribute);
if (description != null) {
answer.append(fixedAttribute + ".info " + description + "\n");
}
Threshold threshold = configuration.getThresholds().get(attribute);
if (threshold != null) {
ThresholdValues individualValues = threshold.getIndividualThresholds().get(collector.getConstructedName(objectName));
String low;
String high;
// Warnings
if (individualValues == null) {
low = threshold.getWarningLowThreshold();
high = threshold.getWarningHighThreshold();
} else {
low = individualValues.getWarningLowThreshold();
high = individualValues.getWarningHighThreshold();
}
// TODO When Munin Ticket 1016 is impl. the calculation may not be needed
String tmp = Threshold.calculateThreshold(low, collector, objectName, attribute)
+ ":"
+ Threshold.calculateThreshold(high, collector, objectName, attribute);
if (!tmp.equals(":")) {
answer.append(fixedAttribute + ".warning " + tmp + "\n");
}
// Critical
if (individualValues == null) {
low = threshold.getCriticalLowThreshold();
high = threshold.getCriticalHighThreshold();
} else {
low = individualValues.getCriticalLowThreshold();
high = individualValues.getCriticalHighThreshold();
}
// TODO When Munin Ticket 1016 is impl. the calculation may not be needed
tmp = Threshold.calculateThreshold(low, collector, objectName, attribute)
+ ":"
+ Threshold.calculateThreshold(high, collector, objectName, attribute);
if (!tmp.equals(":")) {
answer.append(fixedAttribute + ".critical " + tmp + "\n");
}
}
}
}
}
return answer.append(".\n").toString();
}
private String executeFetch() throws InstanceNotFoundException, ReflectionException, AttributeNotFoundException, MBeanException {
StringBuilder answer = new StringBuilder();
for (Configuration configuration : setup.jmole.getConfiguration()) {
MBeanFinder finder = configuration.getMBeanFinder();
MBeanCollector collector = configuration.getMBeanCollector();
for (ObjectName objectName : finder.getMatchingObjectNames()){
answer.append("multigraph " + fixForMunin(collector.getConstructedName(objectName)) + "\n");
for (Entry entry : collector.getValues(objectName).entrySet()) {
String valueString = translateValue(entry.getValue());
answer.append(fixForMunin(entry.getKey()) + ".value " + valueString + "\n");
}
}
}
return answer.append(".\n").toString();
}
// Munin can only handle numeric values
private String translateValue(Object value) {
if (value == null) {
// TODO Or should we return 0?
return "";
}
if (value instanceof Boolean) {
if ((Boolean) value) {
return "1";
}
return "0";
}
return value.toString();
}
// Munin can't handle special characters
private String fixForMunin(String input) {
return input.replaceAll("[^a-zA-Z0-9]", "_");
}
}