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

fix for colon split for windows paths #364

Closed
wants to merge 1 commit into from
Closed
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.prometheus.jmx;

class AgentParameters {

private final String hostName;
private final int port;
private final String settingsFilePath;

AgentParameters(String hostName, int port, String settingsFilePath) {
this.hostName = hostName;
this.port = port;
this.settingsFilePath = settingsFilePath;
}

String getHost() {
return hostName;
}

int getPort() {
return port;
}

String getSettingsFilePath() {
return settingsFilePath;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,54 +3,72 @@
import java.io.File;
import java.lang.instrument.Instrumentation;
import java.net.InetSocketAddress;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exporter.HTTPServer;
import io.prometheus.client.hotspot.DefaultExports;

public class JavaAgent {

static HTTPServer server;

public static void agentmain(String agentArgument, Instrumentation instrumentation) throws Exception {
premain(agentArgument, instrumentation);
}

public static void premain(String agentArgument, Instrumentation instrumentation) throws Exception {
// Bind to all interfaces by default (this includes IPv6).
String host = "0.0.0.0";

// If we have IPv6 address in square brackets, extract it first and then
// remove it from arguments to prevent confusion from too many colons.
Integer indexOfClosingSquareBracket = agentArgument.indexOf("]:");
if (indexOfClosingSquareBracket >= 0) {
host = agentArgument.substring(0, indexOfClosingSquareBracket + 1);
agentArgument = agentArgument.substring(indexOfClosingSquareBracket + 2);
}

String[] args = agentArgument.split(":");
if (args.length < 2 || args.length > 3) {
System.err.println("Usage: -javaagent:/path/to/JavaAgent.jar=[host:]<port>:<yaml configuration file>");
System.exit(1);
}

int port;
String file;
InetSocketAddress socket;

if (args.length == 3) {
port = Integer.parseInt(args[1]);
socket = new InetSocketAddress(args[0], port);
file = args[2];
} else {
port = Integer.parseInt(args[0]);
socket = new InetSocketAddress(host, port);
file = args[1];
}

new BuildInfoCollector().register();
new JmxCollector(new File(file)).register();
DefaultExports.initialize();
server = new HTTPServer(socket, CollectorRegistry.defaultRegistry, true);
}
static final String DEFAULT_HOST = "0.0.0.0";

private static final String IPV6_REGEX = "((\\[.*\\]+):)";
private static final String DNS_IPV4_REGEX = "(((\\w+\\.)+\\w+):)";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about DNS is v4?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I get your question there.
The DNS_IPV4_REGEX means that regex applies to both DNS names and ipv4 addresses.

private static final String PORT_REGEX = "(([0-9]+):)";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does java support port names?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by port names?
If you meant group names, yes, java does support them but only starting from version 7 while the pom file in the project specifies java 6.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http is 80 for example, from /etc/services.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typically, if you use HTTP and you don't specify a port, the default one would be taken, which is 80. Same for HTTPS; 443 would be your default port if you don't specify a custom one.

I don't see how that's relevant to the arg parsing tho.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point is that the string http is equivalent to 80, and both are valid ports. You're only matching numbers.

private static final String PATH_REGEX = "(.*)";

private static final Pattern IPV6_PATTERN = Pattern.compile("^" + IPV6_REGEX + PORT_REGEX + PATH_REGEX);
private static final Pattern PORT_PATTERN = Pattern.compile("^" + PORT_REGEX + PATH_REGEX);
private static final Pattern DNS_IPV4_PATTERN = Pattern.compile("^" + DNS_IPV4_REGEX + PORT_REGEX + PATH_REGEX);

static HTTPServer server;

public static void agentmain(String agentArgument, Instrumentation instrumentation) throws Exception {
premain(agentArgument, instrumentation);
}

public static void premain(String agentArgument, Instrumentation instrumentation) throws Exception {

AgentParameters params = parseParameters(agentArgument);
InetSocketAddress socket = new InetSocketAddress(params.getHost(), params.getPort());
new BuildInfoCollector().register();
new JmxCollector(new File(params.getSettingsFilePath())).register();
DefaultExports.initialize();
server = new HTTPServer(socket, CollectorRegistry.defaultRegistry, true);
}

static AgentParameters parseParameters(String agentArguments) {

Matcher ipv6Matcher = IPV6_PATTERN.matcher(agentArguments);
Matcher portMatcher = PORT_PATTERN.matcher(agentArguments);
Matcher dnsMatcher = DNS_IPV4_PATTERN.matcher(agentArguments);

try {
if (ipv6Matcher.find()) {

String host = ipv6Matcher.group(2);
int port = Integer.parseInt(ipv6Matcher.group(4));
String settingsFile = ipv6Matcher.group(5);
return new AgentParameters(host, port, settingsFile);
} else if (portMatcher.find()) {

int port = Integer.parseInt(portMatcher.group(2));
String settingsFile = portMatcher.group(3);
return new AgentParameters(DEFAULT_HOST, port, settingsFile);
} else if (dnsMatcher.find()) {

String host = dnsMatcher.group(2);
int port = Integer.parseInt(dnsMatcher.group(5));
String settingsFile = dnsMatcher.group(6);
return new AgentParameters(host, port, settingsFile);
} else {
throw new IllegalArgumentException("Could not parse arguments: " + agentArguments);
}
} catch (Exception e) {
throw new IllegalArgumentException(
"Usage: -javaagent:/path/to/JavaAgent.jar=[host]:<port>:<yaml configuration file>", e);
}
}
}
Loading