code: @Override
      public void collectMetrics() {
          long nanosBefore = System.nanoTime();
          /*
           * Optimisation tip: no need to skip 'mbeanServer.queryNames()' if the ObjectName is not a pattern
           * (i.e. not '*' or '?' wildcard) because the mbeanserver internally performs the check.
           * Seen on com.sun.jmx.interceptor.DefaultMBeanServerInterceptor
           */
          Set<ObjectName> matchingObjectNames = embeddedJmxTrans.getMbeanServer().queryNames(this.objectName, null);
          logger.trace("Query {} returned {}", objectName, matchingObjectNames);
  
          for (ObjectName matchingObjectName : matchingObjectNames) {
              long epochInMillis = System.currentTimeMillis();
              try {
                  AttributeList jmxAttributes = embeddedJmxTrans.getMbeanServer().getAttributes(matchingObjectName, this.attributeNames);
                  logger.trace("Query {} returned {}", matchingObjectName, jmxAttributes);
                  for (Attribute jmxAttribute : jmxAttributes.asList()) {
                      QueryAttribute queryAttribute = this.attributesByName.get(jmxAttribute.getName());
                      Object value = jmxAttribute.getValue();
                      int count = queryAttribute.collectMetrics(matchingObjectName, value, epochInMillis, this.queryResults);
                      collectedMetricsCount.addAndGet(count);
                  }
              } catch (Exception e) {
                  logger.warn("Exception processing query {}", this, e);
              }
          }
          collectionCount.incrementAndGet();
          long nanosAfter = System.nanoTime();
          collectionDurationInNanos.addAndGet(nanosAfter - nanosBefore);
      }
docs: Collect the values for this query and store them as {@link QueryResult} in the {@linkplain Query#queryResults} queue