Как опубликовать метрики в InfluxDB с простой формой HTML? - PullRequest
0 голосов
/ 24 января 2020

Я пытаюсь отправить 0 или 1 в базу данных моего экземпляра InfluxDB через запрос POST из формы HTML. Я успешно делал это много раз через curl, но я не могу заставить его работать с простой формой HTML. Рассмотрим этот HTML код:

<!doctype html>
<!-- this file is called like http://my.influx.server/my_page_name.html -->
<html>
  <head>
    <title>my simple html/influx sender</title>
    <meta charset="UTF-8"/>
  </head>
  <body>
    <form action="http://my.influx.server:8086/write?db=db_name" method="post" enctype="text/plain">
      <input name="data" type="hidden" value="my_measurement,tag_name=stuff value=1"/>
      <input type="submit" value="insert 1"/>
    </form>

    <form action="http://my.influx.server:8086/write?db=db_name" method="post" enctype="text/plain">
      <input name="data" type="hidden" value="my_measurement,tag_name=stuff value=0"/>
      <input type="submit" value="insert 0"/>
    </form>
  </body>
</html>

Команда curl для отправки 1 будет выглядеть так:

curl -i -XPOST 'http://my.influx.server:8086/write?db=mydb' --data-binary 'my_measurement,tag_name=stuff value=1'

Поэтому я попытался сделать простое HTML Форма всего с 2 кнопками. Приведенный выше код является наиболее близким к тому, что я мог, по крайней мере, попытаться обработать синтаксисом «линейного интерфейса», однако я получаю либо сообщение об ошибке, либо просто нет ответа, и я ничего не получаю в своей InfluxDB. Сообщение об ошибке из приведенного выше кода выглядит следующим образом:

unable to parse 'data=my_measurement,tag_name=stuff value=1\r': invalid number

Если вы внимательно посмотрите на конец строки, вы увидите \r, который, очевидно, добавляется, и я подозреваю, что это разбивает число при разборе ( У меня когда-то было что-то похожее go), но, по крайней мере, это, кажется, пытается оценить линию вообще. Тем не менее, я не нашел способ удалить или избежать \r. Кто-нибудь знает, как этого добиться?

Также, пожалуйста, рассмотрите следующую дополнительную информацию:

  • Я хочу, чтобы это было действительно просто, просто маленький HTML файл, возможно, с небольшим количеством JavaScript кода, но я бы действительно хотел избежать использования PHP, jQuery и подобных. Кроме того, я пытаюсь привыкнуть к HTML5, как вы могли заметить, но это не должно быть проблемой.
  • В этом случае мне не нужна временная метка для каждого нажатия клавиши, поэтому вместо передачи временной метки я просто использую текущее время. Это достигается путем опускания метки времени, поэтому строка, исключающая \r, должна быть синтаксически правильной.
  • Я также искал альтернативы, однако была только идея использовать JSON, и, похоже, это не так. поддерживается больше из-за соображений производительности (чего я не ожидал в моем случае).
  • Команда curl использует параметр --data-binary, но, похоже, у меня нет ничего подобного в HTML. Мне известны двоичные enctype, подобные application/x-binary, но они не работают, потому что они URL-кодируют строку, и это не пройдет проверку синтаксиса. Единственный enctype, который я обнаружил, который работал по крайней мере достаточно близко, это text/plain.
  • Я также знаю о том, что данные формы не отправляются, если соответствующий элемент <input> не имеет атрибута name. Затем я заметил, что строка curl была построена как my_measurement,tag_name=stuff value=1, возможно, несколько таких строк разделены \n, что не похоже на пары ключ-значение POST, как в a=1&b=2 (т.е. нет ключа, который бы быть атрибутом name). Попытка обмануть его с помощью name="my_measurement,tag_name" и value="stuff value=1" (что будет похоже на исходную строку) не увенчалась успехом, и я до сих пор не мог понять, какой ключ ожидается. Я пробовал с content, query et c. и в итоге использовал data. Я сохранил это тогда, потому что в документах они говорят о «данных», и ни один из ключей не имеет никакого значения, пока один предоставлен. Я подозреваю, что InfluxDB просто использует первую переменную POST, игнорируя имя, но я не могу найти какое-либо четкое утверждение по этому поводу.
  • Я также пробовал несколько невидимых <input> типов, таких как hidden или обычное текстовое поле. скрыто по стилю. Это не имеет значения. Ни один не сделал видимых элементов.
  • Я также рассмотрел использование AJAX, но я не мог найти ничего полезного о бинарных POST без содержимого значения ключа. Я бы даже справился со страницей, которая пока работает только, например, для Firefox, поэтому мне не нужно переключаться между различными AJAX алгоритмами создания объектов и тому подобным (да, я знаю, jQuery помогает, но сначала посмотрите точка выше).

EDIT 1 : Я пытался воспроизвести ошибку с curl:

curl -i -XPOST 'http://my.influx.server:8086/write?db=home' --data-binary 'my_measurement,tag_name=stuff value=1\r'

Это привело к ошибке сообщение:

unable to parse 'my_measurement,tag_name=stuff value=1\\r': invalid number

с заголовками:

HTTP/1.1 400 Bad Request
Content-Type: application/json
Request-Id: ...
X-Influxdb-Build: OSS
X-Influxdb-Error: unable to parse 'my_measurement,tag_name=stuff value=1\r': invalid number
X-Influxdb-Version: 1.7.9
X-Request-Id: ...
Date: ...
Content-Length: 78

Я заключаю:

  • \r, похоже, по-разному закодировано в сообщении об ошибке (символы \ и r вместо фактического возврата каретки), но в заголовке это всего лишь \r, однако это не имеет значения в отношении ошибки синтаксического анализа, так что это сопоставимо.
  • Очевидно, что имя ключа не задействовано, поэтому оно по-прежнему отличается от моей попытки выше.

EDIT 2 : я узнал, как отобразить запрос заголовки от звонка до curl. Команда:

curl -v -XPOST 'http://my.influx.server:8086/write?db=db_name' --data-binary 'my_measurement,tag_name=stuff value=1'

Соответствующая часть вывода команды:

> POST /write?db=db_name HTTP/1.1
> Host: my.influx.server:8086
> User-Agent: curl/7.58.0
> Accept: */*
> Content-Length: 37
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 37 out of 37 bytes
< HTTP/1.1 204 No Content
< Content-Type: application/json
< Request-Id: ...
< X-Influxdb-Build: OSS
< X-Influxdb-Version: 1.7.9
< X-Request-Id: ...
< Date: Sat, 25 Jan 2020 10:54:11 GMT

Я заключаю:

  • Тип содержимого запроса curl с --binary-data вызывается application/x-www-form-urlencoded.
  • К сожалению, мне не удалось увидеть фактическое тело запроса, поэтому я попробую еще раз с некоторыми вариантами в кодировке URL. Тем не менее, my_measurement,tag_name=stuff value=1 - это 37 символов, как в заголовке запроса, поэтому я предполагаю, что имя ключа, например data, отсутствует. В настоящее время я получаю то же сообщение об ошибке, которое было до того, как опубликовал этот вопрос: unable to parse 'data=my_measurement%2Ctag_name%3Dstuff+value%3D1': missing fields

  • \r больше нет, но я все еще не могу отправить данные без имени ключа и вся строка недопустима из-за URL-кодировки. Как избавиться от URL-кодировки?

1 Ответ

0 голосов
/ 03 февраля 2020

Наконец-то я нашел решение с JavaScript, которое сработало. Эта страница Mozilla do c page была ключом к форме POST без ключей. Моя HTML страница теперь выглядит так:

<!doctype html>
<!-- this file is called like http://my.influx.server/my_page_name.html -->
<html>
  <head>
    <title>my simple html/influx sender</title>
    <meta charset="UTF-8"/>
  </head>
  <body>
    <form id="form1">
      <button>insert 1</button>
    </form>

    <form id="form0">
      <button>insert 0</button>
    </form>

    <script>
        function sendData(value)
        {
            const str = "my_measurement,tag_name=stuff value=" + value;
            const xhr = new XMLHttpRequest();

            xhr.addEventListener("load", function(event) {
                alert("Success");
            });

            xhr.addEventListener("error", function(event) {
                alert("Error");
            });

            xhr.open("POST", "http://my.influx.server:8086/write?db=db_name");
            xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

            xhr.send(str);
        }

        const form0 = document.getElementById("form0");
        const form1 = document.getElementById("form1");

        form0.addEventListener("submit", function(event) {
            event.preventDefault();
            sendData(0);
        });
        form1.addEventListener("submit", function(event) {
            event.preventDefault();
            sendData(1);
        });
    </script>
  </body>
</html>

Обратите внимание на урезанные определения форм: больше нет action s, method s или enctype s, поскольку они устанавливается через JavaScript. Также нет обычного элемента submit, вместо этого это обычная кнопка, однако я не знаю, нужно ли это. Я исследую это позже.

Основная часть находится в теге script под формами. Функция sendData подготавливает объект XMLHttpRequest для POST подготовленной строки и вызывает метод send. Эта функция используется в событиях submit каждой формы. Кроме того, эта функция регистрирует обработчики событий для успешных и неудачных запросов.

Строки под функцией sendData идентифицируют формы и регистрируют прослушиватели событий для их события submit. Каждый слушатель предотвращает регулярную отправку своей формы и вместо этого вызывает соответствующий вызов sendData, который успешно вставит значения в InfluxDB.

Имейте в виду, что гарантии обнаружения каждой ошибки все еще нет. Я попытался вставить строку в целочисленное поле, но это не удалось, но я все еще получил "Success" -alert. Я собираюсь исследовать это позже.

Итак, в целом, я считаю, что эта проблема достаточно решена для моих целей, и я надеюсь, что это поможет любому наткнуться на нее.

...