定制 v4codes/observer 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

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

v4codes/observer

最新稳定版本:v0.1.1

Composer 安装命令:

composer require v4codes/observer

包简介

Self-hosted APM for Laravel with zero external dependencies. Parent/child observability over native Laravel events, stored in your existing RDBMS.

README 文档

README

Zero external dependencies. Parent/child observability built entirely on native Laravel events, stored in the relational database you already run (MySQL / MariaDB / PostgreSQL).

Observer is a single installable package that gives you full application-performance coverage — requests, queries, jobs, exceptions, logs, mail, notifications, cache, commands, scheduled tasks, outbound HTTP, users and host metrics — with correlated traces, exception grouping into issues, aggregated dashboards and internal alerting. No SaaS, no third-party agent, no external service.

Screenshots

The parent's self-hosted dashboard (Blade + Tailwind, no build step):

Fleet overview Project dashboard
Fleet overview Project dashboard
Trace timeline (N+1 flagged) Issues
Trace timeline Issues

How it works

One app runs as the parent (ingests, stores, aggregates, exposes read contracts). Every other app runs as a child (observes its own lifecycle via native Laravel events and ships batches to the parent). Capture is fully decoupled from delivery:

request lifecycle ──> in-memory buffer ──(terminate)──> obs_outbox ──(observer:ship daemon)──> parent /ingest

The request path never does network I/O or heavy serialization. If the parent is offline the outbox accumulates and drains later — the host app never breaks (RNF-2).

Getting started

You need one parent app (collects + shows the data) and one or more children (the apps you want to observe). The same package powers both — only the mode differs.

Step 1 — Set up the parent

composer require v4codes/observer
php artisan observer:install --parent   # writes .env, publishes, migrates

That's it — the parent is in parent mode, the dashboard is live at https://apm.example.com/observer, and the maintenance schedule (aggregate / evaluate / partition / prune) is auto-registered. Just make sure the Laravel scheduler cron is running (Forge configures it by default):

* * * * * cd /path && php artisan schedule:run >> /dev/null 2>&1

Step 2 — Create a project (in the dashboard)

Open the dashboard, go to Manage projects, and create one project per child. On create, the panel shows a ready-to-run install command (the secret is shown only once) — copy it. You can also do it from the CLI:

php artisan observer:project "My App"            # scheduler delivery (default)
php artisan observer:project "My App" --delivery=daemon

Step 3 — Connect a child

Paste the command from Step 2 into the child app (or into your Forge deploy script — it is fully non-interactive):

php artisan observer:install --child \
  --parent-url=https://apm.example.com \
  --project=my-app \
  --token=Yz3... \
  --secret=9aF...

This writes the child's .env, publishes, migrates, and — with delivery=scheduler (the default) — auto-registers observer:ship --once every minute. With the scheduler cron already running, nothing else is needed.

High volume? Create the project with --delivery=daemon (or set OBSERVER_DELIVERY=daemon) and supervise php artisan observer:ship under Supervisor / a Forge Daemon for near-real-time delivery.

Step 4 — Verify

Generate some traffic on the child (load a page, run a job). Within a minute you'll see the project light up on the parent's overview, with traces, slow queries, issues and host metrics. Tune what's captured and how long it's kept in config/observer.php.

Tuning knobs (most common)

OBSERVER_SAMPLE_REQUEST=1.0        # keep 100% of request traces (lower for high volume)
OBSERVER_ALWAYS_KEEP_MS=1000       # always keep traces slower than this, regardless of sampling
OBSERVER_RAW_RETENTION_DAYS=7      # how long raw events live
OBSERVER_AGG_RETENTION_DAYS=90     # how long aggregates live
OBSERVER_DELIVERY=scheduler        # scheduler (cron) or daemon (supervised observer:ship)

Disable a noisy recorder entirely, or sample a category, in config/observer.php (child.recorders and child.sample.type_gate).

Commands

Command Mode What it does
observer:install --parent|--child both Write .env, publish config + migrations, migrate
observer:project {name} parent Create a project (mints token + secret); --list to list
observer:ship child Drain the outbox and ship batches (daemon; --once for the scheduler)
observer:aggregate parent Roll raw events into aggregates + group exceptions into issues
observer:evaluate parent Evaluate heartbeats/issues, open/resolve incidents, fire alerts
observer:partition parent Ensure/pre-create obs_events partitions (MySQL)
observer:prune parent Apply retention (drop old raw events + aggregates)

The parent's maintenance schedule and the child's shipping (scheduler delivery) are auto-registered by the package — you only need the Laravel scheduler cron running. Set OBSERVER_PARENT_SCHEDULE=false / OBSERVER_CHILD_SCHEDULE=false to opt out and wire them by hand.

Dashboard

The parent serves a self-contained dashboard (Blade + Tailwind via CDN — no build step, no NPM, no Composer package outside Laravel core) at the route prefix:

https://apm.example.com/observer

It reads exclusively through the read layer (ObserverRepository / DashboardRepository) and covers an overview of all projects (health, throughput, error rate, p95), per-project drill-down (requests, slow queries + N+1, jobs/queues, cache hit rate, schedule + heartbeats, outgoing HTTP, logs, mail/notifications, host metrics), grouped issues with stack traces, and a span-waterfall trace viewer. Access is guarded by the viewObserver ability — define it in a service provider to open it beyond the local environment:

use Illuminate\Support\Facades\Gate;

Gate::define('viewObserver', fn ($user) => $user->isAdmin());

Write actions (creating/rotating projects, triggering maintenance commands) are guarded by a separate manageObserver ability. Define it the same way:

use Illuminate\Support\Facades\Gate;

Gate::define('manageObserver', fn ($user) => $user->isAdmin());

Alerting

Incidents (a dead scheduler, an error spike) fire through internal channels listed in observer.alerts.channels. By default that's the Database channel (the incident surfaces in the dashboard) and the Log channel. To also send e-mail, enable the mail channel and set recipients — it uses the parent app's own mailer (config/mail.php / your .env SMTP), no separate transport:

OBSERVER_ALERT_EMAILS=ops@example.com,oncall@example.com
// config/observer.php — observer.alerts.channels
\Stochero\Observer\Alerting\Channels\MailAlertChannel::class,

Quality

composer test       # PHPUnit — acceptance criteria from the spec (§15) + dashboard render
composer phpstan    # PHPStan at level max (Larastan), green

Static analysis runs at level max with no baseline — zero errors. mixed from config(), json_decode() and query-builder rows is narrowed at the edges with typed helpers (Support\Cast, Support\Json) and precise array-shape / generic annotations, so the type information flows all the way through. PHPStan and Larastan are dev-only — they don't affect the zero runtime-dependency guarantee.

See config/observer.php for the full configuration surface and docs/ARCHITECTURE.md for the design.

Scaling & databases

  • MySQL / MariaDB: obs_events is RANGE-partitioned on occurred_date; observer:prune drops whole partitions (cheap at any volume).
  • PostgreSQL / SQLite: a single table pruned with chunked DELETEs — fine for moderate volume; for very high volume prefer MySQL partitioning.
  • The parent ingest is a single write path. Past roughly 5–10M events/day on one node, scale the parent's database (faster disk, more IOPS) first.
  • High shipping volume? Create the project with --delivery=daemon and lower observer:ship --batch if individual traces are large — the parent rejects a POST over OBSERVER_MAX_BODY_BYTES or OBSERVER_MAX_EVENTS with HTTP 413.

Security

  • Children authenticate with a per-project token and sign each batch body with an HMAC-SHA256 secret (timing-safe comparison, anti-replay window). Secrets are stored encrypted and shown only once.
  • Sensitive keys (observer.child.scrub) are redacted from query bindings, request input, headers, log context and exception messages; stack-trace file paths are relativized to the app base path.
  • Dashboard read access is gated by the viewObserver ability; write actions (managing projects, triggering maintenance) by a separate manageObserver. Define both in a service provider to open access beyond local.

License

MIT.

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-09

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固