Skip to content

Conversation

@adnull
Copy link

@adnull adnull commented Aug 11, 2024

According to #1081 this change adds websocket target support to monitor availability and functionality of websocket servers.

This probe provides features as follows:

  • Basic HTTP authentification
  • Bearer token
  • Arbitrary HTTP headers
  • TLS configuration
  • Send/Receive sequences with regexp matching to ensure the server is working correctly ( similar to the TCP probe)

New metrics:

  • probe_websocket_status_code: resulting http status code on the connection
  • probe_websocket_connection_upgraded: is the connection successfuly upgraded to a websocket connection
  • probe_websocket_failed_due_to_regex: 1 when send/receive sequence wasn't matched to server messages

CHANGES:

[FEATURE] Add websocket connection prober
  • Tests updated
  • Documentation added
  • CHANGELOG added in release-notes section of PR Desc.

@sanya2022
Copy link

Any updates here?

@adnull
Copy link
Author

adnull commented Jun 6, 2025

Any updates here?

If only.. althrough the year isn't passed yet :)

@github-actions github-actions bot removed the stale label Jul 1, 2025
@github-actions github-actions bot added the stale label Sep 1, 2025
@bilkoua
Copy link

bilkoua commented Oct 13, 2025

Could you either approve this merge or let us know what needs to be revised?
@electron0zero @SuperQ

FailIfNoneMatchesRegexp []string `yaml:"fail_if_none_matches_regexp,omitempty"`
}

type WebsocketProbe struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add tests for the probe config.


```

### `<tls_config>`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am bit confused by this change in tls_config, why is this added?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you address this requested change? this looks like a duplicate of the existing <tls_config> section

config/config.go Outdated
QueryResponse []QueryResponse `yaml:"query_response,omitempty"`
}

type HTTPClientConfig struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reasons to redefine this instead of using config.HTTPClientConfig from github.com/prometheus/common/config package?

we use it in HTTPProbe so it would be a good idea to use the same struct and keep things common and uniform.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

config.HTTPClientConfig is used to construct new http client using prometheus internal functions while I need to create a custom Dialer with a set of http headers to establish a connection. I still don't see any way to create raw headers from it, so it needs a third-party implementation to provide full support of the config options (including password files etc). That's why I made my own config structure.

InsecureSkipVerify bool `yaml:"insecure_skip_verify,omitempty"`
}

type HTTPBasicAuth struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as HTTPClientConfig, the BasicAuth in the github.com/prometheus/common/config has File support and is more rich, any reasons to NOT use it?

if we use github.com/prometheus/common/config's HTTPClientConfig, we don't need this type.

registry.MustRegister(httpStatusCode)

dialer := websocket.Dialer{
TLSClientConfig: &tls.Config{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once we use the TLSConfig from github.com/prometheus/common/config, please configure more fields so end users can control those.

TLS MinVersion and TLS ServerName seems to be something I can think we need to expose but it also make sense to expose CA cert and client cert configs so folks can configure tls for websocket probes.


if len(module.Websocket.QueryResponse) > 0 {
probeFailedDueToRegex := prometheus.NewGauge(prometheus.GaugeOpts{
Name: "probe_failed_due_to_regex",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, please see metric names in other probers and follow their lead.

registry.MustRegister(probeFailedDueToRegex)

queryMatched := true
for _, qr := range module.Websocket.QueryResponse {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this block is deeply nested and hard to read. can you simplify it and make it easier to read please.

@electron0zero
Copy link
Member

electron0zero commented Oct 30, 2025

please rebase with master and resolve conflicts and update the PR desc to follow the new PR template: https://github.com/prometheus/blackbox_exporter/blob/master/.github/PULL_REQUEST_TEMPLATE.md 🙏🏼

@github-actions github-actions bot removed the stale label Nov 1, 2025
@bilkoua
Copy link

bilkoua commented Nov 10, 2025

@adnull Could you bring the pull request up to date so it can be merged into master? Do you need any help with that?

@adnull
Copy link
Author

adnull commented Nov 10, 2025

@bilkoua Hi! Will do shortly.

@bilkoua
Copy link

bilkoua commented Dec 5, 2025

@adnull any updates? Do you need any help with that?

adnull and others added 4 commits December 5, 2025 20:40
Signed-off-by: adnull <[email protected]>
Co-authored-by: Suraj Nath <[email protected]>
Signed-off-by: Alex <[email protected]>
@adnull adnull force-pushed the websocket-support branch from 869a6a3 to 6017309 Compare December 5, 2025 19:52
@adnull
Copy link
Author

adnull commented Dec 5, 2025

@bilkoua Just rebased on master, fixed suggested things, except using standart http and tls config structures. I can't use prometheus HTTPConfig as TLSConfig as they are only used in prometheus functions and probes whereas I need to make Dialer myself and I'm only able to pass headers into it, so it needs additional implementation to construct headers from prometheus config structures if we want to use it.

@bilkoua
Copy link

bilkoua commented Dec 8, 2025

@adnull Thank you very much. Could you also fix ci/circleci: test and DCO? Without that, it’s unlikely we’ll be able to proceed with the pull request.

@adnull adnull force-pushed the websocket-support branch from 6017309 to 0d8e05f Compare December 8, 2025 21:08
Signed-off-by: adnull <[email protected]>
@adnull
Copy link
Author

adnull commented Dec 8, 2025

@bilkoua Sure, fixed the things

@bilkoua
Copy link

bilkoua commented Dec 11, 2025

@electron0zero Could you take a look at this PR after the changes?

X-API-Key:
files:
- /path/to/api-key.txt

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

trim this line and add the missing newline at the end of file

```

**Example configurations:**

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should link to example.yaml for examples and add all the examples in one place (example.yml), only add the config options exposed by the websocket probe in this page.


```

### `<tls_config>`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you address this requested change? this looks like a duplicate of the existing <tls_config> section

### `<tls_config>`

```yml
[ http_config: <websocket_http_config>]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like a stray change? can you remove it?

[ max_version: <string> ]
```

#### `<oauth2>`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be removed as well, looks like a copy of existing oauth config section?

HTTPHeaders map[string]interface{} `yaml:"headers,omitempty"`
BasicAuth HTTPBasicAuth `yaml:"basic_auth,omitempty"`
BearerToken string `yaml:"bearer_token,omitempty"`
TLSConfig *tls.Config `yaml:"tls_config,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reasons to not use config.TLSConfig in this case? we use that type across all probes so it's better to stay consistent with TLS config options we expose?

type WSHTTPClientConfig struct {
HTTPHeaders map[string]interface{} `yaml:"headers,omitempty"`
BasicAuth HTTPBasicAuth `yaml:"basic_auth,omitempty"`
BearerToken string `yaml:"bearer_token,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a secret so you should be using Secret type from the common/config: https://github.com/prometheus/common/blob/d80d8544703e59a080a204b6f7429ac6561fb24f/config/config.go#L28

if you don't use Secret type in this case, the token will be logged by the logs and will be exposed in the config page.

}

type WSHTTPClientConfig struct {
HTTPHeaders map[string]interface{} `yaml:"headers,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use https://github.com/prometheus/common/blob/main/config/headers.go

they have secret type, support for files and validation logic methods that you can reuse those.

see https://github.com/prometheus/common/blob/d80d8544703e59a080a204b6f7429ac6561fb24f/config/headers.go#L116 on how to build headers from all sources.


type HTTPBasicAuth struct {
Username string `yaml:"username"`
Password string `yaml:"password"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

password should be Secret type.

}

func (c *HTTPBasicAuth) BasicAuthHeader() string {
return "Basic " + base64.StdEncoding.EncodeToString([]byte(c.Username+":"+c.Password))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we are converting the basic auth into a Header, do we need to support a basic auth?

we can just document that they can use Basic Auth with headers and let users set this header by supported methods, including files, etc.

@bilkoua
Copy link

bilkoua commented Jan 3, 2026

@electron0zero Thanks
@adnull Could you make these fixes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants