Skip to content

Commit dc288d5

Browse files
lohanidamodarclaude
andcommitted
feat: add country and userAgent as event columns
- country: LowCardinality(Nullable(String)) for efficient low-cardinality storage - userAgent: Nullable(String) with bloom filter index - Both extracted from tags into dedicated columns like other event fields - Added getCountry() and getUserAgent() getters on Metric Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2b7ddb2 commit dc288d5

2 files changed

Lines changed: 56 additions & 1 deletion

File tree

src/Usage/Adapter/ClickHouse.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,11 @@ private function getColumnType(string $id, string $type = 'event'): string
12021202
throw new Exception("Attribute {$id} not found in {$type} schema");
12031203
}
12041204

1205+
// Country uses LowCardinality for efficient storage of low-cardinality values
1206+
if ($id === 'country') {
1207+
return 'LowCardinality(Nullable(String))';
1208+
}
1209+
12051210
$attributeType = is_string($attribute['type'] ?? null) ? $attribute['type'] : 'string';
12061211
$baseType = match ($attributeType) {
12071212
'integer' => 'Int64',

src/Usage/Metric.php

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class Metric extends ArrayObject
4040
/**
4141
* Event-specific column names that are extracted from tags into dedicated columns.
4242
*/
43-
public const EVENT_COLUMNS = ['path', 'method', 'status', 'resource', 'resourceId'];
43+
public const EVENT_COLUMNS = ['path', 'method', 'status', 'resource', 'resourceId', 'country', 'userAgent'];
4444

4545
/**
4646
* Construct a new metric object.
@@ -199,6 +199,28 @@ public function getResourceId(): ?string
199199
return is_string($resourceId) ? $resourceId : null;
200200
}
201201

202+
/**
203+
* Get country code (event metrics only).
204+
*
205+
* @return string|null ISO 3166-1 alpha-2 country code, or null if not set
206+
*/
207+
public function getCountry(): ?string
208+
{
209+
$country = $this->getAttribute('country', null);
210+
return is_string($country) ? $country : null;
211+
}
212+
213+
/**
214+
* Get user agent (event metrics only).
215+
*
216+
* @return string|null The user agent string, or null if not set
217+
*/
218+
public function getUserAgent(): ?string
219+
{
220+
$userAgent = $this->getAttribute('userAgent', null);
221+
return is_string($userAgent) ? $userAgent : null;
222+
}
223+
202224
/**
203225
* Get tags.
204226
*
@@ -450,6 +472,24 @@ public static function getEventSchema(): array
450472
'array' => false,
451473
'filters' => [],
452474
],
475+
[
476+
'$id' => 'country',
477+
'type' => 'string',
478+
'size' => 2,
479+
'required' => false,
480+
'signed' => true,
481+
'array' => false,
482+
'filters' => [],
483+
],
484+
[
485+
'$id' => 'userAgent',
486+
'type' => 'string',
487+
'size' => 512,
488+
'required' => false,
489+
'signed' => true,
490+
'array' => false,
491+
'filters' => [],
492+
],
453493
[
454494
'$id' => 'tags',
455495
'type' => 'string',
@@ -569,6 +609,16 @@ public static function getEventIndexes(): array
569609
'type' => 'key',
570610
'attributes' => ['resourceId'],
571611
],
612+
[
613+
'$id' => 'index-country',
614+
'type' => 'key',
615+
'attributes' => ['country'],
616+
],
617+
[
618+
'$id' => 'index-userAgent',
619+
'type' => 'key',
620+
'attributes' => ['userAgent'],
621+
],
572622
];
573623
}
574624

0 commit comments

Comments
 (0)