* feat(exporters): replace opencensus with opentelemetry
* feat(exporters): replace opencensus with opentelemetry
* fix(stackdriver_exporter): use metrics util constants
* chore: use global meter and init
* feat(exporters): add resource info, use global meter
* chore: update deps
* fix: use a gauge directly, narrow scope info
* cleanup: deps
* fix: try initOnce pattern for global problem metrics
* fix(problemmetrics): init is being called too late
* fix(gauge): remove _ratio suffix
* fix: clean up after rebase
* fix: cleanup after rebase
* fix: cleanup after rebase
* fix: cleanup after rebase
* fix: remove nodename
* fix(test): remove instance id check
* fix(test): add attr values
* fix(test): unexported resources
* fix(test): initialize global problem metrics manager
* fix(lint): make the linter happy
* fix(test): allow for summary and histogram types to be emit
* fix(otel): remove otel_scope labels
* fix(stackdriver_exporter): filter resource attributes for gcp
* fix(metrics): retain early nil return with no name
* chore(exporters): remove deprecated prometheus opts, use otel translator
* feat(metric): use metricdata for unit tests
* fix(metrics/test): test our New() funcs
* feat(stackdriver_exporter/test): add cloudmock and use it to test metrics export
* chore(lint): make the linter happy by not returning some errs
* fix(stackdriver): restore gce_instance resource, instance_name and apiEndpoint
* fix(prometheus): serve metrics from a dedicated registry
* fix(metrics): error on unsupported aggregation and undeclared labels
* refactor(metrics): dedupe int64/float64 metric implementations
* chore: remove dead code from metrics, otel and cloudmock
* refactor(metrics): simplify otelMetric internals
* fix(prometheus): drop target_info from scrape output
* fix(systemstatsmonitor): key disk_percent_used by device_name only
disk_percent_used declared only device_name but recorded four labels
(device_name, fs_type, mount_option, state). With per-metric label
validation, Record now rejects the undeclared labels and the metric is
dropped from the export (caught by the metriconly e2e).
Record only device_name, preserving the schema NPD has exported since the
metric was introduced: the OpenCensus view aggregated by device_name and
dropped the other tags, so on the wire this metric has always had a single
label. It also maps to the Google-owned
compute.googleapis.com/guest/disk/percent_used descriptor, which can reject
writes carrying undeclared label keys. Add a regression test pinning the
schema.
* fix(prometheus): preserve legacy metric names
* fix(stackdriver): disable client telemetry
* fix(metrics): preserve legacy metric names
* fix(metrics): preserve declared labels
* fix(stackdriver): skip descriptor management
* chore(deps): update module metadata
* fix(metrics): align fake label handling
* fix(metrics): reject normalized name collisions
* fix(stackdriver): preserve custom metric names
* fix(stackdriver): use portable metric paths
* fix(otel): shut down meter provider on exit and reject late registrations
Address review comments from #1297:
- Shut down the OTel meter provider when npdMain exits so push readers
flush pending metrics.
- Return an error from AddMetricReader/AddResourceAttributes when the
meter provider is already initialized, instead of silently ignoring
the registration.
* chore(deps): tidy go.sum after rebase
* chore(deps): remove OTel migration scaffold
* refactor(metrics): consolidate metric mappings
---------
Co-authored-by: Dave Young <dave.andrew.young@gmail.com>
Co-authored-by: Dave Young <dyoung@coreweave.com>
The log buffer joins every buffered line and scans all of them for
each pattern on every push, which is wasted work when a pattern
cannot even match across lines. The buffer now caches the joined
string, and Push invalidates the cache. CompilePattern marks the
patterns that cannot match across lines (no start anchor, no way to
match a newline, and the appended \z anchor binds every branch) and
Match checks them against the most recent line alone.
Compile fixed patterns during monitor and log counter initialization, pass compiled expressions to the log buffer, and reject invalid log counter patterns before watching logs.
config/disk-log-message-filelog.json contained trailing commas and no
trailing newline, so it could not be parsed by encoding/json and NPD
would fail to start when configured with it.
- Fix the invalid JSON
- Add TestShippedConfigs, which verifies that every shipped JSON config
under config/ (top level and one directory down) parses (catching
trailing commas, UTF-8 BOMs and other syntax errors) and is in the
canonical format (2-space indent, trailing newline), showing a diff on
failure
- Add `make fmt-configs` to rewrite nonconforming files in place
(UPDATE_EXPECTED=y)
- Normalize the existing config files to the canonical format
(whitespace-only changes)
This change keeps each compiled regular expression in a cache in the
log buffer. The cache size is not more than the number of patterns
given to Match.
This change removes the TODO in log_buffer.go.
The restart path closes the failed parser before retrying. If stopping
is signaled during the retry wait, watchLoop's deferred cleanup closed
the same parser again, logging a spurious 'file already closed' error
at shutdown. Clear the reference after closing and nil-check the defer.
The log monitor stops draining logCh before calling watcher.Stop(), so
with a full channel (e.g. a kmsg burst at shutdown) watchLoop blocked
on the send forever, never called tomb.Done(), and Stop() hung.
Select on tomb.Stopping() alongside the send.
If the restarted parser's channel closes again right away (reads keep
failing on the reopened /dev/kmsg), the watcher restarts in a tight
loop with no delay, spinning a CPU core and flooding the logs
(measured 37k restarts in 200ms). Delay the first attempt when the
previous restart was less than retryDelay ago.
Closing the parser in Stop() triggers kmsgparser's read goroutine to
close its output channel, which made watchLoop take the restart path
(added in #1192) during intentional shutdown. Leave parser cleanup to
watchLoop's defer, which is the single owner of the parser lifecycle.
If you're using some monitoring solution that aggregates events from
your Kubernetes cluster, having the underlying reason why a condition
triggered could be very useful, especially if you are using custom
plugin monitors.
Co-authored-by: Micah Norman <micnorman@paypal.com>
Signed-off-by: Ryan Eschinger <reschinger@paypal.com>