PHP code example of utopia-php / usage

1. Go to this page and download the library: Download utopia-php/usage library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

utopia-php / usage example snippets




use Utopia\Usage\Usage;
use Utopia\Usage\Adapter\ClickHouse;

// Configuration is fixed at construction. The adapter is fully stateless —
// the tenant is passed explicitly on every call (see below).
$adapter = new ClickHouse(
    host: 'clickhouse-server',
    username: 'default',
    password: '',
    port: 8123,
    secure: false,
    namespace: 'my_app',
    sharedTables: true,
);

$usage = new Usage($adapter);
$usage->setup(); // Creates events, gauges, and daily MV tables



use Utopia\Usage\Usage;
use Utopia\Usage\Adapter\Database as DatabaseAdapter;

$adapter = new DatabaseAdapter($database); // Utopia\Database\Database instance
$usage = new Usage($adapter);
$usage->setup();

$usage->getTotal('project_123', 'bandwidth');           // read for one tenant
$usage->addBatch([
    ['tenant' => 'project_123', 'metric' => 'bandwidth', 'value' => 5000, 'tags' => []],
    ['tenant' => 'project_456', 'metric' => 'bandwidth', 'value' => 2000, 'tags' => []],
], Usage::TYPE_EVENT);

use Utopia\Usage\Tenant;

$tenant = new Tenant($usage, 'project_123');
$tenant->getTotal('bandwidth');                          // no tenant argument
$tenant->addBatch([
    ['metric' => 'bandwidth', 'value' => 5000, 'tags' => []], // tenant stamped automatically
], Usage::TYPE_EVENT);

use Utopia\Usage\Accumulator;

// Buffer metrics in memory and flush them in batch
$accumulator = new Accumulator($usage);

// Collect events — tenant first; values accumulate in-memory (summed per tenant+metric)
$accumulator->collect('project_123', 'bandwidth', 5000, Usage::TYPE_EVENT, [
    'path' => '/v1/storage/files',
    'method' => 'POST',
    'status' => '201',
    'service' => 'storage',
    'resourceType' => 'bucket',
    'resourceId' => 'abc123',
    'resourceInternalId' => '42',
    'teamId' => 'team_x',
    'teamInternalId' => '7',
    'country' => 'US',
    'region' => 'us-east',
    'hostname' => 'app.example.com',
    'osName' => 'iOS',
    'clientName' => 'Appwrite SDK',
    'deviceName' => 'smartphone',
]);

// Collect gauges — last value wins per tenant+metric in buffer
$accumulator->collect('project_123', 'users', 1500, Usage::TYPE_GAUGE);
$accumulator->collect('project_123', 'storage.size', 1048576, Usage::TYPE_GAUGE, [
    'teamId' => 'team_x',
    'teamInternalId' => '7',
    'resourceId' => 'abc123',
    'resourceInternalId' => '42',
]);

// Flush when the buffer grows large or enough time has passed
if ($accumulator->count() >= 5000 || $accumulator->elapsedSeconds() >= 10) {
    $accumulator->flush(); // Writes events to events table, gauges to gauges table
}

// Write directly without buffering — each row carries its tenant
$usage->addBatch([
    ['tenant' => 'project_123', 'metric' => 'requests', 'value' => 100, 'tags' => ['path' => '/v1/users', 'method' => 'GET']],
    ['tenant' => 'project_123', 'metric' => 'bandwidth', 'value' => 50000, 'tags' => ['country' => 'DE', 'region' => 'fra']],
], Usage::TYPE_EVENT);

$usage->addBatch([
    ['tenant' => 'project_123', 'metric' => 'users', 'value' => 42, 'tags' => ['teamId' => 'team_x']],
], Usage::TYPE_GAUGE);

use Utopia\Usage\Sample;
use Utopia\Usage\SampleRange;

$sample = new Sample(
    environment: 'production',
    region: 'fra1',
    projectInternalId: '101',
    databaseInternalId: '202',
    member: 'mysql-0',
    generation: '01J...',
    sequence: 42,
    metric: 'bandwidth.inbound',
    intervalStart: new DateTimeImmutable('2026-08-01T00:42:00Z'),
    intervalEnd: new DateTimeImmutable('2026-08-01T00:43:00Z'),
    value: 4096,
    eventVersion: 1,
);

$range = new SampleRange(
    environment: 'production',
    region: 'fra1',
    projectInternalId: '101',
    databaseInternalId: '202',
    member: 'mysql-0',
    generation: '01J...',
    metric: 'bandwidth.inbound',
    firstSequence: 42,
    lastSequence: 42,
    intervalStart: new DateTimeImmutable('2026-08-01T00:42:00Z'),
    intervalEnd: new DateTimeImmutable('2026-08-01T00:43:00Z'),
);

$usage->addSamples([$sample]);
$watermark = $usage->getSampleWatermark($range, limit: 100);
$result = $usage->findSamples(
    $range,
    $watermark,
    limit: 100,
);

if (!$result->isComplete()) {
    // Refuse billing. Inspect conflicts, compact gap ranges and truncation.
}

use Utopia\Query\Query;

// Find events filtered by metric and time range (tenant first)
$metrics = $usage->find('project_123', [
    Query::equal('metric', ['bandwidth']),
    Query::equal('country', ['US']),
    Query::greaterThanEqual('time', '2026-01-01'),
    Query::orderDesc('time'),
    Query::limit(100),
], Usage::TYPE_EVENT);

// Find gauges
$gauges = $usage->find('project_123', [
    Query::equal('metric', ['users', 'storage.size']),
], Usage::TYPE_GAUGE);

// Query both tables (type = null)
$all = $usage->find('project_123', [
    Query::equal('metric', ['bandwidth']),
]);

// Get total for a single metric (SUM for events, latest for gauges)
$total = $usage->getTotal('project_123', 'bandwidth', [
    Query::greaterThanEqual('time', '2026-03-01'),
], Usage::TYPE_EVENT);

// Batch totals — single query with GROUP BY
$totals = $usage->getTotalBatch(
    'project_123',
    ['bandwidth', 'executions', 'requests'],
    [Query::greaterThanEqual('time', '2026-03-01')],
    Usage::TYPE_EVENT
);

// Get time series with query-time aggregation
// Events: SUM per bucket, Gauges: argMax per bucket
$series = $usage->getTimeSeries(
    tenant: 'project_123',
    metrics: ['bandwidth', 'requests'],
    interval: '1d',        // '1h' or '1d'
    startDate: '2026-03-01',
    endDate: '2026-04-01',
    zeroFill: true,        // Fill gaps with zeros
    type: Usage::TYPE_EVENT
);

// Returns: ['bandwidth' => ['total' => 5000000, 'data' => [['value' => 100, 'date' => '...'], ...]]]

// Sum a single metric from the daily table
$total = $usage->sumDaily('project_123', [
    Query::equal('metric', ['bandwidth']),
    Query::between('time', '2026-03-01', '2026-04-01'),
]);

// Sum multiple metrics in one query
$totals = $usage->sumDailyBatch(
    'project_123',
    ['bandwidth', 'executions', 'storage.size'],
    [Query::between('time', '2026-03-01', '2026-04-01')]
);
// Returns: ['bandwidth' => 5000000, 'executions' => 12345, 'storage.size' => 0]

// Find daily aggregated rows
$rows = $usage->findDaily('project_123', [
    Query::equal('metric', ['bandwidth']),
    Query::orderDesc('time'),
    Query::limit(30),
]);

// Purge all event metrics older than 90 days
$usage->purge('project_123', [
    Query::lessThan('time', '2026-01-01'),
], Usage::TYPE_EVENT);

// Purge all gauge metrics
$usage->purge('project_123', [], Usage::TYPE_GAUGE);
bash
composer