Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parse OTLP endpoint address #156

Merged
merged 2 commits into from
Nov 18, 2021
Merged

parse OTLP endpoint address #156

merged 2 commits into from
Nov 18, 2021

Conversation

Geal
Copy link
Contributor

@Geal Geal commented Nov 17, 2021

Fix #149

the endpoint address is often specified as host:port instead of a full
URL: https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/otlpexporter/README.md#getting-started

Unfortunately, the url crate would parse 'collector:4317' as an URL with
the 'collector' scheme and no host. It also will not recognize
'IP:port'.

This adds a layer to URl parsing to recognize those cases, and configure
the HTTPS scheme manually

@Geal Geal requested review from cecton and o0Ignition0o November 17, 2021 14:31
the endpoint address is often specified as host:port instead of a full
URL: https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/otlpexporter/README.md#getting-started

Unfortunately, the url crate would parse 'collector:4317' as an URL with
the 'collector' scheme and no host. It also will not recognize
'IP:port'.

This adds a layer to URl parsing to recognize those cases, and configure
the HTTPS scheme manually
@Geal Geal force-pushed the configuration-endpoint-parsing branch from fb1e380 to c5553bb Compare November 17, 2021 15:07
Copy link
Contributor

@o0Ignition0o o0Ignition0o left a comment

Choose a reason for hiding this comment

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

Lgtm, just a question about documentation


// support the case of a IP:port endpoint
if buf.parse::<std::net::SocketAddr>().is_ok() {
buf = format!("https://{}", buf);
Copy link
Contributor

Choose a reason for hiding this comment

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

should we document somewhere that we're falling back to https ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

in https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/otlpexporter/README.md#getting-started "By default, TLS is enabled" so it's expected. But I agree that it should be in the documentation.
I'm planning to rewrite the part of the documentation about telemetry once this week's pull requests have settled a bit

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(transparent)]
pub struct EndpointUrl {
#[serde(deserialize_with = "endpoint_url")]
Copy link
Contributor

Choose a reason for hiding this comment

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

You can probably do this trick in the ExportConfig struct directly and skip EndpointUrl struct entirely

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried various approaches with or without EndpointUrl, like serde(flatten) and those did not work. Unfortunately I do not remember the error messages

Copy link
Contributor

Choose a reason for hiding this comment

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

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(deny_unknown_fields, rename_all = "snake_case")]
pub struct ExportConfig {
    #[serde(deserialize_with = "endpoint_url")]
    pub endpoint: Option<Url>,
    pub protocol: Option<Protocol>,
    pub timeout: Option<u64>,
}

fn endpoint_url<'de, D>(deserializer: D) -> Result<Option<Url>, D::Error>
where
    D: serde::Deserializer<'de>,
{
    let buf = String::deserialize(deserializer)?;
    Ok(Some(Url::parse(&buf).map_err(serde::de::Error::custom)?))
}

Copy link
Contributor

Choose a reason for hiding this comment

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

With the http fix:

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(deny_unknown_fields, rename_all = "snake_case")]
pub struct ExportConfig {
    #[serde(deserialize_with = "endpoint_url")]
    pub endpoint: Option<Url>,
    pub protocol: Option<Protocol>,
    pub timeout: Option<u64>,
}

fn endpoint_url<'de, D>(deserializer: D) -> Result<Option<Url>, D::Error>
where
    D: serde::Deserializer<'de>,
{
    let mut buf = String::deserialize(deserializer)?;
    if !buf.starts_with("http") {
        buf.insert_str(0, "https://");
    }
    Ok(Some(Url::parse(&buf).map_err(serde::de::Error::custom)?))
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

did you test it? That was the first thing I tried. IIRC It complains that it expects to find an endpoint field.
From what I understand, with that annotation, serde-json first looks for an endpoint field, then passes its content to the function that then returns an Option. Instead of recognizing the field as optional

Copy link
Contributor

Choose a reason for hiding this comment

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

ah yes you need to add default so it can fallback to None before it fails to parse:

    #[serde(deserialize_with = "endpoint_url", default)]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nice! updating the code rn

@Geal Geal merged commit c5b05b6 into main Nov 18, 2021
@Geal Geal deleted the configuration-endpoint-parsing branch November 18, 2021 13:13
@abernix abernix mentioned this pull request Nov 19, 2021
@Geal Geal self-assigned this Dec 1, 2021
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.

Open Telemetry with tonic panics if configured with an endpoint address without scheme
3 participants