Skip to content

Commit 331ea82

Browse files
committed
Add MongoDB instrumentation
1 parent f0970e6 commit 331ea82

File tree

9 files changed

+247
-2
lines changed

9 files changed

+247
-2
lines changed

agent/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ dependencies {
133133
runtime "org.glowroot.instrumentation:instrumentation-struts:$instrumentationVersion" // need for operation name
134134
runtime "org.glowroot.instrumentation:instrumentation-jdbc:$instrumentationVersion"
135135
runtime "org.glowroot.instrumentation:instrumentation-redis:$instrumentationVersion"
136+
runtime "org.glowroot.instrumentation:instrumentation-mongodb:$instrumentationVersion"
136137
runtime "org.glowroot.instrumentation:instrumentation-apache-http-client:$instrumentationVersion"
137138
runtime "org.glowroot.instrumentation:instrumentation-okhttp:$instrumentationVersion"
138139
runtime "org.glowroot.instrumentation:instrumentation-http-url-connection:$instrumentationVersion"

agent/src/main/java/com/microsoft/applicationinsights/agent/internal/model/QuerySpanImpl.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,16 @@ private long endInternalPart1() {
136136
}
137137

138138
private void endInternalPart2() {
139-
if (!type.equals("SQL")) {
139+
if (!type.equals("SQL") && !type.equals("MongoDB")) {
140140
return;
141141
}
142142
RemoteDependencyTelemetry telemetry = new RemoteDependencyTelemetry(startTimeMillis, totalMillis, type,
143143
exception == null);
144-
telemetry.setName(dest);
144+
if (dest.isEmpty()) {
145+
telemetry.setName(type);
146+
} else {
147+
telemetry.setName(dest);
148+
}
145149
telemetry.setCommandName(text);
146150

147151
Map<String, ?> detail = messageSupplier.get();

settings.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ include ':test:smoke:testApps:HeartBeat'
7575
include ':test:smoke:testApps:SpringBootTest'
7676
include ':test:smoke:testApps:FixedRateSampling'
7777
include ':test:smoke:testApps:Jdbc'
78+
include ':test:smoke:testApps:MongoDB'
7879
include ':test:smoke:testApps:HttpClients'
7980
include ':test:smoke:testApps:CustomInstrumentation'
8081
include ':test:smoke:testApps:WebAuto'
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apply plugin: 'war'
2+
3+
dependencies {
4+
compile aiCoreJar
5+
compile aiWebJar
6+
7+
compile group: 'org.mongodb', name: 'mongodb-driver', version: '3.11.0'
8+
9+
providedCompile 'javax.servlet:javax.servlet-api:3.0.1'
10+
}
11+
12+
sourceCompatibility = 1.7
13+
targetCompatibility = 1.7
14+
compileSmokeTestJava.sourceCompatibility = 1.8
15+
compileSmokeTestJava.targetCompatibility = 1.8
16+
17+
ext.testAppArtifactDir = war.destinationDirectory
18+
ext.testAppArtifactFilename = war.archiveFileName.get()
19+
ext.dependencyContainers = ['mongo:latest']
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package com.microsoft.applicationinsights.smoketestapp;
2+
3+
import java.util.concurrent.Callable;
4+
import java.util.concurrent.TimeUnit;
5+
import javax.servlet.ServletException;
6+
import javax.servlet.annotation.WebServlet;
7+
import javax.servlet.http.HttpServlet;
8+
import javax.servlet.http.HttpServletRequest;
9+
import javax.servlet.http.HttpServletResponse;
10+
11+
import com.google.common.base.Stopwatch;
12+
import com.mongodb.client.MongoClient;
13+
import com.mongodb.client.MongoClients;
14+
import com.mongodb.client.MongoCollection;
15+
import com.mongodb.client.MongoCursor;
16+
import com.mongodb.client.MongoDatabase;
17+
import org.bson.Document;
18+
19+
@WebServlet("/*")
20+
public class MongoTestServlet extends HttpServlet {
21+
22+
public void init() throws ServletException {
23+
try {
24+
setupMongo();
25+
} catch (Exception e) {
26+
throw new ServletException(e);
27+
}
28+
}
29+
30+
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
31+
try {
32+
doGetInternal(req);
33+
resp.getWriter().println("ok");
34+
} catch (ServletException e) {
35+
throw e;
36+
} catch (Exception e) {
37+
throw new ServletException(e);
38+
}
39+
}
40+
41+
private void doGetInternal(HttpServletRequest req) throws Exception {
42+
String pathInfo = req.getPathInfo();
43+
if (pathInfo.equals("/mongo")) {
44+
mongo();
45+
} else if (!pathInfo.equals("/")) {
46+
throw new ServletException("Unexpected url: " + pathInfo);
47+
}
48+
}
49+
50+
private void mongo() throws Exception {
51+
MongoClient mongoClient = getMongoClient();
52+
executeFind(mongoClient);
53+
mongoClient.close();
54+
}
55+
56+
private static void executeFind(MongoClient mongoClient) {
57+
MongoDatabase database = mongoClient.getDatabase("testdb");
58+
MongoCollection<Document> collection = database.getCollection("test");
59+
MongoCursor<Document> i = collection.find().iterator();
60+
while (i.hasNext()) {
61+
i.next();
62+
}
63+
}
64+
65+
private static void setupMongo() throws Exception {
66+
MongoClient mongoClient = getMongoClient();
67+
setup(mongoClient);
68+
mongoClient.close();
69+
}
70+
71+
private static MongoClient getMongoClient() throws Exception {
72+
return getMongoClient(new Callable<MongoClient>() {
73+
@Override public MongoClient call() {
74+
String hostname = System.getenv("MONGO");
75+
return MongoClients.create("mongodb://" + hostname);
76+
}
77+
});
78+
}
79+
80+
private static MongoClient getMongoClient(Callable<MongoClient> callable) throws Exception {
81+
Exception exception;
82+
Stopwatch stopwatch = Stopwatch.createStarted();
83+
do {
84+
try {
85+
return callable.call();
86+
} catch (Exception e) {
87+
exception = e;
88+
}
89+
} while (stopwatch.elapsed(TimeUnit.SECONDS) < 30);
90+
throw exception;
91+
}
92+
93+
private static void setup(MongoClient mongoClient) {
94+
MongoDatabase database = mongoClient.getDatabase("testdb");
95+
MongoCollection<Document> collection = database.getCollection("test");
96+
collection.insertOne(new Document("one", "two"));
97+
}
98+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings" schemaVersion="2014-05-30">
3+
4+
<!-- The key from the portal: -->
5+
6+
<InstrumentationKey>00000000-0000-0000-0000-0FEEDDADBEEF</InstrumentationKey>
7+
8+
<SDKLogger type="CONSOLE">
9+
<enabled>true</enabled>
10+
<UniquePrefix>JavaSDKLog</UniquePrefix>
11+
</SDKLogger>
12+
13+
<QuickPulse enabled="false" />
14+
15+
<!-- HTTP request component (not required for bare API) -->
16+
17+
<TelemetryModules>
18+
<Add type="com.microsoft.applicationinsights.web.extensibility.modules.WebRequestTrackingTelemetryModule" />
19+
<Add type="com.microsoft.applicationinsights.web.extensibility.modules.WebSessionTrackingTelemetryModule" />
20+
<Add type="com.microsoft.applicationinsights.web.extensibility.modules.WebUserTrackingTelemetryModule" />
21+
</TelemetryModules>
22+
23+
<!-- Events correlation (not required for bare API) -->
24+
<!-- These initializers add context data to each event -->
25+
26+
<TelemetryInitializers>
27+
<Add type="com.microsoft.applicationinsights.web.extensibility.initializers.WebOperationIdTelemetryInitializer" />
28+
<Add type="com.microsoft.applicationinsights.web.extensibility.initializers.WebOperationNameTelemetryInitializer" />
29+
<Add type="com.microsoft.applicationinsights.web.extensibility.initializers.WebSessionTelemetryInitializer" />
30+
<Add type="com.microsoft.applicationinsights.web.extensibility.initializers.WebUserTelemetryInitializer" />
31+
<Add type="com.microsoft.applicationinsights.web.extensibility.initializers.WebUserAgentTelemetryInitializer" />
32+
<Add type="com.microsoft.applicationinsights.extensibility.initializer.docker.DockerContextInitializer" />
33+
</TelemetryInitializers>
34+
35+
<Channel>
36+
<EndpointAddress>http://fakeingestion:60606/v2/track</EndpointAddress>
37+
<DeveloperMode>true</DeveloperMode>
38+
<FlushIntervalInSeconds>1</FlushIntervalInSeconds>
39+
</Channel>
40+
41+
</ApplicationInsights>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
3+
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
4+
id="SimpleCalculator_1" version="3.0">
5+
<filter>
6+
<filter-name>ApplicationInsightsWebFilter</filter-name>
7+
<filter-class>com.microsoft.applicationinsights.web.internal.WebRequestTrackingFilter</filter-class>
8+
</filter>
9+
<filter-mapping>
10+
<filter-name>ApplicationInsightsWebFilter</filter-name>
11+
<url-pattern>/*</url-pattern>
12+
</filter-mapping>
13+
</web-app>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.microsoft.applicationinsights.smoketestapp;
2+
3+
import java.util.List;
4+
import java.util.concurrent.TimeUnit;
5+
6+
import com.google.common.base.Predicate;
7+
import com.microsoft.applicationinsights.internal.schemav2.Data;
8+
import com.microsoft.applicationinsights.internal.schemav2.Envelope;
9+
import com.microsoft.applicationinsights.internal.schemav2.RemoteDependencyData;
10+
import com.microsoft.applicationinsights.internal.schemav2.RequestData;
11+
import com.microsoft.applicationinsights.smoketest.AiSmokeTest;
12+
import com.microsoft.applicationinsights.smoketest.DependencyContainer;
13+
import com.microsoft.applicationinsights.smoketest.TargetUri;
14+
import com.microsoft.applicationinsights.smoketest.UseAgent;
15+
import com.microsoft.applicationinsights.smoketest.WithDependencyContainers;
16+
import org.junit.Ignore;
17+
import org.junit.Test;
18+
19+
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertNotNull;
21+
import static org.junit.Assert.assertTrue;
22+
23+
@UseAgent
24+
@WithDependencyContainers(
25+
@DependencyContainer(
26+
value = "mongo:4",
27+
portMapping = "27017",
28+
hostnameEnvironmentVariable = "MONGO")
29+
)
30+
public class MongoSmokeTest extends AiSmokeTest {
31+
32+
@Test
33+
@TargetUri("/mongo")
34+
public void mongo() throws Exception {
35+
List<Envelope> rdList = mockedIngestion.waitForItems("RequestData", 1);
36+
List<Envelope> rddList = mockedIngestion.waitForItems("RemoteDependencyData", 1);
37+
38+
Envelope rdEnvelope = rdList.get(0);
39+
Envelope rddEnvelope = rddList.get(0);
40+
41+
RequestData rd = (RequestData) ((Data) rdEnvelope.getData()).getBaseData();
42+
RemoteDependencyData rdd = (RemoteDependencyData) ((Data) rddEnvelope.getData()).getBaseData();
43+
44+
assertTrue(rd.getSuccess());
45+
assertEquals("MongoDB", rdd.getType());
46+
assertEquals("MongoDB", rdd.getName());
47+
assertEquals("find testdb.test", rdd.getData());
48+
assertTrue(rdd.getSuccess());
49+
50+
assertSameOperationId(rdEnvelope, rddEnvelope);
51+
}
52+
53+
private static void assertSameOperationId(Envelope rdEnvelope, Envelope rddEnvelope) {
54+
String operationId = rdEnvelope.getTags().get("ai.operation.id");
55+
String operationParentId = rdEnvelope.getTags().get("ai.operation.parentId");
56+
57+
assertNotNull(operationId);
58+
assertNotNull(operationParentId);
59+
60+
assertEquals(operationId, rddEnvelope.getTags().get("ai.operation.id"));
61+
assertEquals(operationParentId, rddEnvelope.getTags().get("ai.operation.parentId"));
62+
}
63+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
jbosseap6
2+
jbosseap7
3+
tomcat7
4+
tomcat85
5+
jetty9

0 commit comments

Comments
 (0)