FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Bounded-cardinality process grouping (macOS) and hardware sensors summaries, histogram and function by ktsaou · Pull Request #23085 · netdata/netdata · GitHub

Bounded-cardinality process grouping (macOS) and hardware sensors summaries, histogram and function - #23085

Merged
ktsaou merged 10 commits into
netdata:masterfrom
ktsaou:macos-cardinality-and-sensors
Jul 11, 2026
Merged

Bounded-cardinality process grouping (macOS) and hardware sensors summaries, histogram and function#23085
ktsaou merged 10 commits into
netdata:masterfrom
ktsaou:macos-cardinality-and-sensors

Conversation

ktsaou commented Jul 11, 2026
edited by cubic-dev-ai Bot
Loading

Copy link
Copy Markdown
Member

Summary

This PR fixes runaway per-node cardinality on macOS (processes and hardware sensors), fixes three sensor bugs, and introduces two cross-OS conventions: a fleet-aggregatable temperature histogram and a sensors function.

apps.plugin: path-derived process grouping (macOS)

macOS has a flat process tree (launchd spawns almost everything) and the stock apps_groups.conf is Linux-oriented, so every unmatched process became its own group: ~600 groups (~6,000 time-series) per Mac.

Processes not matched by apps_groups.conf are now grouped by their executable path:

Executable Group
Application bundles (*.app, *.appex) one group per application
Apple framework helpers (*.framework, XPC services) system-frameworks
Apple standalone daemons (/usr/libexec, /usr/sbin, ...) system-daemons
Driver extensions (*.dext) driver-extensions
Third-party frameworks one group per framework
Third-party plain binaries one group per process name

Apple's bundle grammar and the sealed system volume (SIP/SSV) make this classification stable across macOS versions - no name lists to maintain. Famous components (WindowServer, Spotlight, media analysis, CoreAudio, iCloud, Time Machine, VideoToolbox, ...) are re-exposed as named groups via the stock apps_groups.conf, and any aggregated component can be re-exposed with one config line.

Live result on an M4 Mac mini: 598 groups → 85, with system-frameworks/system-daemons absorbing ~85% of all processes while contributing almost no CPU to the buckets (WindowServer, previously hidden noise among 600 groups, is now clearly visible as the top consumer).

macos.plugin sensors: three fixes

  1. Label key contract: per-sensor chart labels used name on macOS and Windows while both Linux producers use label. All producers now use label.
  2. Identity stability: IOHID sensor identities embedded the per-boot IORegistryEntryID (PMU_tdie5_registry_1000006e3), minting new time-series on every reboot. Unique product names are now used as-is (PMU_tdie5); true duplicates disambiguate via reboot-stable LocationID.
  3. powermetrics loop was dead on arrival: the loop profiles used -n 0, which on current macOS means "take zero samples and exit". The thermal pressure chart collected data only briefly after each restart, then cycled probe→instant-exit→backoff forever (7,779 identical log errors in 6 days on the test Mac, because the log-once guard was re-armed by every probe sample). The loop now streams until stopped, and the guard only re-arms after a productive loop.

sensors cardinality (macOS)

An M4 Mac mini exposes ~405 sensors (202 temperatures, ~150 per-regulator voltage/current rails). Per-channel charts are now opt-in for temperature/voltage/current/power; the default views are:

  • system.hw.sensor.temperature.subsystem - min/avg/max per subsystem (cpu, soc, memory, storage, ambient, ...)
  • system.hw.sensor.power.subsystem - power totals per subsystem (watts add meaningfully)
  • the cross-OS histogram below

Live result: ~405 sensor charts → ~25, everything still collected internally, per-channel detail one config switch away.

Cross-OS temperature histogram

New permanent contract (src/collectors/common-contexts/hw-sensors.h): system.hw.sensor.temperature.histogram - a population histogram of ALL temperature sensors in fixed, disjoint buckets (upper bounds 40,50,60,70,80,85,90,95,100,+Inf °C; 10°C bands in the benign range, 5°C bands in the 80-100°C action zone). Implemented identically on macOS, Windows (GetSensors) and Linux (debugfs.plugin/libsensors), so bucket counts can be summed across nodes for a fleet-wide thermal distribution view. The chart is only created on hosts that have temperature sensors.

sensors function

A live table of every discovered sensor - including the ones aggregated into summaries: label, kind, subsystem, source, device, current reading, units, state. The per-sensor chart id is the table's unique key (chart ↔ row correlation), per-kind aggregation tiles (Temperature/Fan/Voltage/Current/Power) re-aggregate under user-selected groupings (by kind, subsystem, device, state). Registered only on hosts that actually have sensors.

Implemented on macOS and debugfs.plugin (its first function, served via the functions event loop). The Windows implementation follows on this branch.

Validation

  • macOS: built and deployed on an M4 Mac mini; process grouping, sensor summaries, histogram, function and all three fixes verified live (including powermetrics -n 0 vs streaming behavior verified against the real binary).
  • Linux go.d: initially received the histogram too; reverted intentionally - the go.d sensors collector is disabled by default (debugfs.plugin is the Linux producer) and is treated as a leftover.
  • Linux debugfs.plugin and Windows changes compile-verified by CI (Linux/Windows-only sources).

Notes for reviewers

  • The histogram bucket edges are a permanent public contract - once shipped they must never change, or historical heatmaps break.
  • The macOS per-sensor label key rename (name → label) and the IOHID identity change alter young contexts (first shipped days ago) - migration impact is minimal and intentional.
  • Follow-ups planned on this branch: Windows sensors function, metadata.yaml/docs sync for the three producers.

Summary by cubic

Caps macOS process and sensor cardinality and adds fleet‑ready sensor views across OSes. Introduces path‑based process grouping, per‑subsystem summaries, a cross‑OS temperature histogram, and a unified sensors function, with fixes for labels, identity, stream loops, and hardened histogram, shutdown, and data validity paths.

  • New Features

    • apps.plugin (macOS): Group unmatched processes by executable path; apps keep their own group, Apple helpers/daemons and driver extensions aggregate into system-frameworks, system-daemons, driver-extensions. Stock apps_groups.conf re‑exposes key components; adds sshd-session to managers and treats login shells as interpreters (zsh, dash, csh, tcsh, ksh) so shell roots group by their comm. Result: 600→85 groups.
    • Hardware sensors (macOS): Default to summaries with per‑subsystem temperature min/avg/max and power totals; per‑channel charts are opt‑in for temperature/voltage/current/power. Result: 405→25 charts.
    • Cross‑OS temperature histogram: system.hw.sensor.temperature.histogram with fixed disjoint buckets (40,50,60,70,80,85,90,95,100,+Inf °C), implemented in macos.plugin, windows.plugin (GetSensors), and debugfs.plugin. Shared contract in common-contexts/hw-sensors.h.
    • sensors function: Lists all discovered sensors with live readings and metadata; includes per‑kind tiles and grouping (by kind/subsystem/device/state). Implemented in macos.plugin and debugfs.plugin; shared schema in common-contexts/hw-sensors-function.h. Registered only on hosts with sensors.
    • debugfs.plugin docs: Documented the libsensors module and new histogram/function contexts in metadata.yaml; added taxonomy.yaml with taxonomy_optout.
  • Bug Fixes

    • Labels: Use label as the per‑sensor label key on macOS and Windows to match Linux.
    • Identity stability (macOS IOHID): Use unique product names; disambiguate true duplicates via reboot‑stable LocationID.
    • powermetrics loop (macOS): Remove -n 0 so it streams until stopped; re‑arm the log‑once guard only after a productive loop.
    • debugfs.plugin: Fully synchronized sensors_dict access and function emission; skip sensors missing from the current cycle; write function results under stdout_mutex; honor QUIT and propagate exit status; cancel/join function workers before cleanup; destroy the sensors mutex and release libsensors state on exit; re‑emit histogram CHART on restart.
    • Windows GetSensors: Count temperatures in the histogram only on successful, finite reads; match per‑sensor chart math (incl. external multiplier); retire the histogram chart on cleanup; age sensors out of the histogram when they disappear from enumeration while failed polls freeze last known state; destroy the sensors mutex after the dictionary to avoid future teardown races.
    • Histogram helper: common-contexts/hw-sensors.h rejects non‑finite readings for all producers.
    • macOS sensors cleanup: Run under a mutex; obsolete and free rollup/histogram charts safely.
    • Docs/metadata: Clarify function registration notes and fix minor typos in metadata.yaml.

Written for commit 99bc2af. Summary will update on new commits.

…rs summaries

apps.plugin (macOS):
- group processes by executable path: application bundles keep their own
  group; Apple framework helpers, standalone daemons and driver extensions
  aggregate into system-frameworks / system-daemons / driver-extensions
  (sealed-system-volume path classification; Apple bundle grammar is stable
  across macOS versions, so no per-version maintenance is needed)
- executable path fallback chain: proc_pidpath() then KERN_PROCARGS2
- sshd-session added to the macOS process managers
- stock apps_groups.conf: macOS components of interest (windowserver,
  spotlight, media-analysis, coreaudio, fseventsd, icloud, nsurlsessiond,
  timemachine, videotoolbox)
- live result: ~600 process groups -> ~85 on an M4 Mac mini

macos.plugin sensors:
- fix: per-sensor chart label key renamed 'name' -> 'label' to match the
  Linux producers; same fix applied to windows.plugin GetSensors
- fix: IOHID sensor identities no longer embed the per-boot
  IORegistryEntryID; unique product names are used as-is and duplicates
  disambiguate via LocationID, so identities are stable across reboots
- fix: powermetrics loop mode used '-n 0', which means "zero samples and
  exit" on current macOS - thermal pressure and related charts were
  collected only briefly after each restart; also stop re-arming the
  log-once guard on every stored sample (it flooded the log with the same
  error every backoff cycle)
- per-channel sensor charts are now opt-in for temperature, voltage,
  current and power; the default views are per-subsystem temperature
  min/avg/max and per-subsystem power totals
  (~405 sensor charts -> ~25 on an M4 Mac mini)

hardware sensors, cross-OS:
- new contract in src/collectors/common-contexts/hw-sensors.h:
  system.hw.sensor.temperature.histogram - a population histogram of all
  temperature sensors in fixed, disjoint buckets
  (40,50,60,70,80,85,90,95,100,+Inf upper bounds, degrees Celsius),
  identical on macOS, Windows and Linux (debugfs/libsensors), so Netdata
  Cloud can sum bucket counts across nodes for a fleet-wide thermal view
- new 'sensors' function listing every discovered sensor with live
  readings: the per-sensor chart id is the table key (chart <-> row
  correlation), per-kind aggregation tiles, group-by schemes by
  kind/subsystem/device/state; registered only on hosts that actually
  have sensors; implemented on macOS and debugfs.plugin (the first
  function served by debugfs.plugin, via the functions event loop)

cubic-dev-ai Bot left a comment
edited
Loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

All reported issues were addressed across 15 files

Confidence score: 5/5

  • Safe to merge after the addressed issues were fixed.
Architecture diagram
sequenceDiagram
    participant Kernel as macOS Kernel
    participant apps as apps.plugin (macOS)
    participant macosSensors as macos.plugin (sensors)
    participant pmLoop as powermetrics loop
    participant debugfs as debugfs.plugin (Linux)
    participant winSensors as windows.plugin GetSensors
    participant common as common-contexts/hw-sensors.h
    participant funcEvloop as Functions Event Loop
    participant RRDdb as Netdata Database

    Note over apps,Kernel: CHANGED: Process Grouping (macOS)

    apps->>Kernel: macos_get_executable_path(pid)
    Kernel-->>apps: /System/Library/Frameworks/..., or /Applications/Xcode.app/...
    apps->>apps: Parse path for .app, .framework, .dext, apple system prefix
    alt Application bundle found (*.app, *.appex)
        apps->>apps: Group by app name (e.g., "Finder")
    else Apple framework helper
        apps->>apps: Group => "system-frameworks"
    else Apple standalone daemon (/usr/libexec, /usr/sbin, ...)
        apps->>apps: Group => "system-daemons"
    else Driver extension (*.dext)
        apps->>apps: Group => "driver-extensions"
    else Third-party framework
        apps->>apps: Group by framework name
    else Third-party plain binary (or launchd/interpreter)
        apps->>apps: Fallback: group by comm/name (unchanged)
    end
    apps-->>RRDdb: Registered groups: ~600→~85 per host

    Note over macosSensors,pmLoop: CHANGED: Sensors + powermetrics (macOS)

    macosSensors->>macosSensors: NEW: do_per_sensor_charts[] (opt-in for temp/voltage/current/power)
    macosSensors->>macosSensors: Collect all ~405 sensors (SMC + IOHID)
    alt IOHID sensor identity
        macosSensors->>macosSensors: CHANGED: Prefer LocationID over IORegistryEntryID
        macosSensors->>macosSensors: CHANGED: label key replaces name in all chart labels
    end
    macosSensors->>macosSensors: Rollup per-subsystem (cpu/soc/mem/storage/ambient...)
    Note over macosSensors: temperature_subsystem_* → min/avg/max
    Note over macosSensors: power_subsystem_* → sum
    macosSensors->>common: hw_sensors_temperature_histogram_add() per temp sensor
    common-->>macosSensors: histogram bucket (0=≤40°C, 9=+Inf)
    macosSensors-->>RRDdb: ~25 summary charts + histogram (default)
    opt Per-sensor charts enabled
        macosSensors-->>RRDdb: Per-channel charts also emitted (opt-in)
    end

    pmLoop->>pmLoop: CHANGED: Removed "-n 0" from powermetrics args
    Note over pmLoop: -n 0 caused immediate exit streaming→dead loop
    pmLoop->>pmLoop: Streams until netdata stops it
    alt Productive cycle produced sample
        pmLoop->>pmLoop: reset logged_loop_failure = false
        pmLoop->>pmLoop: backoff = initial (100ms)
    else No sample produced (backoff loop)
        pmLoop->>pmLoop: exponential backoff, log-once guard NOT re-armed
    end
    pmLoop->>macosSensors: Store thermal/smc/gpu sample
    macosSensors->>macosSensors: CHANGED: labels use "label" not "name"

    Note over debugfs,RRDdb: NEW: Functions + Histogram (Linux debugfs.plugin)

    debugfs->>funcEvloop: module_libsensors_register_functions(wg)
    funcEvloop->>debugfs: function invocation (sensors table request)
    debugfs->>debugfs: Lock sensors_data_mutex, iterate sensors_dict
    debugfs-->>funcEvloop: JSON table: chart_id, label, kind, subsystem, device, reading, units, state, ...
    debugfs->>debugfs: CHANGED: libsensors_emit_temperature_histogram()
    Note over debugfs: Mirrors hw-sensors.h bucket contract via PLUGINSD text
    debugfs-->>RRDdb: TEMP HISTOGRAM chart (sensors.temperature_histogram)

    Note over winSensors,common: CHANGED: Windows GetSensors

    winSensors->>common: hw_sensors_temperature_histogram_reset()
    winSensors->>winSensors: Walk sensor dictionary
    alt Sensor is temperature (NETDATA_WIN_SENSOR_CELSIUS)
        winSensors->>common: hw_sensors_temperature_histogram_add(celsius)
    end
    winSensors->>common: common_hw_sensors_temperature_histogram(...)
    common-->>RRDdb: TEMP HISTOGRAM chart (system.hw.sensor.temperature.histogram)
    Note over winSensors: Label key fix: "label" not "name"

    Note over RRDdb: Cross-OS histogram buckets (PERMANENT CONTRACT)
    Note over RRDdb: Upper bounds: 40,50,60,70,80,85,90,95,100,+Inf °C
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

ktsaou requested a review from Copilot July 11, 2026 12:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

…nction schema, sync metadata

- debugfs: netdata_mutex_t is uv_mutex_t and has no static initializer -
  initialize sensors_data_mutex via a constructor (fixes the Linux builds)
- debugfs: serialize ALL sensors_dict traversals (pre-flight, emission,
  histogram, function, cleanup) - the dictionary is single-threaded and is
  now accessed by both the collection thread and function workers
- debugfs: the main loop honors the functions-evloop exit request (QUIT)
  and propagates its exit status; the function result is written under
  stdout_mutex so it cannot interleave with CHART/SET emission
- debugfs: function rows use the cross-OS names (current/V/A/W, healthy
  state 'ok'), point state-only sensors at their _alarm chart, and report
  freshness from the current collection cycle; the histogram keeps
  emitting zero counts once exposed
- macos: sensors cleanup runs under the sensors mutex (constructor
  initialized) and also frees the rollup list and obsoletes the
  rollup/histogram charts
- windows: the histogram uses the exact chart-dimension value math,
  including the external-config multiplier override
- share the 'sensors' function table schema via
  common-contexts/hw-sensors-function.h instead of duplicating it per
  producer; clarify the exclusive-upper-bound bucket semantics in
  hw-sensors.h; add both headers to the CMake sources list
- metadata: rename the per-sensor label key 'name' to 'label' (macos,
  windows), document the new summary/histogram contexts and the new
  per-sensor chart config options
ktsaou requested review from a team and vkalintiris as code owners July 11, 2026 12:49
github-actions Bot added area/build Build system (autotools and cmake). area/metadata Integrations metadata labels Jul 11, 2026

ktsaou commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

@cubic-dev-ai please review again

ktsaou requested a review from Copilot July 11, 2026 12:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

cubic-dev-ai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai please review again

@ktsaou I have started the AI code review. It will take a few minutes to complete.

cubic-dev-ai Bot left a comment
edited
Loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

All reported issues were addressed across 19 files

Confidence score: 5/5

  • Safe to merge after the addressed issues were fixed.
Architecture diagram
sequenceDiagram
    participant apps as apps.plugin (macOS)
    participant os as macOS Kernel/Proc
    participant macoS as macos.plugin
    participant iokit as IOKit / IOHID
    participant pm as powermetrics (ndsudo)
    participant dbg as debugfs.plugin
    participant libs as libsensors
    participant win as windows.plugin (GetSensors)
    participant cc as common-contexts (hw-sensors.h / hw-sensors-function.h)
    participant nd as Netdata Daemon (rrdengine, functions)

    Note over apps,os: PROCESS GROUPING (macOS)

    loop per process
        apps->>os: proc_pidpath(pid) or sysctl KERN_PROCARGS2
        os-->>apps: executable path
        apps->>apps: classify path (Apple vs user, .app/.framework/.dext)
        alt matched by apps_groups.conf
            apps->>apps: use configured group name
        else unmatched
            alt Apple framework helper
                apps->>apps: group = "system-frameworks"
            else Apple standalone daemon
                apps->>apps: group = "system-daemons"
            else driver extension
                apps->>apps: group = "driver-extensions"
            else user application bundle
                apps->>apps: group = bundle basename
            else user plain binary
                apps->>apps: group = process name (comm)
            end
        end
        apps->>nd: update chart dimensions for group
    end

    Note over macoS,pm: SENSOR COLLECTION & SUMMARY (macOS)

    macoS->>iokit: scan SMC keys and IOHID services
    macoS->>macOS: lock macos_sensors_mutex
    Note over macoS: begin_cycle (mark all sensors unseen)
    loop per sensor
        macoS->>macoS: read sensor value (SMC/IOHID)
        macoS->>macoS: store value, set seen, update last_value
        alt per-sensor chart enabled for this kind
            macoS->>nd: create/update per-sensor chart (rrdset)
        else opt-in summary only
            macoS->>macoS: skip per-sensor chart creation
        end
    end
    macoS->>macoS: finish_cycle: accumulate histogram, rollups
    macoS->>cc: hw_sensors_temperature_histogram_add() each temp sensor
    macoS->>cc: common_hw_sensors_temperature_histogram() -> create/update heatmap chart
    loop per subsystem
        macoS->>macoS: create/update temperature.min/avg/max and power.sum rollup charts
    end
    macoS->>macoS: unlock mutex

    Note over macoS,pm: POWERMETRICS LOOP FIX

    pm->>pm: start powermetrics with -b 0 -i <ms> (removed -n 0)
    pm->>macOS: stream plist samples
    macoS->>pm: read from pipe
    alt loop produced sample
        macoS->>macoS: reset logged_loop_failure = false, backoff = initial
    else no sample / failure
        macoS->>macoS: backoff exponential backoff, keep logged_loop_failure true
    end
    macoS->>nd: store thermal pressure data

    Note over dbg,libs: LINUX SENSORS (debugfs.plugin)

    dbg->>nd: register "sensors" function via functions_evloop
    loop collection cycle
        dbg->>dbg: lock sensors_data_mutex
        dbg->>libs: sensors_collect_data()
        libs-->>dbg: sensor readings
        dbg->>dbg: emit histogram via PLUGINSD text
        alt sensors present
            dbg->>nd: CHART sensors.temperature_histogram (heatmap)
            dbg->>nd: SET each bucket count
        end
        dbg->>dbg: unlock mutex
    end

    Note over dbg: FUNCTION HANDLER
    dbg->>nd: function request ('sensors')
    dbg->>dbg: lock sensors_data_mutex
    dbg->>libs: iterate sensors_dict
    dbg->>dbg: build JSON row per sensor (chart_id, label, kind, ...)
    dbg->>dbg: unlock mutex
    dbg->>cc: hw_sensors_function_columns() + hw_sensors_function_presentation()
    dbg->>nd: lock stdout_mutex, pluginsd_function_result_to_stdout()

    Note over win,cc: WINDOWS SENSORS (histogram only)

    win->>win: lock sensors_mutex
    win->>win: iterate dictionary (collect sensors)
    loop per sensor
        win->>cc: hw_sensors_temperature_histogram_add() if type CELSIUS
    end
    win->>cc: common_hw_sensors_temperature_histogram() -> create/update heatmap
    win->>win: unlock mutex

    Note over cc,nd: CROSS-OS CONTRACTS

    cc->>nd: define permanent histogram bucket edges (40,50,...100,+Inf)
    cc->>nd: define sensors function table schema (columns, charts, grouping)
    nd->>nd: Heatmap chart created only when temp sensors exist
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

…ion columns

- debugfs: cancel and join the functions-evloop workers before module
  cleanup and the EXIT marker, on every exit path (early module-disable
  and EPIPE exits now break out of the loop instead of returning) - a
  worker running concurrently with shutdown could otherwise write a
  function result after EXIT or use freed state
- hw-sensors-function.h: define the table columns as data and emit them
  in a loop instead of 17 repeated builder calls
- macos: skip the IOHID pass entirely when no services exist; document
  that the duplicate-name scan is quadratic on a few dozen items at most
- apps.plugin: document the intentionally asymmetric application/framework
  precedence in the bundle parser

ktsaou commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

@cubic-dev-ai please review again

ktsaou requested a review from Copilot July 11, 2026 13:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

cubic-dev-ai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai please review again

@ktsaou I have started the AI code review. It will take a few minutes to complete.

cubic-dev-ai Bot left a comment
edited
Loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

All reported issues were addressed across 19 files

Confidence score: 5/5

  • Safe to merge after the addressed issues were fixed.
Architecture diagram
sequenceDiagram
    participant Client as Netdata Client/UI
    participant Agent as Netdata Agent
    participant AppsPlugin as apps.plugin
    participant MacOSPlugin as macos.plugin (sensors)
    participant LinuxPlugin as debugfs.plugin (libsensors)
    participant WindowsPlugin as windows.plugin (GetSensors)
    participant Kernel as macOS/IOKit/SMC
    participant Histogram as Temperature Histogram "system.hw.sensor.temperature.histogram"
    participant Functions as "sensors" Function
    participant Config as apps_groups.conf

    Note over Agent,Functions: NEW: Cross-OS Sensor Features

    Agent->>Histogram: NEW: Publish temperature histogram across all OSes
    Note over Histogram: Fixed buckets: 40,50,60,70,80,85,90,95,100,+Inf °C
    Agent->>Functions: NEW: Register "sensors" function (only on hosts with sensors)

    rect rgb(200, 200, 255)
        Note over MacOSPlugin: macOS Sensor Changes
        MacOSPlugin->>MacOSPlugin: CHANGED: Use "label" instead of "name" label key
        MacOSPlugin->>MacOSPlugin: FIXED: Remove IORegistryEntryID from sensor identity
        MacOSPlugin->>MacOSPlugin: Use stable LocationID for duplication
        MacOSPlugin->>Kernel: FIXED: Remove -n 0 from powermetrics loop
        Kernel-->>MacOSPlugin: Stream data continuously (no early exit)
        MacOSPlugin->>MacOSPlugin: CHANGED: Per-channel charts are opt-in for temperature/voltage/current/power
    end

    rect rgb(255, 200, 200)
        Note over AppsPlugin: macOS Process Grouping
        AppsPlugin->>Config: Read apps_groups.conf (with new macOS entries)
        AppsPlugin->>AppsPlugin: NEW: Path-based grouping for unmatched processes
        alt Application bundles (.app, .appex)
            AppsPlugin->>AppsPlugin: Group per application (e.g., Finder, Xcode)
        else Apple framework helpers (.framework)
            AppsPlugin->>AppsPlugin: Aggregate into "system-frameworks"
        else Apple standalone daemons (/usr/libexec, /usr/sbin, ...)
            AppsPlugin->>AppsPlugin: Aggregate into "system-daemons"
        else Driver extensions (.dext)
            AppsPlugin->>AppsPlugin: Aggregate into "driver-extensions"
        else Third-party frameworks
            AppsPlugin->>AppsPlugin: Group per framework
        else Third-party plain binaries
            AppsPlugin->>AppsPlugin: Group per process name (comm)
        end
    end

    par macOS
        MacOSPlugin->>MacOSPlugin: NEW: Build per-subsystem temperature summary (min/avg/max)
        MacOSPlugin->>MacOSPlugin: NEW: Build per-subsystem power summary (sum)
        MacOSPlugin->>Histogram: NEW: Feed temperature histogram
        MacOSPlugin->>Functions: NEW: List all sensors in response
    and Linux
        LinuxPlugin->>LinuxPlugin: CHANGED: Serialize sensors_dict access with mutex
        LinuxPlugin->>LinuxPlugin: CHANGED: Write function results under stdout_mutex
        LinuxPlugin->>LinuxPlugin: CHANGED: Cancel/join function threads on exit
        LinuxPlugin->>Histogram: NEW: Emit temperature histogram via PLUGINSD text
        LinuxPlugin->>Functions: NEW: First function (using functions_event_loop)
    and Windows
        WindowsPlugin->>WindowsPlugin: CHANGED: Use "label" instead of "name" label key
        WindowsPlugin->>WindowsPlugin: CHANGED: Include external multiplier in histogram math
        WindowsPlugin->>Histogram: NEW: Feed temperature histogram
        WindowsPlugin->>Functions: NEW: (Pending on this branch)
    end

    Agent-->>Client: Serve summary charts (25 instead of 405)
    Agent-->>Client: Serve process groups (85 instead of 598)
    Agent-->>Client: Serve temperature histogram
    Agent-->>Client: Serve "sensors" function table

    Note over Agent,Client: Result: Mac M4 Mini → 598→85 process groups, 405→25 sensor charts
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

- debugfs: the histogram chart-exposed flag moves to file scope and is
  reset at cleanup, so a future in-process module restart re-emits the
  CHART definition instead of sending orphan SETs
- debugfs: sensor states are refreshed in the same locked section as the
  collection, so a concurrent 'sensors' function request never observes
  values derived from the previous cycle
- windows: guard the histogram insertion with isfinite(), matching the
  validation the macOS and libsensors producers already apply

ktsaou commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

@cubic-dev-ai please review again

cubic-dev-ai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai please review again

@ktsaou I have started the AI code review. It will take a few minutes to complete.

cubic-dev-ai Bot left a comment
edited
Loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

All reported issues were addressed across 20 files

Confidence score: 5/5

  • Safe to merge after the addressed issues were fixed.
Architecture diagram
sequenceDiagram
    participant AppsPlugin as apps.plugin (macOS)
    participant MacProcess as macOS Process
    participant MacSensorPlugin as macos.plugin sensors
    participant DebugfsPlugin as debugfs.plugin libsensors
    participant WinPlugin as windows.plugin GetSensors
    participant IOHID as IOHID / SMC
    participant Powermetrics as powermetrics
    participant Histogram as HW Sensors Histogram
    participant SensorFunc as Sensors Function
    participant NetdataCloud as Netdata Cloud / UI

    Note over AppsPlugin: Path-Based Process Grouping (macOS)

    MacProcess->>AppsPlugin: PID, executable path (/System, .app, .framework, .dext)
    AppsPlugin->>AppsPlugin: NEW: Classify path (apple vs user, bundle type)
    alt Application bundle (*.app / *.appex)
        AppsPlugin->>AppsPlugin: Group by app name (e.g. Finder)
    else Apple framework helper (*.framework, /System)
        AppsPlugin->>AppsPlugin: Group "system-frameworks"
    else Apple standalone daemon (/usr/libexec, /usr/sbin, /bin)
        AppsPlugin->>AppsPlugin: Group "system-daemons"
    else Driver extension (*.dext)
        AppsPlugin->>AppsPlugin: Group "driver-extensions"
    else Third-party framework
        AppsPlugin->>AppsPlugin: Group by framework name
    else Third-party plain binary
        AppsPlugin->>AppsPlugin: Fallback to process comm name
    end
    Note over AppsPlugin: Result: ~600 groups -> ~85 groups

    Note over MacSensorPlugin,IOHID: Sensor Identity Stability & Label Fix

    IOHID->>MacSensorPlugin: Sensor with IORegistryEntryID (per-boot)
    MacSensorPlugin->>MacSensorPlugin: NEW: Use LocationID for stable identity
    MacSensorPlugin->>MacSensorPlugin: Use unique product names (e.g. PMU_tdie5)
    MacSensorPlugin->>MacSensorPlugin: CHANGED: Label key "name" -> "label"

    Note over MacSensorPlugin,Powermetrics: powermetrics Loop Fix

    Powermetrics->>MacSensorPlugin: -n 0 (zero samples, exit immediately)
    MacSensorPlugin->>MacSensorPlugin: CHANGED: Remove -n flag, stream continuously
    MacSensorPlugin->>MacSensorPlugin: NEW: Reset log-once guard only after productive loop

    Note over MacSensorPlugin,Histogram: Sensor Cardinality Reduction

    MacSensorPlugin->>MacSensorPlugin: NEW: Per-channel charts opt-in (default off for temp/volt/current/power)
    MacSensorPlugin->>Histogram: Build per-subsystem temperature summary (min/avg/max)
    MacSensorPlugin->>Histogram: Build per-subsystem power summary (total watts)
    MacSensorPlugin->>Histogram: Build temperature histogram (10 disjoint buckets)

    Note over DebugfsPlugin: Linux libsensors Integration

    DebugfsPlugin->>DebugfsPlugin: NEW: Register "sensors" function via functions event loop
    DebugfsPlugin->>Histogram: Mirror histogram contract (PLUGINSD text protocol)
    DebugfsPlugin->>DebugfsPlugin: NEW: sychronized sensor data access for function threads
    DebugfsPlugin->>DebugfsPlugin: NEW: Graceful shutdown handling (QUIT, EPIPE)

    Note over WinPlugin: Windows Sensor Integration

    WinPlugin->>WinPlugin: CHANGED: Label key "name" -> "label"
    WinPlugin->>Histogram: Count temperatures only on successful/finite reads
    WinPlugin->>Histogram: Match histogram value math with per-sensor charts
    WinPlugin->>WinPlugin: NEW: Retire histogram chart on cleanup

    Note over Histogram: Cross-OS Temperature Histogram Contract

    Histogram->>NetdataCloud: Fixed bucket edges (40,50,60,70,80,85,90,95,100,+Inf °C)
    Histogram->>NetdataCloud: Fleet-aggregatable (bucket counts sum across nodes)
    Note over Histogram: Permanent contract - never change bucket definitions

    Note over SensorFunc: Cross-OS Sensors Function

    SensorFunc->>NetdataCloud: One row per sensor
    SensorFunc->>NetdataCloud: Columns: chart_id, label, kind, subsystem, source, device, sensor_id, reading, units, state, chart_mode
    SensorFunc->>NetdataCloud: Per-kind columns (Temperature/Fan/Voltage/Current/Power)
    SensorFunc->>NetdataCloud: Groupable by kind, subsystem, device, state
    SensorFunc->>NetdataCloud: Registration follows discovery (only on hosts with sensors)
Loading

You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.

Re-trigger cubic

Sensors absent from the Sensor API enumeration kept their last read_ok
and cached value, so the temperature histogram counted them forever.
Every enumerated sensor is now stamped with the enumeration generation,
which advances only after a completed pass: a sensor missing from one
completed pass stops being counted, sensors not yet visited by the
in-flight pass keep one pass of grace, and a failed poll freezes the
last known state instead of aging everything out.

ktsaou commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

@cubic-dev-ai please review again

cubic-dev-ai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai please review again

@ktsaou I have started the AI code review. It will take a few minutes to complete.

cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

No issues found across 20 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.

Re-trigger cubic

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.

ktsaou added 2 commits July 11, 2026 19:05
Interpreters already fall back to comm naming in the macOS tree-target
hook, but the default interpreters list was missing zsh - the macOS
default login shell - and the other login shells macOS ships. An SSH
session (a shell that is a tree root under the sshd-session manager)
was therefore bucketed into system-daemons together with everything the
user ran in it. Add zsh, dash, csh, tcsh and ksh to the defaults, so
shell tree roots group by their comm on all platforms alike.
The libsensors module had no metadata entry at all while this branch
adds a new public context and a function to it. Document the module:
per-sensor input/average/alarm contexts for every sensor class (only
the average contexts libsensors actually provides - voltage, current,
power), the chart labels, the alarm states, and the cross-OS
temperature histogram with its fixed bands.

Also document why macos_sensors_mutex deliberately has no destructor:
the daemon exits with collector threads alive, and destroying a held
uv mutex aborts.

ktsaou commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

@cubic-dev-ai please review again

ktsaou requested a review from Copilot July 11, 2026 16:05

cubic-dev-ai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai please review again

@ktsaou I have started the AI code review. It will take a few minutes to complete.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

cubic-dev-ai Bot left a comment
edited
Loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

All reported issues were addressed across 21 files

Confidence score: 5/5

  • Safe to merge after the addressed issues were fixed.
Architecture diagram
sequenceDiagram
    participant MacOS as macOS System
    participant AppsPlugin as apps.plugin
    participant Targets as Target Tree
    participant MacSensors as macos.plugin (sensors)
    participant WinSensors as windows.plugin (GetSensors)
    participant DebugFS as debugfs.plugin (libsensors)
    participant Histogram as Temperature Histogram
    participant FuncAPI as Sensors Function API
    participant RRD as Netdata DB / Charts
    participant Powermetrics as powermetrics

    Note over MacOS,Targets: NEW: Path-derived process grouping (macOS)

    MacOS->>AppsPlugin: collect process list
    AppsPlugin->>AppsPlugin: get_executable_path(pid)
    alt Executable path available
        AppsPlugin->>AppsPlugin: classify by path (app, framework, dext, system, user)
        alt Application bundle (*.app, *.appex)
            AppsPlugin->>Targets: group = app name
        else Apple framework helper
            AppsPlugin->>Targets: group = "system-frameworks"
        else Apple standalone daemon (/usr/libexec, /usr/sbin, ...)
            AppsPlugin->>Targets: group = "system-daemons"
        else Driver extension (*.dext)
            AppsPlugin->>Targets: group = "driver-extensions"
        else Third-party framework
            AppsPlugin->>Targets: group = framework name
        else Third-party binary
            AppsPlugin->>Targets: fallback to comm naming
        end
    else No executable path
        AppsPlugin->>Targets: fallback to comm naming
    end
    AppsPlugin->>Targets: add to target tree
    Note over MacOS,Targets: Result: ~598 groups → ~85 on M4 Mac mini

    Note over MacOS,Powermetrics: CHANGED: powermetrics loop fix

    Powermetrics->>Powermetrics: removed -n 0 (streams until stopped)
    Powermetrics->>MacOS: continuous data stream
    MacSensors->>Powermetrics: CHANGED: reset logged_loop_failure only after productive loop
    Powermetrics-->>MacSensors: thermal/smc/gpu data

    Note over MacSensors,Histogram: NEW: sensor summaries + histogram

    MacSensors->>MacSensors: collect all sensor values
    MacSensors->>MacSensors: only chart per-channel for do_per_sensor_charts[kind]=true
    alt Temperature sensor
        MacSensors->>Histogram: hw_sensors_temperature_histogram_add(value)
        MacSensors->>MacSensors: update temperature_subsystem_* rollup (min/avg/max)
    else Power sensor
        MacSensors->>MacSensors: update power_subsystem_* rollup (sum)
    end
    MacSensors->>RRD: create/update system.hw.sensor.temperature.histogram
    MacSensors->>RRD: create/update system.hw.sensor.temperature.subsystem.*
    MacSensors->>RRD: create/update system.hw.sensor.power.subsystem.*

    Note over WinSensors,Histogram: CHANGED: Windows histogram integration

    WinSensors->>WinSensors: collect sensor data
    WinSensors->>WinSensors: CHANGED: use 'label' key instead of 'name'
    WinSensors->>WinSensors: track read_ok per sensor
    WinSensors->>WinSensors: track seen_generation vs sensors_enum_generation
    alt Temperature sensor with successful read
        WinSensors->>Histogram: hw_sensors_temperature_histogram_add(celsius)
    end
    WinSensors->>RRD: create/update system.hw.sensor.temperature.histogram

    Note over DebugFS,Histogram: NEW: libsensors histogram + functions

    DebugFS->>DebugFS: read hwmon sensors via libsensors
    DebugFS->>Histogram: emit PLUGINSD CHART/DIMENSION/BEGIN/SET
    DebugFS->>RRD: system.hw.sensor.temperature.histogram (heatmap)
    DebugFS->>FuncAPI: register "sensors" function

    Note over FuncAPI,RRD: NEW: cross-OS sensors function

    Client->>FuncAPI: request sensors function
    FuncAPI->>MacSensors: read sensor data (under mutex)
    FuncAPI->>DebugFS: read sensor data (under mutex)
    FuncAPI->>FuncAPI: build table rows with per-kind columns
    FuncAPI-->>Client: JSON table (chart, label, kind, subsystem, source, device, reading, units, state, per-kind values)
    Note over FuncAPI,Client: Same schema on macOS, Linux, Windows
Loading

You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.

Re-trigger cubic

ktsaou added 2 commits July 11, 2026 19:28
- windows.plugin: destroy the sensors mutex after the dictionary, so a
  future dictionary delete callback can never observe a destroyed mutex
- macos.plugin: document why the function-registration check reads the
  sensors list without the mutex (collection, the check, and the pthread
  cleanup handler all run on the plugin thread; function workers lock)
- debugfs.plugin metadata: fix the Additional typo in all module entries
The collector taxonomy checker requires a sibling taxonomy.yaml when a
collector's metadata metrics change. Follow the macos.plugin and
windows.plugin precedent: taxonomy_optout with a reason, since dashboard
placement for these heterogeneous kernel-subsystem contexts is not yet
defined.

ktsaou commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

@cubic-dev-ai please review again

cubic-dev-ai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai please review again

@ktsaou I have started the AI code review. It will take a few minutes to complete.

Copy link
Copy Markdown

cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

No issues found across 22 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.

Re-trigger cubic

ktsaou merged commit c50431d into netdata:master Jul 11, 2026
155 of 157 checks passed
stelfrag added a commit to stelfrag/netdata that referenced this pull request Jul 12, 2026
…#23085)

Backport the macos.plugin sensor collectors (gpu, sensors/SMC, power,
powermetrics, nvme, iohid) and the shared hw-sensors histogram/function
framework to the 2.10.x line. macOS-only paths taken from master tip;
the functions_evloop/logs/network-viewer/status-file changes bundled in
those PRs are excluded (not needed by the in-process macOS collector).
Adds the ndsudo powermetrics whitelist (with <errno.h>) and CMake wiring.
stelfrag mentioned this pull request Jul 12, 2026
stelfrag pushed a commit to stelfrag/netdata that referenced this pull request Jul 14, 2026
Backport the apps.plugin half of netdata#23085, the companion to the macOS
sensor collectors already backported. Adds apps_os_tree_target_name_macos()
(derive process groups from the executable path so macOS does not create one
group per distinct process name) plus the macOS component definitions in
apps_groups.conf. apps_os_tree_target_name() is a compile-time no-op on
non-macOS (returns NULL -> existing name/comm naming), so Linux/Windows/
FreeBSD behavior is unchanged. Depends only on the managed_list/tree
mechanism already present since netdata#18594.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ferroin pushed a commit that referenced this pull request Jul 15, 2026
Backport the macos.plugin sensor collectors (gpu, sensors/SMC, power,
powermetrics, nvme, iohid) and the shared hw-sensors histogram/function
framework to the 2.10.x line. macOS-only paths taken from master tip;
the functions_evloop/logs/network-viewer/status-file changes bundled in
those PRs are excluded (not needed by the in-process macOS collector).
Adds the ndsudo powermetrics whitelist (with <errno.h>) and CMake wiring.
Ferroin pushed a commit that referenced this pull request Jul 15, 2026
Backport the apps.plugin half of #23085, the companion to the macOS
sensor collectors already backported. Adds apps_os_tree_target_name_macos()
(derive process groups from the executable path so macOS does not create one
group per distinct process name) plus the macOS component definitions in
apps_groups.conf. apps_os_tree_target_name() is a compile-time no-op on
non-macOS (returns NULL -> existing name/comm naming), so Linux/Windows/
FreeBSD behavior is unchanged. Depends only on the managed_list/tree
mechanism already present since #18594.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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

Labels

area/build Build system (autotools and cmake). area/collectors Everything related to data collection area/docs area/metadata Integrations metadata collectors/apps collectors/debugfs collectors/macos collectors/windows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants


Back | FazBrowse Home | New Git URL