Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions charts/cmk-rustik/templates/metrics-cache/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ spec:
- --push-registration-insecure-skip-site-ca-verification
{{- end }}
{{- end }}
{{- if .Values.otel.enabled }}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Following the logic from push mode

- --otel-endpoint={{ required "otel.endpoint is required when otel is enabled" .Values.otel.endpoint }}
- --otel-push-interval={{ .Values.otel.interval }}
{{- end }}
{{- range $k, $v := .Values.emitAll }}
{{- if $v }}
- --all-{{ $k }}
Expand Down
14 changes: 14 additions & 0 deletions charts/cmk-rustik/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,20 @@ pull:
# certificate, in days. It is ignored when existingSecret is set.
longevity: 3650

# otel allows you to enable, disable, and configure the OpenTelemetry export.
# Unlike push mode, this does not send Checkmk sections: it exports pod- and
# container-level metrics derived from the kubelet data, using OTLP over HTTP.
otel:
# enabled controls whether the OpenTelemetry export is activated or not.
enabled: false

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Not sure

# endpoint is the base URL of an OpenTelemetry collector's OTLP/HTTP receiver.
# Do *not* include the signal path: "/v1/metrics" is appended for you.
# Required when otel.enabled is true.
endpoint: ""
# interval is how often, in seconds, metrics are collected and exported to
# the collector. Must be greater than zero.
interval: 60

# hostLabels defines how annotations get imported as labels in Checkmk. By
# default annotations do not become host labels.
hostLabels:
Expand Down
17 changes: 16 additions & 1 deletion metrics-cache/src/cli_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,14 @@ pub struct CliArgs {
#[arg(long = "otel-endpoint")]
pub otel_endpoint: Option<String>,

/// Push interval in seconds for sending otel metrics.
#[arg(
long = "otel-push-interval",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I recently discovered, you don't need to specify the value to long if it can be derived from the name of the field. If you just specify long (without the = "otel-push-interval") it will default to the correct thing.

value_parser = parse_push_interval,
default_value = "60"
)]
pub otel_push_interval: Duration,

/// Emit all Pod resources rather than only annotated ones
#[arg(long = "all-pods")]
pub all_pods: bool,
Expand Down Expand Up @@ -406,12 +414,19 @@ mod tests {
}

#[test]
fn push_interval_cannot_be_zero() {
fn otel_push_interval_cannot_be_less_than_one() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this isn't testing --otel-push-interval so I don't think the rename is right

assert_eq!(
parse(&["--push-interval", "0"])
.expect_err("push interval of zero should fail")
.kind(),
ErrorKind::ValueValidation
);

assert_eq!(
parse(&["--push-interval=-1"])
.expect_err("push interval of -1 should fail")
.kind(),
ErrorKind::ValueValidation
);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressing your comment from the last PR

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd do that in a separate patch

}
}
2 changes: 1 addition & 1 deletion metrics-cache/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ async fn main() -> anyhow::Result<()> {
// Push to OpenTelemetry collector
() = async {
match otel_client {
Some(client) => otel_loop(client, state.clone()).await,
Some(client) => otel_loop(client, state.clone(), args.otel_push_interval).await,
None => std::future::pending().await,
}
} => {
Expand Down
8 changes: 6 additions & 2 deletions metrics-cache/src/otel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,12 @@ use crate::state::AppState;
///
/// Depends entirely on the kubelet stats cache in `state` and does effectively
/// nothing if it is not yet populated.
pub async fn otel_loop(client: OtelClient, state: AppState<impl TokenValidator>) {
let mut interval = time::interval(Duration::from_secs(60)); // TODO: Unhardcode
pub async fn otel_loop(
client: OtelClient,
state: AppState<impl TokenValidator>,
otel_push_interval: Duration,
) {
let mut interval = time::interval(otel_push_interval);
loop {
interval.tick().await; // note: The very first tick() is no-op
let stat_summaries = state.kubelet_stats_summary_cache.iter().map(|(_, v)| v);
Expand Down
Loading