public List<MetricFamilySamples> collect() {

      List<MetricFamilySamples> mfs = new ArrayList<>(List.of(
        new GaugeMetricFamily("jvm_available_processors", "Result of Runtime.getRuntime().availableProcessors()",
          Runtime.getRuntime().availableProcessors()),
        new GaugeMetricFamily("jvm_system_load_avg", "Result of OperatingSystemMXBean.getSystemLoadAverage()",
          osBean.getSystemLoadAverage())
      ));

      CounterMetricFamily threadCpuTimes = new CounterMetricFamily("jvm_thread_cpu_time_seconds",
        "CPU time used by each thread", List.of("name", "id"));
      mfs.add(threadCpuTimes);
      CounterMetricFamily threadUserTimes = new CounterMetricFamily("jvm_thread_user_time_seconds",
        "User time used by each thread", List.of("name", "id"));
      mfs.add(threadUserTimes);
      threads.putAll(ProcessInfo.getThreadStats());
      for (ProcessInfo.ThreadState thread : threads.values()) {
        var labels = List.of(thread.name(), Long.toString(thread.id()));
        threadUserTimes.addMetric(labels, thread.userTime().toNanos() / NANOSECONDS_PER_SECOND);
        threadCpuTimes.addMetric(labels, thread.cpuTime().toNanos() / NANOSECONDS_PER_SECOND);
      }

      return mfs;
    }
Reports more detailed stats on CPU usage statistics by thread than prometheus collects by default.
planetiler-core/src/main/java/com/onthegomap/planetiler/stats/PrometheusStats.java