From 4833c8bf7489124dfce9846a0b7dc91d8d68deb5 Mon Sep 17 00:00:00 2001 From: Frederic Hemberger Date: Tue, 1 Jun 2021 10:35:22 +0200 Subject: [PATCH] Release: v2.2.0 - Initial support for text-based OpenMetrics endpoints - Improved popup dialog readability --- README.md | 6 +++--- extension/html/popup.html | 13 ++++++++++--- extension/js/content.js | 26 ++++++++++++++++---------- extension/manifest.json | 4 ++-- package.json | 4 ++-- 5 files changed, 33 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 8ea7d3d..0edf144 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Prometheus Formatter -Browser extension which makes plain Prometheus metrics easier to read. +Browser extension which makes plain Prometheus/OpenMetrics output easier to read. -This extension is a simple syntax highlighter for plain text Prometheus metrics. -By default it works on URL paths matching '/metrics', '/federate', '/probe', '/prometheus' and '/actuator/prometheus'. By clicking on the extension's icon, you can define your own paths (Regular Expressions are suppported), which will override the default list. +This extension is a simple syntax highlighter for Prometheus and OpenMetrics formats. For the highlighting to work, metric endpoints **must** use either HTTP Content-Type [`application/openmetrics-text`](https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#overall-structure) or [text/plain](https://prometheus.io/docs/instrumenting/exposition_formats/#text-based-format). +For plain-text metrics, parsing is limited by default on URL paths matching '/metrics', '/federate', '/probe', '/prometheus' and '/actuator/prometheus'. By clicking on the extension's icon, you can define your own paths (Regular Expressions are suppported), which will override the default list. ###### Before: ![](_images/before.png) diff --git a/extension/html/popup.html b/extension/html/popup.html index d65f761..2f91d83 100644 --- a/extension/html/popup.html +++ b/extension/html/popup.html @@ -13,7 +13,6 @@ body { font-family: sans-serif; - height: 250px; width: 350px; outline: none; font-size: 100%; @@ -27,19 +26,27 @@ textarea { width: 100%; - height: 70%; + min-height: 10rem; font-size: inherit; } p { font-size: 85%; + line-height: 1.3; + } + + p code { + font-size: inherit; + padding: .2em .4em; + background: #f0f0f0; + border-radius: 0.2em; }

Paths treated as Prometheus endpoints

-

Separate paths by new line. Regular Expressions are supported, e.g.: ^/prometheus

+

Documents with encoding text/plain matching these paths will be highlighted. Separate paths by new line. Regular Expressions are supported, e.g.: ^/prometheus.

diff --git a/extension/js/content.js b/extension/js/content.js index f572c1a..d16fe3e 100755 --- a/extension/js/content.js +++ b/extension/js/content.js @@ -3,17 +3,23 @@ // Don't process HTTP response bodies over 30MB const MAX_BODY_SIZE_BYTES = 30 * 1024 * 1024 -const sendBodyToFormatter = (storedData) => { - // Check if it is a Prometheus plain text response - // This is quite a basic assumption, as the browser cannot access the - // 'version' part of the content type to verify. - if (document.contentType !== 'text/plain') { - port.disconnect() - return - } +// OpenMetrics endpoints have a dedicated HTTP content-type, but Prometheus +// sends a plain-text response. Parsing all text/plain types is a too broad +// assumption, and the browser cannot access the 'version' part of the +// content-type to verify it's actually a Prometheus endpoint. Some exporters +// might not even include the version string. Thus, for text/plain responses, +// the current page's path *must* be contained in the allow list. +const isValidEndpoint = (allowedPaths) => { + if (document.contentType === 'application/openmetrics-text') { return true } + if ( + document.contentType === 'text/plain' && + allowedPaths.some(path => document.location.pathname.match(path)) + ) { return true } + return false +} - // Check if the current page's paths matches one of our whitelist - if (!storedData.paths.some(path => document.location.pathname.match(path))) { +const sendBodyToFormatter = (storedData) => { + if (!isValidEndpoint(storedData.paths)) { port.disconnect() return } diff --git a/extension/manifest.json b/extension/manifest.json index b23100b..62a72fa 100755 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -1,8 +1,8 @@ { "name": "Prometheus Formatter", - "version": "2.1.0", + "version": "2.2.0", "manifest_version": 2, - "description": "Makes plain Prometheus metrics easier to read.", + "description": "Makes plain Prometheus/OpenMetrics endpoints easier to read.", "homepage_url": "https://github.com/fhemberger/prometheus-formatter", "minimum_chrome_version": "60", "icons": { diff --git a/package.json b/package.json index b846522..e8220be 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "prometheus-formatter", - "version": "2.1.0", - "description": "Browser extension which makes plain Prometheus metrics easier to read.", + "version": "2.2.0", + "description": "Browser extension which makes plain Prometheus/OpenMetrics endpoints easier to read.", "scripts": { "test": "standard js/*.js --fix", "release": "./package/package.sh"