Оценки здоровья¶
Qualimetrix определяет шесть измерений здоровья классов, пространств имён и проекта. Оценка от 0 (худшее) до 100 (лучшее) появляется при применимых измеренных входах выбранной формулы. Без этих входов числовой оценки нет; числовой 0 остаётся измерением.
Определения разрешаются отдельно для каждого запуска анализа и вычисляются после агрегации исходных метрик. При повторном запуске в одном процессе набор определений заменяется атомарно, поэтому конфигурация предыдущего запуска не может протечь в следующий.
Rule ID: computed — пользовательские вычисляемые метрики.
Каждое встроенное измерение — самостоятельный производитель и публикует свои находки под собственным rule ID:
- Rule ID:
health.complexity - Rule ID:
health.cohesion - Rule ID:
health.coupling - Rule ID:
health.typing - Rule ID:
health.maintainability - Rule ID:
health.overall
Измерения¶
| Измерение | Что измеряет | Ключевые метрики | Пороги (warning / error) |
|---|---|---|---|
health.complexity |
Сложность методов и классов | CCN (avg, max, p95), Cognitive Complexity | 50 / 25 |
health.cohesion |
Связность методов внутри класса | TCC, LCOM4, количество методов | 50 / 25 |
health.coupling |
Зависимости между классами и пространствами имён | Исходящая связность (Ce, Ce packages), применимая Distance from Main Sequence | 50 / 25 |
health.typing |
Покрытие типами | Типы параметров, возвращаемых значений, свойств | 80 / 50 |
health.maintainability |
Лёгкость безопасной модификации | Maintainability Index (avg, p5, min) | 50 / 25 |
health.overall |
Взвешенное среднее всех измерений | Все вышеперечисленные | 50 / 30 |
Уровни оценки¶
Каждой оценке присваивается текстовый уровень на основе значения относительно порогов warning (W) и error (E):
- Excellent: score > W + (100 − W) × 0.6
- Good: score > W + (100 − W) × 0.3
- Fair: score > W
- Poor: score > E
- Critical: score ≤ E
Для стандартных измерений (W=50, E=25):
| Уровень | Диапазон |
|---|---|
| Excellent | > 80 |
| Good | 65 – 80 |
| Fair | 50 – 65 |
| Poor | 25 – 50 |
| Critical | ≤ 25 |
Пороги health.typing отличаются
У health.typing пороги по умолчанию W=80, E=50, поэтому границы уровней сдвинуты: Excellent > 92, Good > 86, Fair > 80, Poor > 50, Critical ≤ 50.
Как работают оценки¶
Встроенные измерения используют измеренные входы своего уровня, а overall — их взвешенное среднее. Отсутствующие или неприменимые входы не превращаются в выдуманные значения штрафов. Формулы классов читают значения классов, а формулы пространств имён и проекта — соответствующие агрегаты.
health.complexity¶
Штрафует за высокую цикломатическую и когнитивную сложность. На уровне класса учитывается средняя и максимальная сложность методов. На уровне пространства имён дополнительно анализируется p95 (95-й перцентиль), что позволяет обнаруживать выбросы — отдельные аномально сложные методы. Максимальная сложность масштабируется через квадратный корень, чтобы один метод-монстр не обрушивал оценку всего пространства имён.
Методы интерфейсов включены в агрегацию
Методы интерфейсов имеют минимальную сложность (CCN=1, cognitive=0, NPath=1) и включены в расчёт .avg и .p95 на уровне пространства имён. В проектах с большим количеством интерфейсов средняя сложность может оказаться ниже ожидаемой. Это сделано намеренно — интерфейсы являются частью кодовой базы — но добавление интерфейсов может немного улучшить оценку сложности без реальных изменений логики.
health.cohesion¶
Объединяет доступные вклады TCC (Tight Class Cohesion) и LCOM4 и делит на сумму участвующих весов. Отсутствующая половина не заменяется значением по умолчанию, в том числе у классов менее чем с шестью методами. Масштабирование TCC через квадратный корень сохраняется; поправка на чистые методы делится на cohesion.tcc-method-count, а не на size.method-count. Если нет ни измеренного TCC, ни LCOM, оценки cohesion у класса нет.
Cohesion пространства имён и проекта применяет ту же поправку на чистые
методы через cohesion.pure-method-count.avg и
cohesion.tcc-method-count.avg: пространство имён с одним классом получает его
оценку. Health не наследует фильтр минимального числа методов правила LCOM.
LCOM-вклад непустого графа из одной вершины по построению равен 100
(вся оценка равна 100 при отсутствующем TCC); две несвязанные
вершины без поправки на чистые методы дают 40. Это форма графа, а не достаточное
свидетельство разделения обязанностей. В проверенном корпусе одновершинных
классов было 209/877 у Qualimetrix, 164/242 у PHP-Parser, 359/826 у PHPUnit и
153/856 у Laravel.
Вклады LCOM класса и пространства имён используют размах пять. Проверка объявленной сетки из 27 кандидатов сохранила прежнюю шкалу пространства имён. Cohesion проекта наследует эту формулу и вычисляется по агрегированным входам проекта, а не усредняет оценки health пространств имён. Корректное усреднение взаимно дополняющих входов TCC/LCOM может дать оценку выше всех дочерних даже при одинаковой формуле и популяции участников. ADR 0116 сохраняет нативный пример (50/50 → 60.355339) и обязательные проверки реальной потери входов. Сравнения родителя и детей остаются диагностикой.
Измеренная калибровка
Выбраны размах LCOM пять, вес дистанции проекта шесть и вес ширины четыре. ADR 0116 сохраняет результаты всех 27 кандидатов и полные таблицы «до/после» для 17 проектов. Пересмотри зависимые ограничения с учётом новых измеренных популяций.
health.coupling¶
Измеряет зависимости на уровне класса, пространства имён и проекта. Везде применяется гиперболическое затухание: зависимости за пределами порога снижают оценку, но каждая следующая зависимость влияет слабее предыдущей.
- На уровне класса смешиваются
coupling.ce-packages(количество внешних пакетов) и сглаженный rawcoupling.ce(efferent coupling). - На уровне пространства имён используются только efferent-сигналы: средняя
coupling.ce.avgиcoupling.ce-packages.avgпо классам, выброс отдельного класса (coupling.ce.max), а также общая исходящая ширина пространства имён (coupling.ce), плюс Distance from Main Sequence. Двунаправленный CBO здесь намеренно не используется — он смешивает Ca с Ce и несправедливо штрафует «контрактные» пространства имён со стабильно высоким Ca и низким Ce. - На уровне проекта применяется Form B только по исходящим связям:
средняя ширина исходящих пакетов (
coupling.ce-packages.avg),coupling.ce.avgс масштабированием через квадратный корень, исходящие выбросы (coupling.ce.max) и применимаяcoupling.distance-own.avg. Дистанция взвешена подходящими типами измеренных собственных областей. Входящая популярность не штрафует проект; двунаправленный CBO не входит в формулу.
На калибровочном корпусе из 17 проектов штраф ширины был нулевым во всех проектах: составной вход не достигал порога четыре (максимум 2.996722 у Guzzle). Вес ширины четыре выбран порядком сетки при ничьей, а не измеренным эффектом на корпусе. Поэтому на этом корпусе штраф определяется собственной дистанцией и худшим исходящим классом; различать ширину ниже порога формула не обещает.
Project Form B использует вес дистанции шесть и вес ширины четыре:
clamp(100 * 18 / (18 + (m["coupling.distance-own.avg"] ?? 0) * 6 + max((m["coupling.ce-packages.avg"] ?? 0) * 3.0 + (m["coupling.ce.avg"] ?? 0) ** 0.5 * 0.5 - 4, 0) * 4 + max((m["coupling.ce.max"] ?? 0) - 30, 0) ** 0.5 * 0.8), 0, 100)
Для применимости нужен хотя бы один конечный измеренный вход из
coupling.distance-own.avg, coupling.ce-packages.avg, coupling.ce.avg и
coupling.ce.max. Декомпозиция использует те же четыре входа. Отсутствующая
дистанция остаётся отсутствующей в метриках и покрытии; подстановка для
пропущенного слагаемого в формуле не публикует измеренный ноль.
Coupling класса остаётся применимым при измеренном 0. Для coupling пространства имён нужно хотя бы одно конечное измеренное значение среди coupling.distance, coupling.ce-packages.avg, coupling.ce.avg, coupling.ce.max и coupling.ce. Пространство имён только с функциями и без всех пяти входов не получает встроенную оценку coupling. Когда применимое distance не опубликовано, формула использует только остальные измеренные входы; пространству имён без рёбер не назначается distance 1.
health.typing¶
Использует процент класса, когда есть что типизировать. Оценки пространства имён и проекта делят суммы типизированных объявлений на фактическую сумму параметров, возвращаемых значений и свойств. При нулевом знаменателе оценки нет; при положительном знаменателе и отсутствии типов оценка равна 0.
health.maintainability¶
Основана на Maintainability Index. На уровне класса штрафует за низкий средний MI и за отдельные методы с экстремально низким MI (масштабирование через квадратный корень). На уровне пространства имён основные дифференциаторы — p5 (5-й перцентиль) и минимальное значение. Границы штрафов взяты из опубликованных значений Coleman: 85 — «highly maintainable», 65 — «difficult to maintain». Ранее измеренный калибровочный корпус из семнадцати проектов давал от 33.7 до 100.0 на уровне проекта; это исторические данные калибровки.
health.overall¶
Взвешенное среднее всех измерений. Веса различаются по уровням:
- Класс: complexity 35%, cohesion 25%, coupling 25%, typing 15% (maintainability исключена — MI является метрикой уровня метода и её сигнал уже учтён через complexity и cohesion)
- Пространство имён / проект: complexity 30%, cohesion 20%, coupling 20%, typing 10%, maintainability 20%
Overall усредняет только доступные измерения, сохраняя указанный порядок и исходные веса и деля на сумму участвующих весов. Отсутствующим измерениям не подставляется нейтральное значение 75; измеренный 0 участвует. Без участвующих измерений значения overall нет.
Чтение оценок здоровья¶
Оценки здоровья доступны в нескольких форматах вывода:
summary (по умолчанию) — прогресс-бары в терминале:
Qualimetrix — 45 files analyzed, 1.23s
Complexity ████████████████░░░░ 78 Excellent
Cohesion ██████████████░░░░░░ 68 Good
Coupling ████████████░░░░░░░░ 59 Fair
Typing ██████████████████░░ 88 Excellent
Maintainability████████████████░░░░ 80 Good
Overall ██████████████░░░░░░ 72 Good
json — структурированные данные для CI/CD:
health — текстовая таблица оценок здоровья в терминале:
html — интерактивный отчёт с drill-down по пространствам имён и классам:
Подробнее о форматах вывода — в разделе Форматы вывода.
Что именно покрывает оценка¶
Оценка описывает ту часть кода, которую покрывают участвующие входы. Если TCC отсутствует, а cohesion даёт измеренный LCOM, покрытие оценки следует LCOM, а не отсутствующей половине TCC. Покрытие и декомпозиция следуют выбранной формуле, включая входы, которые авторская формула действительно читает; одного имени встроенной метрики недостаточно для подтверждения её данных.
Поэтому каждое измерение здоровья публикует рядом с оценкой поле coverage:
.count самого узкого участвующего входного агрегата, размер популяции, долей которой этот
счёт является, и имя самого .count (basis). Оценка при этом не
приглушается покрытием: число публикуется, чтобы читатель мог судить сам, а не
подмешивается в оценку (см. ADR 0062).
Состояния — measured, not-measured и not-applicable. При положительной
подходящей популяции и отсутствии измеренного входа not-measured показывает
0/N; пустая популяция даёт not-applicable с причиной. Числовой 0 остаётся
измеренным значением. Включённые встроенные измерения проекта сохраняются с
null-оценкой, когда недоступны; выключенные опускаются. Отсутствующие значения
декомпозиции равны null и сохраняют своё покрытие вместо числового 0. При
выборе класса или пространства имён отсутствующая оценка не заменяется
оценкой проекта.
Там, где покрытие не определено, поле говорит об этом явно и с причиной, а не
показывает ноль: health.overall складывается из остальных измерений,
health.typing считается из сумм typed/total, для которых .count не
публикуется, а оценка уровня класса или отфильтрованного пространства имён
вообще не является агрегатом по символам.
Входы классов и size.symbol-class-count считают объявления, включая
отдельные объявления одного имени. Размеры выборок используют ту же популяцию;
покрытие не ограничивается сверху ради сокрытия расхождения.
Отклонение от оригинальной спецификации
Метрики графа связей определены на логических именах. Если у имени несколько объявлений, его графовые значения входят в агрегаты namespace и project по одному разу на объявление. Это расширение метрик графа с весами по числу объявлений.
Покрытие выводится в --format=json (объект coverage у каждого измерения), в
--format=health (колонка Coverage плюс строка на измерение в декомпозиции), в
--format=summary (строка под каждой оценкой) и в --format=html (объект
summary.healthCoverage и подготовленная summary.healthDecomposition рядом с
summary.healthScores). Viewer отображает эти данные PHP без вычисления формул
в JavaScript.
Участники cohesion ранжируются по TCC для всей выбранной области, если она измерена хотя бы у одного кандидата, включая числовой ноль; иначе — по LCOM, от большего значения к меньшему. Кандидаты без выбранной метрики опускаются. Прогон без агрегированных метрик проекта не публикует health: его популяции неизвестны, а не равны нулю.
Покрытие меньше 100% — не обязательно дефект прогона. Часть разрывов постоянна по построению: у маленьких классов TCC может отсутствовать, а у пространства имён, объявляющего одни только голые enum, нет собственной абстрактности — голый enum намеренно вне этого знаменателя (см. Distance from Main Sequence), — поэтому собственная distance для него не публикуется, хотя популяция его считает: тип он объявляет. Знаменатель намеренно не сужен до тех пространств имён, до которых агрегат дошёл: знаменатель, равный собственному обходу агрегата, печатает 100% по построению и не способен показать, куда обход не добрался, — а ради этого строка и существует.
Настройка¶
Допустимые ключи¶
Каждая запись computed_metrics: принимает ровно девять ключей: formula,
formulas, levels, description, inverted, threshold, warning,
error и enabled. threshold задаёт warning и error одним и тем же
значением и не сочетается ни с одним из них в одном слое. Внутри formulas: допустимы
только три слова уровня: class, namespace и project.
Неизвестный ключ, значение неверного типа или имя health.* вне шести
встроенных измерений (health.complexity, health.cohesion,
health.coupling, health.typing, health.maintainability,
health.overall) отклоняются с кодом возврата 3 и сообщением, называющим
написанное и допустимое — ни один из этих случаев не игнорируется молча. Ключ
распознаётся и при значении ~, поэтому warnign: ~ тоже отклоняется.
Между пресетами и вашим файлом¶
computed_metrics сливается метрика за метрикой, а внутри одной метрики — по
ключам: метрика пресета и ключи вашего файла для того же имени объединяются, а
метрика, которую другой слой не называет, остаётся как есть.
thresholdраскрывается вwarningиerrorв написавшем его слое, поэтому файл, написавший поверхthresholdпресета толькоwarning, сохраняет значение пресета какerror.formulaзадаёт все уровни, аformulas.<level>уточняет один уровень — какими бы слоями они ни были написаны:formulas: {class: …}файла поверхformulaпресета меняет только уровень class.- Метрика убирается только через
enabled: false.computed_metrics: {}иhealth.complexity: ~оставляют значения нижнего слоя — ни то, ни другое не сбрасывает ничего к встроенным умолчаниям. exclude_healthнакапливается между слоями.
Правила, общие для всех ключей конфигурации, — в разделе Как сливаются слои.
Настройка порогов¶
# qmx.yaml
computed_metrics:
health.complexity:
warning: 60 # Stricter than default 50
error: 30 # Stricter than default 25
Отключение измерения¶
Или через CLI:
Оба варианта убирают измерение и его каноническое слагаемое overall. Исходные веса и порядок сохраняются; среднее делится на сумму участвующих весов. Неподдерживаемая авторская форма overall отказывает с источником выбранной формулы. Перепиши её в поддерживаемую каноническую форму взвешенного среднего или явно обработай доступность входов в авторской формуле.
Два похожих переключателя, которые делают разное
Каждое встроенное измерение — сам себе производитель, поэтому его можно выключить двумя способами, читающимися почти одинаково:
rules: { health.cohesion: { enabled: false } }останавливает публикацию находок производителемhealth.cohesion. Измерение всё равно вычисляется и продолжает участвовать вhealth.overall.computed_metrics: { health.cohesion: { enabled: false } }убирает само измерение — это переключатель из раздела «Отключение измерения» выше. Весаhealth.overallренормализуются по оставшимся измерениям.
У измерения, убранного вторым способом, у производителя не остаётся ни одного канала. Ключ suppress_namespace_channels, который раньше адресовал health.cohesion, после этого отвергается: ключ обязан называть канал, который правило под ним действительно эмитит, а после удаления оно не эмитит ни одного.
Переопределение формул¶
computed_metrics:
health.maintainability:
# Same formula for all levels
formula: "clamp(m['maintainability.mi.avg'], 0, 100)"
Формула — это выражение, записанное строкой, а константа — тоже выражение:
formula: "80" задаёт метрику, равную 80 везде. Кавычки обязательны: 80 без
них — число, а число формулой не является.
Авторская формула остаётся авторской даже при дословном копировании встроенной. Она использует Always для выбранной формулы, и константа 80 не требует встроенных входов. Изменение только метаданных сохраняет встроенную применимость. Константа не может заявлять декомпозицию или покрытие встроенной формулы; без известной измеренной популяции символов её покрытие равно not-applicable.
computed_metrics:
health.maintainability:
# Different formulas per level
formulas:
class: "clamp(m['maintainability.mi.avg'], 0, 100)"
namespace: "clamp(m['maintainability.mi.avg'] * 0.7 + m['maintainability.mi.p5'] * 0.3, 0, 100)"
project: "clamp(m['maintainability.mi.avg'] * 0.7 + m['maintainability.mi.p5'] * 0.3, 0, 100)"
Пользовательские вычисляемые метрики¶
computed_metrics:
computed.code-density:
formula: "clamp((m['size.lloc'] ?? 0) / max(m['size.loc'] ?? 1, 1) * 100, 0, 100)"
description: "Ratio of logical to physical lines (higher = denser code)"
levels: [namespace] # size.lloc / size.loc — сырые ключи только на уровне namespace
warning: 80
error: 90
inverted: false # Higher values trigger violations
Именование метрик
Имя пользовательской метрики обязано начинаться с health. или computed. — другие префиксы не принимаются. Рекомендуемое соглашение для собственных метрик — computed.*; health.* зарезервирован за шестью встроенными измерениями. Оба префикса требуют строчных kebab-case сегментов после точки (например, computed.code-density); подчёркивания и заглавные буквы отвергаются, а последний сегмент не может совпадать с именем стратегии агрегации (sum, avg, max, min, count, p95, p5 — например, computed.sum отклоняется).
Доступные переменные¶
Формулы обращаются к метрикам через единственный массив m, индексированный настоящим ключом метрики: m["complexity.ccn.avg"]. Отдельного «имени переменной» запоминать не нужно — ключ, который вы видите в выводе --format=metrics/--format=json, и есть индекс.
| Ключ метрики | Доступен на уровне |
|---|---|
complexity.ccn.avg |
class, namespace, project |
complexity.ccn.max |
class, namespace, project |
complexity.ccn.sum |
namespace, project |
complexity.ccn.p95 |
namespace, project |
complexity.cognitive.avg |
class, namespace, project |
complexity.cognitive.max |
class, namespace, project |
complexity.cognitive.sum |
namespace, project |
complexity.cognitive.p95 |
namespace, project |
cohesion.tcc |
class |
cohesion.tcc.avg |
namespace, project |
cohesion.lcom |
class |
cohesion.lcom-method-count |
class |
cohesion.tcc-method-count |
class |
cohesion.unread-trait-count |
class |
cohesion.lcom.avg |
namespace, project |
coupling.cbo.avg |
namespace, project |
coupling.cbo.max |
namespace, project |
coupling.cbo.p95 |
namespace, project |
coupling.ce |
class, namespace |
coupling.ce.avg |
namespace, project |
coupling.ce.max |
namespace, project |
coupling.ce-packages |
class |
coupling.ce-packages.avg |
namespace, project |
coupling.abstractness |
namespace |
coupling.distance |
namespace |
coupling.ca-own |
namespace |
coupling.ce-own |
namespace |
coupling.instability-own |
namespace |
coupling.abstractness-own |
namespace |
coupling.distance-own |
namespace |
coupling.distance-own.avg |
project |
coupling.distance-own.count |
project |
size.symbol-declaring-namespace-count |
project |
maintainability.mi.avg |
class, namespace, project |
maintainability.mi.min |
class, namespace, project |
maintainability.mi.p5 |
namespace, project |
design.type-coverage.all |
class |
design.type-coverage.param.total.sum |
namespace, project |
design.type-coverage.param.typed.sum |
namespace, project |
design.type-coverage.return.total.sum |
namespace, project |
design.type-coverage.return.typed.sum |
namespace, project |
design.type-coverage.property.total.sum |
namespace, project |
design.type-coverage.property.typed.sum |
namespace, project |
size.method-count |
class |
size.symbol-method-count |
class, namespace, project |
cohesion.pure-method-count |
class |
size.loc |
namespace |
size.lloc |
namespace |
health.complexity |
class, namespace, project |
health.cohesion |
class, namespace, project |
health.coupling |
class, namespace, project |
health.typing |
class, namespace, project |
health.maintainability |
class, namespace, project |
Частые агрегатные суффиксы у ключа: .avg, .min, .max, .sum, .p5, .p95.
coupling.instability-own (как и coupling.cbo-own) доступен только на пространстве имён, объявляющем собственный тип: на остальных ключ отсутствует, а не равен 0. Формула, читающая m["coupling.instability-own"] без ??, не получает там значения, и такое пространство имён попадает в computedMetricOutcomes; чтобы сохранить значение, пишите m["coupling.instability-own"] ?? 0. Пространство имён с типом, но без собственных рёбер (Ca-own = Ce-own = 0), несёт 0 по соглашению.
Это не исчерпывающий список — в формулах можно использовать любую метрику, собираемую Qualimetrix, по её ключу. Команда bin/qmx check src/ --format=metrics покажет все доступные метрики и их точные ключи для вашего проекта.
Неизвестные ссылки на метрики
Если формула ссылается на несуществующий ключ метрики (например, опечатка m["complexity.ccn.abg"] вместо m["complexity.ccn.avg"]), Qualimetrix выдаст явную ошибку вместо молчаливого возврата нуля. Используй ??, когда запасное значение имеет смысл для формулы; отсутствие входа отличается от выбранного 0 или нейтрального значения.
Метрики, которых нет на уровне
Формула выполняется на каждом из своих levels:, и ключ проверяется на этом уровне:
- Ни один символ уровня не несёт ключ, а формула читает его без
??— ошибка конфигурации (код выхода 3). Сюда относится и чтение другой computed-метрики на уровне, которого нет в её собственныхlevels::computed.aсlevels: [class]нельзя читать без??в формуле уровняproject, и ошибка называет уровни, на которыхcomputed.aпубликуется. Уровеньproject, унаследовавший формулуnamespace, проверяется какproject. - Ключ есть у части символов — символы без него не получают значения вместо сфабрикованного 0, а успешный отчёт содержит структурную сводку по метрике и уровню: отдельные счётчики недостающих входов и null-результатов, точные недостающие ключи и не более трёх детерминированных примеров точных предметов.
m["a"] ?? m["b"] читает b только там, где нет a, поэтому символ пропускается, лишь когда у него нет ни того, ни другого. Чтобы значение получил каждый символ, завершите цепочку литералом: m["a"] ?? m["b"] ?? 0.
Тернарный оператор читает только ту ветвь, которую выбрал. m["size.method-count"] > 0 ? 7 : m["cohesion.tcc"] читает cohesion.tcc лишь у класса без методов, поэтому ключ, который читает только одна ветвь, никогда не даёт ошибку конфигурации: каждый символ судится по ветви, выбранной его собственными значениями, а символ, чья ветвь читает отсутствующий у него ключ, попадает в ту же сводку отсутствующих значений. Правая часть and / or судится так же. Условие выполняется всегда, поэтому чтение без ?? в нём считается как в арифметике — отсутствующая метрика выбрала бы ветвь ни на чём (null > 0 ложно); защищайте его через ??. Ключ, который читают обе ветви, считается прочитанным.
weighted_mean принимает упорядоченные чередующиеся допускающие null значения и положительные конечные числовые веса. Пропускается только null, 0 сохраняется; без участвующих значений результат равен null. Этот null сохраняется только в точной форме внешнего clamp от weighted mean; обычный clamp от null завершается ошибкой. Остальные функции сохраняют семантику PHP. Неприменимость встроенной формулы не создаёт сообщения; отсутствие у применимой встроенной формулы и ошибки вычисления отказывают с источником выбранной формулы и кодом 3, без успешного частичного отчёта.
Доступные функции¶
| Функция | Описание |
|---|---|
min(a, b) |
Минимум из двух значений |
max(a, b) |
Максимум из двух значений |
abs(x) |
Модуль числа |
sqrt(x) |
Квадратный корень |
log(x) |
Натуральный логарифм |
log10(x) |
Десятичный логарифм |
clamp(value, min, max) |
Ограничение значения диапазоном [min, max] |
weighted_mean(value, weight, ...) |
Среднее участвующих nullable-значений с положительными конечными весами |
?? |
Null coalescing (значение по умолчанию, если метрики нет) |
** |
Возведение в степень |
Выбирай осмысленные значения по умолчанию
Используй ??, когда запасное значение имеет смысл для формулы. Отсутствие входа отличается от выбранного 0 или нейтрального значения; допускающие null значения weighted mean могут оставаться отсутствующими.
Граница для отдельного класса¶
В docblock класса можно установить конечную границу:
@qmx-threshold health.cohesion 40 либо другое точное встроенное правило health.
Поддерживается одна граница: число или одинаковые warning/error. Она меняет
находки этого объявления; пороги неймспейса и проекта остаются в конфигурации,
а действие директивы проверяет qmx directives. Пользовательские метрики
computed.* сохраняют пороги уровня конфигурации.