Last active
April 2, 2021 15:43
-
-
Save Nex-Otaku/0117b1593aaf1dcf82bda0c9d1e92f40 to your computer and use it in GitHub Desktop.
Serializing metrics to InfluxDB line format
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class InfluxdbLine | |
{ | |
// https://docs.influxdata.com/influxdb/v2.0/reference/syntax/line-protocol/ | |
public function format(string $measurement, array $tags, array $fields, string $timestampNanoSeconds): string | |
{ | |
$measurementEscaped = $this->escapeMeasurement($measurement); | |
$tagsFlat = $this->flattenTags($tags); | |
$fieldsFlat = $this->flattenFields($fields); | |
return "{$measurementEscaped}{$tagsFlat} {$fieldsFlat} {$timestampNanoSeconds}"; | |
} | |
private function escapeMeasurement(string $measurement): string | |
{ | |
return $this->escapeComma($this->escapeSpace($measurement)); | |
} | |
private function escapeKey(string $key): string | |
{ | |
return $this->escapeComma($this->escapeEqual($this->escapeSpace($key))); | |
} | |
private function escapeTagValue(string $value): string | |
{ | |
return $this->escapeComma($this->escapeEqual($this->escapeSpace($value))); | |
} | |
private function escapeFieldValue($value): string | |
{ | |
if (is_string($value)) { | |
return '"' . $this->escapeDoubleQuote($this->escapeBackslash($value)) . '"'; | |
} | |
if (is_int($value)) { | |
return ((string)$value) . 'i'; | |
} | |
if (is_float($value)) { | |
return (string)$value; | |
} | |
if (is_bool($value)) { | |
return $value ? 'true' : 'false'; | |
} | |
throw new \LogicException('Неподдерживаемый тип значения для метрики'); | |
} | |
private function flattenTags(array $tags): string | |
{ | |
if (count($tags) === 0) { | |
return ''; | |
} | |
return ',' . implode(',', $this->valuePairs($tags, false)); | |
} | |
private function flattenFields(array $fields): string | |
{ | |
if (count($fields) === 0) { | |
throw new \LogicException('Не указаны поля для метрик'); | |
} | |
return implode(',', $this->valuePairs($fields, true)); | |
} | |
private function valuePairs(array $items, bool $isFields): array | |
{ | |
if (count($items) === 0) { | |
return []; | |
} | |
$result = []; | |
foreach ($items as $key => $value) { | |
$result[] = $this->escapeKey($key) . '=' . ($isFields ? $this->escapeFieldValue($value) : $this->escapeTagValue($value)); | |
} | |
return $result; | |
} | |
private function escapeSpace(string $value): string | |
{ | |
return str_replace(' ', '\ ', $value); | |
} | |
private function escapeComma(string $value): string | |
{ | |
return str_replace(',', '\,', $value); | |
} | |
private function escapeEqual(string $value): string | |
{ | |
return str_replace('=', '\=', $value); | |
} | |
private function escapeDoubleQuote(string $value): string | |
{ | |
return str_replace('"', '\"', $value); | |
} | |
private function escapeBackslash(string $value): string | |
{ | |
return str_replace('\\', '\\\\', $value); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment