@7n/rules 1.15.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.16.0] - 2026-07-18
4
+
5
+ ### Added
6
+
7
+ - k8s: новий концерн dremio_logging — logback.xml Dremio Helm-чарту має містити WARN-оверрайди для шести відомо-шумних loggerів (rego, XML через conftest, detection-only)
8
+
3
9
  ## [1.15.0] - 2026-07-18
4
10
 
5
11
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7n/rules",
3
- "version": "1.15.0",
3
+ "version": "1.16.0",
4
4
  "description": "CLI еталонних правил і skills (префікс n-): синк у репозиторій, дельта-lint, конформність",
5
5
  "keywords": [
6
6
  "cli",
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "https://unpkg.com/@7n/rules/schemas/concern.json",
3
+ "policy": {
4
+ "files": {
5
+ "walkGlob": "**/dremio_v2/config/logback.xml"
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,31 @@
1
+ ## WARN-оверрайди шумних loggerів у logback.xml Dremio
2
+
3
+ Rego-пакет: `k8s.dremio_logging`
4
+
5
+ **Цільові файли:** `**/dremio_v2/config/logback.xml` — vendored-конфіг логування Dremio Helm-чарту. Це XML (не YAML): conftest парсить його нативно (парсер інферується за розширенням). Кожна env-копія (`dev/dremio_v2/…`, `ua/dremio_v2/…` тощо) перевіряється окремо — без крос-файлової дедуплікації. Cross-file gating (як у `hasura_configmap`) не потрібен: шлях сам ідентифікує Dremio-чарт.
6
+
7
+ **Що перевіряється:** для кожного FQCN зі списку нижче має існувати `<logger name="<FQCN>" level="warn"/>` (рівень case-insensitive; «строгіше» — `error`/`off` — теж ок). Кожен запис-дублікат для FQCN має задовольняти вимогу окремо (конфліктні дублікати — порушення: logback бере останній, конфіг має бути однозначним).
8
+
9
+ | FQCN |
10
+ |------|
11
+ | `com.dremio.sabot.exec.fragment.FragmentExecutor` |
12
+ | `com.dremio.sabot.exec.fragment.FragmentStatusReporter` |
13
+ | `com.dremio.sabot.exec.QueryTicket` |
14
+ | `com.dremio.service.reflection.descriptor.MaterializationCache` |
15
+ | `com.dremio.exec.planner.plancache.PlanCacheSynchronizer` |
16
+ | `com.dremio.exec.planner.plancache.CacheRefresher` |
17
+
18
+ **Чому:** ці loggerи (усі на одному `planning-cache-refresher` треді; підтверджено живою перевіркою в проді) пишуть INFO на кожен запит/фоновий цикл і домінують обсяг логів у Cloud Logging без діагностичної цінності понад WARN. Список фіксований — не розширюй «про запас»; нові loggerи — окремою ітерацією.
19
+
20
+ **Приклад валідного фрагмента:**
21
+
22
+ ```xml
23
+ <logger name="com.dremio.sabot.exec.fragment.FragmentExecutor" level="warn"/>
24
+ <logger name="com.dremio.sabot.exec.fragment.FragmentStatusReporter" level="warn"/>
25
+ <logger name="com.dremio.sabot.exec.QueryTicket" level="warn"/>
26
+ <logger name="com.dremio.service.reflection.descriptor.MaterializationCache" level="warn"/>
27
+ <logger name="com.dremio.exec.planner.plancache.PlanCacheSynchronizer" level="warn"/>
28
+ <logger name="com.dremio.exec.planner.plancache.CacheRefresher" level="warn"/>
29
+ ```
30
+
31
+ **Autofix:** відсутній (detection-only, як `hasura_httproute`) — XML-трансформ складніший за YAML `setIn`; T0-fix, за потреби, окремою ітерацією.
@@ -0,0 +1,86 @@
1
+ # WARN-оверрайди шумних loggerів у logback.xml Dremio Helm-чарту.
2
+ #
3
+ # Проблема: перелічені нижче FQCN (усі живуть на одному `planning-cache-refresher`
4
+ # треді) пишуть INFO-логи на кожен запит/фоновий цикл і домінують обсяг у
5
+ # Cloud Logging без діагностичної цінності понад WARN. Вимога: у кожній копії
6
+ # vendored-конфігу `dremio_v2/config/logback.xml` (наприклад `dev/…` і `ua/…` —
7
+ # кожна env-копія перевіряється окремо, без крос-файлової дедуплікації) має бути
8
+ # `<logger name="<FQCN>" level="warn"/>` для кожного FQCN зі списку
9
+ # `required_loggers`, з рівнем "warn" або строгішим ("error", "off").
10
+ #
11
+ # Вхід — XML: conftest інферить парсер за розширенням `.xml`. Конвенція
12
+ # представлення (див. `conftest parse`):
13
+ # - атрибути мають префікс "-" (`-name`, `-level`);
14
+ # - один дочірній елемент → об'єкт, кілька → масив. Тому `<logger>`
15
+ # нормалізується у `loggers` (завжди масив).
16
+ #
17
+ # Запуск (локально):
18
+ # conftest test path/to/dremio_v2/config/logback.xml \
19
+ # -p npm/rules/k8s/dremio_logging \
20
+ # --namespace k8s.dremio_logging
21
+ #
22
+ # Список FQCN підтверджено живою перевіркою в проді — не розширюй «про запас».
23
+ #
24
+ # Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
25
+ # Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`.
26
+ package k8s.dremio_logging
27
+
28
+ import rego.v1
29
+
30
+ # Обов'язкові WARN-оверрайди (FQCN відомо-шумних loggerів Dremio).
31
+ required_loggers := {
32
+ "com.dremio.sabot.exec.fragment.FragmentExecutor",
33
+ "com.dremio.sabot.exec.fragment.FragmentStatusReporter",
34
+ "com.dremio.sabot.exec.QueryTicket",
35
+ "com.dremio.service.reflection.descriptor.MaterializationCache",
36
+ "com.dremio.exec.planner.plancache.PlanCacheSynchronizer",
37
+ "com.dremio.exec.planner.plancache.CacheRefresher",
38
+ }
39
+
40
+ # Рівні logback, що задовольняють вимогу «warn або строгіше».
41
+ allowed_levels := {"warn", "error", "off"}
42
+
43
+ # Нормалізація <logger>: один елемент XML-парсер віддає об'єктом, кілька — масивом.
44
+ # Тіла взаємовиключні (is_array/is_object), default покриває відсутність елемента
45
+ # (зокрема logback.xml без <configuration>-кореня → порожній список → deny на
46
+ # кожен обов'язковий FQCN).
47
+ default loggers := []
48
+
49
+ loggers := input.configuration.logger if is_array(input.configuration.logger)
50
+
51
+ loggers := [input.configuration.logger] if is_object(input.configuration.logger)
52
+
53
+ # Усі записи <logger> для заданого FQCN (записи без атрибута name пропускаються).
54
+ entries_for(name) := [l |
55
+ some l in loggers
56
+ l["-name"] == name
57
+ ]
58
+
59
+ # Нормалізований рівень запису; undefined, якщо атрибут level відсутній або не рядок.
60
+ entry_level(l) := lower(trim_space(l["-level"])) if is_string(l["-level"])
61
+
62
+ # Запис задовольняє вимогу: level читається і є warn/error/off.
63
+ entry_ok(l) if entry_level(l) in allowed_levels
64
+
65
+ # FQCN узагалі не має <logger>-оверрайду.
66
+ deny contains msg if {
67
+ some name in required_loggers
68
+ count(entries_for(name)) == 0
69
+ msg := sprintf(
70
+ "logback.xml: додай <logger name=\"%s\" level=\"warn\"/> — шумний Dremio-logger заливає Cloud Logging (k8s.mdc)",
71
+ [name],
72
+ )
73
+ }
74
+
75
+ # Оверрайд є, але слабший за warn (info/debug/trace), без level або з не-рядковим
76
+ # level. Вимога до КОЖНОГО запису з цим FQCN: дублікати з конфліктними рівнями
77
+ # (logback бере останній) — теж порушення, конфіг має бути однозначним.
78
+ deny contains msg if {
79
+ some name in required_loggers
80
+ some l in entries_for(name)
81
+ not entry_ok(l)
82
+ msg := sprintf(
83
+ "logback.xml: <logger name=\"%s\"> має рівень %v — постав level=\"warn\" або строгіше (error/off) (k8s.mdc)",
84
+ [name, object.get(l, "-level", "«відсутній»")],
85
+ )
86
+ }