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

[jmxfetch] transition to auto-discovery nomenclature, support legacy SD. #142

Merged
merged 3 commits into from
Jun 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
59 changes: 33 additions & 26 deletions src/main/java/org/datadog/jmxfetch/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@
@SuppressWarnings("unchecked")
public class App {
private final static Logger LOGGER = Logger.getLogger(App.class.getName());
private final static String SERVICE_DISCOVERY_PREFIX = "SD-";
private final static String AUTO_DISCOVERY_PREFIX = "AD-";
public static final String CANNOT_CONNECT_TO_INSTANCE = "Cannot connect to instance ";
private static final String SD_CONFIG_SEP = "#### SERVICE-DISCOVERY ####";
private static final String AD_CONFIG_SEP = "#### AUTO-DISCOVERY ####";
private static final String AD_LEGACY_CONFIG_SEP = "#### SERVICE-DISCOVERY ####";
private static int loopCounter;
private AtomicBoolean reinit = new AtomicBoolean(false);
private ConcurrentHashMap<String, YamlParser> configs;
private ConcurrentHashMap<String, YamlParser> sdConfigs = new ConcurrentHashMap<String, YamlParser>();
private ConcurrentHashMap<String, YamlParser> adConfigs = new ConcurrentHashMap<String, YamlParser>();
private ArrayList<Instance> instances = new ArrayList<Instance>();
private LinkedList<Instance> brokenInstances = new LinkedList<Instance>();
private AppConfig appConfig;
Expand Down Expand Up @@ -161,30 +162,36 @@ private static void clearInstances(List<Instance> instances) {
}
}

private String getSDName(String config){
private String getAutoDiscoveryName(String config){
String[] splitted = config.split(System.getProperty("line.separator"), 2);

return SERVICE_DISCOVERY_PREFIX + splitted[0].substring(2, splitted[0].length());
return AUTO_DISCOVERY_PREFIX + splitted[0].substring(2, splitted[0].length());
}

private FileInputStream newSdPipe() {
FileInputStream sdPipe = null;
private FileInputStream newAutoDiscoveryPipe() {
FileInputStream adPipe = null;
try {
sdPipe = new FileInputStream(appConfig.getServiceDiscoveryPipe()); //Should we use RandomAccessFile?
LOGGER.info("Named pipe for Service Discovery opened");
adPipe = new FileInputStream(appConfig.getAutoDiscoveryPipe()); //Should we use RandomAccessFile?
LOGGER.info("Named pipe for Auto-Discovery opened");
} catch (FileNotFoundException e) {
LOGGER.info("Unable to open named pipe for Service Discovery.");
LOGGER.info("Unable to open named pipe for Auto-Discovery.");
}
return sdPipe;

return adPipe;
}

public boolean processServiceDiscovery(byte[] buffer) {
public boolean processAutoDiscovery(byte[] buffer) {
boolean reinit = false;
String[] discovered;

try {
String configs = new String(buffer, CharEncoding.UTF_8);
discovered = configs.split(App.SD_CONFIG_SEP + System.getProperty("line.separator"));
String separator = App.AD_CONFIG_SEP;

if (configs.indexOf(App.AD_LEGACY_CONFIG_SEP) != -1) {
separator = App.AD_LEGACY_CONFIG_SEP;
}
discovered = configs.split(separator + System.getProperty("line.separator"));
} catch(UnsupportedEncodingException e) {
LOGGER.debug("Unable to parse byte buffer to UTF-8 String.");
return false;
Expand All @@ -196,7 +203,7 @@ public boolean processServiceDiscovery(byte[] buffer) {
}

try{
String name = getSDName(config);
String name = getAutoDiscoveryName(config);
LOGGER.debug("Attempting to apply config. Name: " + name + "\nconfig: \n" + config);
InputStream stream = new ByteArrayInputStream(config.getBytes(CharEncoding.UTF_8));
YamlParser yaml = new YamlParser(stream);
Expand All @@ -217,11 +224,11 @@ void start() {
// Main Loop that will periodically collect metrics from the JMX Server
long start_ms = System.currentTimeMillis();
long delta_s = 0;
FileInputStream sdPipe = null;
FileInputStream adPipe = null;

if(appConfig.getSDEnabled()) {
LOGGER.info("Service Discovery enabled");
sdPipe = newSdPipe();
if(appConfig.getAutoDiscoveryEnabled()) {
LOGGER.info("Auto Discovery enabled");
adPipe = newAutoDiscoveryPipe();
}

while (true) {
Expand All @@ -232,16 +239,16 @@ void start() {
}

// any SD configs waiting in pipe?
if(sdPipe == null && appConfig.getSDEnabled()) {
if(adPipe == null && appConfig.getAutoDiscoveryEnabled()) {
// If SD is enabled and the pipe is not open, retry opening pipe
sdPipe = newSdPipe();
adPipe = newAutoDiscoveryPipe();
}
try {
int len;
if(sdPipe != null && (len = sdPipe.available()) > 0) {
if(adPipe != null && (len = adPipe.available()) > 0) {
byte[] buffer = new byte[len];
sdPipe.read(buffer);
setReinit(processServiceDiscovery(buffer));
adPipe.read(buffer);
setReinit(processAutoDiscovery(buffer));
}
} catch(IOException e) {
LOGGER.warn("Unable to read from pipe - Service Discovery configuration may have been skipped.");
Expand Down Expand Up @@ -383,7 +390,7 @@ public void doIteration() {

public boolean addConfig(String name, YamlParser config) {
// named groups not supported with Java6: "(?<check>.{1,30})_(?<version>\\d{0,30})"
Pattern pattern = Pattern.compile(SERVICE_DISCOVERY_PREFIX+"(.{1,30})_(\\d{0,30})");
Pattern pattern = Pattern.compile(AUTO_DISCOVERY_PREFIX+"(.{1,30})_(\\d{0,30})");

Matcher matcher = pattern.matcher(name);
if (!matcher.find()) {
Expand All @@ -398,7 +405,7 @@ public boolean addConfig(String name, YamlParser config) {
return false;
}

this.sdConfigs.put(name, config);
this.adConfigs.put(name, config);
this.setReinit(true);

return true;
Expand Down Expand Up @@ -469,7 +476,7 @@ public void init(boolean forceNewConnection) {

Iterator<Entry<String, YamlParser>> it = configs.entrySet().iterator();
// SD config cache doesn't remove configs - it just overwrites.
Iterator<Entry<String, YamlParser>> itSD = sdConfigs.entrySet().iterator();
Iterator<Entry<String, YamlParser>> itSD = adConfigs.entrySet().iterator();
while (it.hasNext() || itSD.hasNext()) {
Map.Entry<String, YamlParser> entry;
boolean sdIterator = false;
Expand Down
27 changes: 14 additions & 13 deletions src/main/java/org/datadog/jmxfetch/AppConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ class AppConfig {
public static final HashSet<String> ACTIONS = new HashSet<String>(Arrays.asList(ACTION_COLLECT, ACTION_LIST_EVERYTHING,
ACTION_LIST_COLLECTED, ACTION_LIST_MATCHING, ACTION_LIST_NOT_MATCHING, ACTION_LIST_LIMITED, ACTION_HELP, ACTION_LIST_JVMS));

private static final String SD_WIN_PIPE_PATH = "\\\\.\\pipe\\";
private static final String SD_PIPE_NAME = "dd-service_discovery";
private static final String AD_WIN_PIPE_PATH = "\\\\.\\pipe\\";
private static final String AD_LEGACY_PIPE_NAME = "dd-service_discovery";
private static final String AD_PIPE_NAME = "dd-auto_discovery";

@Parameter(names = {"--help", "-h"},
description = "Display this help page",
Expand Down Expand Up @@ -76,15 +77,15 @@ class AppConfig {
required = false)
private int checkPeriod = 15000;

@Parameter(names = {"--sd_enabled", "-w"},
description = "Enable Service Discovery.",
@Parameter(names = {"--ad_enabled", "--sd_enabled", "-w"},
description = "Enable Auto Discovery.",
required = false)
private boolean sdEnabled = false;
private boolean adEnabled = false;

@Parameter(names = {"--sd_pipe", "-S"},
description = "Service Discovery pipe name.",
@Parameter(names = {"--ad_pipe", "--sd_pipe", "-P"},
description = "Auto Discovery pipe name.",
required = false)
private String sdPipe = SD_PIPE_NAME;
private String adPipe = AD_PIPE_NAME;

@Parameter(names = {"--status_location", "-s"},
description = "Absolute path of the status file. (default to null = no status file written)",
Expand Down Expand Up @@ -128,8 +129,8 @@ public int getCheckPeriod() {
return checkPeriod;
}

public boolean getSDEnabled() {
return sdEnabled;
public boolean getAutoDiscoveryEnabled() {
return adEnabled;
}

public Reporter getReporter() {
Expand All @@ -156,13 +157,13 @@ public String getLogLocation() {
return logLocation;
}

public String getServiceDiscoveryPipe() {
public String getAutoDiscoveryPipe() {
String pipePath;

if (System.getProperty("os.name").startsWith("Windows")) {
pipePath = SD_WIN_PIPE_PATH + "/" + sdPipe;
pipePath = AD_WIN_PIPE_PATH + "/" + adPipe;
} else {
pipePath = getTmpDirectory() + "/" + sdPipe;
pipePath = getTmpDirectory() + "/" + adPipe;
}
return pipePath;
}
Expand Down
14 changes: 7 additions & 7 deletions src/test/java/org/datadog/jmxfetch/TestCommon.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ public void unregisterMBean() throws MBeanRegistrationException, InstanceNotFoun
/**
* Init JMXFetch with the given YAML configuration file.
*/
protected void initApplication(String yamlFileName, String serviceDiscoveryPipeFile) throws FileNotFoundException, IOException {
protected void initApplication(String yamlFileName, String autoDiscoveryPipeFile) throws FileNotFoundException, IOException {
// We do a first collection
// We initialize the main app that will collect these metrics using JMX
String confdDirectory = Thread.currentThread().getContextClassLoader().getResource(yamlFileName).getPath();
confdDirectory = new String(confdDirectory.substring(0, confdDirectory.length() - yamlFileName.length()));
List<String> params = new ArrayList<String>();
boolean sdEnabled = (serviceDiscoveryPipeFile.length() > 0);
boolean sdEnabled = (autoDiscoveryPipeFile.length() > 0);
params.add("--reporter");
params.add("console");
params.add("-c");
Expand All @@ -108,18 +108,18 @@ protected void initApplication(String yamlFileName, String serviceDiscoveryPipeF
new JCommander(appConfig, params.toArray(new String[params.size()]));

if (sdEnabled) {
String SDPipe = Thread.currentThread().getContextClassLoader().getResource(
serviceDiscoveryPipeFile).getPath();
when(appConfig.getServiceDiscoveryPipe()).thenReturn(SDPipe); //mocking with fixture file.
String autoDiscoveryPipe = Thread.currentThread().getContextClassLoader().getResource(
autoDiscoveryPipeFile).getPath();
when(appConfig.getAutoDiscoveryPipe()).thenReturn(autoDiscoveryPipe); //mocking with fixture file.
}

app = new App(appConfig);
if (sdEnabled) {
FileInputStream sdPipe = new FileInputStream(appConfig.getServiceDiscoveryPipe());
FileInputStream sdPipe = new FileInputStream(appConfig.getAutoDiscoveryPipe());
int len = sdPipe.available();
byte[] buffer = new byte[len];
sdPipe.read(buffer);
app.setReinit(app.processServiceDiscovery(buffer));
app.setReinit(app.processAutoDiscovery(buffer));
}

app.init(false);
Expand Down