Repository navigation
Conversation
maxlengdell
approved these changes
Oct 30, 2026
armru
added a commit
to cloudnative-pg/cloudnative-pg
that referenced
this pull request
Nov 3, 2026
…s written The instance manager decoded the records that wal-archive and wal-restore write on the log pipe, even with the export disabled, and exported them with the time it forwarded them at. It now hands the JSON line to ForwardToOpenTelemetry, from cloudnative-pg/machinery#343, so the records keep their own time and nothing is decoded while the export is disabled. The documentation now lists the timestamp among the exported fields, and names the stack trace of a record without an error. Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
armru
added a commit
to cloudnative-pg/cloudnative-pg
that referenced
this pull request
Nov 3, 2026
cloudnative-pg/machinery#343 gained an option for processes that build their own log provider, and WithOpenTelemetry now reaches the export through the same helper. Pin its new head, so this branch builds and runs against the code that is going to be merged. Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
Member
Author
|
Klio can reuse this framework with one additive option, which is now part Verified in cloudnative-pg/klio#562 with unit tests and the |
fcanovai
pushed a commit
to cloudnative-pg/klio
that referenced
this pull request
Nov 5, 2026
Klio exports its traces and metrics through OpenTelemetry, but its logs only reach the standard output, so collecting them still needs a node agent or a sidecar. Every Klio process now builds a log provider with the resource and the exporter selection of its other signals, and hands it to the logging of machinery before configuring it, so the records written on the standard output are exported too. OTEL_LOGS_EXPORTER enables the export and is unset by default, so a configuration written for the traces and the metrics does not start sending the logs. Each command exports its own records and flushes them before exiting, including the short-lived commands that the plugin sidecar spawns, while `retention get` now runs without the OTEL_* variables like `get-metadata`, as its output is captured. The operator moves from the controller-runtime logger to the one of machinery, which the server and the sidecar already use: it now logs in JSON at the info level by default, and keeps accepting the --zap-* arguments along with --log-level. This needs cloudnative-pg/machinery#343, pinned to its head until it is released. Closes #549 Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
fcanovai
pushed a commit
to cloudnative-pg/cloudnative-pg
that referenced
this pull request
Nov 10, 2026
…s written The instance manager decoded the records that wal-archive and wal-restore write on the log pipe, even with the export disabled, and exported them with the time it forwarded them at. It now hands the JSON line to ForwardToOpenTelemetry, from cloudnative-pg/machinery#343, so the records keep their own time and nothing is decoded while the export is disabled. The documentation now lists the timestamp among the exported fields, and names the stack trace of a record without an error. Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
fcanovai
pushed a commit
to cloudnative-pg/cloudnative-pg
that referenced
this pull request
Nov 10, 2026
cloudnative-pg/machinery#343 gained an option for processes that build their own log provider, and WithOpenTelemetry now reaches the export through the same helper. Pin its new head, so this branch builds and runs against the code that is going to be merged. Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
fcanovai
pushed a commit
to cloudnative-pg/klio
that referenced
this pull request
Nov 10, 2026
Klio exports its traces and metrics through OpenTelemetry, but its logs only reach the standard output, so collecting them still needs a node agent or a sidecar. Every Klio process now builds a log provider with the resource and the exporter selection of its other signals, and hands it to the logging of machinery before configuring it, so the records written on the standard output are exported too. OTEL_LOGS_EXPORTER enables the export and is unset by default, so a configuration written for the traces and the metrics does not start sending the logs. Each command exports its own records and flushes them before exiting, including the short-lived commands that the plugin sidecar spawns, while `retention get` now runs without the OTEL_* variables like `get-metadata`, as its output is captured. The operator moves from the controller-runtime logger to the one of machinery, which the server and the sidecar already use: it now logs in JSON at the info level by default, and keeps accepting the --zap-* arguments along with --log-level. This needs cloudnative-pg/machinery#343, pinned to its head until it is released. Closes #549 Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
fcanovai
approved these changes
Nov 11, 2026
Collecting the logs of a process today requires something reading its standard output from outside, usually a DaemonSet tailing the container logs on every node, which is not available in every environment. This adds an optional `WithOpenTelemetry()` argument to `Flags.ConfigureLogging`. When the standard `OTEL_EXPORTER_OTLP_ENDPOINT` or `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` environment variable is set, the records are also pushed via OTLP to an OpenTelemetry collector, while the log destination keeps getting them unchanged. The exporter takes its configuration from the standard `OTEL_*` variables, using `http/protobuf` unless `grpc` is requested, as the OpenTelemetry specification prescribes. The records reach the zap bridge of OpenTelemetry through a core teed with the existing one, inside the duplicate-message sampler, so both outputs get the same records at the same log level. The core maps the custom debug and trace levels to the zap debug level, which the bridge understands, and it turns reflected values into their JSON form, so a struct such as a PostgreSQL log record is exported as a map with the keys it has on the log destination instead of a Go-formatted string. A batch processor exports the records in the background, dropping them instead of blocking the caller when the collector cannot keep up. `ShutdownOpenTelemetry` exports the queued records and stops the export before the process exits, and `OpenTelemetryLogger` writes only to the export, for records already written to the log destination by another process. Refs cloudnative-pg/cloudnative-pg#11085 Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
OpenTelemetryLogger exported the records written on the log destination by a spawned process through a logr logger, so they took the time they were forwarded at, and every caller had to decode them first. ForwardToOpenTelemetry takes the JSON line instead: the record keeps the time, level and logger name it was written with, its integers stay integers, and nothing is decoded while the export is disabled. Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
A process that already configures OpenTelemetry for its metrics and traces builds their resource and picks their exporters from the environment itself. With WithOpenTelemetry its log records would leave through a second provider, without that resource and ignoring OTEL_LOGS_EXPORTER, so a backend could not correlate them with the other signals of the same process. WithOpenTelemetryLoggerProvider tees the records into a provider the caller creates instead, keeping the level filter and the field mapping of WithOpenTelemetry. The caller owns that provider, so ShutdownOpenTelemetry leaves it running. Refs cloudnative-pg/klio#549 Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
…ests The exporter prefers a signal-specific variable such as OTEL_EXPORTER_OTLP_LOGS_ENDPOINT over the generic endpoint the tests point at their receiver. Dagger sets those variables in the containers it runs, so in CI the records went to its own collector and the tests found nothing. Clear every OTEL_* variable before each test. Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
Reflected values were exported through json.Unmarshal into any, which turns every number into a float64: the integers above 2^53 are rounded, and the others reach the OpenTelemetry bridge as doubles. The records forwarded from other processes kept the numbers of the top level only, so the nested ones were exported as strings. Decode both with UnmarshalCaseSensitivePreserveInts of sigs.k8s.io/json, which gives an int64 when the number fits and a float64 otherwise, at any depth, as the Kubernetes objects are decoded. The tests of the forwarded records only checked small numbers, which a plain float64 decoding also gets right. Forward a record with an integer beyond 2^53 at the top level, in an object and in a list, and check that it is exported as an exact integer. Assisted-by: Claude Signed-off-by: Francesco Canovai <francesco.canovai@enterprisedb.com>
The OpenTelemetry export of the log records started whenever an OTLP endpoint was set, so a collector configured for the traces and the metrics could not be kept from receiving the logs. OTEL_SDK_DISABLED=true, the standard switch that turns off every signal, and OTEL_LOGS_EXPORTER=none, the standard way to turn off the export of the logs only, now disable it even when the endpoint is set. As the specification asks, "true" is matched case-insensitively and the exporter name is interpreted in a case-insensitive manner, so "None" and "NONE" work as well. Assisted-by: Claude Signed-off-by: Francesco Canovai <francesco.canovai@enterprisedb.com>
gbartolini
force-pushed
the
dev/11085
branch
from
November 11, 2026 12:57
0f58adc to
050de2c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Collecting the logs of a process today needs something reading its
output from outside, usually a DaemonSet on every node, which is not
available everywhere.
This adds
WithOpenTelemetry()toFlags.ConfigureLogging: whenOTEL_EXPORTER_OTLP_ENDPOINT(or its logs variant) is set, the recordsare also pushed via OTLP to an OpenTelemetry collector, configured with
the standard
OTEL_*variables, usinghttp/protobufunlessgrpcisrequested. The log destination is unchanged.
The export is a zap core teed with the existing one inside the sampler,
so both outputs get the same records at the same log level. Structs are
exported as maps with the keys of the JSON output, and the custom debug
and trace levels get the DEBUG severity. The records are batched in the
background and dropped, never blocking, when the collector cannot keep
up.
ShutdownOpenTelemetryflushes the queue before exiting, andForwardToOpenTelemetryexports the JSON records that a spawned processwrote on the shared log destination, with the time, level and fields
they were written with.
A process that already configures OpenTelemetry for its traces and
metrics passes its own provider with
WithOpenTelemetryLoggerProviderinstead, so the records share the resource and the exporter selection
of its other signals, and the caller owns the shutdown.
The CloudNativePG side is in cloudnative-pg/cloudnative-pg#11783, the
Klio one in cloudnative-pg/klio#562.
Refs cloudnative-pg/cloudnative-pg#11085
Refs cloudnative-pg/klio#549