* data_sources: render RRDtool Tune Info as balanced div boxes rrdtool_tune() emitted an unbalanced mix of html_header() and html_end_box() calls wrapped around raw table rows inside the single box opened by data_sources.php. The premature and extra closing tags corrupted the DOM, which (depending on theme) clipped the Save button at the bottom of the Data Source edit page while in Data Source Info mode. - Separate the execute, CLI and HTML code paths in rrdtool_tune() and, for HTML, render each section as a self contained, balanced div box. - Extract and rename the helper print_leaves() to the standalone rrdtool_tune_print_leaves(), matching the rrdtool_tune_* naming convention, and emit div rows instead of table rows. - Switch the data_sources.php wrapper box to div mode to match. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * data_debug: require POST for the Data Source repair actions Applying RRDfile repairs and rerunning the debugger are state changing operations, so they should not be reachable with a GET. Driving them through a GET also meant the follow up redirect was pulled into the content area as a full page, losing the theme and navigation on rerender. Register data_debug.php run_repair and run_debug in the cactiIsPostActionUrl() allowlist so loadUrl() upgrades them to a token-bearing POST, and add the matching csrf_require_post() guard so the browser transport and server side guard stay in sync. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * rrd: split rrdtool_tune into testable render and execute helpers Break rrdtool_tune() into small single-purpose helpers so each path can be exercised directly by unit tests (the web display path is otherwise unreachable under CACTI_CLI): - rrdtool_tune_print_leaves() takes an explicit $html flag instead of branching on CACTI_CLI, so both the div and plain-text branches are testable. - rrdtool_tune_execute() applies the tune/resize commands for a repair. - rrdtool_tune_print_cli() prints the source commands as plain text. - rrdtool_tune_print_html() renders the balanced div boxes. - rrdtool_tune() becomes a thin dispatcher over the three. Add tests/Unit/RrdTuneRenderTest.php covering the leaf printer, the HTML and CLI printers, the execute path and the dispatcher, asserting the output is balanced div markup with no table rows. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * review: post Data Source Troubleshooter actions via cactiPostAction Address PR review feedback: - Switch the Apply Suggested Fixes and Rerun Analysis links to the existing cactiPostAction/data-url idiom (as data_sources.php already does for ds_repair) instead of upgrading a loadUrl() GET through the cactiIsPostActionUrl allowlist. The allowlist path replayed the query-free mutation URL into browser history, so a refresh reopened the list instead of the selected Data Source; a full cactiPostAction submission follows the server redirect to the read-only view URL and records that in history. The run_repair / run_debug csrf_require_post guards are retained, and the data_debug.php allowlist entry (and its now redundant click handlers) are removed. - Add a callable $executor test seam to rrdtool_tune_execute() (matching rrdtool_dump_document) so the unit tests assert the tune and resize commands are actually executed, with resize.rrd produced only when the resize command runs, rather than passing on the rename alone. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * review: move RrdTuneRenderTest into the Unit/Core/Rrd category folder Per AGENTS.md, new unit tests belong in a category subfolder rather than directly under tests/Unit. Move RrdTuneRenderTest there and update the UnitStubs include depth accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: TheWitness <copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cacti
Overview
Cacti is an open-source network monitoring and graphing platform built on RRDtool.
It provides a scalable framework to collect, store, and visualize time-series data from network devices, servers, and applications.
Core capabilities include:
- Automated device discovery
- Local and remote data collection
- Graph, data source, and RRA templating
- SNMP polling (v1/v2/v3) and IPv6 support
- Role-based access control (RBAC)
- Plugin framework
- Dynamic graph viewing and export options
Release Branches
Cacti maintains two primary branches:
| Branch | Purpose |
|---|---|
1.2.x |
Stable long-lived release series |
develop |
Active development toward Cacti 1.3.x |
For the latest published version, see GitHub Releases.
System Requirements
Minimum supported dependencies by branch:
| Dependency | Cacti 1.2.x |
Cacti develop (1.3.x) |
|---|---|---|
| MariaDB | 10.5+ | 10.11+ |
| MySQL | 8.0+ | 8.4+ |
| PHP | 8.2+ | 8.3+ |
| RRDtool | 1.7+ | 1.8+ |
| Net-SNMP | 5.9+ | 5.9+ |
Notes:
- RRDtool 1.9+ is recommended for newer dynamic graph features in 1.3.x.
- A web server with PHP support is required.
- PHP should be available as CLI or CGI for scheduled polling and maintenance scripts.
php-snmpis now fully supported. When bothphp-snmpand the Net-SNMP binaries are available,php-snmpis used by default; to force the Net-SNMP binaries, set$php_snmp_support = false;ininclude/config.php.- Full support for the upcoming PHP 8.6 release is planned, which brings significant performance improvements that speed up data collection in Script and Script Server data input methods.
Operating system guidance:
1.2.x: RHEL/Rocky/Alma 8+ (or equivalent) is a common baseline.1.3.x: RHEL/Rocky/Alma 9+ or CentOS Stream 9+ is preferred for modern PHP packaging.- Debian and Ubuntu are also well supported.
Installation (Source Checkout)
Clone the repository:
git clone https://github.com/Cacti/cacti.git
cd cacti
Dependency management:
- For a source checkout on both
1.2.xanddevelop, install dependencies with Composer before serving Cacti. Composer-managed packages underinclude/vendorare generated and intentionally not committed; the remaining legacy libraries in that directory are not Composer-managed and remain in the repository. - On
develop,composer installuses the committed lock file resolved against Cacti's PHP 8.3 floor. - Use
composer updateonly in an intentional dependency-update change, and commit the resultingcomposer.lockupdate. - Release packages must build
include/vendorfrom the lock withcomposer install --no-devand verify the real build host withcomposer check-platform-reqs --no-dev. - Tags under
release/*build a deterministic archive, SHA-256 checksum, CycloneDX SBOM, and GitHub provenance attestation through the release-artifact workflow.
Install dependencies:
composer install
Windows users may need:
composer install --ignore-platform-req=ext-pcntl --ignore-platform-req=ext-posix
For a source checkout, install the locked browser dependencies before configuring the web server. Node.js is required for this build; release archives already contain the generated assets. Run this command as the owner of the Cacti files:
npm ci
Then configure your database and web server, and complete setup using the official docs:
https://github.com/Cacti/documentation
Database Upgrades and Schema Checks
When running from source (especially develop), schema updates may be required after pulling changes.
Upgrade the database schema:
sudo -u cacti php -q cli/upgrade_database.php --forcever=`cat include/cacti_version`
If needed, force a re-upgrade from an earlier version:
php -q cli/upgrade_database.php --forcever=<older_version>
Audit schema consistency:
php cli/audit_database.php --report
Data Collection and Polling
Cacti collects data through data sources, which can use:
- SNMP
- Scripts
- Command output
- Databases
- Custom input methods
Polling engines:
| Poller | Description |
|---|---|
| PHP Poller | Built-in polling engine |
| Spine | High-performance C-based poller |
Spine supports SNMPv1/v2 and SNMPv3 with IPv6, with some advanced protocol support depending on how Net-SNMP is compiled on your platform.
Features
- Device discovery and automation workflows
- Reusable templates for graphs and data sources
- Distributed remote data collectors
- Plugin architecture for extensibility
- Dynamic graph interactions (time navigation, realtime view, CSV export)
- Fine-grained user and group permissions using RBAC
- Broad RRDtool graphing support (including VDEFs and stacked lines)
Documentation
Official documentation is maintained in a separate repository:
https://github.com/Cacti/documentation
Development and Validation
Install the locked Composer dependencies before running PHP contracts. From the repository root:
composer install
include/vendor/bin/pest --configuration=tests/phpunit.xml --testsuite=Unit,Integration
composer run-script phpstan -- --memory-limit=2G
Coverage reports for the PRs checked on October 14, 2026 measure changed first-party executable statements. Applicable changes exceed 80%; this is not whole-project coverage. Formatting-only PHP changes are checked for equivalent syntax trees. Documentation, workflow definitions, lockfiles and generated vendor bundles are outside this execution metric. The validation snapshot records the measured counts and scope.
Run the disposable browser and SQL/RRD profile with Docker and mise installed:
bash tests/performance/profile.sh
The runner selects Node 22 and Python 3.12 through mise and seeds 500 disabled devices and 50 deterministic RRD graphs. It profiles all shipped themes, AJAX navigation, realtime responses, and graph rendering with Boost enabled and disabled. Containers are removed after the run; the printed results directory retains traces, CPU and memory measurements, SQL counts and Callgrind profiles. See profiling instructions and the measured rendering change. The October 14 profile found 400 redundant option-array loads across 200 graph renders. Removing those loads reduced median warm PHP CPU use by 70.7% without Boost and 46.6% with Boost in the equally instrumented fixture. Browser profiles still show retained DOM growth and expensive Midwinter styling.
Timings include Xdebug overhead and use synthetic data; they do not measure live SNMP, collector throughput or production fleet capacity. The current fixture uses RRDtool 1.7.2 for basic rendering; it does not exercise newer RRDtool features.
Contributing
Contributions are welcome.
- Fork this repository.
- Create a branch for your change.
- Submit a pull request.
You can also help improve docs in:
https://github.com/Cacti/documentation
Community
Community support is available on the Cacti forums:
Contributors
Thanks go to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind are welcome.
License
Cacti is licensed under the GNU General Public License v2.0.
See LICENSE for details.
Copyright (c) 2004-2026 The Cacti Group, Inc.