Справочник: журнал
Журнал — то, чем отвечают на вопрос «что случилось на этой машине». Он же единственный источник для разбора инцидентов: решения служба принимает молча, и в интерфейсе их не видно.
Где лежит журнал
Каталог %ProgramData%\LaPorta USB\logs, файлы вида laportausb-2026-09-18.jsonl —
по файлу на сутки, по строке JSON на событие.
Кодировка — UTF-8 без метки порядка байтов. Метка ломает строгий разбор (jq,
json.loads) на стороне сетевого ресурса, куда журнал выгружается.
При удалении программы каталог с журналом не трогается: записи аудита за три месяца не собственность программы.
Строка журнала
Пустые поля не пишутся вовсе — так «поля нет» отличимо от «поле пустое», а строка остаётся читаемой глазами.
| Поле | Значение |
|---|---|
ts | Время события с часовым поясом: 2026-09-18T11:20:54.123+11:00 |
event | Вид события, см. ниже |
computer | Имя компьютера |
user | Пользователь сеанса |
device.class | flash, external_hdd, token, other, unknown |
device.serial | Серийный номер |
device.serial_trusted | Заслуживает ли серийный номер доверия |
device.vid, device.pid | Идентификаторы изготовителя и изделия |
device.vendor, device.product | Изготовитель и модель словами |
device.instance_id | Идентификатор экземпляра устройства в системе |
device.interfaces | Состав интерфейсов. У устройств не по USB поля нет |
volumes[] | Тома носителя: letter, label, fs, volume_serial, size_bytes |
decision | allow, readonly либо block |
rule_id | Правило, по которому принято решение. Пусто — решение по умолчанию |
reason | Почему принято именно это решение, см. policy-reference.md |
mode | audit либо enforce |
applied | Применено ли решение на деле |
enforcement_failed | Была ли попытка применения неудачной |
policy_version | Версия политики, по которой принято решение |
message | Пояснение для человека |
Поле reason принимает значения token_never_enforced, exact_rule_serial,
group_rule_vid_pid, default_flash, default_external_hdd, default_other —
они разобраны в policy-reference.md.
Виды событий
| Вид | Когда пишется |
|---|---|
attach | Носитель подключён, решение по нему принято |
detach | Носитель исчез из системы |
enforced | Решение применено позже подключения: служба вернулась к носителю, который при подключении запретить не удалось |
restriction_lifted | Ограничение снято: новая политика этот носитель больше не ограничивает, и служба вернула его в обычное состояние, не дожидаясь извлечения |
attach_blocked | Подключён носитель, узел которого уже отключён |
apply_failed | Применить решение не удалось. В message — текст отказа и код, если система его сообщила |
policy_reloaded | Политика перечитана и оказалась новее прежней. В message — версия |
policy_unavailable | Политика недоступна. Пишется один раз при входе в это состояние, а не на каждом цикле опроса |
strict_mode_conflict | В ветке ограничений установки устройств найдены чужие значения: служба осталась на реактивном слое и ничего не перезаписала. Пишется один раз при входе в это состояние |
service_started | Служба запущена. В message — версия политики, с которой она начала |
service_stopping | Служба останавливается |
Почему enforced — отдельный вид, а не второе attach: повторное attach означало бы,
что носитель вставляли дважды, и в аудите это разные вещи. По той же причине отдельно
стоит restriction_lifted: в enforced решение применяют, здесь — отменяют.
Почему отдельно стоит attach_blocked: решение по такому носителю не пересчитывается —
у неработающего узла не прочитать ни томов, ни сменности, и класс остаётся неопределённым.
Событие отвечает на вопрос «носитель приносили», на который без него ответа не было
вовсе: заблокированную флешку можно было втыкать сколько угодно, и в журнале оставалась
одна запись. Найдено на приёмке.
Увидев strict_mode_conflict. Ветка ограничений установки устройств была занята
не этой программой — её заполнили доменная политика или средства защиты, причём под
теми же именами значений, какими пользуется программа. Служба такую ветку не трогает
и не перезаписывает, чтобы не снять чужую защиту, и пока она занята, превентивного
запрета на машине нет: машина остаётся на одном реактивном слое. Устранять занятость
нужно со стороны того, кто её создал (доменная политика, антивирус) — сама программа
за это не берётся. Устройство превентивного слоя — в overview.md.
Пара attach — detach после запрета
После успешного запрета в журнале появляется detach через несколько миллисекунд после
attach. Это не извлечение носителя человеком, а исчезновение отключённого узла
из системы: служба отключила узел, и система перестала о нём сообщать.
Отдельного вида события для «исчез из-за запрета» нет. Отличить одно от другого можно
по соседней записи: у запрета рядом стоит attach с decision равным block
и applied равным true, и разделяют их миллисекунды, а не минуты.
Срок хранения и выгрузка
Управляются политикой, разделом log:
log.retention_days— файлы старше этого срока удаляются. Без раздела — 90 дней;log.share_path— каталог, куда выгружается копия журнала. Пусто — выгрузка не выполняется.
Выгрузка идёт в подкаталог с именем компьютера: <share_path>\<имя компьютера>. Файлы
копируются целиком и перезаписываются, сбой на одном файле не прерывает остальные.
По умолчанию — раз в пятнадцать минут.
Подробнее о разделе log — в policy-reference.md.
Выгрузка в CSV
Окно администратора выгружает журнал в CSV для Excel. Столбцы: время, событие, компьютер, пользователь, класс, серийник, доверен ли серийник, VID, PID, производитель, модель, тома, решение, правило, причина, режим, применено, отказ применения, версия политики.
Разделитель — точка с запятой: русская локаль Excel разбирает по ней, а не по запятой.
Кодировка — UTF-8 с меткой порядка байтов, в противоположность файлам .jsonl:
без метки Excel читает UTF-8 как ANSI и показывает кириллицу мусором. Это не разнобой,
а два разных потребителя.