class TraceMongoCommandListener implements CommandListener {

  @Override public void commandStarted(CommandStartedEvent event) {
    String databaseName = event.getDatabaseName();
    if ("admin".equals(databaseName)) return; // don't trace commands like "endSessions"

    Span span = threadLocalSpan.next();
    if (span == null || span.isNoop()) return;

    String commandName = event.getCommandName();
    BsonDocument command = event.getCommand();
    String collectionName = getCollectionName(command, commandName);

    span.name(getSpanName(commandName, collectionName))
      .kind(CLIENT)
      .remoteServiceName("mongodb-" + databaseName)
      .tag("mongodb.command", commandName);

    if (collectionName != null) {
      span.tag("mongodb.collection", collectionName);
    }

    ConnectionDescription connectionDescription = event.getConnectionDescription();
    if (connectionDescription != null) {
      ConnectionId connectionId = connectionDescription.getConnectionId();
      if (connectionId != null) {
        span.tag("mongodb.cluster_id", connectionId.getServerId().getClusterId().getValue());
      }

      try {
        InetSocketAddress socketAddress =
          connectionDescription.getServerAddress().getSocketAddress();
        span.remoteIpAndPort(socketAddress.getAddress().getHostAddress(), socketAddress.getPort());
      } catch (MongoSocketException ignored) {

      }
    }

    span.start();
  }

    TraceMongoCommandListener(MongoDBTracing mongoDBTracing);
    TraceMongoCommandListener(ThreadLocalSpan threadLocalSpan);

}