Watch
0
0
Fork
You've already forked hyperhive
0

queue collector exports on disk and retry without a time limit

This commit is contained in:
atlas 2026-10-26 22:28:23 +01:00
commit eac7f2a7c1
5 changed files with 85 additions and 0 deletions

View file

@ -526,6 +526,7 @@ in
# samples get labelled as.
endpoint = "https://${swarmOtelCfg.domain}" + lib.optionalString senderAuth "/${toString hiveName}";
}
// import ../otel-export-queue.nix
// lib.optionalAttrs senderAuth { auth.authenticator = authName; };
# ⚠️ An extension not listed here is INERT: the collector starts

View file

@ -1264,6 +1264,7 @@ in
${if upstream.protocol == "grpc" then "otlp" else "otlphttp"} = {
endpoint = upstream.endpoint;
}
// import ../otel-export-queue.nix
// lib.optionalAttrs (upstream.headersCredential != null) {
# Interpolated by the collector from its environment at
# runtime, never by nix: `EnvironmentFile` below is what
@ -1296,6 +1297,7 @@ in
logs_endpoint =
logsPushUrl + "?_msg_field=MESSAGE&_stream_fields=_HOSTNAME,_MACHINE_ID,_SYSTEMD_UNIT";
}
// import ../otel-export-queue.nix
// lib.optionalAttrs haveCollectorSecret {
auth.authenticator = pushAuthenticator "victorialogs";
};

View file

@ -404,6 +404,23 @@ let
&& hiveOtelSettings.extensions."oauth2client/swarm".endpoint_params.audience == "hive-h1"
&& hiveOtelSettings.exporters."otlphttp/swarm".endpoint == "https://${otel.domain}/h1";
}
{
# Same reason as the swarm tier's case in ./swarm-otel-core.nix: the
# queue in front of the swarm exporter has to be on `file_storage` or a
# restart drops what the journald receiver already counted as consumed.
name = "the hive collector queues on disk and retries without a time limit";
ok =
let
e = hiveOtelSettings.exporters."otlphttp/swarm";
in
e.sending_queue.enabled
&& e.sending_queue.storage == "file_storage"
&& e.sending_queue.queue_size > 0
&& e.retry_on_failure.max_elapsed_time == "0s"
&& e.endpoint == "https://${hiveOtel.services.hyperhive.swarm.otel.domain}/h1"
&& hiveOtelSettings.extensions ? file_storage
&& builtins.elem "file_storage" hiveOtelSettings.service.extensions;
}
];
in
runGroup "hive-otel" cases

View file

@ -338,6 +338,32 @@ let
&& lib.hasInfix "Exporting failed" (lib.head f.logs.log_record)
&& lib.hasInfix "otlphttp/victorialogs" (lib.head f.logs.log_record);
}
{
# The journald receiver saves its cursor before an entry reaches the
# exporter, so an entry in an in-memory queue when the store is down or
# the collector restarts is gone for good. The queue has to sit on the
# `file_storage` extension, and the retry has to outlast a switch.
# Presence controls: the extension is defined and started, the queue is
# bounded, and the exporters carry their endpoints.
name = "the log exporters queue on disk and retry without a time limit";
ok =
let
s = otelSettings otelNoStores;
queued =
e:
e.sending_queue.enabled
&& e.sending_queue.storage == "file_storage"
&& e.sending_queue.queue_size > 0
&& e.retry_on_failure.enabled
&& e.retry_on_failure.max_elapsed_time == "0s";
in
queued s.exporters."otlphttp/victorialogs"
&& queued s.exporters.otlphttp
&& s.exporters."otlphttp/victorialogs" ? logs_endpoint
&& s.exporters.otlphttp.endpoint == "https://upstream.example/otel"
&& s.extensions ? file_storage
&& builtins.elem "file_storage" s.service.extensions;
}
{
# Presence control: the default sends both signals to the upstream, so
# the negative arms below cannot pass on a misspelled exporter name.

27
nix/otel-export-queue.nix Normal file
View file

@ -0,0 +1,27 @@
# Export settings every forwarding exporter in this tree attaches, imported by
# both collector tiers (`host-modules/otel.nix`, `host-modules/swarm-otel.nix`).
#
# `sending_queue.storage` puts the queue on the `file_storage` extension, so
# batches waiting for an exporter survive a collector restart. The journald
# receiver saves its cursor before it hands an entry on: an entry sitting in an
# in-memory queue when the exporter's target is down or the collector restarts
# counts as consumed and is not read again.
#
# `queue_size` counts requests (batches), not records. When the queue is full
# the exporter refuses new data and logs the drop; the oldest queued batches
# are kept.
#
# `max_elapsed_time = "0s"` retries a failing batch until it is accepted.
# The queue bound is what limits the disk used; the default of five minutes
# gives up on a backlog that a store restart outlasts.
{
sending_queue = {
enabled = true;
storage = "file_storage";
queue_size = 5000;
};
retry_on_failure = {
enabled = true;
max_elapsed_time = "0s";
};
}