Skip to content

Instantly share code, notes, and snippets.

@Nex-Otaku
Last active April 2, 2021 15:43
Show Gist options
  • Save Nex-Otaku/0117b1593aaf1dcf82bda0c9d1e92f40 to your computer and use it in GitHub Desktop.
Save Nex-Otaku/0117b1593aaf1dcf82bda0c9d1e92f40 to your computer and use it in GitHub Desktop.
Serializing metrics to InfluxDB line format
<?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