Skip to content

Conversation

@tallpsmith
Copy link
Contributor

Overview

Multi-phase enhancement to Darwin PMDA adding memory, VFS, and network protocol metrics. Work is tracked incrementally with full test coverage per step.

See DARWIN-PMDA-ENHANCEMENT-PLAN.md for complete plan, patterns, and progress tracking.

Completed Work

Phase 1: Memory Enhancement ✅

  • vm_statistics64 upgrade: Migrated to 64-bit API (⚠️ breaks archive compatibility)
  • Compression metrics: 5 new metrics (mem.util.compressed, mem.compressions, etc.)
  • VFS statistics: 7 new metrics for file/vnode/process/thread counts via sysctl

Phase 2: Network Enhancement 🚧

  • UDP statistics: 5 metrics (datagrams, errors) via net.inet.udp.stats
  • ICMP statistics: 8 metrics (messages, echos, errors) via net.inet.icmp.stats
  • Next: Socket counts (2 metrics)

Testing & Infrastructure

  • Unit test framework via dbpmda (scripts/darwin/test/unit/)
  • Integration tests via PCP tools
  • Fast local build system for development

Code Organization

Modular pattern with dedicated .c/.h files per subsystem (vfs, udp, icmp), following existing darwin PMDA architecture.

Status

Completed: Phases 1.1-1.2, 2.1-2.2
Next: Phase 2.3 (socket counts)
Remaining: TCP metrics, process I/O enhancements


Draft PR for early visibility. Feedback welcome on approach and implementation.

tallpsmith and others added 30 commits December 11, 2025 13:59
- Add scripts/darwin/ directory with complete development toolkit
- Standalone GNUmakefile enables 5-10 second rebuilds (vs 5-30 min full build)
- Unit tests use dbpmda for pre-install testing without system installation
- Integration tests validate pminfo, pmval, pmstat work correctly
- Update .github/workflows/macOS.yml with 3 new CI test phases:
  * Unit tests (after build, before install)
  * Integration tests (after install)
  * pmstat validation
- Quick-test.sh runs build and all tests in ~30 seconds total

Solves fast local iteration for Darwin PMDA development by:
1. Using locally built libraries from Makepkgs output (pcp-X.Y.Z/)
2. Building only the Darwin PMDA, not entire PCP
3. Automating test execution in CI/CD
4. Providing clear error messages for missing prerequisites
Replace dbpmda-based tests with basic DSO/binary validation tests:
- Verify DSO is valid Mach-O dylib
- Verify binary executable was built
- Check for required PMDA symbols
- Verify binary responds to --help

This approach works with locally-built libraries from Makepkgs
without requiring PCP to be installed system-wide or having
compiled namespace files.

Full dbpmda testing remains available via integration tests
after PCP system installation.
- Add scripts/darwin/ directory with complete development toolkit
- Standalone GNUmakefile enables 5-10 second rebuilds (vs 5-30 min full build)
- Unit tests use dbpmda for pre-install testing without system installation
- Integration tests validate pminfo, pmval, pmstat work correctly
- Update .github/workflows/macOS.yml with 3 new CI test phases:
  * Unit tests (after build, before install)
  * Integration tests (after install)
  * pmstat validation
- Quick-test.sh runs build and all tests in ~30 seconds total

Solves fast local iteration for Darwin PMDA development by:
1. Using locally built libraries from Makepkgs output (pcp-X.Y.Z/)
2. Building only the Darwin PMDA, not entire PCP
3. Automating test execution in CI/CD
4. Providing clear error messages for missing prerequisites
Replace dbpmda-based tests with basic DSO/binary validation tests:
- Verify DSO is valid Mach-O dylib
- Verify binary executable was built
- Check for required PMDA symbols
- Verify binary responds to --help

This approach works with locally-built libraries from Makepkgs
without requiring PCP to be installed system-wide or having
compiled namespace files.

Full dbpmda testing remains available via integration tests
after PCP system installation.
…art VM.

It appeared that doing the `pkgbuild` inside whatever filesystem it was originally caused a .PKG corruption, so we simply write it initially to a cleaner temp area before copying it back in one hit.
… macos-darwin-pmda-qa

# Conflicts:
#	scripts/darwin/test/integration/run-integration-tests.sh
…uild tree and not rely on (accidentally) having run configure in the root of the source tree.
BREAKING CHANGE: Memory counters now 64-bit (affects archive compatibility)

- Use host_statistics64() with HOST_VM_INFO64 instead of host_statistics()
- Prevents counter overflow on high-activity systems
Add 5 new metrics exclusive to vm_statistics64 API that expose
macOS memory compressor functionality:

- mem.util.compressed - KB of compressed memory
- mem.compressions - cumulative compression operations
- mem.decompressions - cumulative decompression operations
- mem.compressor.pages - current pages in compressor
- mem.compressor.uncompressed_pages - uncompressed size of compressed pages

These metrics provide visibility into memory pressure relief via
the macOS memory compression subsystem.

Changes:
- pmda.c: Added 5 metrictab entries (items 130-134) and fetch_vmstat case 130
- pmns: Added PMNS entries for all 5 metrics
- help: Added documentation for compression metrics
- test-memory-compression.txt: Unit test for new metrics
Add 7 new metrics for system resource tracking via kern.* sysctls:
- vfs.files.count, vfs.files.max, vfs.files.free
- vfs.vnodes.count, vfs.vnodes.max
- kernel.all.nprocs, kernel.all.nthreads

Implementation follows modular pattern with dedicated vfs.c/vfs.h files.
Includes unit and integration tests.
…s, but oriented towards what is available for Mac.

Note: Swap metrics are commented out deliberately, waiting on a previous PR to merge until they become available.
Add detailed diagnostic output to diagnose pmcd connection failures in
GitHub Actions CI environment. Changes include:

- Pre-startup configuration checks (pmconfig, pmcd.conf, env vars)
- Post-startup verification (process status, network ports, connectivity)
- Enhanced failure debugging with logs and connection tests
- Network connectivity tests for both localhost and 127.0.0.1
- Port binding verification using lsof
- Test pminfo with multiple host specifications

This will help identify whether issues are with pmcd startup, network
binding, localhost resolution, or client configuration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add detailed pre-startup and post-startup diagnostics to identify why
pmcd is running but not listening on network ports. New checks include:

Pre-startup:
- Binary locations for pmcd and pminfo
- Critical directory existence (/var/log/pcp/pmcd, /var/lib/pcp)
- PMDA installation directory contents

Startup:
- Explicit logging of which start method succeeded
- Capture error output from all start attempts

Post-startup:
- Full process details (ps aux output)
- Command line arguments pmcd was started with
- Log directory status and permissions
- All open file descriptors for pmcd process
- System log entries for pmcd errors

This will help identify if the issue is missing directories, incorrect
startup command, or pmcd failing to bind to network sockets.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The previous build showed pmcd was starting with --verify -A flags,
which puts it in verification mode instead of daemon mode. This caused
pmcd to check the config but not actually listen on network ports.

Root cause:
- launchctl load was failing (I/O error)
- Falling back to 'pmcd start' ran /etc/init.d/pmcd
- The init script incorrectly launched pmcd with --verify -A

Fix:
- Bypass all init scripts and launchd
- Run pmcd directly: /usr/local/libexec/pcp/bin/pmcd -f
- The -f flag runs in foreground mode (needed for background job)
- Increased sleep to 5s to allow full initialization

Also added:
- Display launchd plist contents for debugging
- Display plist.stdout/stderr from failed launchd attempts

This should make pmcd actually listen on port 44321 for client
connections.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Follow the same approach as .cirrus.yml - let the installer start pmcd
via launchd, then wait for it to become ready. This validates that the
actual installation works correctly, rather than bypassing the normal
startup mechanism.

Changes:
- Removed manual pmcd startup attempts (launchctl, init scripts, direct)
- Added wait loop (60s timeout, 3s intervals) like .cirrus.yml pattern
- Tests both 'pcp' command and 'pminfo' to verify pmcd is responding
- If timeout expires, shows diagnostics and fails the build
- Simplified pre-checks to focus on installation verification

This properly tests that:
1. The installer creates the launchd plist correctly
2. pmcd starts automatically post-install
3. The service becomes available within reasonable time
4. All components are properly configured

Rather than masking installation issues with manual workarounds.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
PCP tools (pmstat, pmrep, pmval) all support the -s flag to specify
number of samples before exiting. The timeout wrapper was:
- Redundant: tools already exit after N samples
- Non-portable: GNU timeout doesn't exist on macOS
- Unnecessary complexity

Changed:
- pmstat -t 1 -s 2: naturally exits after 2 samples
- pmrep -t 1 -s 2: naturally exits after 2 samples
- pmval -t 1 -s 1: naturally exits after 1 sample

This fixes the "timeout: command not found" errors on macOS while
maintaining the same test behavior.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
pmrep is failing with "ModuleNotFoundError: No module named 'pcp'"
while it works fine in Cirrus CI. Adding diagnostics to identify:

- Which Python interpreter pmrep is using
- Python sys.path for that interpreter
- Where the pcp module is installed (if anywhere)
- Whether pcp module can be imported

This will help identify if:
1. PCP Python module wasn't installed by the package
2. It was installed to wrong Python location
3. PYTHONPATH needs to be set
4. There's a Python version mismatch

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The pcp Python module is installed at /usr/local/lib/python3.13/site-packages
but pmrep uses pmpython which has sys.path pointing to the build venv.

Root cause:
- pmrep shebang: #!/usr/bin/env pmpython
- pmpython sys.path includes build venv, not /usr/local
- pcp module is installed to /usr/local/lib/python3.13/site-packages
- Module exists but isn't in Python's search path

Fix:
- Export PYTHONPATH=/usr/local/lib/python3.13/site-packages
- Verify pcp module can be imported before running tests
- This makes the installed pcp module accessible to pmrep

This should fix the 2 failing pmrep :macstat tests.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Missed this script in the previous timeout removal commit.
pmstat already exits after -s 2 samples, no need for timeout wrapper.

Fixes: "timeout: command not found" error on macOS in test-pmstat.sh

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The test was failing because grep patterns expected column names
and values on the same line, but pmstat's formatted output has:
- Line 1: Column headers (loadavg, memory, io, cpu)
- Line 2: Sub-headers (1 min, swpd, free, etc.)
- Line 3+: Numeric data

Fixed by separating checks:
- Verify column headers exist
- Verify numeric data is present in output
- Made memory check lenient (only checks header) since some
  values show "?" on macOS which is expected behavior

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…w them to be exposed for things like pmstat

Used Claude Code to generate this.
Now that swap metrics have been added to the darwin PMDA, enable
the swap.used metric in both :macstat and :macstat-x configurations.

Tested with integration tests - pmrep :macstat correctly displays
the swpd column with swap usage data.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
tallpsmith and others added 29 commits January 2, 2026 10:39
Add 5 new metrics for UDP protocol monitoring via net.inet.udp.stats sysctl:
- network.udp.indatagrams, network.udp.outdatagrams
- network.udp.noports, network.udp.inerrors
- network.udp.rcvbuferrors

Implementation follows modular pattern with dedicated udp.c/udp.h files.
Includes unit and integration tests.
Add 8 new metrics for ICMP protocol monitoring via net.inet.icmp.stats sysctl:
- network.icmp.inmsgs, network.icmp.outmsgs (message totals)
- network.icmp.inerrors (error sum)
- network.icmp.indestunreachs, network.icmp.inechos, network.icmp.inechoreps
- network.icmp.outechos, network.icmp.outechoreps

Implementation follows modular pattern with dedicated icmp.c/icmp.h files.
Includes unit and integration tests.
This plan document tracks the multi-phase enhancement effort for the
Darwin PMDA, covering memory, VFS, network, and process metrics.

Includes:
- Step-by-step implementation guide with progress tracking
- Code organization patterns and best practices
- Unit and integration test patterns
- Technical notes on macOS APIs and limitations
- Phase 4 finalization step to transform into permanent documentation

Also update .gitignore to allow tracking this file as permanent docs.
New cluster: CLUSTER_SOCKSTAT (15)

Added 2 metrics via pcbcount sysctls:
- network.sockstat.tcp.inuse (net.inet.tcp.pcbcount)
- network.sockstat.udp.inuse (net.inet.udp.pcbcount)

Implementation:
- Modular design with dedicated sockstat.c/sockstat.h files
- Direct metrictab pointers (no computed values)
- Refresh via refresh_sockstat() using sysctlbyname()
- PMNS hierarchy: network.sockstat.{tcp,udp}.inuse
- Full help text documentation

Testing:
- Unit tests: test-sockstat.txt
- Integration tests in run-integration-tests.sh
- Marked Step 2.3 as COMPLETED in progress tracker
- Added implementation notes documenting socket statistics
- Updated current step to 2.4 (TCP connection states investigation)
The refresh_vfs() function was using error accumulation which would
overwrite earlier errors with later ones, potentially losing important
error information.

Changed to fail-fast pattern to match:
- Darwin PMDA conventions (refresh_vmstat, refresh_swap, etc.)
- Recent network code (refresh_udp, refresh_icmp, refresh_sockstat)
- Darwin kernel programming best practices

Now returns immediately on first sysctl failure rather than
continuing and overwriting the error code.

Identified by pcp-code-reviewer agent.
Updated execution workflow to include mandatory code review step using
the pcp-code-reviewer agent before committing changes.

Added new section on Error Handling and Code Quality covering:
- Fail-fast error handling pattern (darwin PMDA standard)
- Correct vs incorrect error handling examples
- Rationale for fail-fast on macOS
- Code review process and workflow
- Lessons learned from VFS error handling fix

This ensures future implementations follow PCP conventions and darwin
PMDA best practices from the start.
Implement network.tcpconn.* metrics providing counts of TCP connections
in each state (ESTABLISHED, LISTEN, TIME_WAIT, etc.).

New metrics (11 total):
- network.tcpconn.established - active established connections
- network.tcpconn.listen - listening sockets
- network.tcpconn.time_wait - connections in TIME_WAIT state
- network.tcpconn.syn_sent - active opening (SYN sent)
- network.tcpconn.syn_recv - passive opening (SYN received)
- network.tcpconn.fin_wait1 - active close, FIN sent
- network.tcpconn.fin_wait2 - active close, FIN acked
- network.tcpconn.close - closed connections
- network.tcpconn.close_wait - passive close, waiting
- network.tcpconn.last_ack - passive close, FIN sent
- network.tcpconn.closing - simultaneous close

Implementation:
- Created tcpconn.c/tcpconn.h following modular pattern
- Uses sysctlbyname("net.inet.tcp.pcblist64") to parse TCP PCB list
- Binary structure parsing to extract t_state from xtcpcb64
- Hardcoded 10MB soft limit with debug logging for large buffers
- Cross-platform compatible with Linux PMDA network.tcpconn.* namespace

Testing:
- Unit tests: test-tcpconn.txt (all 11 metrics)
- Integration tests: validate all metrics exist and are non-negative

This completes Step 2.4 of the Darwin PMDA enhancement plan.
Add enable_tcp_stats_script to set net.inet.tcp.disable_access_to_stats=0
before PCP build and installation. This ensures TCP statistics are available
when PMCD starts, preparing for Step 2.5a TCP protocol statistics implementation.

Also update plan document to mark Step 2.5-pre as completed.
Implement 15 TCP protocol statistics metrics matching Linux PMDA parity.
This provides comprehensive TCP monitoring including connection lifecycle,
segment counts, errors, and retransmission metrics.

New cluster: CLUSTER_TCP (17)

Metrics implemented:
- network.tcp.activeopens - Active connection attempts (SYN sent)
- network.tcp.passiveopens - Passive connections accepted
- network.tcp.attemptfails - Failed connection attempts
- network.tcp.estabresets - Connections reset from ESTABLISHED
- network.tcp.currestab - Current established connections
- network.tcp.insegs - Total TCP segments received
- network.tcp.outsegs - Total TCP segments sent
- network.tcp.retranssegs - Segments retransmitted
- network.tcp.inerrs - Input errors (aggregated)
- network.tcp.outrsts - RST segments sent
- network.tcp.incsumerrors - Checksum errors
- network.tcp.rtoalgorithm - RTO algorithm (Van Jacobson = 4)
- network.tcp.rtomin - Minimum RTO (200ms)
- network.tcp.rtomax - Maximum RTO (64000ms)
- network.tcp.maxconn - Max connections (-1 = unlimited)

Implementation:
- tcp.h: tcpstats_t structure definition
- tcp.c: refresh_tcp() and fetch_tcp() implementations
- pmda.c: CLUSTER_TCP, metrictab entries, dispatch integration
- pmns: network.tcp.* namespace hierarchy
- help: Documentation for all 15 metrics
- GNUmakefile: Build integration

Testing:
- Unit tests: test-tcp.txt (all 15 metrics)
- Integration tests: 18 test cases added

Technical notes:
- Uses sysctlbyname("net.inet.tcp.stats") for data collection
- Computed metrics: currestab (from tcpconn), inerrs, outrsts
- Constants: rtoalgorithm, rtomin, rtomax, maxconn
- Requires net.inet.tcp.disable_access_to_stats=0 (enabled in CI)
Convert 4-space indentation to tabs to match PCP coding style and
be consistent with pmda.c, udp.c, icmp.c, and other darwin PMDA files.
- Add critical code style requirements section (tabs, not spaces)
- Emphasize fixing ALL code review issues including minor ones
- Document lessons learned from TCP implementation (indentation fix)
- Update progress tracker: Step 2.5a completed, Step 2.5b next
- Add verification commands for checking indentation
Add detection and user documentation for macOS TCP statistics access
control restriction (net.inet.tcp.disable_access_to_stats).

Changes:
- pmda.c: Add check_tcp_stats_access() function called during darwin_init()
  to detect if TCP stats are disabled and log comprehensive warning with
  configuration instructions
- pmdadarwin.1: Create first man page for darwin PMDA with dedicated
  TCP STATISTICS CONFIGURATION section explaining the requirement and
  providing both temporary (sysctl -w) and permanent (/etc/sysctl.conf)
  configuration instructions
- help: Add cluster-level help text for network.tcp metrics referencing
  the configuration requirement and man page
- GNUmakefile: Add man page installation with MAN_SECTION, MAN_PAGES,
  MAN_DEST variables, INSTALL_MAN directive, and MANLINT check rule

This completes Step 2.5b of the darwin PMDA enhancement plan.

When TCP statistics access is disabled (the default on macOS), users will
see a clear warning in the PMCD log with actionable remediation steps,
and can reference the man page for detailed configuration guidance.
Move fetch_disk() and fetch_network() from pmda.c to disk.c and network.c
respectively to improve code organization and reduce pmda.c size.

Changes:
- disk.h: Add fetch_disk() function declaration
- disk.c: Move fetch_disk() from pmda.c with extern pattern for globals
- network.h: Add fetch_network() function declaration
- network.c: Move fetch_network() from pmda.c with extern pattern for globals
- pmda.c: Remove fetch_disk() and fetch_network() functions

This follows the modular pattern established in newer subsystems (vfs, udp,
icmp, tcp, tcpconn) where fetch functions live in their respective .c files
rather than in the monolithic pmda.c. This makes pmda.c a cleaner coordination
layer focused on initialization, dispatch, and metrictab definitions.

Size reduction: pmda.c reduced from 1631 to 1466 lines (10% reduction)
Add six macOS-specific pmrep monitoring configurations to provide
specialized system analysis views:

- :macstat (enhanced): Added network interface total metrics
- :macstat-x (enhanced): Added VFS metrics and disk byte I/O
- :macstat-mem (new): Memory deep-dive with compression, paging, cache analysis
- :macstat-dsk (new): Disk I/O deep-dive with IOPS, throughput, latency metrics
- :macstat-tcp (new): TCP connection states and error monitoring
- :macstat-proto (new): Multi-protocol overview (UDP, ICMP, TCP summary)

These views provide out-of-the-box monitoring configurations for memory,
disk, network, and protocol administrators without requiring custom pmrep
configs. Each view is organized with clear section comments and follows
established PCP abbreviation conventions (vmstat/iostat patterns).

Fixes from code review:
- Corrected metric names (network.interface.total.bytes, not .in/.out)
- Fixed derived metric identifier (cache_hit_ratio) and unit (%)
- Consolidated redundant section headers
- Updated file header with usage examples for all six views

🤖 Generated with Claude Code

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Add comprehensive tests for the four new pmrep views:
- :macstat-mem: Memory deep-dive with compression, paging, cache metrics
- :macstat-dsk: Disk I/O deep-dive with IOPS, throughput, latency
- :macstat-tcp: TCP connection and error monitoring
- :macstat-proto: Multi-protocol overview (UDP, ICMP, TCP, sockets)

Each view test validates the presence of expected metric columns/labels
using pattern matching on pmrep output. Tests are non-blocking (warnings
rather than failures) to allow graceful degradation if new views aren't
available in the PCP installation.
Change all new pmrep view tests (:macstat-mem, :macstat-dsk, :macstat-tcp,
:macstat-proto) from non-blocking (warnings) to blocking (errors).

Now the test suite:
- Exits immediately if pmrep command fails for any view
- Exits immediately if any expected metric is missing from view output
- Uses red error indicators for failures instead of yellow warnings
- Validates the complete output as expected, not just that views exist

This ensures the automated test suite properly confirms all new monitoring
views work correctly and produce the expected metric output.
The recent refactoring (commit 776116b) moved fetch_disk() and
fetch_network() to their respective modules (disk.c, network.c), but
the indom enum definitions remained in pmda.c, causing build errors
when these modules referenced DISK_INDOM and NETWORK_INDOM.

Changes:
- Move indom enum from pmda.c to darwin.h for shared access
- Add darwin.h include to disk.c and network.c
- Update pmda.c comment to note enum is now in darwin.h

This fixes the build error:
  disk.c:284:23: error: use of undeclared identifier 'DISK_INDOM'
The indomtab array needs to be globally visible for disk.c and
network.c to reference it via extern declarations. Removing the
static keyword allows the linker to resolve these references.
ConfigParser treats % as a special interpolation character, so it must
be escaped as %% in configuration files. This fixes the pmrep error:

  configparser.InterpolationSyntaxError: '%' must be followed by '%' or '(', found: '%'

Also remove redundant cluster help text from darwin PMDA help file.
The label 'hit%' also needs escaping for ConfigParser. Both .label
and .unit values containing % must be escaped as %%.
Fix cache_hit_ratio type mismatch error by restructuring ternary operator
to return final value from both branches instead of divisor, avoiding
PM_TYPE_U64 vs PM_TYPE_32 conflict.

Replace per-interface network metrics in :macstat with aggregated totals
using sum() to prevent excessive column width. Users can now see total
network in/out bandwidth across all interfaces in compact format.

Add colxrow to :macstat-proto view to display interfaces as rows instead
of columns (similar to sar -n DEV), making output readable. Users can
filter specific interfaces with pmrep -i option.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Document the three issues discovered during QA testing of pmrep views:
- cache_hit_ratio type mismatch bug and fix
- :macstat layout improvement with aggregated network totals
- :macstat-proto layout improvement with colxrow

Add lessons learned about pmrep sum() aggregation, instance domain
handling, and importance of real-world QA testing beyond unit tests.

Update Mode 1 and Mode 6 descriptions to reflect final implementation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add per-process disk I/O statistics via proc_pid_rusage() API.

New metrics:
- proc.io.read_bytes  - cumulative bytes read from disk
- proc.io.write_bytes - cumulative bytes written to disk

Implementation:
- Added read_bytes/write_bytes fields to darwin_proc_t structure
- Collect I/O stats using proc_pid_rusage(RUSAGE_INFO_V3)
- Added CLUSTER_PROC_IO (cluster 5) with two U64 counter metrics
- Updated PMNS with proc.io namespace
- Added help text documenting the new metrics

The metrics provide cumulative I/O byte counts since process start,
enabling I/O rate calculations and process I/O profiling.

Refactoring:
- Broke down 175-line darwin_refresh_processes() into focused helpers:
  * darwin_process_set_basic_fields() - extract kinfo_proc data
  * darwin_process_set_command_info() - get command/path/cwd
  * darwin_process_set_taskinfo() - collect libproc stats and I/O
- Improved code readability and maintainability
- Added parameter documentation following PCP conventions
- Main loop now clearly shows the processing sequence

Code review: APPROVED by pcp-code-reviewer agent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant