Skip to content

Commit

Permalink
Merge remote-tracking branch 'fork/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
dnazaruk committed Nov 26, 2019
2 parents 2fd4b38 + 55ee16f commit 1d47b1d
Show file tree
Hide file tree
Showing 16 changed files with 336 additions and 62 deletions.
18 changes: 18 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: 2
jobs:
build:
working_directory: ~/circleci-java
docker:
- image: circleci/openjdk:8-jdk-stretch

steps:
- checkout
- restore_cache: # restore the saved cache after the first run or if `pom.xml` has changed
key: circleci-demo-java-spring-{{ checksum "pom.xml" }}
- run: mvn dependency:go-offline # gets the project dependencies
- save_cache:
paths:
- ~/.m2
key: circleci-demo-java-spring-{{ checksum "pom.xml" }}

- run: mvn package
2 changes: 0 additions & 2 deletions .travis.yml

This file was deleted.

13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@ Agent is thus strongly encouraged.

## Running

To run as a javaagent [download the jar](https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.11.0/jmx_prometheus_javaagent-0.11.0.jar) and run:
To run as a javaagent [download the jar](https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.12.0/jmx_prometheus_javaagent-0.12.0.jar) and run:

```
java -javaagent:./jmx_prometheus_javaagent-0.11.0.jar=8080:config.yaml -jar yourJar.jar
java -javaagent:./jmx_prometheus_javaagent-0.12.0.jar=8080:config.yaml -jar yourJar.jar
```
Metrics will now be accessible at http://localhost:8080/metrics

To bind the java agent to a specific IP change the port number to `host:port`.

See `./run_sample_httpserver.sh` for a sample script that runs the httpserver against itself.

Please note that due to the nature of JMX the `/metrics` endpoint might exceed Prometheus default scrape timeout of 10 seconds.

## Building

`mvn package` to build.
Expand Down Expand Up @@ -114,7 +116,12 @@ If a given part isn't set, it'll be excluded.
You can start the jmx's scraper in standalone mode in order to debug what is called
`java -cp jmx_exporter.jar io.prometheus.jmx.JmxScraper service:jmx:rmi:your_url`
```
git clone https://github.com/prometheus/jmx_exporter.git
cd jmx_exporter
mvn package
java -cp collector/target/collector*.jar io.prometheus.jmx.JmxScraper service:jmx:rmi:your_url
```
To get finer logs (including the duration of each jmx call),
create a file called logging.properties with this content:
Expand Down
2 changes: 1 addition & 1 deletion collector/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>io.prometheus.jmx</groupId>
<artifactId>parent</artifactId>
<version>0.11.1-SNAPSHOT</version>
<version>0.12.1-SNAPSHOT</version>
</parent>

<groupId>io.prometheus.jmx</groupId>
Expand Down
19 changes: 16 additions & 3 deletions collector/src/main/java/io/prometheus/jmx/JmxCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
Expand Down Expand Up @@ -79,6 +80,10 @@ public JmxCollector(String yamlConfig) throws MalformedObjectNameException {
config = loadConfig((Map<String, Object>)new Yaml().load(yamlConfig));
}

public JmxCollector(InputStream inputStream) throws MalformedObjectNameException {
config = loadConfig((Map<String, Object>)new Yaml().load(inputStream));
}

private void reloadConfig() {
try {
FileReader fr = new FileReader(configFile);
Expand Down Expand Up @@ -127,15 +132,15 @@ private Config loadConfig(Map<String, Object> yamlConfig) throws MalformedObject
if (yamlConfig.containsKey("username")) {
cfg.username = (String)yamlConfig.get("username");
}

if (yamlConfig.containsKey("password")) {
cfg.password = (String)yamlConfig.get("password");
}

if (yamlConfig.containsKey("ssl")) {
cfg.ssl = (Boolean)yamlConfig.get("ssl");
}

if (yamlConfig.containsKey("lowercaseOutputName")) {
cfg.lowercaseOutputName = (Boolean)yamlConfig.get("lowercaseOutputName");
}
Expand Down Expand Up @@ -253,7 +258,7 @@ static String safeName(String name) {
safeNameBuilder.append("_");
}
for (char nameChar : name.toCharArray()) {
boolean isUnsafeChar = !(Character.isLetterOrDigit(nameChar) || nameChar == ':' || nameChar == '_');
boolean isUnsafeChar = !JmxCollector.isLegalCharacter(nameChar);
if ((isUnsafeChar || nameChar == '_')) {
if (prevCharIsUnderscore) {
continue;
Expand All @@ -270,6 +275,14 @@ static String safeName(String name) {
return safeNameBuilder.toString();
}

private static boolean isLegalCharacter(char input) {
return ((input == ':') ||
(input == '_') ||
(input >= 'a' && input <= 'z') ||
(input >= 'A' && input <= 'Z') ||
(input >= '0' && input <= '9'));
}

class Receiver implements JmxScraper.MBeanReceiver {
Map<String, MetricFamilySamples> metricFamilySamplesMap =
new HashMap<String, MetricFamilySamples>();
Expand Down
10 changes: 9 additions & 1 deletion collector/src/main/java/io/prometheus/jmx/JmxScraper.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ private void scrapeBean(MBeanServerConnection beanConn, ObjectName mbeanName) {
final AttributeList attributes;
try {
attributes = beanConn.getAttributes(mbeanName, name2AttrInfo.keySet().toArray(new String[0]));
if (attributes == null) {
logScrape(mbeanName.toString(), "getAttributes Fail: attributes are null");
return;
}
} catch (Exception e) {
logScrape(mbeanName, name2AttrInfo.keySet(), "Fail: " + e);
return;
Expand Down Expand Up @@ -186,7 +190,11 @@ private void processBeanValue(
Object value) {
if (value == null) {
logScrape(domain + beanProperties + attrName, "null");
} else if (value instanceof Number || value instanceof String || value instanceof Boolean) {
} else if (value instanceof Number || value instanceof String || value instanceof Boolean || value instanceof java.util.Date) {
if (value instanceof java.util.Date) {
attrType = "java.lang.Double";
value = ((java.util.Date) value).getTime() / 1000.0;
}
logScrape(domain + beanProperties + attrName, value.toString());
this.receiver.recordBean(
domain,
Expand Down
26 changes: 26 additions & 0 deletions collector/src/test/java/io/prometheus/jmx/CamelMBean.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.prometheus.jmx;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.util.Date;

public interface CamelMBean {
double EXPECTED_SECONDS = 1.573285945111E9;

Date getLastExchangeFailureTimestamp();
}

class Camel implements CamelMBean {
public static void registerBean(MBeanServer mbs)
throws javax.management.JMException {
ObjectName mbeanName = new ObjectName(
"org.apache.camel:context=my-camel-context,type=routes,name=\"my-route-name\"");
Camel mbean = new Camel();
mbs.registerMBean(mbean, mbeanName);
}

@Override
public Date getLastExchangeFailureTimestamp() {
return new Date((long)(EXPECTED_SECONDS * 1000));
}
}
17 changes: 17 additions & 0 deletions collector/src/test/java/io/prometheus/jmx/JmxCollectorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public static void OneTimeSetUp() throws Exception {

TomcatServlet.registerBean(mbs);
Bool.registerBean(mbs);
Camel.registerBean(mbs);
}

@Before
Expand Down Expand Up @@ -252,4 +253,20 @@ public void testDelayedStartReady() throws Exception {
Thread.sleep(2000);
assertEquals(1.0, registry.getSampleValue("boolean_Test_True", new String[]{}, new String[]{}), .001);
}

@Test
public void testCamelLastExchangFailureTimestamp() throws Exception{
String rulePattern =
"\n---\nrules:\n- pattern: 'org.apache.camel<context=([^,]+), type=routes, name=\"([^\"]+)\"><>LastExchangeFailureTimestamp'\n" +
" name: org.apache.camel.LastExchangeFailureTimestamp\n" +
" help: Exchanges Last Failure Timestamps\n" +
" type: UNTYPED\n" +
" labels:\n" +
" context: \"$1\"\n" +
" route: \"$2\"\n" +
" type: routes";
JmxCollector jc = new JmxCollector(rulePattern).register(registry);
Double actual = registry.getSampleValue("org_apache_camel_LastExchangeFailureTimestamp", new String[]{"context", "route", "type"}, new String[]{"my-camel-context", "my-route-name", "routes"});
assertEquals(Camel.EXPECTED_SECONDS, actual, 0);
}
}
4 changes: 4 additions & 0 deletions collector/src/test/java/io/prometheus/jmx/SafeNameTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ public static Iterable<Object[]> data() {
// A very long string
{ "_asetstjlk_testkljsek_tesktjsekrslk_testkljsetkl_tkesjtk_sljtslkjetesslelse_lktsjetlkesltel_kesjltelksjetkl_tesktjksjltse_sljteslselkselse_tsjetlksetklsjekl_slkfjrtlskek_",
"$asetstjlk_$testkljsek_$tesktjsekrslk_$testkljsetkl_$tkesjtk_$sljtslkjetesslelse_$lktsjetlkesltel_$kesjltelksjetkl_$tesktjksjltse_$sljteslselkselse_$tsjetlksetklsjekl_$slkfjrtlskek___" },
{ "test_swedish_chars_", "test_swedish_chars_åäö" },
{ "test_test", "test@test" },
{ "test_test", "test;test" },
{ "test:test", "test:test" },
});
}

Expand Down
35 changes: 35 additions & 0 deletions example_configs/activemq.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
lowercaseOutputName: true
lowercaseOutputLabelNames: true
blacklistObjectNames:
- "org.apache.activemq:clientId=*,*"
whitelistObjectNames:
- "org.apache.activemq:destinationType=Queue,*"
- "org.apache.activemq:destinationType=Topic,*"
- "org.apache.activemq:type=Broker,brokerName=*"
- "org.apache.activemq:type=Topic,brokerName=*"

rules:
- pattern: org.apache.activemq<type=Broker, brokerName=(\S*), destinationType=Queue, destinationName=(\S*)><>(\w+)
name: activemq_queue_$3
attrNameSnakeCase: true
labels:
destination: $2

- pattern: org.apache.activemq<type=Broker, brokerName=(\S*), destinationType=Topic, destinationName=(\S*)><>(\w+)
name: activemq_topic_$3
attrNameSnakeCase: true
labels:
destination: $2

- pattern: org.apache.activemq<type=Broker, brokerName=(\S*)><>CurrentConnectionsCount
name: activemq_connections
type: GAUGE

- pattern: org.apache.activemq<type=Broker, brokerName=(\S*)><>Total(.*)Count
name: activemq_$2_total
type: COUNTER

- pattern: org.apache.activemq<type=Broker, brokerName=(\S*)><>(.*)PercentUsage
name: activemq_$2_usage_ratio
type: GAUGE
valueFactor: 0.01
19 changes: 18 additions & 1 deletion example_configs/kafka-2_0_0.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ rules:
labels:
clientId: "$3"
broker: "$4:$5"
- pattern : kafka.coordinator.(\w+)<type=(.+), name=(.+)><>Value
name: kafka_coordinator_$1_$2_$3
type: GAUGE

# Generic per-second counters with 0-2 key/value pairs
- pattern: kafka.(\w+)<type=(.+), name=(.+)PerSec\w*, (.+)=(.+), (.+)=(.+)><>Count
Expand All @@ -28,11 +31,25 @@ rules:
type: COUNTER
labels:
"$4": "$5"
type: COUNTER
- pattern: kafka.(\w+)<type=(.+), name=(.+)PerSec\w*><>Count
name: kafka_$1_$2_$3_total
type: COUNTER

- pattern: kafka.server<type=(.+), client-id=(.+)><>([a-z-]+)
name: kafka_server_quota_$3
type: GAUGE
labels:
resource: "$1"
clientId: "$2"

- pattern: kafka.server<type=(.+), user=(.+), client-id=(.+)><>([a-z-]+)
name: kafka_server_quota_$4
type: GAUGE
labels:
resource: "$1"
user: "$2"
clientId: "$3"

# Generic gauges with 0-2 key/value pairs
- pattern: kafka.(\w+)<type=(.+), name=(.+), (.+)=(.+), (.+)=(.+)><>Value
name: kafka_$1_$2_$3
Expand Down
6 changes: 3 additions & 3 deletions jmx_prometheus_httpserver/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>io.prometheus.jmx</groupId>
<artifactId>parent</artifactId>
<version>0.11.1-SNAPSHOT</version>
<version>0.12.1-SNAPSHOT</version>
</parent>

<artifactId>jmx_prometheus_httpserver</artifactId>
Expand All @@ -17,12 +17,12 @@
<dependency>
<groupId>io.prometheus.jmx</groupId>
<artifactId>collector</artifactId>
<version>0.11.1-SNAPSHOT</version>
<version>0.12.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_httpserver</artifactId>
<version>0.3.0</version>
<version>0.6.0</version>
</dependency>
</dependencies>

Expand Down
8 changes: 4 additions & 4 deletions jmx_prometheus_javaagent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>io.prometheus.jmx</groupId>
<artifactId>parent</artifactId>
<version>0.11.1-SNAPSHOT</version>
<version>0.12.1-SNAPSHOT</version>
</parent>

<groupId>io.prometheus.jmx</groupId>
Expand All @@ -18,17 +18,17 @@
<dependency>
<groupId>io.prometheus.jmx</groupId>
<artifactId>collector</artifactId>
<version>0.11.1-SNAPSHOT</version>
<version>0.12.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_hotspot</artifactId>
<version>0.3.0</version>
<version>0.6.0</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_httpserver</artifactId>
<version>0.3.0</version>
<version>0.6.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
Expand Down
Loading

0 comments on commit 1d47b1d

Please sign in to comment.