Add operation and collection attributes for MongoDB spans (#1398)

* Add mongodb attributes for operation and collection

* Switch to using SemanticAttributes.MONGODB_COLLECTION

* Remove unused imports

* Fix import order

* Fix formatting

* Update tests to keep more readable closure syntax

* Run spotlessApply
This commit is contained in:
Jamal Fanaian 2020-10-18 23:20:46 -07:00 committed by GitHub
parent 9e37231662
commit 69ea2f7491
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 41 deletions

View File

@ -3,10 +3,6 @@
* SPDX-License-Identifier: Apache-2.0
*/
import static io.opentelemetry.instrumentation.test.utils.PortUtils.UNUSABLE_PORT
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
import static io.opentelemetry.trace.Span.Kind.CLIENT
import com.mongodb.MongoClient
import com.mongodb.MongoClientOptions
import com.mongodb.MongoTimeoutException
@ -21,6 +17,10 @@ import org.bson.BsonString
import org.bson.Document
import spock.lang.Shared
import static io.opentelemetry.instrumentation.test.utils.PortUtils.UNUSABLE_PORT
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
import static io.opentelemetry.trace.Span.Kind.CLIENT
class MongoClientTest extends MongoBaseTest {
@Shared
@ -48,7 +48,7 @@ class MongoClientTest extends MongoBaseTest {
then:
assertTraces(1) {
trace(0, 1) {
mongoSpan(it, 0, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
mongoSpan(it, 0, "create", collectionName, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
}
}
@ -72,7 +72,7 @@ class MongoClientTest extends MongoBaseTest {
then:
assertTraces(1) {
trace(0, 1) {
mongoSpan(it, 0, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
mongoSpan(it, 0, "create", collectionName, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
}
}
@ -91,7 +91,7 @@ class MongoClientTest extends MongoBaseTest {
then:
assertTraces(1) {
trace(0, 1) {
mongoSpan(it, 0, "{\"create\":\"$collectionName\",\"capped\":\"?\"}", dbName)
mongoSpan(it, 0, "create", collectionName, "{\"create\":\"$collectionName\",\"capped\":\"?\"}", dbName)
}
}
@ -111,7 +111,7 @@ class MongoClientTest extends MongoBaseTest {
count == 0
assertTraces(1) {
trace(0, 1) {
mongoSpan(it, 0, "{\"count\":\"$collectionName\",\"query\":{}}")
mongoSpan(it, 0, "count", collectionName, "{\"count\":\"$collectionName\",\"query\":{}}")
}
}
@ -137,10 +137,10 @@ class MongoClientTest extends MongoBaseTest {
collection.count() == 1
assertTraces(2) {
trace(0, 1) {
mongoSpan(it, 0, "{\"insert\":\"$collectionName\",\"ordered\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}")
mongoSpan(it, 0, "insert", collectionName, "{\"insert\":\"$collectionName\",\"ordered\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}")
}
trace(1, 1) {
mongoSpan(it, 0, "{\"count\":\"$collectionName\",\"query\":{}}")
mongoSpan(it, 0, "count", collectionName, "{\"count\":\"$collectionName\",\"query\":{}}")
}
}
@ -171,10 +171,10 @@ class MongoClientTest extends MongoBaseTest {
collection.count() == 1
assertTraces(2) {
trace(0, 1) {
mongoSpan(it, 0, "{\"update\":\"?\",\"ordered\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"\$set\":{\"password\":\"?\"}}}]}")
mongoSpan(it, 0, "update", collectionName, "{\"update\":\"?\",\"ordered\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"\$set\":{\"password\":\"?\"}}}]}")
}
trace(1, 1) {
mongoSpan(it, 0, "{\"count\":\"$collectionName\",\"query\":{}}")
mongoSpan(it, 0, "count", collectionName, "{\"count\":\"$collectionName\",\"query\":{}}")
}
}
@ -203,10 +203,10 @@ class MongoClientTest extends MongoBaseTest {
collection.count() == 0
assertTraces(2) {
trace(0, 1) {
mongoSpan(it, 0, "{\"delete\":\"?\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}")
mongoSpan(it, 0, "delete", collectionName, "{\"delete\":\"?\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}")
}
trace(1, 1) {
mongoSpan(it, 0, "{\"count\":\"$collectionName\",\"query\":{}}")
mongoSpan(it, 0, "count", collectionName, "{\"count\":\"$collectionName\",\"query\":{}}")
}
}
@ -257,7 +257,7 @@ class MongoClientTest extends MongoBaseTest {
collectionName = "testCollection"
}
def mongoSpan(TraceAssert trace, int index, String statement, String instance = "some-description", Object parentSpan = null, Throwable exception = null) {
def mongoSpan(TraceAssert trace, int index, String operation, String collection, String statement, String instance = "some-description", Object parentSpan = null, Throwable exception = null) {
trace.span(index) {
name { it.replace(" ", "") == statement }
kind CLIENT
@ -276,6 +276,8 @@ class MongoClientTest extends MongoBaseTest {
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "mongodb://localhost:" + port
"${SemanticAttributes.DB_SYSTEM.key()}" "mongodb"
"${SemanticAttributes.DB_NAME.key()}" instance
"${SemanticAttributes.DB_OPERATION.key()}" operation
"${SemanticAttributes.MONGODB_COLLECTION.key()}" collection
}
}
}

View File

@ -3,10 +3,6 @@
* SPDX-License-Identifier: Apache-2.0
*/
import static io.opentelemetry.instrumentation.test.utils.PortUtils.UNUSABLE_PORT
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
import static io.opentelemetry.trace.Span.Kind.CLIENT
import com.mongodb.MongoClientSettings
import com.mongodb.MongoTimeoutException
import com.mongodb.ServerAddress
@ -22,6 +18,10 @@ import org.bson.BsonString
import org.bson.Document
import spock.lang.Shared
import static io.opentelemetry.instrumentation.test.utils.PortUtils.UNUSABLE_PORT
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
import static io.opentelemetry.trace.Span.Kind.CLIENT
class MongoClientTest extends MongoBaseTest {
@Shared
@ -52,7 +52,7 @@ class MongoClientTest extends MongoBaseTest {
then:
assertTraces(1) {
trace(0, 1) {
mongoSpan(it, 0, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
mongoSpan(it, 0, "create", collectionName, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
}
}
@ -82,7 +82,7 @@ class MongoClientTest extends MongoBaseTest {
then:
assertTraces(1) {
trace(0, 1) {
mongoSpan(it, 0, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
mongoSpan(it, 0, "create", collectionName, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
}
}
@ -101,7 +101,7 @@ class MongoClientTest extends MongoBaseTest {
then:
assertTraces(1) {
trace(0, 1) {
mongoSpan(it, 0, "{\"create\":\"$collectionName\",\"capped\":\"?\"}", dbName)
mongoSpan(it, 0, "create", collectionName, "{\"create\":\"$collectionName\",\"capped\":\"?\"}", dbName)
}
}
@ -121,7 +121,7 @@ class MongoClientTest extends MongoBaseTest {
count == 0
assertTraces(1) {
trace(0, 1) {
mongoSpan(it, 0, "{\"count\":\"$collectionName\",\"query\":{}}")
mongoSpan(it, 0, "count", collectionName, "{\"count\":\"$collectionName\",\"query\":{}}")
}
}
@ -147,10 +147,10 @@ class MongoClientTest extends MongoBaseTest {
collection.count() == 1
assertTraces(2) {
trace(0, 1) {
mongoSpan(it, 0, "{\"insert\":\"$collectionName\",\"ordered\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}")
mongoSpan(it, 0, "insert", collectionName, "{\"insert\":\"$collectionName\",\"ordered\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}")
}
trace(1, 1) {
mongoSpan(it, 0, "{\"count\":\"$collectionName\",\"query\":{}}")
mongoSpan(it, 0, "count", collectionName, "{\"count\":\"$collectionName\",\"query\":{}}")
}
}
@ -181,10 +181,10 @@ class MongoClientTest extends MongoBaseTest {
collection.count() == 1
assertTraces(2) {
trace(0, 1) {
mongoSpan(it, 0, "{\"update\":\"?\",\"ordered\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"\$set\":{\"password\":\"?\"}}}]}")
mongoSpan(it, 0, "update", collectionName, "{\"update\":\"?\",\"ordered\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"\$set\":{\"password\":\"?\"}}}]}")
}
trace(1, 1) {
mongoSpan(it, 0, "{\"count\":\"$collectionName\",\"query\":{}}")
mongoSpan(it, 0, "count", collectionName, "{\"count\":\"$collectionName\",\"query\":{}}")
}
}
@ -213,10 +213,10 @@ class MongoClientTest extends MongoBaseTest {
collection.count() == 0
assertTraces(2) {
trace(0, 1) {
mongoSpan(it, 0, "{\"delete\":\"?\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}")
mongoSpan(it, 0, "delete", collectionName, "{\"delete\":\"?\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}")
}
trace(1, 1) {
mongoSpan(it, 0, "{\"count\":\"$collectionName\",\"query\":{}}")
mongoSpan(it, 0, "count", collectionName, "{\"count\":\"$collectionName\",\"query\":{}}")
}
}
@ -266,7 +266,7 @@ class MongoClientTest extends MongoBaseTest {
collectionName = "testCollection"
}
def mongoSpan(TraceAssert trace, int index, String statement, String instance = "some-description", Object parentSpan = null, Throwable exception = null) {
def mongoSpan(TraceAssert trace, int index, String operation, String collection, String statement, String instance = "some-description", Object parentSpan = null, Throwable exception = null) {
trace.span(index) {
name { it.replace(" ", "") == statement }
kind CLIENT
@ -285,6 +285,8 @@ class MongoClientTest extends MongoBaseTest {
"${SemanticAttributes.DB_SYSTEM.key()}" "mongodb"
"${SemanticAttributes.DB_CONNECTION_STRING.key()}" "mongodb://localhost:" + port
"${SemanticAttributes.DB_NAME.key()}" instance
"${SemanticAttributes.DB_OPERATION.key()}" operation
"${SemanticAttributes.MONGODB_COLLECTION.key()}" collection
}
}
}

View File

@ -59,7 +59,7 @@ class MongoAsyncClientTest extends MongoBaseTest {
then:
assertTraces(1) {
trace(0, 1) {
mongoSpan(it, 0) {
mongoSpan(it, 0, "create", collectionName) {
assert it.replaceAll(" ", "") == "{\"create\":\"$collectionName\",\"capped\":\"?\"}" ||
it == "{\"create\": \"$collectionName\", \"capped\": \"?\", \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
true
@ -87,7 +87,7 @@ class MongoAsyncClientTest extends MongoBaseTest {
then:
assertTraces(1) {
trace(0, 1) {
mongoSpan(it, 0) {
mongoSpan(it, 0, "create", collectionName) {
assert it.replaceAll(" ", "") == "{\"create\":\"$collectionName\",\"capped\":\"?\"}" ||
it == "{\"create\": \"$collectionName\", \"capped\": \"?\", \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
true
@ -110,7 +110,7 @@ class MongoAsyncClientTest extends MongoBaseTest {
then:
assertTraces(1) {
trace(0, 1) {
mongoSpan(it, 0, {
mongoSpan(it, 0, "create", collectionName, {
assert it.replaceAll(" ", "") == "{\"create\":\"$collectionName\",\"capped\":\"?\"}" ||
it == "{\"create\": \"$collectionName\", \"capped\": \"?\", \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
true
@ -135,7 +135,7 @@ class MongoAsyncClientTest extends MongoBaseTest {
count.get() == 0
assertTraces(1) {
trace(0, 1) {
mongoSpan(it, 0) {
mongoSpan(it, 0, "count", collectionName) {
assert it.replaceAll(" ", "") == "{\"count\":\"$collectionName\",\"query\":{}}" ||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
true
@ -170,14 +170,14 @@ class MongoAsyncClientTest extends MongoBaseTest {
count.get() == 1
assertTraces(2) {
trace(0, 1) {
mongoSpan(it, 0) {
mongoSpan(it, 0, "insert", collectionName) {
assert it.replaceAll(" ", "") == "{\"insert\":\"$collectionName\",\"ordered\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}" ||
it == "{\"insert\": \"$collectionName\", \"ordered\": \"?\", \"\$db\": \"?\", \"documents\": [{\"_id\": \"?\", \"password\": \"?\"}]}"
true
}
}
trace(1, 1) {
mongoSpan(it, 0) {
mongoSpan(it, 0, "count", collectionName) {
assert it.replaceAll(" ", "") == "{\"count\":\"$collectionName\",\"query\":{}}" ||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
true
@ -221,14 +221,14 @@ class MongoAsyncClientTest extends MongoBaseTest {
count.get() == 1
assertTraces(2) {
trace(0, 1) {
mongoSpan(it, 0) {
mongoSpan(it, 0, "update", collectionName) {
assert it.replaceAll(" ", "") == "{\"update\":\"?\",\"ordered\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"\$set\":{\"password\":\"?\"}}}]}" ||
it == "{\"update\": \"?\", \"ordered\": \"?\", \"\$db\": \"?\", \"updates\": [{\"q\": {\"password\": \"?\"}, \"u\": {\"\$set\": {\"password\": \"?\"}}}]}"
true
}
}
trace(1, 1) {
mongoSpan(it, 0) {
mongoSpan(it, 0, "count", collectionName) {
assert it.replaceAll(" ", "") == "{\"count\":\"$collectionName\",\"query\":{}}" ||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
true
@ -270,14 +270,14 @@ class MongoAsyncClientTest extends MongoBaseTest {
count.get() == 0
assertTraces(2) {
trace(0, 1) {
mongoSpan(it, 0) {
mongoSpan(it, 0, "delete", collectionName) {
assert it.replaceAll(" ", "") == "{\"delete\":\"?\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}" ||
it == "{\"delete\": \"?\", \"ordered\": \"?\", \"\$db\": \"?\", \"deletes\": [{\"q\": {\"password\": \"?\"}, \"limit\": \"?\"}]}"
true
}
}
trace(1, 1) {
mongoSpan(it, 0) {
mongoSpan(it, 0, "count", collectionName) {
assert it.replaceAll(" ", "") == "{\"count\":\"$collectionName\",\"query\":{}}" ||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
true
@ -303,7 +303,7 @@ class MongoAsyncClientTest extends MongoBaseTest {
}
}
def mongoSpan(TraceAssert trace, int index, Closure<Boolean> statementEval, String instance = "some-description", Object parentSpan = null, Throwable exception = null) {
def mongoSpan(TraceAssert trace, int index, String operation, String collection, Closure<Boolean> statementEval, String instance = "some-description", Object parentSpan = null, Throwable exception = null) {
trace.span(index) {
name statementEval
kind CLIENT
@ -320,6 +320,8 @@ class MongoAsyncClientTest extends MongoBaseTest {
"${SemanticAttributes.DB_STATEMENT.key()}" statementEval
"${SemanticAttributes.DB_SYSTEM.key()}" "mongodb"
"${SemanticAttributes.DB_NAME.key()}" instance
"${SemanticAttributes.DB_OPERATION.key()}" operation
"${SemanticAttributes.MONGODB_COLLECTION.key()}" collection
}
}
}

View File

@ -13,6 +13,8 @@ import com.mongodb.connection.ServerId;
import com.mongodb.event.CommandStartedEvent;
import io.opentelemetry.instrumentation.api.tracer.DatabaseClientTracer;
import io.opentelemetry.javaagent.instrumentation.api.jdbc.DbSystem;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.attributes.SemanticAttributes;
import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.List;
@ -36,6 +38,16 @@ public class MongoClientTracer extends DatabaseClientTracer<CommandStartedEvent,
return DbSystem.MONGODB;
}
@Override
protected Span onConnection(Span span, CommandStartedEvent event) {
span.setAttribute(SemanticAttributes.DB_OPERATION, event.getCommandName());
String collection = collectionName(event);
if (collection != null) {
span.setAttribute(SemanticAttributes.MONGODB_COLLECTION, collection);
}
return super.onConnection(span, event);
}
@Override
protected String dbName(CommandStartedEvent event) {
// Use description if set.
@ -135,4 +147,12 @@ public class MongoClientTracer extends DatabaseClientTracer<CommandStartedEvent,
}
return scrubbed;
}
private static String collectionName(CommandStartedEvent event) {
BsonValue collectionValue = event.getCommand().get(event.getCommandName());
if (collectionValue != null && collectionValue.isString()) {
return collectionValue.asString().getValue();
}
return null;
}
}