PHP 业务监控指标采集

wen PHP项目 2

本文目录导读:

PHP 业务监控指标采集

  1. 基础监控类
  2. 业务指标监控
  3. 监控数据导出
  4. 集成示例
  5. 自动化部署和集成
  6. 配置和最佳实践

我来为您设计一个完整的PHP业务监控指标采集方案,包括核心代码实现和最佳实践。

基础监控类

1 指标采集器基类

<?php
namespace App\Monitor;
/**
 * 监控指标采集器基类
 */
abstract class BaseCollector
{
    protected array $metrics = [];
    protected float $startTime;
    protected float $endTime;
    public function start(): void
    {
        $this->startTime = microtime(true);
    }
    public function end(): void
    {
        $this->endTime = microtime(true);
    }
    abstract public function collect(): array;
    protected function duration(): float
    {
        return round(($this->endTime - $this->startTime) * 1000, 2);
    }
}

2 请求监控采集器

<?php
namespace App\Monitor\Collectors;
use App\Monitor\BaseCollector;
/**
 * HTTP请求监控
 */
class RequestCollector extends BaseCollector
{
    private array $requestData;
    public function __construct(array $requestData)
    {
        $this->requestData = $requestData;
        $this->start();
    }
    public function collect(): array
    {
        $this->end();
        return [
            'type' => 'request',
            'timestamp' => time(),
            'duration_ms' => $this->duration(),
            'method' => $this->requestData['method'] ?? 'GET',
            'path' => $this->requestData['path'] ?? '/',
            'status_code' => $this->requestData['status_code'] ?? 200,
            'ip' => $this->requestData['ip'] ?? '',
            'user_agent' => substr($this->requestData['user_agent'] ?? '', 0, 200),
            'memory_usage' => memory_get_usage(true),
            'memory_peak' => memory_get_peak_usage(true),
        ];
    }
}

3 数据库查询监控

<?php
namespace App\Monitor\Collectors;
use App\Monitor\BaseCollector;
/**
 * 数据库查询监控
 */
class DatabaseCollector extends BaseCollector
{
    private array $queryLog = [];
    private int $queryCount = 0;
    private float $totalTime = 0;
    public function addQuery(string $sql, array $bindings, float $time): void
    {
        $this->queryCount++;
        $this->totalTime += $time;
        $this->queryLog[] = [
            'sql' => $sql,
            'bindings' => $bindings,
            'time_ms' => $time
        ];
    }
    public function collect(): array
    {
        return [
            'type' => 'database',
            'timestamp' => time(),
            'query_count' => $this->queryCount,
            'total_time_ms' => round($this->totalTime, 2),
            'avg_time_ms' => $this->queryCount > 0 ? round($this->totalTime / $this->queryCount, 2) : 0,
            'slow_queries' => $this->getSlowQueries(),
            'queries' => $this->queryLog
        ];
    }
    private function getSlowQueries(int $threshold = 100): array
    {
        return array_filter($this->queryLog, fn($q) => $q['time_ms'] > $threshold);
    }
}

4 缓存监控

<?php
namespace App\Monitor\Collectors;
use App\Monitor\BaseCollector;
/**
 * 缓存监控
 */
class CacheCollector extends BaseCollector
{
    private array $cacheStats = [
        'hits' => 0,
        'misses' => 0,
        'writes' => 0,
        'deletes' => 0,
        'hit_keys' => [],
        'miss_keys' => []
    ];
    public function addHit(string $key): void
    {
        $this->cacheStats['hits']++;
        $this->cacheStats['hit_keys'][] = $key;
    }
    public function addMiss(string $key): void
    {
        $this->cacheStats['misses']++;
        $this->cacheStats['miss_keys'][] = $key;
    }
    public function addWrite(string $key): void
    {
        $this->cacheStats['writes']++;
    }
    public function addDelete(string $key): void
    {
        $this->cacheStats['deletes']++;
    }
    public function collect(): array
    {
        $total = $this->cacheStats['hits'] + $this->cacheStats['misses'];
        return [
            'type' => 'cache',
            'timestamp' => time(),
            'hits' => $this->cacheStats['hits'],
            'misses' => $this->cacheStats['misses'],
            'hit_rate' => $total > 0 ? round($this->cacheStats['hits'] / $total * 100, 2) : 0,
            'writes' => $this->cacheStats['writes'],
            'deletes' => $this->cacheStats['deletes'],
            'recent_hit_keys' => array_slice($this->cacheStats['hit_keys'], -10),
            'recent_miss_keys' => array_slice($this->cacheStats['miss_keys'], -10)
        ];
    }
}

业务指标监控

1 业务指标管理器

<?php
namespace App\Monitor;
/**
 * 业务监控中心
 */
class BusinessMonitor
{
    private static ?BusinessMonitor $instance = null;
    private array $counters = [];
    private array $gauges = [];
    private array $timers = [];
    private array $histograms = [];
    private array $events = [];
    private function __construct() {}
    private function __clone() {}
    public static function getInstance(): BusinessMonitor
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    /**
     * 计数器增加
     */
    public function increment(string $name, int $value = 1, array $labels = []): void
    {
        $key = $this->buildKey($name, $labels);
        if (!isset($this->counters[$key])) {
            $this->counters[$key] = [
                'name' => $name,
                'labels' => $labels,
                'value' => 0
            ];
        }
        $this->counters[$key]['value'] += $value;
    }
    /**
     * 设置瞬时值
     */
    public function gauge(string $name, $value, array $labels = []): void
    {
        $key = $this->buildKey($name, $labels);
        $this->gauges[$key] = [
            'name' => $name,
            'labels' => $labels,
            'value' => $value,
            'updated_at' => time()
        ];
    }
    /**
     * 计时器记录
     */
    public function timing(string $name, float $duration, array $labels = []): void
    {
        $key = $this->buildKey($name, $labels);
        if (!isset($this->timers[$key])) {
            $this->timers[$key] = [
                'name' => $name,
                'labels' => $labels,
                'values' => []
            ];
        }
        $this->timers[$key]['values'][] = $duration;
        // 限制保留最近1000个值
        if (count($this->timers[$key]['values']) > 1000) {
            array_shift($this->timers[$key]['values']);
        }
    }
    /**
     * 直方图记录
     */
    public function histogram(string $name, $value, array $labels = []): void
    {
        $key = $this->buildKey($name, $labels);
        if (!isset($this->histograms[$key])) {
            $this->histograms[$key] = [
                'name' => $name,
                'labels' => $labels,
                'values' => []
            ];
        }
        $this->histograms[$key]['values'][] = $value;
    }
    /**
     * 记录业务事件
     */
    public function event(string $name, array $data = []): void
    {
        $this->events[] = [
            'name' => $name,
            'data' => $data,
            'timestamp' => time()
        ];
        // 保留最近100个事件
        if (count($this->events) > 100) {
            array_shift($this->events);
        }
    }
    /**
     * 获取所有指标
     */
    public function getMetrics(): array
    {
        return [
            'counters' => array_values($this->counters),
            'gauges' => array_values($this->gauges),
            'timers' => array_map([$this, 'processTimers'], $this->timers),
            'histograms' => array_map([$this, 'processHistograms'], $this->histograms),
            'events' => $this->events
        ];
    }
    /**
     * 重置所有指标
     */
    public function reset(): void
    {
        $this->counters = [];
        $this->gauges = [];
        $this->timers = [];
        $this->histograms = [];
        $this->events = [];
    }
    private function buildKey(string $name, array $labels): string
    {
        return $name . ':' . json_encode($labels);
    }
    private function processTimers(array $timer): array
    {
        $values = $timer['values'];
        $count = count($values);
        return [
            'name' => $timer['name'],
            'labels' => $timer['labels'],
            'count' => $count,
            'sum' => array_sum($values),
            'avg' => $count > 0 ? array_sum($values) / $count : 0,
            'min' => $count > 0 ? min($values) : 0,
            'max' => $count > 0 ? max($values) : 0,
            'p50' => $this->percentile($values, 50),
            'p95' => $this->percentile($values, 95),
            'p99' => $this->percentile($values, 99)
        ];
    }
    private function processHistograms(array $histogram): array
    {
        $values = $histogram['values'];
        $count = count($values);
        return [
            'name' => $histogram['name'],
            'labels' => $histogram['labels'],
            'count' => $count,
            'sum' => array_sum($values),
            'avg' => $count > 0 ? array_sum($values) / $count : 0,
            'min' => $count > 0 ? min($values) : 0,
            'max' => $count > 0 ? max($values) : 0,
            'buckets' => $this->createBuckets($values)
        ];
    }
    private function percentile(array $values, int $percentile): float
    {
        if (empty($values)) return 0;
        sort($values);
        $index = ceil($percentile / 100 * count($values)) - 1;
        return $values[$index];
    }
    private function createBuckets(array $values): array
    {
        $buckets = [];
        $limits = [
            10, 25, 50, 100, 250, 500, 1000, 2500, 5000
        ];
        foreach ($limits as $limit) {
            $buckets[$limit] = count(array_filter($values, fn($v) => $v <= $limit));
        }
        // 超过最大限制的值
        $buckets['+Inf'] = count($values);
        return $buckets;
    }
}

监控数据导出

1 Prometheus格式导出

<?php
namespace App\Monitor\Exporters;
use App\Monitor\BusinessMonitor;
/**
 * Prometheus格式导出器
 */
class PrometheusExporter
{
    private BusinessMonitor $monitor;
    public function __construct(BusinessMonitor $monitor)
    {
        $this->monitor = $monitor;
    }
    public function export(): string
    {
        $metrics = $this->monitor->getMetrics();
        $output = '';
        // 导出计数器
        foreach ($metrics['counters'] as $counter) {
            $output .= $this->formatCounter($counter);
        }
        // 导出Gauges
        foreach ($metrics['gauges'] as $gauge) {
            $output .= $this->formatGauge($gauge);
        }
        // 导出Timers
        foreach ($metrics['timers'] as $timer) {
            $output .= $this->formatTimer($timer);
        }
        // 导出Histograms
        foreach ($metrics['histograms'] as $histogram) {
            $output .= $this->formatHistogram($histogram);
        }
        return $output;
    }
    private function formatLabels(array $labels): string
    {
        if (empty($labels)) return '';
        $pairs = [];
        foreach ($labels as $key => $value) {
            $pairs[] = sprintf('%s="%s"', $key, $value);
        }
        return '{' . implode(',', $pairs) . '}';
    }
    private function formatCounter(array $counter): string
    {
        $line = sprintf(
            "# TYPE %s counter\n%s%s %d\n",
            $counter['name'],
            $counter['name'],
            $this->formatLabels($counter['labels']),
            $counter['value']
        );
        return $line;
    }
    private function formatGauge(array $gauge): string
    {
        $line = sprintf(
            "# TYPE %s gauge\n%s%s %s\n",
            $gauge['name'],
            $gauge['name'],
            $this->formatLabels($gauge['labels']),
            $gauge['value']
        );
        return $line;
    }
    private function formatTimer(array $timer): string
    {
        $output = '';
        // 主指标
        $output .= sprintf(
            "# TYPE %s_seconds summary\n",
            $timer['name']
        );
        $output .= sprintf(
            "%s_sum%s %f\n",
            $timer['name'],
            $this->formatLabels($timer['labels']),
            $timer['sum']
        );
        $output .= sprintf(
            "%s_count%s %d\n",
            $timer['name'],
            $this->formatLabels($timer['labels']),
            $timer['count']
        );
        // 百分位数
        foreach (['p50' => 0.5, 'p95' => 0.95, 'p99' => 0.99] as $percent => $quantile) {
            $output .= sprintf(
                "%s%s{%s,quantile=\"%s\"} %f\n",
                $timer['name'],
                '_seconds',
                $this->formatLabels($timer['labels']),
                $quantile,
                $timer[$percent]
            );
        }
        return $output;
    }
    private function formatHistogram(array $histogram): string
    {
        $output = '';
        $labels = $this->formatLabels($histogram['labels']);
        $output .= sprintf(
            "# TYPE %s histogram\n",
            $histogram['name']
        );
        // 桶数据
        foreach ($histogram['buckets'] as $le => $count) {
            $output .= sprintf(
                "%s_bucket{%s,le=\"%s\"} %d\n",
                $histogram['name'],
                $labels,
                $le,
                $count
            );
        }
        // 计数和总和
        $output .= sprintf(
            "%s_bucket{%s,le=\"+Inf\"} %d\n",
            $histogram['name'],
            $labels,
            $histogram['count']
        );
        $output .= sprintf(
            "%s_sum%s %f\n",
            $histogram['name'],
            $labels,
            $histogram['sum']
        );
        $output .= sprintf(
            "%s_count%s %d\n",
            $histogram['name'],
            $labels,
            $histogram['count']
        );
        return $output;
    }
}

2 JSON导出器

<?php
namespace App\Monitor\Exporters;
use App\Monitor\BusinessMonitor;
/**
 * JSON格式导出器
 */
class JsonExporter
{
    private BusinessMonitor $monitor;
    public function __construct(BusinessMonitor $monitor)
    {
        $this->monitor = $monitor;
    }
    public function export(bool $pretty = false): string
    {
        $metrics = $this->monitor->getMetrics();
        // 添加系统资源信息
        $metrics['system'] = [
            'memory' => [
                'usage' => memory_get_usage(true),
                'peak' => memory_get_peak_usage(true),
                'limit' => ini_get('memory_limit')
            ],
            'cpu' => [
                'usage' => sys_getloadavg()
            ],
            'server_time' => date('c'),
            'php_version' => PHP_VERSION
        ];
        return json_encode(
            $metrics,
            $pretty ? JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE : 0
        );
    }
}

集成示例

1 中间件集成

<?php
namespace App\Http\Middleware;
use Closure;
use App\Monitor\BusinessMonitor;
use App\Monitor\Collectors\RequestCollector;
use App\Monitor\Collectors\DatabaseCollector;
use Illuminate\Support\Facades\DB;
/**
 * 监控中间件
 */
class MonitorMiddleware
{
    private BusinessMonitor $monitor;
    private RequestCollector $requestCollector;
    private DatabaseCollector $dbCollector;
    public function __construct(BusinessMonitor $monitor)
    {
        $this->monitor = $monitor;
        $this->requestCollector = new RequestCollector(request()->all());
        $this->dbCollector = new DatabaseCollector();
        // 启用数据库查询日志
        DB::enableQueryLog();
    }
    public function handle($request, Closure $next)
    {
        $startTime = microtime(true);
        // 记录请求开始
        $this->monitor->increment('http_requests_total');
        // 处理业务
        $response = $next($request);
        // 收集数据库查询
        $this->collectDatabaseMetrics();
        // 收集请求指标
        $this->collectRequestMetrics($response);
        // 将监控数据附加到响应
        $this->attachMetricsToResponse($response);
        return $response;
    }
    private function collectDatabaseMetrics(): void
    {
        $queries = DB::getQueryLog();
        foreach ($queries as $query) {
            $this->dbCollector->addQuery(
                $query['query'],
                $query['bindings'],
                $query['time']
            );
        }
        $metrics = $this->dbCollector->collect();
        // 记录到全局监控
        $this->monitor->gauge('db_query_count', $metrics['query_count']);
        $this->monitor->gauge('db_total_time', $metrics['total_time_ms']);
        $this->monitor->gauge('db_avg_time', $metrics['avg_time_ms']);
        if (!empty($metrics['slow_queries'])) {
            $this->monitor->event('slow_queries', [
                'count' => count($metrics['slow_queries']),
                'queries' => $metrics['slow_queries']
            ]);
        }
    }
    private function collectRequestMetrics($response): void
    {
        $duration = microtime(true) - $this->requestCollector->startTime;
        // 按状态码分类
        $statusCode = $response->getStatusCode();
        $this->monitor->increment(
            'http_requests_total',
            1,
            ['status_code' => $statusCode]
        );
        // 记录请求耗时
        $this->monitor->timing(
            'http_request_duration_seconds',
            $duration,
            ['method' => request()->method(), 'status_code' => $statusCode]
        );
        // 记录内存使用
        $this->monitor->gauge('memory_usage', memory_get_usage(true));
        $this->monitor->gauge('memory_peak', memory_get_peak_usage(true));
    }
    private function attachMetricsToResponse($response): void
    {
        if (method_exists($response, 'headers')) {
            $metrics = $this->monitor->getMetrics();
            $response->headers->set('X-Monitor-Timestamp', time());
            $response->headers->set('X-Monitor-Duration', 
                round((microtime(true) - $this->requestCollector->startTime) * 1000, 2)
            );
        }
    }
}

2 业务逻辑监控示例

<?php
namespace App\Services;
use App\Monitor\BusinessMonitor;
/**
 * 订单服务 - 业务监控示例
 */
class OrderService
{
    private BusinessMonitor $monitor;
    public function __construct()
    {
        $this->monitor = BusinessMonitor::getInstance();
    }
    public function createOrder(array $orderData)
    {
        $startTime = microtime(true);
        try {
            // 业务处理
            $order = $this->processOrder($orderData);
            // 监控成功
            $this->monitor->increment('orders_created_total');
            $this->monitor->increment('orders_total', 1, [
                'type' => $order['type'],
                'channel' => $order['channel']
            ]);
            // 记录订单金额
            $this->monitor->histogram(
                'order_amount',
                $order['amount'],
                ['currency' => $order['currency']]
            );
            // 记录处理时间
            $duration = microtime(true) - $startTime;
            $this->monitor->timing('order_create_duration', $duration);
            // 监控订单状态
            $this->monitor->gauge('active_orders', $this->getActiveOrders());
            return $order;
        } catch (\Exception $e) {
            // 监控失败
            $this->monitor->increment('orders_failed_total', 1, [
                'error' => get_class($e),
                'stage' => 'create'
            ]);
            // 记录异常事件
            $this->monitor->event('order_error', [
                'order_id' => $orderData['id'] ?? null,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            throw $e;
        }
    }
    public function cancelOrder(int $orderId)
    {
        // 监控取消操作
        $this->monitor->increment('orders_cancelled_total');
        $reason = request()->input('reason', 'unknown');
        $this->monitor->increment('orders_cancelled_total', 1, [
            'reason' => $reason
        ]);
        // 其他业务逻辑...
    }
    private function processOrder(array $orderData)
    {
        // 模拟订单处理
        return array_merge($orderData, [
            'id' => rand(1000, 9999),
            'status' => 'created',
            'created_at' => time()
        ]);
    }
    private function getActiveOrders()
    {
        // 模拟获取活跃订单数
        return rand(10, 100);
    }
}

3 监控端点路由

<?php
// routes/web.php 或 routes/api.php
use App\Monitor\BusinessMonitor;
use App\Monitor\Exporters\PrometheusExporter;
use App\Monitor\Exporters\JsonExporter;
// 监控指标端点(需要认证)
Route::get('/metrics', function () {
    // 认证检查
    if (!auth()->user()->isAdmin()) {
        abort(403);
    }
    $monitor = BusinessMonitor::getInstance();
    $exporter = new PrometheusExporter($monitor);
    return response($exporter->export(), 200, [
        'Content-Type' => 'text/plain; version=0.0.4'
    ]);
})->middleware('auth');
// JSON格式监控端点
Route::get('/metrics/json', function () {
    if (!auth()->user()->isAdmin()) {
        abort(403);
    }
    $monitor = BusinessMonitor::getInstance();
    $exporter = new JsonExporter($monitor);
    return response($exporter->export(true), 200, [
        'Content-Type' => 'application/json'
    ]);
})->middleware('auth');
// 监控端点(用于Prometheus)
Route::get('/health', function () {
    return response()->json([
        'status' => 'ok',
        'timestamp' => time(),
        'memory' => memory_get_usage(true),
        'load' => sys_getloadavg()
    ]);
});

自动化部署和集成

1 Docker部署监控

version: '3.8'
services:
  app:
    image: php:8.2-fpm
    volumes:
      - ./:/var/www/html
    environment:
      - APP_MONITOR_ENABLED=true
  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    ports:
      - "9090:9090"
  grafana:
    image: grafana/grafana:latest
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana
  node-exporter:
    image: prom/node-exporter:latest
    ports:
      - "9100:9100"
  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    ports:
      - "8080:8080"
volumes:
  prometheus_data:
  grafana_data:

2 Prometheus配置

# prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s
alerting:
  alertmanagers:
    - static_configs:
        - targets: []
rule_files:
  - "alerts.yml"
scrape_configs:
  - job_name: 'php-app'
    static_configs:
      - targets: ['app:8080']
    metrics_path: /metrics
    scrape_interval: 10s
  - job_name: 'node'
    static_configs:
      - targets: ['node-exporter:9100']
  - job_name: 'docker'
    static_configs:
      - targets: ['cadvisor:8080']
  - job_name: 'mysql'
    static_configs:
      - targets: ['mysql-exporter:9104']

3 监控告警规则

# alerts.yml
groups:
  - name: php_alerts
    rules:
      - alert: HighErrorRate
        expr: sum(rate(http_requests_total{status_code=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) > 0.05
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "High HTTP error rate"
          description: "Error rate is {{ $value }}%"
      - alert: SlowResponse
        expr: histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le)) > 2
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Slow HTTP responses"
          description: "P95 response time is over 2 seconds"
      - alert: HighMemoryUsage
        expr: memory_usage / memory_peak > 0.8
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "High memory usage"
          description: "Memory usage is {{ $value }}%"

配置和最佳实践

1 配置文件

<?php
// config/monitor.php
return [
    'enabled' => env('APP_MONITOR_ENABLED', true),
    'export' => [
        'format' => env('MONITOR_EXPORT_FORMAT', 'prometheus'),
        'endpoint' => '/metrics',
        'auth' => [
            'enabled' => true,
            'token' => env('MONITOR_AUTH_TOKEN')
        ]
    ],
    'collectors' => [
        'request' => true,
        'database' => true,
        'cache' => true,
        'business' => true
    ],
    'thresholds' => [
        'slow_query' => 100, // ms
        'slow_request' => 500, // ms
        'error_rate' => 0.05 // 5%
    ],
    'storage' => [
        'driver' => 'redis', // redis, file, array
        'ttl' => 86400, // 24 hours
        'path' => storage_path('monitor') // for file driver
    ]
];

2 最佳实践清单

<?php
/**
 * 监控最佳实践
 */
class MonitorBestPractices
{
    /**
     * 1. 命名规范
     */
    public function namingConventions(): void
    {
        // 计数器:_total 后缀
        $this->monitor->increment('http_requests_total');
        // 时间:_duration_seconds 后缀
        $this->monitor->timing('order_create_duration_seconds', $duration);
        // 数值:_count 后缀
        $this->monitor->gauge('active_orders_count', $count);
        // 非官方但常用:_total, _sum, _bucket
        // 使用 namespace: 应用名_模块名_指标名
        $this->monitor->increment('app_checkout_orders_total');
    }
    /**
     * 2. 标签使用
     */
    public function labelUsage(): void
    {
        // 少用标签,但要有足够维度
        $this->monitor->increment('orders_total', 1, [
            'channel' => 'mobile',  // 渠道
            'status' => 'paid'      // 状态
        ]);
        // 避免高基数标签
        // 不要使用:order_id, uuid, timestamp
        // 预定义标签
        $this->monitor->increment('requests_total', 1, [
            'method' => 'GET',
            'path' => '/api/orders',
            'status' => '200'
        ]);
    }
    /**
     * 3. 采样策略
     */
    public function samplingStrategy(): void
    {
        // 1% 采样
        if (rand(1, 100) === 1) {
            $this->monitor->timing('payment_duration', $duration);
        }
        // 错误全量记录
        if ($error) {
            $this->monitor->increment('errors_total');
            $this->monitor->event('error_details', $errorData);
        }
    }
    /**
     * 4. 性能考虑
     */
    public function performanceConsiderations(): void
    {
        // 使用内存存储,异步导出
        $monitor = BusinessMonitor::getInstance();
        // 限制数据结构大小
        // - 计数器:无限制
        // - Gauges:数量控制
        // - Timers:保留最近1000个
        // - Events:保留最近100个
        // 避免在循环中调用监控
        foreach ($largeArray as $item) {
            // 批量处理,而不是逐条记录
        }
        // 批量导出
        if ($batchSize >= 100) {
            $this->flushToStorage();
        }
    }
    /**
     * 5. 错误处理
     */
    public function errorHandling(): void
    {
        try {
            // 业务代码
        } catch (\Exception $e) {
            // 记录错误但不影响业务
            try {
                $this->monitor->increment('errors_total', 1, [
                    'type' => get_class($e)
                ]);
            } catch (\Throwable $monitorError) {
                // 监控失败不应影响主流程
                error_log('Monitor error: ' . $monitorError->getMessage());
            }
            throw $e;
        }
    }
    /**
     * 6. 数据保护
     */
    public function dataProtection(): void
    {
        // 不记录敏感数据
        $this->monitor->event('user_login', [
            // 'password' => $password,  // NEVER!
            // 'ssn' => $ssn,           // NEVER!
            'user_id' => $userId,
            'ip' => $ip
        ]);
        // 对用户数据进行脱敏
        $safeEmail = substr($email, 0, 3) . '***@' . substr(strrchr($email, '@'), 1);
    }
}

这个完整的PHP业务监控方案包括:

  1. 基础监控采集器 - 请求、数据库、缓存监控
  2. 业务指标管理器 - 计数器、计时器、直方图等
  3. 多种导出格式 - Prometheus、JSON
  4. 集成示例 - 中间件、业务服务
  5. 自动化和部署 - Docker、Prometheus、Grafana
  6. 最佳实践 - 命名、标签、采样、安全性

您可以根据实际需求选择使用的组件,并进行适当调整。

抱歉,评论功能暂时关闭!