generatePrometheusResponse() {
		const content = [];

		const val = value => (value == null ? "NaN" : value);

		this.registry.store.forEach(metric => {
			// Filtering
			if (!this.matchMetricName(metric.name)) return;
			// Skip datetime metrics (register too much labels)
			if (metric.name.startsWith("os.datetime")) return;

			const metricName = this.formatMetricName(metric.name).replace(/[.-]/g, "_");
			const metricDesc = metric.description
				? metric.description
				: metric.name + (metric.unit ? ` (${metric.unit})` : "");
			const metricType = metric.type;

			const snapshot = metric.snapshot();
			if (snapshot.length == 0) return;

			switch (metric.type) {
				case METRIC.TYPE_COUNTER:
				case METRIC.TYPE_GAUGE: {
					content.push(`# HELP ${metricName} ${metricDesc}`);
					content.push(`# TYPE ${metricName} ${metricType}`);
					snapshot.forEach(item => {
						const labelStr = this.labelsToStr(item.labels);
						content.push(`${metricName}${labelStr} ${val(item.value)}`);

						if (item.rate) {
							content.push(`${metricName}_rate${labelStr} ${val(item.rate)}`);
						}
					});
					content.push("");

					break;
				}
				case METRIC.TYPE_INFO: {
					content.push(`# HELP ${metricName} ${metricDesc}`);
					content.push(`# TYPE ${metricName} gauge`);
					snapshot.forEach(item => {
						const labelStr = this.labelsToStr(item.labels, { value: item.value });
						content.push(`${metricName}${labelStr} 1`);
					});
					content.push("");

					break;
				}
				case METRIC.TYPE_HISTOGRAM: {
					content.push(`# HELP ${metricName} ${metricDesc}`);
					content.push(`# TYPE ${metricName} ${metricType}`);
					snapshot.forEach(item => {
						if (item.buckets) {
							Object.keys(item.buckets).forEach(le => {
								const labelStr = this.labelsToStr(item.labels, { le });
								content.push(
									`${metricName}_bucket${labelStr} ${val(item.buckets[le])}`
								);
							});
							// +Inf
							const labelStr = this.labelsToStr(item.labels, { le: "+Inf" });
							content.push(`${metricName}_bucket${labelStr} ${val(item.count)}`);
						}

						if (item.quantiles) {
							Object.keys(item.quantiles).forEach(key => {
								const labelStr = this.labelsToStr(item.labels, { quantile: key });
								content.push(
									`${metricName}${labelStr} ${val(item.quantiles[key])}`
								);
							});

							// Add other calculated values
							const labelStr = this.labelsToStr(item.labels);
							content.push(`${metricName}_sum${labelStr} ${val(item.sum)}`);
							content.push(`${metricName}_count${labelStr} ${val(item.count)}`);
							content.push(`${metricName}_min${labelStr} ${val(item.min)}`);
							content.push(`${metricName}_mean${labelStr} ${val(item.mean)}`);
							content.push(`${metricName}_variance${labelStr} ${val(item.variance)}`);
							content.push(`${metricName}_stddev${labelStr} ${val(item.stdDev)}`);
							content.push(`${metricName}_max${labelStr} ${val(item.max)}`);
						}

						if (item.rate) {
							const labelStr = this.labelsToStr(item.labels);
							content.push(`${metricName}_rate${labelStr} ${val(item.rate)}`);
						}
					});
					content.push("");
					break;
				}
			}
		});

		return content.join("\n");
	}
Generate Prometheus response.
@returns {String}
@memberof PrometheusReporter