// src/services/voiceDiag/checks/wan/wanAppRtpMos.js // // Per-application audio MOS — measured on ACTUAL RTP voice traffic // via Prisma DPI, not on synthetic link probes. Metric name on the // v2.6 monitor/metrics endpoint is `AppAudioMos` (unit: count), // requires filter.direction="Ingress". // // Which app is measured depends on the tenant's configured voice // application (PRISMA_APP_ID_VOICE env). Common choices are // `Webex_Calling_RTP` (recommended for Webex Calling shops — the // Webex-specific DPI signature excludes noise from other UDP // traffic that pollutes generic RTP), `rtp-base`, `MS_Teams_RTP`, // etc. The check is app-agnostic; the app name is threaded through // the message + details so operators know which app was graded. // // Grades against the WORST-window MOS in the series. A store that // averages 4.0 MOS over 24h but dipped to 1.85 for several 5-min // windows had unusable calls in those windows — the average smooths // that away and the LQM link-probe average smooths it away twice. // This check is the escape hatch for that failure mode. // // Skipped when the voice-app env is not configured (feature-gated // to keep the extra Prisma API load opt-in per tenant). import { maybeSkippedByKillSwitch, getAppAudio, evaluateAppAudioMetric, getAppMosWarn, getAppMosError, } from './_helpers.js'; export const WAN_APP_RTP_MOS_STANDARDS = Object.freeze({ minWarnMos: 4.0, minErrorMos: 3.5, unit: 'count', reference: 'ITU-T P.800 (MOS)', gradeAgainst: 'worst-window', }); export const wanAppRtpMosCheck = { id: 'wanAppRtpMos', label: 'SD-WAN Voice Traffic MOS (worst window)', requires: ['sdwanSite'], scope: null, standards: WAN_APP_RTP_MOS_STANDARDS, async run(ctx) { const skip = maybeSkippedByKillSwitch(wanAppRtpMosCheck); if (skip) return skip; const audio = getAppAudio(ctx, 'mos'); const warnThresh = getAppMosWarn(); const errorThresh = getAppMosError(); return evaluateAppAudioMetric({ audio, label: 'MOS', unit: '', warnThresh, errorThresh, lowIsBad: true, standardLabel: `warn < ${warnThresh}, error < ${errorThresh}`, }); }, };