-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Expand file tree
/
Copy pathBuild.php
More file actions
85 lines (77 loc) · 4.05 KB
/
Copy pathBuild.php
File metadata and controls
85 lines (77 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?php
namespace Appwrite\Usage;
use Appwrite\Event\Message\Usage as UsageMessage;
use Appwrite\Event\Publisher\Usage as UsagePublisher;
use Utopia\Config\Config;
use Utopia\Database\Document;
/**
* Emits build usage/billing metrics for a completed deployment. Shared by the
* Jobs worker and the Builds worker, so a build is counted identically whether
* it finished on the jobs-service or failed before reaching it.
*/
final class Build
{
/**
* Record the metrics for a terminal deployment (status 'ready' or 'failed')
* onto the usage context and publish them.
*/
public static function publish(
Context $usage,
Document $resource,
Document $deployment,
Document $project,
UsagePublisher $publisherForUsage,
): void {
$spec = Config::getParam('specifications')[$resource->getAttribute('buildSpecification', APP_COMPUTE_SPECIFICATION_DEFAULT)];
$cpus = (int) ($spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT);
$memory = (int) ($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT);
$resourceType = $deployment->getAttribute('resourceType');
$buildDuration = (int) $deployment->getAttribute('buildDuration', 0) * 1000;
$mbSeconds = (int) ($memory * $deployment->getAttribute('buildDuration', 0) * $cpus);
// Without a start stamp buildDuration falls back to wall clock since the
// deployment was created, which would bill queue wait as build compute.
if (empty($deployment->getAttribute('buildStartedAt'))) {
$buildDuration = 0;
$mbSeconds = 0;
}
// Per-resource breakdown travels as resource dimensions on the Context
// instead of per-{resourceInternalId} metric-name templates.
$usage
->setResource(rtrim($resourceType, 's'))
->setResourceId($resource->getId())
->setResourceInternalId((string) $resource->getSequence());
switch ($deployment->getAttribute('status')) {
case 'ready':
$usage
->addMetric(METRIC_BUILDS_SUCCESS, 1) // per project
->addMetric(METRIC_BUILDS_COMPUTE_SUCCESS, $buildDuration)
->addMetric(str_replace(['{resourceType}'], [$resourceType], METRIC_RESOURCE_TYPE_BUILDS_SUCCESS), 1) // per resource type
->addMetric(str_replace(['{resourceType}'], [$resourceType], METRIC_RESOURCE_TYPE_BUILDS_COMPUTE_SUCCESS), $buildDuration);
break;
case 'failed':
$usage
->addMetric(METRIC_BUILDS_FAILED, 1) // per project
->addMetric(METRIC_BUILDS_COMPUTE_FAILED, $buildDuration)
->addMetric(str_replace(['{resourceType}'], [$resourceType], METRIC_RESOURCE_TYPE_BUILDS_FAILED), 1) // per resource type
->addMetric(str_replace(['{resourceType}'], [$resourceType], METRIC_RESOURCE_TYPE_BUILDS_COMPUTE_FAILED), $buildDuration);
break;
}
$usage
->addMetric(METRIC_BUILDS, 1) // per project
->addMetric(METRIC_BUILDS_STORAGE, $deployment->getAttribute('buildSize', 0))
->addMetric(METRIC_BUILDS_COMPUTE, $buildDuration)
->addMetric(METRIC_BUILDS_MB_SECONDS, $mbSeconds)
->addMetric(str_replace(['{resourceType}'], [$resourceType], METRIC_RESOURCE_TYPE_BUILDS), 1) // per resource type
->addMetric(str_replace(['{resourceType}'], [$resourceType], METRIC_RESOURCE_TYPE_BUILDS_STORAGE), $deployment->getAttribute('buildSize', 0))
->addMetric(str_replace(['{resourceType}'], [$resourceType], METRIC_RESOURCE_TYPE_BUILDS_COMPUTE), $buildDuration)
->addMetric(str_replace(['{resourceType}'], [$resourceType], METRIC_RESOURCE_TYPE_BUILDS_MB_SECONDS), $mbSeconds);
if (! $usage->isEmpty()) {
$publisherForUsage->enqueue(new UsageMessage(
project: $project,
metrics: $usage->getMetrics(),
reduce: $usage->getReduce()
));
$usage->reset();
}
}
}