承接 zeixcom/craftmonitoring 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

zeixcom/craftmonitoring

Composer 安装命令:

composer require zeixcom/craftmonitoring

包简介

Token-protected JSON endpoint exposing Craft version, plugin, environment, health and available-update info for an external monitoring dashboard.

README 文档

README

A token-protected JSON endpoint that exposes information about a Craft CMS installation (versions, plugins, environment, health, available updates) so an external dashboard can keep an overview of all your sites.

It is the agent side: each site runs this plugin and exposes a read-only report; a central dashboard polls every site and aggregates the results.

  • Requires Craft CMS 5.8+ and PHP 8.2+
  • Env-only configuration — no control-panel settings, no secrets in the database

Installation

composer require zeixcom/craftmonitoring
./craft plugin/install craft-monitoring

Configuration

Copy config.example.php (shipped with the plugin) to your project's config/craft-monitoring.php:

<?php

use craft\helpers\App;

return [
    'clientSecret' => App::env('MONITORING_CLIENT_SECRET'),
];

The plugin rejects any secret shorter than 32 characters (it returns 404 as if the endpoint did not exist). Generate a strong secret:

openssl rand -hex 32

That gives you 64 hex characters (~256 bits of entropy). Put it in .env:

MONITORING_CLIENT_SECRET="<paste-output-here>"

Treat this secret like an admin password — rotate it if it leaks, and never commit it. The matching value lives in the monitoring dashboard's config.

Endpoint

POST <cpTrigger>/monitoring/api/system-report

The endpoint is mounted on the CP URL manager, so it sits behind any IP allowlist, basic-auth, or WAF rule scoped to the CP host. If your CP trigger is admin, the URL is https://<site>/admin/monitoring/api/system-report. If you ever IP-restrict the CP at the webserver layer, the dashboard's egress IP must be on that allowlist.

Authentication

The endpoint accepts the secret in any of these places (first match wins):

Method Example
HTTP header X-Client-Secret: <secret>
Authorization bearer Authorization: Bearer <secret>
POST form parameter clientSecret=<secret>
JSON body field {"clientSecret": "<secret>"}

The URL query string is not accepted — secrets in URLs leak into webserver logs, CDN logs, and browser history.

# Header (recommended)
curl -X POST \
  -H "X-Client-Secret: $MONITORING_CLIENT_SECRET" \
  https://<site>/admin/monitoring/api/system-report

Response

A successful call returns 200 with a JSON body. The top-level reportVersion (currently 1) lets the dashboard evolve independently of the agent — bump it on any breaking change to the payload shape. The body contains reportVersion, generatedAt, craft, php, database, environment, system, updates, health, plugins, modules.

updates

Reads Craft's cached update info only — the monitoring request never makes an outbound call to the update server.

Field Meaning
infoCached false ⇒ Craft hasn't checked recently; the counts below are stale (0/false)
available Total available updates (Craft + plugins)
criticalAvailable A critical/security update is available
migrationsPending Code was updated but migrations haven't run

health

Field Meaning
queueTotalJobs Pending queue jobs (incl. failed); steady growth ⇒ stuck
deprecationWarnings Count of logged deprecation warnings
pendingProjectConfigChanges Project config YAML is out of sync with the database

Any health/update field is null if its probe threw.

Update timestamps in craft

Field Meaning
lastSystemOrPluginUpdateAt Last Craft CMS core or plugin update (use this in the dashboard)
systemInfoUpdatedAt Last craft_info write — includes project config applies

lastSystemOrPluginUpdateAt is derived from migration history (craft and plugin:* tracks) plus a version fingerprint stored in storage/runtime/monitoring/last-system-update.json. Project config applies that only bump systemInfoUpdatedAt are ignored.

Security posture

  • Timing-safe comparison via hash_equals().
  • Opaque failures: missing secret, invalid secret, wrong method, and unknown path all return the same 404 to unauthenticated callers — the endpoint is indistinguishable from a non-existent route. Failure reasons are still logged server-side at warning level.
  • CSRF disabled (this is a token-based API, not a session endpoint).
  • No caching: response sets Cache-Control: no-store.
  • Minimum secret length enforced at 32 chars.
  • No sensitive identifiers in the report: internal hostname, kernel version, and the Craft system UID are intentionally not emitted.

Dev-mode note: with CRAFT_DEV_MODE=true, Craft's debug error page may render slightly different bodies for different 404 sources. With dev mode off (production), all 404s render the same template and the distinction disappears. Monitor production, not dev.

Migrating from an in-repo craftmonitoring module

If you previously ran this as a copied Yii module:

  1. composer require zeixcom/craftmonitoring and ./craft plugin/install craft-monitoring.
  2. Remove the module from config/app.php (modules + bootstrap entries) and delete modules/craftmonitoring/.
  3. Rename config/monitoring.phpconfig/craft-monitoring.php (the plugin reads its config by handle). The MONITORING_CLIENT_SECRET env var is unchanged.

The route, payload, and storage/runtime/monitoring/ state file are identical, so the dashboard needs no changes.

License

MIT — see LICENSE.md.

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: mit
  • 更新时间: 2026-06-24

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固