# php4u/module-watchtower-m2-connector

> Watchtower monitoring connector - observes store data locally and reports coarse anomaly statuses to the Watchtower platform. See LICENSE.

`composer require php4u/module-watchtower-m2-connector`

Canonical URL: https://packagento.com/php4u/module-watchtower-m2-connector

## At a glance

- **Vendor**: Php4u Limited (https://packagento.com/php4u.md)
- **Latest version**: v1.30.1 — released 2026-09-02
- **Pricing**: Free
- **Package type**: Magento 2 module
- **Status**: active, accepting new buyers

## Installation

Packagento is licence-gated, so even free packages need a licence on a project before Composer can resolve them.

1. **Sign in or create an account** at https://packagento.com/customer/account/.

2. **Add the package to your account.** Open https://packagento.com/php4u/module-watchtower-m2-connector and complete the free checkout. A licence is minted automatically.

3. **Create or pick a project, then activate the licence on it.**
   - Projects represent the Magento installs you deploy to. Manage them at https://packagento.com/projects/.
   - Activate the new licence on the project you'll deploy this package to. Activation is what generates the Composer credentials scoped to that project.

4. **Add the project credentials to your Magento codebase.**

   Grab the project's public + private key from https://packagento.com/projects/ (open the project, then its Credentials tab), and add them to `auth.json`:

   ```json
   {
     "http-basic": {
       "packagento.com": {
         "username": "ppk_live_...",
         "password": "psk_live_..."
       }
     }
   }
   ```

   Add the Packagento Composer repository to `composer.json`:

   ```json
   {
     "repositories": [
       { "type": "composer", "url": "https://packagento.com" }
     ]
   }
   ```

5. **Install and apply.**

   ```bash
   composer require php4u/module-watchtower-m2-connector:*
   bin/magento setup:upgrade
   bin/magento setup:di:compile
   bin/magento cache:flush
   ```

## What it does

Watchtower monitoring connector - observes store data locally and reports coarse anomaly statuses to the Watchtower platform. See LICENSE.

## README

Your checkout broke at 2am. Nobody noticed until a customer emailed at 9.

Uptime monitors do not catch this. The site was up the whole time. It was
returning 200s, serving pages, and quietly failing to take money.

Watchtower Connector watches the things that actually mean your shop is
working: orders completing, carts being created, customers signing in, your ERP
sync still running, cron still ticking, queues still draining. When one of them
stops behaving the way it normally does, you hear about it.

The platform side lives at [watchtower-commerce.com](https://watchtower-commerce.com).
The [documentation](https://watchtower-commerce.com/docs) covers creating a
project, connecting a store, and what each signal means.

### Your numbers never leave your store

This matters enough to be the second thing on the page.

Everything is worked out inside your Magento install. The baseline, the
thresholds, the comparison, the decision that something looks wrong: all of it
runs locally, on your own server.

What gets sent is a word. `NORMAL`, or `SEVERE_DROP`, or `INSUFFICIENT_DATA`,
per signal, per store view. Never an order count, a revenue figure, a customer
name, a product, an email address, or an error message. The build fails if
anything beyond the documented fields reaches the payload, or if the API key
ever turns up in a request body. Those tests live in the source repository, so
you can read them rather than take our word for it.

So you can run this on a store whose numbers you would not share with anyone,
and the answer to "what does Watchtower know about my business" stays "whether
each signal looked normal this hour".

### What it watches

Nine signals. Some compare against your own history, some against fixed
thresholds, some are a straight pass or fail.

**Against your own baseline.** These learn what a normal Tuesday at 3pm looks
like for your shop specifically, then tell you when this Tuesday at 3pm is not
that. A store doing 40 orders a day and a store doing 40,000 each get judged
against themselves.

| Signal | Catches |
|---|---|
| `checkout` | Orders stopped completing |
| `basket_quote` | Nobody is filling carts any more |
| `customer_account` | Sign-ins and registrations fell off a cliff |

**Against fixed thresholds.** No warm-up period. These work on your first day
and on a store of any size, because "half of checkout attempts are failing" is
bad regardless of what normal looks like for you.

| Signal | Catches |
|---|---|
| `checkout_failure` | A payment method, a shipping rate call, or a tax service breaking order placement |
| `admin_auth_failure` | A burst of failed admin sign-ins |

**Pass or fail.** Infrastructure that either works or does not.

| Signal | Catches |
|---|---|
| `cron_health` | Magento's scheduler stopped. Nothing else in Magento works properly when this happens, and stores run for days without noticing |
| `integration_health` | Your ERP, PIM, marketplace or feed sync stopped running |
| `indexer_health` | An indexer stuck invalid, or a materialized-view backlog nothing is draining |
| `queue_health` | Queued work piling up with no consumer attached to it |

`cron_health`, `admin_auth_failure`, `indexer_health` and `queue_health` cover
the whole installation. The rest are reported per store view, so a problem on
your German storefront does not get averaged away by a healthy UK one.

#### How fast you hear about it

Signals are evaluated once an hour, on the last complete hour, and a change is
only reported once it has held for two consecutive evaluations. In practice
that means **about one to two hours** from a problem starting to an alert
arriving.

That two-evaluation wait is deliberate. Monitoring you learn to ignore is worse
than none, and a single odd hour is usually just a quiet hour.

#### Integrations, without the guesswork

`integration_health` is the one signal you choose the contents of, and it tries
hard not to make that your problem.

The connector reads the scheduled jobs your store actually runs and groups them
under the extension that installed them, so you tick **Mailchimp** rather than
hunting for `ebizmarts_ecommerce` among sixty-odd job codes. Pick as many as
you like.

There is no interval to enter. The connector measures how often each job really
runs on your server and judges it against that. A nightly sync gets judged as a
nightly sync. A job that runs every five minutes gets five minutes. Get that
number wrong by hand and you either miss real outages or cry wolf every night,
which is why the connector works it out instead of asking you.

Integrations that run no cron at all, like an ERP pushing into Magento over the
API, can send a `watchtower_integration_health` event from your own code and
appear in the same list.

### Requirements

- **Magento 2.4.7, 2.4.8 or 2.4.9** (Open Source or Adobe Commerce on-prem)
- **PHP 8.3, 8.4 or 8.5**

Magento's own cron must be running. If it is not, this module cannot do
anything, and `cron_health` is the signal that would have told you.

<details>
<summary>Exact Composer constraints</summary>

```
php                                      ~8.3.0||~8.4.0||~8.5.0
magento/framework                        103.0.*
magento/framework-amqp                   100.4.*
magento/framework-bulk                   101.0.*
magento/framework-message-queue          100.4.*
magento/module-asynchronous-operations   100.4.*
magento/module-backend                   102.0.*
magento/module-config                    101.2.*
magento/module-cron                      100.4.*
magento/module-store                     101.1.*
```

`composer.json` is authoritative; this list is generated from it.
</details>

### Install

```
composer require php4u/module-watchtower-m2-connector
bin/magento module:enable Watchtower_Connector
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
```

Then go to **Stores > Configuration > Watchtower > Connection** and fill in two
fields:

_(README truncated for .md surface. Full README on https://packagento.com/php4u/module-watchtower-m2-connector.)_

## Changelog

All notable changes to this module are documented here. Versioning follows
[Semantic Versioning](https://semver.org/), tracked via git tags on this
repository (`composer.json` deliberately carries no hardcoded `version`
field — Composer's VCS-repository support resolves it from the tag).

### [1.30.1] - 2026-09-02

Packaging fix only, no code change. The distributed package now excludes
`docs/`, `README.md`, `CHANGELOG.md`, `phpcs.xml`, `phpstan.neon`, and
`bin/`, none of which Magento reads at runtime, alongside `Test/` which
was already excluded. `docs/` in particular named a real merchant's
store in an internal design record.

### [1.30.0] - 2026-09-02

The **Watchtower > Diagnostics** page now reads as merchant-facing status,
not internal wire state. A store view still building its baseline shows a
calm "Warming up" note instead of the same red "Needs attention" banner a
real anomaly gets, status and reason values are plain English ("Warming up",
"Routine check-in") instead of raw values like `INSUFFICIENT_DATA`, and the
internal Sequence Number column is gone.

### [1.29.0] - 2026-09-01

Stops `integration_health` reporting a healthy status for a store whose
watched set is empty. When the set is emptied the signal kept heartbeating its
last confirmed verdict, so a store that lost its selection reported `NORMAL`
every hour while nothing was being watched at all; it now reports
`INSUFFICIENT_DATA`, which keeps the platform's staleness sweep quiet without
claiming health.

If **Watchtower > Integrations** shows nothing selected, re-select the
integrations you want watched: an install that upgraded from 1.24.x or earlier
straight to 1.27.0 or later skipped the migration that carried the old
per-store-view sources over.

### [1.28.0] - 2026-08-28

Reworks the **Watchtower > Integrations** page after reviewing it on a store
with fourteen integrations rather than one. Integrations now lead with a
distinct name, so three Amasty extensions no longer all read "Amasty"; the
per-integration job list is an inline link instead of a heading repeated down
the page; every integration shows how often it was measured running, not only
the awkward ones; and there is a filter box plus a line naming anything you
watch that is currently failing.

Also stops offering cron jobs that have no class behind them. A crontab.xml
config_path naming a different job code than its own job name makes Magento
mint a schedule with nothing to execute, which can only ever look broken. On
one store that was catalog_product_alert, erroring every time it fired.

Upgrade: run `bin/magento setup:upgrade` and `bin/magento setup:di:compile`.
No configuration changes, and anything you already watch stays watched.

### [1.27.0] - 2026-08-27

Internal cleanup with no change to what the connector monitors or reports:
removes the per-store-view integration_health source model that the
Integrations page replaced in 1.25.0, along with its database table.

Upgrade: run `bin/magento setup:upgrade`. It drops
`watchtower_integration_health_config`, which is no longer read.

### [1.26.0] - 2026-08-27

Adds a **Custom integrations** section to **Watchtower > Integrations**, for
integrations that never run as a scheduled job, such as an ERP that pushes into
your store over the API. Your own code sends a `watchtower_integration_health`
event and the label appears there to be ticked. You can only select events we
have actually received, never type a name in, since a name with a typo would
look healthy forever while the integration behind it was dead.
`bin/magento watchtower:status` now names a failing custom integration too.

### [1.25.0] - 2026-08-27

_(Changelog truncated for .md surface. Full history on https://packagento.com/php4u/module-watchtower-m2-connector.)_

## Recent Versions

| Version | Released |
|---|---|
| v1.30.1 | 2026-09-02 |
| v1.30.0 | 2026-09-02 |
| v1.29.0 | 2026-09-01 |
| v1.28.0 | 2026-08-28 |
| v1.27.0 | 2026-08-27 |
| v1.26.0 | 2026-08-27 |
| v1.25.0 | 2026-08-27 |
| v1.24.1 | 2026-08-25 |
| v1.24.0 | 2026-08-25 |
| v1.23.0 | 2026-08-25 |

Showing 10 of 39 versions. Full release history on https://packagento.com/php4u/module-watchtower-m2-connector.

## Dependencies

### Require

| Package | Constraint |
|---|---|
| magento/framework | 103.0.* |
| magento/framework-amqp | 100.4.* |
| magento/framework-bulk | 101.0.* |
| magento/framework-message-queue | 100.4.* |
| magento/module-asynchronous-operations | 100.4.* |
| magento/module-backend | 102.0.* |
| magento/module-config | 101.2.* |
| magento/module-cron | 100.4.* |
| magento/module-store | 101.1.* |
| php | ~8.3.0\|\|~8.4.0\|\|~8.5.0 |

## Quality

Latest release (v1.30.1) fails the Packagento QA pipeline. Verdicts below are per-cell (Magento line × PHP version) for the matrixed tools, and run-once for the static / security tiers.


### Compatibility

Each Magento line is installed on its supported PHP versions, then the module is built (DI compile + static-content deploy). Cells show passed / failed / untested; staircase gaps render as `–`.

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | not tested | Pass | – | – |
| 2.4.8 | – | Pass | Pass | – |
| 2.4.9 | – | – | Pass | Pass |


### Code Quality

Advisory checks against the module's source. Never affect the Compatibility verdict — a phpcs finding can't make a module incompatible.

#### Static Analysis

Coding standards (phpcs), mess detection (phpmd), copy-pasted code (cpd), PHP cross-version compatibility, composer.json validity. Each runs once for the whole module.

| Tool | Status | Findings | Summary |
|---|---|---|---|
| PHPCS | Pass | 0 |  |
| PHPMD | Warning | 22 | 22 rule violations (UnusedPrivateField:20, ExcessiveClassLength:2) |
| Cpd | Warning | 18 | 18 duplicated chunks spanning 352 total lines (min-lines=5, min-tokens=70) |
| Composer validate | Pass | 0 |  |

#### PHPStan

Type-checks the module against a real Magento install. Re-runs per Magento + PHP version because resolvable symbols differ between releases.

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | N/A | 30 | – | – |
| 2.4.8 | – | 30 | 30 | – |
| 2.4.9 | – | – | 30 | 30 |


### Tests

Unit and integration suites run per Magento + PHP cell. Test failures speak to the module's behaviour, not its compatibility with a line, so they're reported here separately.

#### Unit Tests

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | N/A | N/A | – | – |
| 2.4.8 | – | N/A | N/A | – |
| 2.4.9 | – | – | N/A | N/A |

#### Integration Tests

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | N/A | N/A | – | – |
| 2.4.8 | – | N/A | N/A | – |
| 2.4.9 | – | – | N/A | N/A |


### Security

Dependency-advisory audit (composer audit) plus a source malware scan. A malware detection fails the version outright.

| Tool | Status | Findings | Summary |
|---|---|---|---|
| Composer audit | Pass | 0 |  |
| Malware scan | Pass | 0 |  |

## Licence and pricing

Free. A licence is still minted on checkout and bound to your project for Composer access — no payment step.

Refundable within 14 days of first purchase via https://packagento.com/account/refunds/.

## Install via Claude Code or any MCP client

The Packagento MCP server can run the licence + project + Composer steps above in one tool call:

```
purchase_and_install_packages(
  composer_names=["php4u/module-watchtower-m2-connector"],
  project_id="proj_xxx"
)
```

This handles cart, checkout, licence minting, project activation, and writes auth.json credentials. Connect a client with `claude mcp add packagento https://mcp.packagento.com`. Full setup at https://packagento.com/docs/mcp-setup.

## Vendor

Php4u Limited is a Magento 2 vendor on Packagento. See https://packagento.com/php4u.md for their full catalogue.

