Перейти к содержимому

Файлы и папки ​

Всё, что хранит Signal Lab, — обычный JSON (или текст) в одной папке, папке данных. Значений секретов в ней никогда нет.

Папка данных ​

Где работает Signal LabПапка данных
Настольное приложение, WindowsDocuments\SignalLab в вашей пользовательской папке: C:\Users\<you>\Documents\SignalLab
Настольное приложение, Linux~/Documents/SignalLab
Сервер--data-dir или SIGNALLAB_DATA_DIR; если не задано ни то, ни другое, — Documents/SignalLab в домашней папке пользователя, от имени которого он работает
Сервер, образ Docker/data, том (signallab-data в файле compose)
signallab runВременная папка, которая удаляется при выходе, если только --data-dir не называет другую

Настольное приложение тоже берёт SIGNALLAB_DATA_DIR из своего окружения, если она задана. Папка создаётся, когда в неё что-то записывают впервые.

TIP

В Windows приложение использует папку Documents прямо в вашей пользовательской папке, даже если Windows хранит ваши документы в другом месте (OneDrive).

На сервере файлы записываются на машине сервера, а не на вашей. Значок Сервер в шапке сообщает, где именно, в своей подсказке; API отдаёт это как data_dir команды app_info, а /api/files скачивает то, что в ней лежит.

Команды signallab emulate, signallab send и signallab mcp читают библиотеки приложения из той же папки, что и настольное приложение.

Что в ней лежит ​

ФайлЧто этоКогда записывается
experiment.jsonЭксперимент, открытый в редактореВскоре после каждого изменения
signals.jsonБиблиотека сигналов (Сигналы)Вскоре после каждого изменения
emulators.jsonБиблиотека эмуляторов (Эмуляторы)Вскоре после каждого изменения
runs/run-<ms>-<job>.jsonОдин отчёт на каждый запуск, закончившийся самКогда запуск заканчивается
exports/experiment-<ms>-<16 hex digits>.jsonСнимок экспериментаЭкспорт текущей схемы
capture-<ms>.jsonl, capture-<ms>.txtКадры ИнспектораЭкспорт .jsonl, Экспорт .txt
tokenТокен доступа сервера, читаемый только его пользователем--generate-token, при первом запуске
.experiment-<hex>.tmp, .signals-<hex>.tmp, .emulators-<hex>.tmpСохранение в процессеНа мгновение, затем переименовывается

<ms> — время в миллисекундах с 1970 года; <job> — номер задачи запуска. На сервере каждый браузер работает с одним и тем же experiment.json, теми же библиотеками и теми же отчётами.

Форматы ​

Все файлы — JSON в UTF-8, записанный с отступами, чтобы его удобно было читать и сравнивать. В каждом есть version; файл более старой версии читается и переносится на текущую при открытии и записывается обратно уже в текущей версии при следующем сохранении — после чего более старый Signal Lab открыть его не сможет.

experiment.json ​

Документ эксперимента, версия 9 — тот же JSON, который записывает Экспорт текущей схемы и читает Открыть JSON…:

json
{
  "version": 9,
  "name": "HTTP check",
  "params": [],
  "profiles": [],
  "profile": null,
  "seed": null,
  "cookies": true,
  "nodes": [ { "id": "start", "type": "start", "x": 40, "y": 80 }, … ],
  "edges": [ { "from": "start", "to": "request", "port": "next" }, … ]
}
  • Не больше 4 МиБ и от 1 до 64 узлов (doc.node_count).
  • Версии с 1 по 8 переносятся при открытии. Файл старше версии 8 открывается с выключенным cookies, чтобы запускаться как раньше; остальные настройки, которые добавила каждая версия (параметры во 2-й, профили в 3-й, повторные попытки в 4-й, повторы и циклы в 5-й, эмуляторы в 6-й, помехи в 7-й, WebSocket и аутентификация HTTP в 8-й, нагрузка в 9-й), начинаются пустыми.
  • Версия новее той, которую знает этот Signal Lab, отклоняется (doc.version_unsupported), а не открывается без того, что он не может прочитать.
  • Файл, который не разбирается, сопровождается сообщением с путём, строкой и столбцом и никогда не заменяется.
  • Он записывается во временный файл и переименовывается, поэтому неудачная запись оставляет предыдущий.

Что такое узлы, параметры и профили: эксперименты, узлы, данные.

signals.json ​

Библиотека сигналов, версия 2:

json
{
  "version": 2,
  "signals": [
    {
      "id": "…",
      "name": "Go cue",
      "group": "Stage/Cues",
      "note": "",
      "body": { "transport": "osc", "target": "127.0.0.1:9000", "address": "/cue/go", "args": [ { "type": "int", "value": 1 } ] }
    }
  ],
  "folders": [ "Stage", "Stage/Cues" ]
}
  • group — папка сигнала в виде пути через /; пусто означает верхний уровень. folders (добавлено в версии 2) перечисляет все папки, включая пустые, и пропускается, если папок нет. Файл версии 1 читается так же, без пустых папок.
  • body — одно из osc, udp, http или mqtt; их поля описаны в signals_save.
  • Если файла нет, записывается стартовый набор — все цели на 127.0.0.1 — и переименовывается на язык интерфейса.
  • Файл, который не разбирается, сопровождается сообщением с путём, строкой и столбцом (signals.json_invalid) и никогда не заменяется стартовым набором: исправьте или удалите его. Пока он не читается, библиотеку никто не записывает — сохранение отклоняется с той же ошибкой, а файл остаётся как есть, — пока Перечитать файл не прочитает его снова. Сохранение идёт через временный файл в той же папке, поэтому оборванная запись оставляет предыдущий файл.

emulators.json ​

Библиотека эмуляторов, версия 1:

json
{
  "version": 1,
  "emulators": [
    { "id": "demo-api", "note": "…", "emulator": { "name": "Demo API", "bind": "127.0.0.1:8080", "protocol": "http", "routes": [ … ] } }
  ]
}

Каждая запись — документ эмулятора с id и note; сам документ описан в разделе эмуляторы. Как и у сигналов, отсутствующему файлу достаётся стартовый набор (все привязаны к 127.0.0.1), а испорченный файл сопровождается сообщением об ошибке (emulators.json_invalid) и никогда не заменяется. Он записывается через временный файл. signallab emulate читает и собственный файл, в котором один эмулятор, их список или библиотека, подобная этой.

Отчёты о запусках ​

runs/run-<started ms>-<job>.json, отчёт версии 5: один файл на каждый запуск, который прошёл или не прошёл; он никогда не перезаписывается (второй запуск с тем же именем получает -2, -3…). Остановленный запуск не сохраняет ничего.

ПолеЧто это
version5
experimentИмя эксперимента
document_versionВерсия документа, который выполнялся
seed, profileС чем он выполнялся
overridesЗначения, заданные только для этого запуска
paramsВсе значения параметров, которые он использовал
started_ms, ended_msМиллисекунды с 1970 года
outcomepassed или failed
errorЕго первый сбой или null
stepsВсе шаги, как у experiment://step
emulatorsЧто принял и на что ответил каждый узел Эмулятор (с версии 3); пропускается, если таких нет
impairmentsЧто сделало реле каждого узла Сетевые помехи по фазам (с версии 4); пропускается, если таких нет

Измерения шага нагрузки лежат в его последнем шаге (с версии 5). История запусков на ленте запуска и кнопка Сравнить читают эти файлы; отчёт, который не удаётся прочитать, в список не попадает. См. запуски и отчёты.

Экспорт ​

  • exports/experiment-…json: документ эксперимента, как выше. Каждый экспорт — новый файл.
  • capture-….jsonl: по одному кадру Инспектора на строку, с хранимыми им байтами в data, в base64.
  • capture-….txt: кадры для чтения, каждый с hex-дампом.

На сервере экспорт Инспектора скачивается на ваш компьютер по мере создания; экспорт эксперимента предлагает кнопку Скачать, а надпись Отчёт сохранён на ленте запуска — это ссылка, скачивающая отчёт.

Секретов в этих файлах нет ​

Эксперимент называет секрет — {{secret.API_TOKEN}} — и записывается только имя. Значение хранится так:

Где работает Signal LabГде значения секретов
Настольное приложение, WindowsДиспетчер учётных данных Windows, под именем SignalLab (окно Секреты в редакторе)
Настольное приложение, LinuxНигде: секреты хранить нельзя (secret.unsupported)
СерверТолько чтение: переменная окружения SIGNALLAB_SECRET_<NAME> или файл <NAME> в --secrets-dir (по умолчанию /run/secrets/signallab)
signallabТе же файлы и переменные или хранилище системы с --secrets system

WARNING

То, что вы вводите прямо в поле, хранится так, как набрано. Пароль в учётных данных сигнала HTTP, пароль эмулятора брокера MQTT, токен, вставленный в заголовок, — всё это обычный текст в signals.json, emulators.json или experiment.json и в их экспорте. Для всего, что вы не положили бы в общую папку, используйте в эксперименте {{secret.NAME}}.

Настройки интерфейса ​

То, что запоминает интерфейс, — его язык, значения, введённые последними на каждом экране, какая панель открыта и какого она размера, Хранить cookie, когда в последний раз искали обновления и случайный номер установки для обновлений, — хранит сам интерфейс, а не папка данных: в собственном хранилище приложения на настольном компьютере и в хранилище сайта браузера для страницы сервера (у каждого браузера своё). Учётные данные экрана HTTP там не хранятся.

Signal Lab не пишет файлов журнала; см. устранение неполадок.

Копирование, правка, перенос ​

  • Копируйте всю папку целиком. Всё в ней — самодостаточный JSON; значений секретов в ней нет, поэтому на новой машине задайте их заново.
  • Правьте signals.json, emulators.json и experiment.json вручную, пока Signal Lab закрыт (или, на сервере, пока не открыта ни одна страница): приложение записывает весь файл из того, что держит в памяти, поэтому изменение, сделанное во время работы, перезаписывается его следующим сохранением. Ошибка будет показана со строкой и столбцом при следующем чтении файла и никогда не будет молча заменена — для signals.json это так и при сохранении самим приложением: сохранение отклоняется, и файл остаётся таким, каким вы его оставили.
  • Удаляйте файлы runs/, exports/ и capture-* когда угодно. Удаление signals.json или emulators.json возвращает стартовый набор; удаление experiment.json возвращает стартовый эксперимент.
  • Переносите папку, скопировав её и указав Signal Lab новое место: --data-dir для сервера, SIGNALLAB_DATA_DIR для настольного приложения.
  • Делитесь экспериментом, экспортировав его или добавив его JSON в коммит рядом с проектом, который он проверяет; signallab run запустит его оттуда.