{"id":20947747,"url":"https://github.com/alphahydrae/probeit","last_synced_at":"2026-02-12T22:33:07.541Z","repository":{"id":42361003,"uuid":"138319169","full_name":"AlphaHydrae/probeit","owner":"AlphaHydrae","description":"Probe HTTP URLs and AWS S3 buckets to produce metrics in JSON or for Prometheus","archived":false,"fork":false,"pushed_at":"2023-01-07T02:23:10.000Z","size":1266,"stargazers_count":3,"open_issues_count":19,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-16T13:00:49.342Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://probeit.herokuapp.com/?target=http://google.com\u0026pretty=true","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AlphaHydrae.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-06-22T15:31:55.000Z","updated_at":"2023-02-03T16:56:39.000Z","dependencies_parsed_at":"2023-02-06T10:30:47.571Z","dependency_job_id":null,"html_url":"https://github.com/AlphaHydrae/probeit","commit_stats":null,"previous_names":["alphahydrae/probe-srv"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/AlphaHydrae/probeit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlphaHydrae%2Fprobeit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlphaHydrae%2Fprobeit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlphaHydrae%2Fprobeit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlphaHydrae%2Fprobeit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlphaHydrae","download_url":"https://codeload.github.com/AlphaHydrae/probeit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlphaHydrae%2Fprobeit/sbom","scorecard":{"id":12280,"data":{"date":"2025-08-11","repo":{"name":"github.com/AlphaHydrae/probeit","commit":"55ffcd390f8e1b18435ab1fe75106e1945adb1b2"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.8,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: MIT License: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Pinned-Dependencies","score":2,"reason":"dependency not pinned by hash detected -- score normalized to 2","details":["Warn: containerImage not pinned by hash: Dockerfile:1","Warn: containerImage not pinned by hash: Dockerfile:16: pin your Docker image by updating node:12.16.0-alpine to node:12.16.0-alpine@sha256:0d6db03a05b5d8b417204258cfa34f36eac1c00a54946fb31891e89a642eb449","Warn: npmCommand not pinned by hash: Dockerfile:22-26","Info:   0 out of   2 containerImage dependencies pinned","Info:   1 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"61 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-rrc9-gqf8-8rwg","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-ff7x-qrg7-qggm","Warn: Project is vulnerable to: GHSA-vh7m-p724-62c2","Warn: Project is vulnerable to: GHSA-r9p9-mrjm-926w","Warn: Project is vulnerable to: GHSA-434g-2637-qmqr","Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m","Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw","Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-593f-38f6-jp5m","Warn: Project is vulnerable to: GHSA-x2rg-q646-7m2v","Warn: Project is vulnerable to: GHSA-jgmv-j7ww-jx2x","Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq","Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488","Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-82v2-mx6x-wq7q","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-8hfj-j24r-96c4","Warn: Project is vulnerable to: GHSA-wc69-rhjr-hc9g","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-hxcc-f52p-wc94","Warn: Project is vulnerable to: GHSA-vx3p-948g-6vhq","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-w5p7-h5w8-2hfq","Warn: Project is vulnerable to: GHSA-332q-7ff2-57h2","Warn: Project is vulnerable to: GHSA-cf4h-3jhx-xvhq","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-776f-qx25-q3cc","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-14T14:53:45.093Z","repository_id":42361003,"created_at":"2025-08-14T14:53:45.093Z","updated_at":"2025-08-14T14:53:45.093Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275680483,"owners_count":25508579,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-17T02:00:09.119Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-19T00:12:54.582Z","updated_at":"2025-09-17T23:12:05.947Z","avatar_url":"https://github.com/AlphaHydrae.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Probe It\n\nExecute system commands or probe HTTP URLs and [AWS](https://aws.amazon.com)\n[S3](https://aws.amazon.com/s3/) buckets to produce metrics in JSON or for\n[Prometheus](https://prometheus.io). Can be used on the command line or as a\nserver.\n\nInspired by [Prometheus Blackbox\nExporter](https://github.com/prometheus/blackbox_exporter).\n\n[![npm version](https://badge.fury.io/js/probeit.svg)](https://badge.fury.io/js/probeit)\n[![license](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE.txt)\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n\n- [Usage](#usage)\n  - [Installation](#installation)\n- [Metrics](#metrics)\n  - [Prometheus format](#prometheus-format)\n  - [Generic metrics](#generic-metrics)\n    - [`duration`](#duration)\n- [Command probe](#command-probe)\n  - [Function commands](#function-commands)\n  - [System commands](#system-commands)\n    - [System command metrics](#system-command-metrics)\n    - [`commandExitCode`](#commandexitcode)\n- [HTTP probe](#http-probe)\n  - [HTTP probe metrics](#http-probe-metrics)\n    - [`httpCertificateExpiry`](#httpcertificateexpiry)\n    - [`httpContentLength`](#httpcontentlength)\n    - [`httpDuration`](#httpduration)\n    - [`httpRedirects`](#httpredirects)\n    - [`httpSecure`](#httpsecure)\n    - [`httpStatusCode`](#httpstatuscode)\n    - [`httpVersion`](#httpversion)\n  - [HTTP probe parameters](#http-probe-parameters)\n    - [`allowUnauthorized`](#allowunauthorized)\n    - [`followRedirects`](#followredirects)\n    - [`header`](#header)\n    - [`method`](#method)\n  - [HTTP probe expectations](#http-probe-expectations)\n    - [`expectHttpRedirects`](#expecthttpredirects)\n    - [`expectHttpRedirectTo`](#expecthttpredirectto)\n    - [`expectHttpResponseBodyMatch`](#expecthttpresponsebodymatch)\n    - [`expectHttpResponseBodyMismatch`](#expecthttpresponsebodymismatch)\n    - [`expectHttpSecure`](#expecthttpsecure)\n    - [`expectHttpStatusCode`](#expecthttpstatuscode)\n    - [`expectHttpVersion`](#expecthttpversion)\n  - [HTTP probe failures](#http-probe-failures)\n    - [`httpResponseBodyMismatch`](#httpresponsebodymismatch)\n    - [`insecureHttp`](#insecurehttp)\n    - [`invalidHttpRedirectCount`](#invalidhttpredirectcount)\n    - [`invalidHttpRedirectLocation`](#invalidhttpredirectlocation)\n    - [`invalidHttpStatusCode`](#invalidhttpstatuscode)\n    - [`invalidHttpVersion`](#invalidhttpversion)\n    - [`missingHttpRedirect`](#missinghttpredirect)\n    - [`unexpectedHttpRedirect`](#unexpectedhttpredirect)\n    - [`unexpectedHttpResponseBodyMatch`](#unexpectedhttpresponsebodymatch)\n    - [`unexpectedlySecureHttp`](#unexpectedlysecurehttp)\n- [S3 probe](#s3-probe)\n  - [S3 probe metrics](#s3-probe-metrics)\n    - [`s3FirstObjectModificationDate`](#s3firstobjectmodificationdate)\n    - [`s3FirstObjectSize`](#s3firstobjectsize)\n    - [`s3FirstObjectVersionModificationDate`](#s3firstobjectversionmodificationdate)\n    - [`s3FirstObjectVersionSize`](#s3firstobjectversionsize)\n    - [`s3LargestObjectSize`](#s3largestobjectsize)\n    - [`s3LastObjectModificationDate`](#s3lastobjectmodificationdate)\n    - [`s3LastObjectSize`](#s3lastobjectsize)\n    - [`s3LastObjectVersionModificationDate`](#s3lastobjectversionmodificationdate)\n    - [`s3LastObjectVersionSize`](#s3lastobjectversionsize)\n    - [`s3ObjectsCount`](#s3objectscount)\n    - [`s3ObjectsTotalSize`](#s3objectstotalsize)\n    - [`s3ObjectVersionsCount`](#s3objectversionscount)\n    - [`s3SmallestObjectSize`](#s3smallestobjectsize)\n  - [S3 probe parameters](#s3-probe-parameters)\n    - [`s3ByPrefix`](#s3byprefix)\n    - [`s3ByPrefixOnly`](#s3byprefixonly)\n    - [`s3Versions`](#s3versions)\n- [Versioning policy](#versioning-policy)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n\n\n## Usage\n\nVisit\n[http://probeit.herokuapp.com/?target=http://google.com\u0026pretty=true](http://probeit.herokuapp.com/?target=http://google.com\u0026pretty=true)\nfor a sample probe of an HTTP endpoint.\n\nThe `target` query parameter indicates what to probe:\n\n* An HTTP(S) endpoint, e.g. `https://google.com`, to use the [HTTP\n  probe](#http-probe)\n* An S3 bucket URL, e.g. `s3://bucket_name`, to use the [S3 probe](#s3-probe)\n\nThe response will be a JSON object with:\n\n* A `success` boolean property indicating whether the probe was successful.\n* A `metrics` array of objects, describing various metrics collected from the\n  probed target, such as duration of the probe, HTTP status code, number of S3\n  objects, etc.\n* A `failures` array which may indicate possible causes of the probe's failure.\n\n```json\n{\n  \"failures\": [],\n  \"metrics\": [\n    {\n      \"description\": \"How long the probe took to complete in seconds\",\n      \"name\": \"duration\",\n      \"tags\": {},\n      \"type\": \"seconds\",\n      \"value\": 0.12\n    },\n    ...\n  ],\n  \"success\": true\n}\n```\n\n\n\n### Installation\n\n**Run it with [Docker](https://www.docker.com)**\n\n```bash\ndocker run -p 3000:3000 alphahydrae/probeit\n```\n\n**Or, run it with [npx](https://github.com/zkat/npx)**\n\n```bash\nnpx probeit\n```\n\n**Or, install and run it manually**\n\n```bash\nnpm install -g probeit\nprobeit\n```\n\n**Then, try it**\n\nVisit [http://localhost:3000?target=http://google.com\u0026pretty=true](http://localhost:3000?target=http://google.com\u0026pretty=true)\n\n\n\n## Metrics\n\nThe server's probes provide various metrics about their target, mostly numeric\nvalues such as counts, bytesizes, last modification dates, etc.\n\nEach metric is a JSON object with the following format:\n\n```json\n{\n  \"description\": \"What I am\",\n  \"name\": \"myName\",\n  \"tags\": {\n    \"meta\": \"data\"\n  },\n  \"type\": \"seconds\",\n  \"value\": 1.2\n}\n```\n\nThe following metric types exist at this time:\n\n* **boolean** - `true` or `false`.\n* **bytes** - Integer greater than or equal to zero.\n* **datetime** - Date in ISO-8601 format.\n* **number** - Number with no associated unit of measurement.\n* **quantity** - Integer greater than or equal to zero, representing an amount\n  of something.\n* **seconds** - Number greater than or equal to zero.\n\nThe **value of a metric may be `null`** if it cannot be determined (e.g. the\n[`httpCertificateExpiry` metric](#httpcertificateexpiry) can be `null` if the\nHTTP request is not made over TLS, or the [`s3LastObjectModificationDate`\nmetric](#s3lastobjectmodificationdate) can be `null` if the S3 bucket contains\nno objects).\n\n\n\n### Prometheus format\n\nTo get the metrics in [Prometheus](https://prometheus.io)'s text format, use the `/metrics` path:\n\n[http://probeit.herokuapp.com/metrics?target=http://google.com](http://probeit.herokuapp.com/metrics?target=http://google.com)\n\nMetric names are converted from the JSON's camel-case format to **underscored\nformat** and the **`probe_` prefix** is prepended (e.g.  `httpStatusCode`\nbecomes `probe_http_status_code`). Additionally, the metric's **type is added as\na suffix** if it's `bytes` or `seconds` (e.g. `duration` becomes\n`probe_duration_seconds`).\n\nMetric tags are added as labels.\n\nAll metrics will be provided as\n[gauges](https://prometheus.io/docs/concepts/metric_types/#gauge) by applying\nthe following conversions by type:\n\n* **boolean** - `true` becomes `1` and `false` becomes `0`.\n* **bytes** - No conversion, except for `null` which becomes `-1`.\n* **datetime** - Dates are provided in [Unix\n  time](https://en.wikipedia.org/wiki/Unix_time), i.e. the number of seconds\n  that have elapsed since 00:00:00 UTC on Thursday, 1 January 1970. `null`\n  becomes `-1`.\n* **number** - No conversion, except for `null` which becomes `NaN`.\n* **quantity** - No conversion, except for `null` which becomes `-1`.\n* **seconds** - No conversion, except for `null` which becomes `-1`.\n\n\n\n### Generic metrics\n\nThe following sub-headings document metrics that are provided by all probes.\n\n\n\n#### `duration`\n\n**Type:** seconds\n\nHow long the probe took to complete in seconds.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"duration\",\n  \"tags\": {},\n  \"type\": \"seconds\",\n  \"value\": 0.12\n}\n```\n\n\n\n## Command probe\n\nThe command probe is used when the target is an URI that starts with `command:`,\ne.g. `command:foo`. This will execute the command named `foo` and return its\nmetrics.\n\nNamed commands must be pre-defined with the `commands` property of Probe It's\nconfiguration file (`config.yml` by default, or the file indicated by the `-c,\n--config \u003cFILE\u003e` command line option or the `$PROBE_CONFIG` environment\nvariable). The property is an object in which keys are command names and values\nare the definitions of the commands to run:\n\n```yml\ncommands:\n  lsRoot:\n    type: system\n    command: ls\n    args: [ -la, / ]\n  unameAll\n    type: system\n    command: uname\n    args: [ -a ]\n```\n\nThe following command types are supported:\n\n* Arbitrary [JavaScript functions](#function-commands) to be executed by Probe It.\n* [System commands](#system-commands) to spawn in a new process.\n\n\n\n### Function commands\n\nIf your configuration file is a JavaScript file instead of a JSON or YAML file,\nyou can also define a command to probe as an arbitrary JavaScript function:\n\n```js\nexports.commands = {\n  doStuff: {\n    type: 'function',\n    command: async function() {\n\n      try {\n        // Read metrics from a file\n        const metrics = await fs.Promises.readFile('/metrics.json', 'utf8');\n        return {\n          metrics,\n          failures: [],\n          success: true\n        };\n      } catch (err) {\n        // Describe possible failure\n        return {\n          failures: [\n            cause: \"invalidMetricsFile\",\n            description: \"Could not read metrics file\"\n          ],\n          metrics: [],\n          success: false\n        };\n      }\n    }\n  }\n};\n```\n\nThe function may be synchronous or asynchronous, and must return an object with\nthe following properties:\n\n* **`metrics`** - An array of objects describin the metrics produced by running\n  the command. Each metrics object must be in the [correct format](#metrics).\n* **`failures`** - An array of objects describing reasons why the probe failed\n  (it may be empty). Each failure object must have:\n\n  * A `cause` property which is a string code identifying the failure.\n  * A human-readable `description` property.\n  * An optional `expected` property indicating the expected value.\n  * An optional `actual` property indicating the actual value which differs from\n    the expected one.\n  * Optional extra properties describing the failure.\n* **`success`** - `true` or `false` to indicate whether the probe succeeded.\n\n\n\n### System commands\n\nSystem commands are commands that will be spawned in a new process on the\nmachine on which Probe It is running. They can be defined with all configuration\nfile formats (JavaScript, JSON or YAML), for example in JSON:\n\n```json\n{\n  \"commands\": {\n    \"lsRoot\": {\n      \"type\": \"system\",\n      \"command\": \"ls\",\n      \"args\": [ \"-la\", \"/\" ],\n      \"cwd\": \"/\"\n    }\n  }\n}\n```\n\nThe following options describe a system command:\n\n* **`command`** - The executable to run.\n* **`args`** - An optional array of arguments to pass to the executable.\n* **`cwd`** - An optional working directory to run the executable in.\n\n\n\n#### System command metrics\n\nThe following sub-headings document the metrics provided by a system command probe.\n\n#### `commandExitCode`\n\n**Type:** number\n\nThe exit code of the executed command. `0` indicates successful execution, while\nand non-zero code indicates some kind of failure.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"commandExitCode\",\n  \"tags\": {},\n  \"type\": \"number\",\n  \"value\": 0\n}\n```\n\n\n\n## HTTP probe\n\nThe HTTP probe is used when the target is an URL that starts with `http://` or\n`https://`. By default, it will make a `GET` request to that URL, following any\nredirects, and provide various metrics about the HTTP response.\n\n\n\n### HTTP probe metrics\n\nThe following sub-headings document the metrics provided by the HTTP probe.\n\n#### `httpCertificateExpiry`\n\n**Type:** datetime\n\nExpiration date of the SSL certificate (when the target starts with `https://`).\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"httpCertificateExpiry\",\n  \"tags\": {},\n  \"type\": \"datetime\",\n  \"value\": \"2018-05-01T00:00:00Z\"\n}\n```\n\n#### `httpContentLength`\n\n**Type:** bytes\n\nLength of the HTTP response in bytes.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"httpContentLength\",\n  \"tags\": {},\n  \"type\": \"bytes\",\n  \"value\": 2801239\n}\n```\n\n#### `httpDuration`\n\n**Type:** seconds, **Repeated**\n\nDuration of the HTTP request(s) by phase, summed over all redirects, in seconds.\nSeveral instances of this metric will be provided, one for each request phase:\n\n* `dnsLookup` - How long it took to perform the DNS lookup.\n* `tcpConnection` - How long it took to open the TCP connection after the DNS lookup.\n* `tlsHandshake` - How long it took to perform the TLS handshake for an HTTPS probe,\n                   after the TCP connection was established. (This metric will be\n                   absent for URLs starting with `http://`.)\n* `firstByte` - How long it took to receive the first byte of the response after the\n                TLS handshake (or TCP connection).\n* `contentTransfer` - How long it took to transfer the entire response entity once the\n                      first byte was received.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"httpDuration\",\n  \"tags\": {\n    \"phase\": \"tlsHandshake\"\n  },\n  \"type\": \"seconds\",\n  \"value\": 0.02\n}\n```\n\n#### `httpRedirects`\n\n**Type:** quantity\n\nNumber of times HTTP 301 or 302 redirects were followed.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"httpRedirects\",\n  \"tags\": {},\n  \"type\": \"quantity\",\n  \"value\": 2\n}\n```\n\n#### `httpSecure`\n\n**Type:** boolean\n\nIndicates whether SSL/TLS was used for the final redirect.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"httpSecure\",\n  \"tags\": {},\n  \"type\": \"boolean\",\n  \"value\": true\n}\n```\n\n#### `httpStatusCode`\n\n**Type:** number\n\nHTTP status code of the final response.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"httpStatusCode\",\n  \"tags\": {},\n  \"type\": \"number\",\n  \"value\": 404\n}\n```\n\n#### `httpVersion`\n\n**Type:** number\n\nHTTP version of the final response.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"httpVersion\",\n  \"tags\": {},\n  \"type\": \"number\",\n  \"value\": 1.1\n}\n```\n\n\n\n### HTTP probe parameters\n\nThe following sub-headings document URL query parameters that can be provided to\ncustomize the behavior of the HTTP probe.\n\n#### `allowUnauthorized`\n\n**Type:** boolean, **Default:** `false`\n\nWhether to consider an HTTP response with an invalid SSL certificate as a\nsuccess.\n\n```\n?allowUnauthorized=true\n```\n\n#### `followRedirects`\n\n**Type:** boolean, **Default:** `true`\n\nWhether the probe will follow redirects (e.g. HTTP 301 Moved Permanently or HTTP\n302 Found) to provide metrics about the final response, or whether it will\nsimply provide metrics about the first response sent by the server.\n\n```\n?followRedirects=false\n```\n\n#### `header`\n\n**Type:** `key=value` pair, **Repeatable**\n\nHTTP header to add to the probe's request(s). This parameter can be repeated to\nset multiple headers.\n\n```\n// The value is \"Authorization=Basic YWRtaW46Y2hhbmdlbWUh\", URL-encoded\n?header=Authorization%3DBasic%20YWRtaW46Y2hhbmdlbWUh\n```\n\n#### `method`\n\n**Type:** string (`GET`, `POST`, `PUT`, etc.), **Default:** `GET`\n\nThe HTTP method to use for the request on the target URL. `GET` by default.\n\n```\n?method=POST\n```\n\n\n\n### HTTP probe expectations\n\nThe following sub-headings document URL query parameters that can be\nprovided to customize how the HTTP probe will determine if it was successful.\n\nBy default, it only expects that the final HTTP response will have a code in the\n2xx or 3xx range.\n\n#### `expectHttpRedirects`\n\n**Type:** boolean or integer\n\nFor the probe to be considered successful with this parameter:\n\n* If `true`, at least 1 redirect must have been followed.\n* If `false`, no redirect must have been followed.\n* If an integer, exactly that number of redirects must have been followed.\n\n```\n?expectHttpRedirects=true\n?expectHttpRedirects=2\n```\n\n**Possible failures:**\n\n* [`invalidHttpRedirectCount`](#invalidhttpredirectcount)\n* [`missingHttpRedirect`](#missinghttpredirect)\n* [`unexpectedHttpRedirect`](#unexpectedhttpredirect)\n\n#### `expectHttpRedirectTo`\n\n**Type:** URL\n\nFor the probe to be considered successful with this parameter:\n\n* At least 1 redirect must have been followed.\n* The protocol, host, port and path of the final HTTP request's URL must correspond\n  to the specified URL. (Other parts of the URL, such as authentication, query\n  string or hash, are ignored for the comparison.)\n\n```\n// The value is \"http://example.com/path\", URL-encoded\n?expectHttpRedirectTo=http%3A%2F%2Fexample.com%2Fpath\n```\n\n**Possible failures:**\n\n* [`invalidHttpRedirectLocation`](#invalidhttpredirectlocation)\n\n#### `expectHttpResponseBodyMatch`\n\n**Type:** regular expression, **Repeatable**\n\nFor the probe to be considered successful with this parameter, the HTTP response\nbody must match the regular expression.\n\nThis parameter can be repeated to check the presence of multiple patterns.\n\n```\n// The value is \"Catch \\d{2}\", URL-encoded\n?expectHttpResponseBodyMatch=Catch%20%5Cd%7B2%7D\n```\n\n**Possible failures:**\n\n* [`httpResponseBodyMismatch`](#httpresponsebodymismatch)\n\n#### `expectHttpResponseBodyMismatch`\n\n**Type:** regular expression, **Repeatable**\n\nFor the probe to be considered successful with this parameter, the HTTP response\nbody must **not** match the regular expression.\n\nThis parameter can be repeated to check the absence of multiple patterns.\n\n```\n// The value is \"connection lost\", URL-encoded\n?expectHttpResponseBodyMismatch=connection+lost\n```\n\n**Possible failures:**\n\n* [`unexpectedHttpResponseBodyMatch`](#unexpectedhttpresponsebodymatch)\n\n#### `expectHttpSecure`\n\n**Type:** boolean\n\nFor the probe to be considered successful with this parameter:\n\n* If `true`, the final HTTP response must have been over TLS (e.g. `https://`).\n* If `false`, the final HTTP response must **not** have been over TLS (e.g.\n  `http://`).\n\nBy default, either is considered successful.\n\nNote that this does not affect the probe's behavior of failing if an SSL\ncertificate is invalid. Use the [`allowUnauthorized`\nparameter](#allowunauthorized) for that.\n\n```\n?expectHttpSecure=true\n```\n\n**Possible failures:**\n\n* [`insecureHttp`](#insecurehttp)\n* [`unexpectedlySecureHttp`](#unexpectedlysecurehttp)\n\n#### `expectHttpStatusCode`\n\n**Type:** number or HTTP status code class (e.g. `2xx`), **Repeatable**, **Default:** `[ \"2xx\", \"3xx\" ]`\n\nFor the probe to be considered successful with this parameter, the final HTTP\nresponse's status code must be one of the expected codes, or fall within one of\nthe expected classes (e.g. `204` falls within the `2xx` class). Both individual\ncodes and code classes may be provided.\n\n```\n?expectHttpStatusCode=204\n?expectHttpStatusCode=200\u0026expectHttpStatusCode=3xx\n```\n\n**Possible failures:**\n\n* [`invalidHttpStatusCode`](#invalidhttpstatuscode)\n\n#### `expectHttpVersion`\n\n**Type:** number\n\nFor the probe to be considered successful with this parameter, the HTTP version\nof the final response must match the expected version.\n\n```\n?expectHttpVersion=1.1\n```\n\n**Possible failures:**\n\n* [`invalidHttpVersion`](#invalidhttpversion)\n\n\n\n### HTTP probe failures\n\nThe following sub-headings document the possible causes of failure that may be\nincluded in the HTTP probe's result.\n\n#### `httpResponseBodyMismatch`\n\nThe body of the final HTTP response did not match some of the regular\nexpressions provided with the [`expectHttpResponseBodyMatch`\nparameter](#expecthttpresponsebodymatch).\n\nThis failure will be repeated for each regular expression that did not match.\n\n```json\n{\n  \"cause\": \"httpResponseBodyMismatch\",\n  \"description\": \"...\",\n  \"expected\": \"[a-z0-9]+\"\n}\n```\n\n#### `insecureHttp`\n\nThe final HTTP request was expected to be over TLS due to the [`expectHttpSecure`\nparameter](#expecthttpsecure) being set to `true`, but it was not.\n\n```json\n{\n  \"cause\": \"insecureHttp\",\n  \"description\": \"...\"\n}\n```\n\n#### `invalidHttpRedirectCount`\n\nAn integer was provided as the expected number of redirects with the\n[`expectHttpRedirects` parameter](#expecthttpredirects), and the actual number\nof followed redirects until the final HTTP response did not match that\nexpectation.\n\n```json\n{\n  \"actual\": 2,\n  \"cause\": \"invalidHttpRedirectCount\",\n  \"description\": \"...\",\n  \"expected\": 1\n}\n```\n\n#### `invalidHttpRedirectLocation`\n\nThe final redirection was expected to be made to the URL specified with the\n[`expectHttpRedirectTo` parameter](#expecthttpredirectto), but a different URL\nwas provided by the server.\n\n```json\n{\n  \"actual\": \"http://example.com/foo\",\n  \"cause\": \"invalidHttpRedirectLocation\",\n  \"description\": \"...\",\n  \"expected\": \"http://example.com/bar\"\n}\n```\n\n#### `invalidHttpStatusCode`\n\nThe HTTP status code of the final response did not match any of the expected\ncodes or code classes provided with the [`expectHttpStatusCode`\nparameter](#expecthttpstatuscode) (or set by default).\n\n```json\n{\n  \"actual\": 404,\n  \"cause\": \"invalidHttpStatusCode\",\n  \"description\": \"...\",\n  \"expected\": [ \"200\", \"3xx\" ]\n}\n```\n\n#### `invalidHttpVersion`\n\nThe HTTP version of the final response was not the expected version provided\nwith the [`expectHttpVersion` parameter](#expecthttpversion).\n\n```json\n{\n  \"actual\": 2.0,\n  \"cause\": \"invalidHttpStatusCode\",\n  \"description\": \"...\",\n  \"expected\": 1.1\n}\n```\n\n#### `missingHttpRedirect`\n\nThe [`expectHttpRedirects` parameter](#expecthttpredirects) was set to `true`,\nbut no redirect was issued by the server.\n\n```json\n{\n  \"cause\": \"missingHttpRedirect\",\n  \"description\": \"...\"\n}\n```\n\n#### `unexpectedHttpRedirect`\n\nThe [`expectHttpRedirects` parameter](#expecthttpredirects) was set to `false`,\nbut the server issued one or more redirects.\n\n```json\n{\n  \"actual\": 3,\n  \"cause\": \"missingHttpRedirect\",\n  \"description\": \"...\",\n  \"expected\": 0\n}\n```\n\n#### `unexpectedHttpResponseBodyMatch`\n\nThe body of the final HTTP response matched some of the regular expressions\nprovided with the [`expectHttpResponseBodyMismatch`\nparameter](#expecthttpresponsebodymismatch).\n\nThis failure will be repeated for each regular expression that matched.\n\nThe failure object's `actual` property will contain the full regular expression\nmatch.\n\n```json\n{\n  \"actual\": \"error: connection lost\",\n  \"cause\": \"unexpectedHttpResponseBodyMatch\",\n  \"description\": \"...\",\n  \"expected\": \"error: .+\"\n}\n```\n\n#### `unexpectedlySecureHttp`\n\nThe final HTTP request was expected **not** to be over TLS due to the\n[`expectHttpSecure` parameter](#expecthttpsecure) being set to `false`, but it\nwas.\n\n```json\n{\n  \"cause\": \"unexpectedlySecureHttp\",\n  \"description\": \"...\"\n}\n```\n\n\n\n## S3 probe\n\nThe S3 probe is used when the target is an URL that starts with `s3://`.  The\nformat is as follows:\n\n    s3://[access_key_id:secret_access_key@]bucket_name[/prefix]\n\nFor example:\n\n* `s3://my_bucket`\n* `s3://A28sdf8A:oa83ufozsr8b@secure_backups/daily`\n\nBy default, the probe will list all the objects in the bucket and provide\nvarious metrics about these objects' sizes and last modification dates. It can\nalso be configured to list object versions with the [`s3Versions`\nparameter](#s3versions).\n\n\n\n### S3 probe metrics\n\nThe following sub-headings document the metrics provided by the S3 probe.\n\n#### `s3FirstObjectModificationDate`\n\n**Type:** datetime\n\nThe modification date of the earliest modified object.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"s3FirstObjectModificationDate\",\n  \"tags\": {},\n  \"type\": \"datetime\",\n  \"value\": \"2018-05-01T00:00:00Z\"\n}\n```\n\n#### `s3FirstObjectSize`\n\n**Type:** bytes\n\nThe size of the earliest modified object in bytes.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"s3FirstObjectSize\",\n  \"tags\": {},\n  \"type\": \"bytes\",\n  \"value\": 1850912\n}\n```\n\n#### `s3FirstObjectVersionModificationDate`\n\n**Type:** datetime\n\nThe modification date of the earliest modified object version.\n\n**Note:** this metric will only be provided if the [`s3Versions` parameter] is\nset to `true`.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"s3FirstObjectVersionModificationDate\",\n  \"tags\": {},\n  \"type\": \"datetime\",\n  \"value\": \"2018-05-01T00:00:00Z\"\n}\n```\n\n#### `s3FirstObjectVersionSize`\n\n**Type:** bytes\n\nThe size of the earliest modified object version in bytes.\n\n**Note:** this metric will only be provided if the [`s3Versions` parameter] is\nset to `true`.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"s3FirstObjectVersionSize\",\n  \"tags\": {},\n  \"type\": \"bytes\",\n  \"value\": 1850912\n}\n```\n\n#### `s3LargestObjectSize`\n\n**Type:** bytes\n\nThe size of the largest object in bytes.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"s3LargestObjectSize\",\n  \"tags\": {},\n  \"type\": \"bytes\",\n  \"value\": 18392047\n}\n```\n\n#### `s3LastObjectModificationDate`\n\n**Type:** datetime\n\nThe modification date of the most recently modified object.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"s3LastObjectModificationDate\",\n  \"tags\": {},\n  \"type\": \"datetime\",\n  \"value\": \"2018-05-01T00:00:00Z\"\n}\n```\n\n#### `s3LastObjectSize`\n\n**Type:** bytes\n\nThe size of the most recently modified object in bytes.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"s3LastObjectSize\",\n  \"tags\": {},\n  \"type\": \"bytes\",\n  \"value\": 1850912\n}\n```\n\n#### `s3LastObjectVersionModificationDate`\n\n**Type:** datetime\n\nThe modification date of the most recently modified object version.\n\n**Note:** this metric will only be provided if the [`s3Versions` parameter] is\nset to `true`.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"s3LastObjectVersionModificationDate\",\n  \"tags\": {},\n  \"type\": \"datetime\",\n  \"value\": \"2018-05-01T00:00:00Z\"\n}\n```\n\n#### `s3LastObjectVersionSize`\n\n**Type:** bytes\n\nThe size of the most recently modified object version in bytes.\n\n**Note:** this metric will only be provided if the [`s3Versions` parameter] is\nset to `true`.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"s3LastObjectVersionSize\",\n  \"tags\": {},\n  \"type\": \"bytes\",\n  \"value\": 1850912\n}\n```\n\n#### `s3ObjectsCount`\n\n**Type:** quantity\n\nNumber of objects.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"s3ObjectsCount\",\n  \"tags\": {},\n  \"type\": \"quantity\",\n  \"value\": 23\n}\n```\n\n#### `s3ObjectsTotalSize`\n\n**Type:** bytes\n\nTotal size of objects.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"s3ObjectsTotalSize\",\n  \"tags\": {},\n  \"type\": \"bytes\",\n  \"value\": 4027329041\n}\n```\n\n#### `s3ObjectVersionsCount`\n\n**Type:** quantity\n\nNumber of object versions.\n\n**Note:** this metric will only be provided if the [`s3Versions` parameter] is\nset to `true`.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"s3ObjectVersionsCount\",\n  \"tags\": {},\n  \"type\": \"quantity\",\n  \"value\": 32\n}\n```\n\n#### `s3SmallestObjectSize`\n\n**Type:** bytes\n\nThe size of the smallest object in bytes.\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"s3SmallestObjectSize\",\n  \"tags\": {},\n  \"type\": \"bytes\",\n  \"value\": 351\n}\n```\n\n\n\n### S3 probe parameters\n\nThe following sub-headings document URL query parameters that can be provided to\ncustomize the behavior of the S3 probe.\n\n#### `s3ByPrefix`\n\n**Type:** string, **Repeatable**\n\nWhen provided `N` times, this parameter will cause each metric to be provided `N +\n1` times in the response:\n\n* Once for each prefix (`N`)\n* Once for no prefix (`+ 1`)\n\n```\n?s3ByPrefix=daily\u0026s3ByPrefix=monthly\n```\n\nFor example, if the parameter is provided twice with the values `daily` and\n`monthly` like in the example above, the `s3ObjectsTotalSize` metric will be\npresent twice (as will all other metrics of the S3 probe). Those separate metric\nobjects can be differentiated by their `tags` property:\n\n```json\n{\n  \"description\": \"...\",\n  \"name\": \"s3ObjectsTotalSize\",\n  \"tags\": {\n    \"prefix\": \"\"\n  },\n  \"type\": \"bytes\",\n  \"value\": 4027329041\n},\n{\n  \"description\": \"...\",\n  \"name\": \"s3ObjectsTotalSize\",\n  \"tags\": {\n    \"prefix\": \"daily\"\n  },\n  \"type\": \"bytes\",\n  \"value\": 230918\n},\n{\n  \"description\": \"...\",\n  \"name\": \"s3ObjectsTotalSize\",\n  \"tags\": {\n    \"prefix\": \"monthly\"\n  },\n  \"type\": \"bytes\",\n  \"value\": 2507812\n}\n```\n\n#### `s3ByPrefixOnly`\n\nWhen using the previous `s3ByPrefix` option, all S3 objects are analyzed by\ndefault, including those that do not match the provided prefix or prefixes.\nEnabling this option limits the analysis to only those objects that match the\nprefixes.\n\n```\n?s3ByPrefixOnly=true\n```\n\n#### `s3Versions`\n\n**Type:** boolean, **Default:** `false`\n\nWhether to list objects versions in the bucket and generate metrics for them.\n\n```\n?s3Versions=true\n```\n\n\n\n## Versioning policy\n\nThis project follows the rules of [semantic versioning\nv2.0.0](https://semver.org/spec/v2.0.0.html). Check the\n[CHANGELOG](CHANGELOG.md) for breaking changes between major versions.\n\n**Beware:** changes to the `description` property of metrics or failures will\n**not** be considered breaking.\n\nPlease file a bug If you notice an actual breaking change without a\ncorresponding major version number change.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falphahydrae%2Fprobeit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falphahydrae%2Fprobeit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falphahydrae%2Fprobeit/lists"}