igaster / laravel-metrics
描述
dev-master
2020-04-01 05:46 UTC
Requires
- php: >=7.1
- laravel/framework: >=5.6
Requires (Dev)
- orchestra/testbench: ^4.0|^5.0
- phpunit/phpunit: ^8.0
This package is auto-updated.
Last update: 2024-08-29 05:29:22 UTC
README
介绍
配置
示例提供者
这是一个负责配置指标并提供样本的类。
use Carbon\Carbon; use Igaster\LaravelMetrics\Models\Metric; use Igaster\LaravelMetrics\Services\Metrics\MetricsInterface; use Igaster\LaravelMetrics\Services\Metrics\Sample; use Igaster\LaravelMetrics\Services\Metrics\Segments\SegmentLevel; class ExampleSamplesProvider implements MetricsInterface { /** * Register a list of Metrics that this class will provide. * Returns an array of Metric */ public function registerMetrics(): array { // ... } /** * Return an array of Samples that have a timestamp >= $from (inclusive) and < $until (exclusive) * It will be called once for each $metric, every time that it's shortest sampling period has been completed (ie every minute/day etc) */ public function sample(Metric $metric, Carbon $from): array { // ... }
示例
registerMetrics()
:
此方法配置任意数量的指标
public function registerMetrics(): array { return [ Metric::factory('metric-slug', [ SegmentLevel::HOUR, // Aggregation levels SegmentLevel::DAY, SegmentLevel::MONTH, ], [ 'size', // Partition names (keys) 'color', ]), ]; }
sample()
:
此方法将在每个指标最低采样段的末尾执行(例如,每小时/每天等)。它应该返回一个数组,包含在此期间创建的每个事件生成的样本。
public function sample(Metric $metric, Carbon $from, Carbon $until): array { return [ new Sample(4, [ // Each sample may have a value 'size' => 'large', 'color' => 'blue', ]), new Sample(5, [ 'size' => 'large', // a partition can be skipped. Means "any value" ]), new Sample(6, [ 'size' => 'large', 'color' => null, // Null is a normal value. it is not the same with skipping it (=any value) ]), // ... ]; }
来自 Eloquent 模型的样本
您可以在想要采样的模型中使用 HasMetricsTrait
。这个特质自动化了 Eloquent 查询,并提供了一个方便的接口将您的模型转换为样本。
注意:此步骤是 可选的。您可以直接在模型中实现 MetricsInterface
,如前所述。
这是一个示例
use Igaster\LaravelMetrics\Models\Metric; use Igaster\LaravelMetrics\Services\Metrics\HasMetricsTrait; use Igaster\LaravelMetrics\Services\Metrics\MetricsInterface; use Igaster\LaravelMetrics\Services\Metrics\Sample; use Igaster\LaravelMetrics\Services\Metrics\Segments\SegmentLevel; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; class ExampleSamplesModel extends Model implements MetricsInterface { use HasMetricsTrait; /** @var string $samplesTimestampColumn Sets column that will be treated as a timestamp */ private $samplesTimestampColumn = 'created_at'; // This is the default. Declaration can be omitted /** * Register a list of Metrics that this class will provide. * Returns an array of Metric */ public function registerMetrics(): array { return [ Metric::factory('metric-slug', [ SegmentLevel::HOUR, SegmentLevel::DAY, ], [ 'color' ]), ]; } /** * You can customize the query that will get the sampled items. * You don't have filter items based on their timestamp for current time slot. * These will be automatically selected based on the "created_at" value */ public function getSamplesQuery(Metric $metric): Builder { return self::query() ->where('status','=','published') // Add your business logic... ->select([ 'quantity', // It is a good practice to get only the columns that are required in makeSample() 'color' ]); } /** * Transforms current eloquent model to a Sample */ public function makeSample(): Sample { return new Sample( $this->quantity, [ 'color' => $this->color, ] ); } }
获取样本
采样是一个两步过程
1) 创建一个 "Sampler" 对象
- 每个采样器都附属于一个 "样本提供者",该提供者将以常规的时间间隔进行检查。
- 您可以通过以下方式创建采样器:a) 从对象实例创建,或 b) 从模型类名创建。
// a) Create a sampler from an object instance: $samplesProvider = new ExampleSamplesProvider(); // ExampleSamplesProvider implements MetricsInterface. $sampler = new MetricSampler($samplesProvider); // b) Create a sampler from a Model: $sampler = new MetricSampler(SomeModel::class); // SomeModel implements MetricsInterface.
2) 获取并处理某些时间段的样本。
必须满足以下要求
- 必须完成时间槽才能获取有效结果(例如,您可以从上一小时获取样本,但不能从当前小时获取)
- 时间是线性的:时间槽必须按顺序处理。时间槽内的样本可以按任何顺序获取,因为它们作为一批处理。
// Sample a single timeslot that starts at a timestamp. // If a metric doesn't have a time-slot that starts at current timestamp, it will be skipped. $sampler->sample($timestamp); // Sample for a period of time $sampler->samplePeriod($from, $until); // Continue sampling since last sample was taken, and stop at some timestamp. // If this is the 1st time that a metric is processed then current timestamp is initialized as starting time // Only metrics that have a whole time-slot completed since last execution will be executed. // $until doesn't have to match with the end of a time-slot. The end of the latest time-slot for each metric will be calculated and used. // You should design your system to call this method in regular intervals $sampler->sampleUntil($until);
查询指标
计数 & 求和
获取一段时间内的样本的计数/求和。可以可选地指定分区
// Get count of events that occurred between two timestamps // and have size=small, and color=red Metric::get('metric-slug')->count( Carbon::parse('2020-01-01 00:00:00'), Carbon::parse('2020-01-01 02:00:00'), [ 'size' => 'small', 'color' => 'red' ] )); // Get total (sum) of events values that occurred between two timestamps // and have size=small, and color=ANY (includes all color values) Metric::get('metric-slug')->value( Carbon::parse('2020-01-01 00:00:00'), Carbon::parse('2020-01-01 02:00:00'), [ 'size' => 'small', ] )); // Get count of events that occurred between two timestamps // and belong to any partition Metric::get('metric-slug')->count( Carbon::parse('2020-01-01 00:00:00'), Carbon::parse('2020-01-01 02:00:00') ));
按小时/天/月等获取
以下方法在 Metric 类中可用
$metric = Metric::get('metric-slug'); $metric->getByMinute($from, $until, $partitions); $metric->getByHour($from, $until, $partitions); $metric->getByDay($from, $until, $partitions); $metric->getByMonth($from, $until, $partitions); $metric->getByYear($from, $until, $partitions);
示例
Metric::get('metric-slug')->getByDay( Carbon::parse('2020-01-01 00:00:00'), Carbon::parse('2020-01-02 10:00:00'), [ 'color' => 'red', ] ); // Result is a collection for every day: // [ // [ // "from" => "2020-01-01 00:00:00", // "until" => "2020-01-02 00:00:00", // "count" => 72, // "value" => 144.0, // ], // [ // "from" => "2020-01-02 00:00:00", // "until" => "2020-01-03 00:00:00", // "count" => 72, // "value" => 144.0, // ], // ... // ];