From 51bce4624185aa29a95a610437247508849fe88f Mon Sep 17 00:00:00 2001 From: Lucian Ioan <59661554+lucian-ioan@users.noreply.github.com> Date: Fri, 7 Feb 2025 04:21:04 +0200 Subject: [PATCH] [MS365] [Teams Call Quality] Add Teams Call Quality datastream (#12633) --- .github/CODEOWNERS | 1 + .../o365_metrics/_dev/build/docs/README.md | 46 +- packages/o365_metrics/changelog.yml | 8 + .../data_stream/subscriptions/manifest.yml | 2 +- .../_dev/test/pipeline/test-common-config.yml | 2 + .../pipeline/test-teams-call-quality.json | 7 + ...test-teams-call-quality.json-expected.json | 216 +++++++ .../agent/stream/cel.yml.hbs | 133 ++++ .../elasticsearch/ingest_pipeline/default.yml | 182 ++++++ .../teams_call_quality/fields/agent.yml | 33 + .../teams_call_quality/fields/base-fields.yml | 15 + .../teams_call_quality/fields/fields.yml | 504 +++++++++++++++ .../teams_call_quality/manifest.yml | 48 ++ .../teams_call_quality/sample_event.json | 258 ++++++++ packages/o365_metrics/docs/README.md | 580 +++++++++++++++++- packages/o365_metrics/manifest.yml | 2 +- 16 files changed, 2017 insertions(+), 20 deletions(-) create mode 100644 packages/o365_metrics/data_stream/teams_call_quality/_dev/test/pipeline/test-common-config.yml create mode 100644 packages/o365_metrics/data_stream/teams_call_quality/_dev/test/pipeline/test-teams-call-quality.json create mode 100644 packages/o365_metrics/data_stream/teams_call_quality/_dev/test/pipeline/test-teams-call-quality.json-expected.json create mode 100644 packages/o365_metrics/data_stream/teams_call_quality/agent/stream/cel.yml.hbs create mode 100644 packages/o365_metrics/data_stream/teams_call_quality/elasticsearch/ingest_pipeline/default.yml create mode 100644 packages/o365_metrics/data_stream/teams_call_quality/fields/agent.yml create mode 100644 packages/o365_metrics/data_stream/teams_call_quality/fields/base-fields.yml create mode 100644 packages/o365_metrics/data_stream/teams_call_quality/fields/fields.yml create mode 100644 packages/o365_metrics/data_stream/teams_call_quality/manifest.yml create mode 100644 packages/o365_metrics/data_stream/teams_call_quality/sample_event.json diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bb7ef42b683..7903126c180 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -482,3 +482,4 @@ /packages/o365_metrics/data_stream/service_health @elastic/obs-infraobs-integrations /packages/o365_metrics/data_stream/viva_engage_device_usage_user_counts @elastic/obs-infraobs-integrations /packages/o365_metrics/data_stream/subscriptions @elastic/obs-infraobs-integrations +/packages/o365_metrics/data_stream/teams_call_quality @elastic/obs-infraobs-integrations \ No newline at end of file diff --git a/packages/o365_metrics/_dev/build/docs/README.md b/packages/o365_metrics/_dev/build/docs/README.md index 58100f5ad4e..2f558624dc7 100644 --- a/packages/o365_metrics/_dev/build/docs/README.md +++ b/packages/o365_metrics/_dev/build/docs/README.md @@ -8,24 +8,26 @@ Following Microsoft 365 Graph Reports can be collected by Microsoft Office 365 M | Report | API | Data-stream Name | Aggregation Level | |-----------------|-----|-------------|-------------------| -| [Microsoft 365 Active Users Service User Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/active-users-ww?view=o365-worldwide) | [reportRoot: getOffice365ServicesUserCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getoffice365servicesusercounts?view=graph-rest-1.0&tabs=http) | Office 365 Active Users metrics | `Period`-based | +| [Microsoft 365 Active Users Service User Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/active-users-ww?view=o365-worldwide) | [reportRoot: getOffice365ServicesUserCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getoffice365servicesusercounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 Active Users metrics | `Period`-based | | [Microsoft 365 Groups Activity Group Detail](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/office-365-groups-ww?view=o365-worldwide) | [reportRoot: getOffice365GroupsActivityDetail](https://learn.microsoft.com/en-us/graph/api/reportroot-getoffice365groupsactivitydetail?view=graph-rest-1.0&tabs=http) | Microsoft 365 Groups Activity Group Detail | `Day`-based | | [OneDrive Usage Account Detail](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/onedrive-for-business-usage-ww?view=o365-worldwide) | [reportRoot: getOneDriveUsageAccountDetail](https://learn.microsoft.com/en-us/graph/api/reportroot-getonedriveusageaccountdetail?view=graph-rest-1.0&tabs=http) | Microsoft 365 OneDrive Usage Account Detail | `Day`-based | -| [OneDrive Usage Account Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/onedrive-for-business-usage-ww?view=o365-worldwide) | [reportRoot: getOneDriveUsageAccountCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getonedriveusageaccountcounts?view=graph-rest-1.0&tabs=http) | Office 365 One Drive Usage metrics | `Period`-based | -| [OneDrive Usage File Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/onedrive-for-business-usage-ww?view=o365-worldwide) | [reportRoot: getOneDriveUsageFileCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getonedriveusagefilecounts?view=graph-rest-1.0&tabs=http) | Office 365 One Drive Usage metrics | `Period`-based | -| [OneDrive Usage Storage](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/onedrive-for-business-usage-ww?view=o365-worldwide) | [reportRoot: getOneDriveUsageStorage](https://learn.microsoft.com/en-us/graph/api/reportroot-getonedriveusagestorage?view=graph-rest-1.0&tabs=http) | Office 365 One Drive Usage metrics | `Period`-based | -| [Outlook Activity Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/email-activity-ww?view=o365-worldwide) | [reportRoot: getEmailActivityCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getemailactivitycounts?view=graph-rest-1.0&tabs=http) | Office 365 Outlook Activity metrics | `Period`-based | +| [OneDrive Usage Account Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/onedrive-for-business-usage-ww?view=o365-worldwide) | [reportRoot: getOneDriveUsageAccountCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getonedriveusageaccountcounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 One Drive Usage metrics | `Period`-based | +| [OneDrive Usage File Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/onedrive-for-business-usage-ww?view=o365-worldwide) | [reportRoot: getOneDriveUsageFileCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getonedriveusagefilecounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 One Drive Usage metrics | `Period`-based | +| [OneDrive Usage Storage](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/onedrive-for-business-usage-ww?view=o365-worldwide) | [reportRoot: getOneDriveUsageStorage](https://learn.microsoft.com/en-us/graph/api/reportroot-getonedriveusagestorage?view=graph-rest-1.0&tabs=http) | Microsoft 365 One Drive Usage metrics | `Period`-based | +| [Outlook Activity Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/email-activity-ww?view=o365-worldwide) | [reportRoot: getEmailActivityCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getemailactivitycounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 Outlook Activity metrics | `Period`-based | | [Outlook App Usage Version Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/email-apps-usage-ww?view=o365-worldwide) | [reportRoot: getEmailAppUsageVersionsUserCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getemailappusageversionsusercounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 Outlook App Usage Version Counts metrics | `Period`-based | | [Outlook Mailbox Usage Quota Status Mailbox Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/mailbox-usage?view=o365-worldwide) | [reportRoot: getMailboxUsageQuotaStatusMailboxCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getmailboxusagequotastatusmailboxcounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 mailbox usage quota status metrics | `Period`-based | | [Outlook Mailbox Usage Detail](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/mailbox-usage?view=o365-worldwide) | [reportRoot: getMailboxUsageDetail](https://learn.microsoft.com/en-us/graph/api/reportroot-getmailboxusagedetail?view=graph-rest-1.0&tabs=http) | Microsoft 365 mailbox usage detail metrics | `Period`-based | -| [SharePoint Site Usage Storage](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/sharepoint-site-usage-ww?view=o365-worldwide) | [reportRoot: getSharePointSiteUsageStorage](https://learn.microsoft.com/en-us/graph/api/reportroot-getsharepointsiteusagestorage?view=graph-rest-1.0&tabs=http) | Office 365 Sharepoint Site Usage metrics | `Period`-based | -| [SharePoint Site Usage Detail](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/sharepoint-site-usage-ww?view=o365-worldwide) | [reportRoot: getSharePointSiteUsageDetail](https://learn.microsoft.com/en-us/graph/api/reportroot-getsharepointsiteusagedetail?view=graph-rest-1.0&tabs=http) | Office 365 Sharepoint Site Usage metrics | `Period`-based | +| [SharePoint Site Usage Storage](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/sharepoint-site-usage-ww?view=o365-worldwide) | [reportRoot: getSharePointSiteUsageStorage](https://learn.microsoft.com/en-us/graph/api/reportroot-getsharepointsiteusagestorage?view=graph-rest-1.0&tabs=http) | Microsoft 365 Sharepoint Site Usage metrics | `Period`-based | +| [SharePoint Site Usage Detail](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/sharepoint-site-usage-ww?view=o365-worldwide) | [reportRoot: getSharePointSiteUsageDetail](https://learn.microsoft.com/en-us/graph/api/reportroot-getsharepointsiteusagedetail?view=graph-rest-1.0&tabs=http) | Microsoft 365 Sharepoint Site Usage metrics | `Period`-based | | [Teams Device Usage User Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/microsoft-teams-device-usage-preview?view=o365-worldwide) | [reportRoot: getTeamsDeviceUsageUserCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getteamsdeviceusageusercounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 Teams Device Usage User Counts metrics | `Period`-based | | [Teams User Activity User Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/microsoft-teams-user-activity-preview?view=o365-worldwide) | [reportRoot: getTeamsUserActivityUserCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getteamsuseractivityusercounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 Teams User Activity User Counts metrics | `Period`-based | | [Teams User Activity User Detail](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/microsoft-teams-user-activity-preview?view=o365-worldwide) | [reportRoot: getTeamsUserActivityUserDetail](https://learn.microsoft.com/en-us/graph/api/reportroot-getteamsuseractivityuserdetail?view=graph-rest-1.0&tabs=http) | Microsoft 365 Teams User Activity User Detail | `Day`-based | | [Viva Engage Groups Activity Group Detail](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/viva-engage-groups-activity-report-ww?view=o365-worldwide) | [reportRoot: getYammerGroupsActivityDetail](https://learn.microsoft.com/en-us/graph/api/reportroot-getyammergroupsactivitydetail?view=graph-rest-1.0&tabs=http) | Microsoft 365 Viva Engage Groups Activity | `Day`-based | | [Viva Engage Device Usage User Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/viva-engage-device-usage-report-ww?view=o365-worldwide) | [reportRoot: getYammerDeviceUsageUserCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getyammerdeviceusageusercounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 Viva Engage Device Usage User Counts metrics | `Period`-based | -| [Service Health](https://learn.microsoft.com/en-us/graph/service-communications-concept-overview?view=o365-worldwide) | [reportRoot: getServiceHealth](https://learn.microsoft.com/en-us/graph/api/servicehealth-get?view=graph-rest-1.0&tabs=http) | Office 365 Service Health metrics | No aggregation | +| [Service Health](https://learn.microsoft.com/en-us/graph/service-communications-concept-overview?view=o365-worldwide) | [reportRoot: getServiceHealth](https://learn.microsoft.com/en-us/graph/api/servicehealth-get?view=graph-rest-1.0&tabs=http) | Microsoft 365 Service Health metrics | No aggregation | +| [Subscriptions](https://learn.microsoft.com/en-us/graph/api/resources/subscribedsku?view=graph-rest-1.0?view=o365-worldwide) | [reportRoot: subscribedSkus](https://learn.microsoft.com/en-us/graph/api/subscribedsku-list?view=graph-rest-1.0&tabs=http) | Microsoft 365 Subscriptions metrics | No aggregation | +| [Teamms Call Quality](https://learn.microsoft.com/en-us/graph/api/resources/communications-api-overview?view=graph-rest-1.0?view=o365-worldwide) | [reportRoot: callRecords](https://learn.microsoft.com/en-us/graph/api/callrecords-callrecord-list-sessions?view=graph-rest-1.0&tabs=http) | Microsoft 365 Teams Call Quality metrics | No aggregation | ## Setup @@ -41,7 +43,7 @@ Once the application is registered, configure and/or note the following to setup - Navigate to `API permissions` page and click `Add a permission` - Select `Office 365 Management APIs` tile from the listed tiles. - Click `Application permissions`. - - If `User.Read` and `Reports.Read.All` permission under `Microsoft.Graph` tile is not added by default, add this permission. + - If `User.Read` and `Reports.Read.All` permission under `Microsoft.Graph` tile is not added by default, add this permission. Additional permissions, such as `ServiceHealth.Read.All` for data streams like Service Health may be required. Refer to the API documentation under the Permissions section to determine the necessary permissions. - After the permissions are added, the admin has to grant consent for these permissions. Once the secret is created and permissions are granted by admin, setup Elastic Agent's Microsoft O365 integration: @@ -309,3 +311,29 @@ Get details about Service Health from [Microsoft Graph API](https://learn.micros Please refer to the following [document](https://www.elastic.co/guide/en/ecs/current/ecs-field-reference.html) for detailed information on ECS fields. {{fields "service_health"}} + + +### Subscriptions + +Get details about Subscriptions from [Microsoft Graph API](https://learn.microsoft.com/en-us/graph/api/subscribedsku-list?view=graph-rest-1.0&tabs=http). + +{{event "subscriptions"}} + +**ECS Field Reference** + +Please refer to the following [document](https://www.elastic.co/guide/en/ecs/current/ecs-field-reference.html) for detailed information on ECS fields. + +{{fields "subscriptions"}} + + +### Teams Call Quality + +Get details about Teams Call Quality from [Microsoft Graph API](https://learn.microsoft.com/en-us/graph/api/callrecords-callrecord-list-sessions?view=graph-rest-1.0&tabs=http). + +{{event "teams_call_quality"}} + +**ECS Field Reference** + +Please refer to the following [document](https://www.elastic.co/guide/en/ecs/current/ecs-field-reference.html) for detailed information on ECS fields. + +{{fields "teams_call_quality"}} diff --git a/packages/o365_metrics/changelog.yml b/packages/o365_metrics/changelog.yml index 2a69e0d98b0..516bfa6a6c9 100644 --- a/packages/o365_metrics/changelog.yml +++ b/packages/o365_metrics/changelog.yml @@ -1,4 +1,12 @@ # newer versions go on top +- version: "0.5.0" + changes: + - description: Add `subscriptions` data stream. + type: enhancement + link: https://github.com/elastic/integrations/pull/12490 + - description: Add `teams_call_quality` data stream. + type: enhancement + link: https://github.com/elastic/integrations/pull/12633 - version: "0.4.0" changes: - description: Add `teams_device_usage_user_counts` data stream. diff --git a/packages/o365_metrics/data_stream/subscriptions/manifest.yml b/packages/o365_metrics/data_stream/subscriptions/manifest.yml index 548162a372f..c051cb35e4c 100644 --- a/packages/o365_metrics/data_stream/subscriptions/manifest.yml +++ b/packages/o365_metrics/data_stream/subscriptions/manifest.yml @@ -32,7 +32,7 @@ streams: - o365.metrics.subscriptions - name: preserve_original_event required: true - show_user: true + show_user: false title: Preserve original event description: Preserves a raw copy of the original event, added to the field `event.original` type: bool diff --git a/packages/o365_metrics/data_stream/teams_call_quality/_dev/test/pipeline/test-common-config.yml b/packages/o365_metrics/data_stream/teams_call_quality/_dev/test/pipeline/test-common-config.yml new file mode 100644 index 00000000000..e071d397ddf --- /dev/null +++ b/packages/o365_metrics/data_stream/teams_call_quality/_dev/test/pipeline/test-common-config.yml @@ -0,0 +1,2 @@ +dynamic_fields: + "event.ingested": ".*" diff --git a/packages/o365_metrics/data_stream/teams_call_quality/_dev/test/pipeline/test-teams-call-quality.json b/packages/o365_metrics/data_stream/teams_call_quality/_dev/test/pipeline/test-teams-call-quality.json new file mode 100644 index 00000000000..f5f255a490f --- /dev/null +++ b/packages/o365_metrics/data_stream/teams_call_quality/_dev/test/pipeline/test-teams-call-quality.json @@ -0,0 +1,7 @@ +{ + "events": [ + { + "message": "{ \"id\": \"e523d2ed-2966-4b6b-925b-754a88034cc5\", \"modalities\": [ \"audio\" ], \"startDateTime\": \"2020-02-25T18:52:21.2169889Z\", \"endDateTime\": \"2020-02-25T18:52:46.7640013Z\", \"isTest\": false, \"caller\": { \"@odata.type\": \"#microsoft.graph.callRecords.participantEndpoint\", \"name\": \"machineName_1\", \"cpuName\": \"AMD EPYC 7452 32-Core Processor\", \"cpuCoresCount\": 8, \"cpuProcessorSpeedInMhz\": 2346, \"userAgent\": { \"@odata.type\": \"#microsoft.graph.callRecords.clientUserAgent\", \"headerValue\": \"RTCC\/7.0.0.0 UCWA\/7.0.0.0 AndroidLync\/6.25.0.27 (SM-G930U Android 8.0.0)\", \"platform\": \"android\", \"productFamily\": \"skypeForBusiness\" }, \"identity\": { \"@odata.type\": \"#microsoft.graph.identitySet\", \"user\": { \"id\": \"821809f5-0000-0000-0000-3b5136c0e777\", \"displayName\": \"Abbie Wilkins\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\" } } }, \"callee\": { \"@odata.type\": \"#microsoft.graph.callRecords.participantEndpoint\", \"name\": \"machineName_2\", \"cpuName\": \"Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz\", \"cpuCoresCount\": 2, \"cpuProcessorSpeedInMhz\": 2594, \"userAgent\": { \"@odata.type\": \"#microsoft.graph.callRecords.clientUserAgent\", \"headerValue\": \"UCCAPI\/16.0.12527.20122 OC\/16.0.12527.20194 (Skype for Business)\", \"platform\": \"windows\", \"productFamily\": \"skypeForBusiness\" }, \"identity\": { \"user\": { \"id\": \"f69e2c00-0000-0000-0000-185e5f5f5d8a\", \"displayName\": \"Owen Franklin\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\" } }, \"feedback\": { \"rating\": \"poor\", \"tokens\": { \"NoSound\": false, \"OtherNoSound\": false, \"Echo\": false, \"Noisy\": true, \"LowVolume\": false, \"Stopped\": false, \"DistortedSound\": false, \"Interruptions\": false } } }, \"segments\": [ { \"startDateTime\": \"2020-02-25T18:52:21.2169889Z\", \"endDateTime\": \"2020-02-25T18:52:46.7640013Z\", \"id\": \"e523d2ed-2966-4b6b-925b-754a88034cc5\", \"caller\": { \"@odata.type\": \"#microsoft.graph.callRecords.participantEndpoint\", \"name\": \"machineName_1\", \"cpuName\": \"AMD EPYC 7452 32-Core Processor\", \"cpuCoresCount\": 8, \"cpuProcessorSpeedInMhz\": 2346, \"userAgent\": { \"@odata.type\": \"#microsoft.graph.callRecords.clientUserAgent\", \"headerValue\": \"RTCC\/7.0.0.0 UCWA\/7.0.0.0 AndroidLync\/6.25.0.27 (SM-G930U Android 8.0.0)\", \"platform\": \"android\", \"productFamily\": \"skypeForBusiness\" }, \"identity\": { \"user\": { \"id\": \"821809f5-0000-0000-0000-3b5136c0e777\", \"displayName\": \"Abbie Wilkins\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\" } } }, \"callee\": { \"@odata.type\": \"#microsoft.graph.callRecords.participantEndpoint\", \"name\": \"machineName_2\", \"cpuName\": \"Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz\", \"cpuCoresCount\": 2, \"userAgent\": { \"@odata.type\": \"#microsoft.graph.callRecords.clientUserAgent\", \"headerValue\": \"UCCAPI\/16.0.12527.20122 OC\/16.0.12527.20194 (Skype for Business)\", \"platform\": \"windows\", \"productFamily\": \"skypeForBusiness\" }, \"identity\": { \"user\": { \"id\": \"f69e2c00-0000-0000-0000-185e5f5f5d8a\", \"displayName\": \"Owen Franklin\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\" } } }, \"media\": [ { \"label\": \"main-audio\", \"callerNetwork\": { \"ipAddress\": \"10.150.0.2\", \"subnet\": \"10.150.0.0\", \"linkSpeed\": 54000000, \"connectionType\": \"wifi\", \"port\": 27288, \"reflexiveIPAddress\": \"127.0.0.2\", \"relayIPAddress\": \"52.114.188.32\", \"relayPort\": 53889, \"macAddress\": \"00-00-00-00-00-00\", \"dnsSuffix\": null, \"sentQualityEventRatio\": 0, \"receivedQualityEventRatio\": 0.27, \"delayEventRatio\": 0, \"bandwidthLowEventRatio\": 0 }, \"calleeNetwork\": { \"ipAddress\": \"10.139.0.12\", \"subnet\": \"10.139.80.0\", \"linkSpeed\": 4294967295, \"connectionType\": \"wired\", \"port\": 50011, \"reflexiveIPAddress\": \"127.0.0.2\", \"relayIPAddress\": \"52.114.188.102\", \"relayPort\": 52810, \"macAddress\": \"00-00-00-00-00-00-00-00\", \"dnsSuffix\": null, \"sentQualityEventRatio\": 0.31, \"receivedQualityEventRatio\": 0, \"delayEventRatio\": 0, \"bandwidthLowEventRatio\": 0 }, \"callerDevice\": { \"captureDeviceName\": \"Default input device\", \"renderDeviceName\": \"Default output device\", \"receivedSignalLevel\": -10, \"receivedNoiseLevel\": -68, \"initialSignalLevelRootMeanSquare\": 60.25816, \"renderZeroVolumeEventRatio\": 1, \"renderMuteEventRatio\": 1, \"micGlitchRate\": 23, \"speakerGlitchRate\": 3830 }, \"calleeDevice\": { \"captureDeviceName\": \"Microphone (Microsoft Virtual Audio Device (Simple) (WDM))\", \"captureDeviceDriver\": \"Microsoft: 5.0.8638.1100\", \"renderDeviceName\": \"Speakers (Microsoft Virtual Audio Device (Simple) (WDM))\", \"renderDeviceDriver\": \"Microsoft: 5.0.8638.1100\", \"receivedSignalLevel\": -14, \"receivedNoiseLevel\": -86, \"initialSignalLevelRootMeanSquare\": 146.7885, \"micGlitchRate\": 143, \"speakerGlitchRate\": 182 }, \"streams\": [ { \"streamId\": \"1504545584\", \"streamDirection\": \"callerToCallee\", \"averageAudioDegradation\": null, \"averageJitter\": \"PT0.016S\", \"maxJitter\": \"PT0.021S\", \"averagePacketLossRate\": 0, \"maxPacketLossRate\": 0, \"averageRatioOfConcealedSamples\": null, \"maxRatioOfConcealedSamples\": null, \"averageRoundTripTime\": \"PT0.061S\", \"maxRoundTripTime\": \"PT0.079S\", \"packetUtilization\": 67, \"averageBandwidthEstimate\": 9965083, \"wasMediaBypassed\": false, \"averageAudioNetworkJitter\": \"PT0.043S\", \"maxAudioNetworkJitter\": \"PT0.046S\", \"rmsFreezeDuration\": null, \"averageFreezeDuration\": null, \"isAudioForwardErrorCorrectionUsed\": true }, { \"streamId\": \"1785122252\", \"streamDirection\": \"calleeToCaller\", \"averageAudioDegradation\": 1.160898, \"averageJitter\": \"PT0.007S\", \"maxJitter\": \"PT0.012S\", \"averagePacketLossRate\": 0.01381693, \"maxPacketLossRate\": 0.03738318, \"averageRatioOfConcealedSamples\": 0.06233422, \"maxRatioOfConcealedSamples\": 0.07192807, \"averageRoundTripTime\": \"PT0.064S\", \"maxRoundTripTime\": \"PT0.106S\", \"packetUtilization\": 709, \"averageBandwidthEstimate\": 15644878, \"wasMediaBypassed\": false, \"averageAudioNetworkJitter\": \"PT0.266S\", \"maxAudioNetworkJitter\": \"PT0.474S\", \"rmsFreezeDuration\": null, \"averageFreezeDuration\": null, \"isAudioForwardErrorCorrectionUsed\": false } ] } ] } ] }" + } + ] +} diff --git a/packages/o365_metrics/data_stream/teams_call_quality/_dev/test/pipeline/test-teams-call-quality.json-expected.json b/packages/o365_metrics/data_stream/teams_call_quality/_dev/test/pipeline/test-teams-call-quality.json-expected.json new file mode 100644 index 00000000000..37af0553fc0 --- /dev/null +++ b/packages/o365_metrics/data_stream/teams_call_quality/_dev/test/pipeline/test-teams-call-quality.json-expected.json @@ -0,0 +1,216 @@ +{ + "expected": [ + { + "@timestamp": "2020-02-25T18:52:21.2169889Z", + "ecs": { + "version": "8.16.0" + }, + "o365": { + "metrics": { + "teams": { + "call": { + "quality": { + "callee": { + "cpu_cores": { + "count": 2 + }, + "cpu_name": "Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz", + "cpu_processor_speed": { + "mhz": 2594 + }, + "feedback": { + "rating": "poor", + "tokens": { + "distorted_sound": false, + "echo": false, + "interruptions": false, + "low_volume": false, + "no_sound": false, + "noisy": true, + "other_no_sound": false, + "stopped": false + } + }, + "identity": { + "user": { + "display_name": "Owen Franklin", + "id": "f69e2c00-0000-0000-0000-185e5f5f5d8a", + "tenant_id": "dc368399-474c-4d40-900c-6265431fd81f" + } + }, + "name": "machineName_2", + "user_agent": { + "header_value": "UCCAPI/16.0.12527.20122 OC/16.0.12527.20194 (Skype for Business)", + "platform": "windows", + "product_family": "skypeForBusiness" + } + }, + "caller": { + "cpu_cores": { + "count": 8 + }, + "cpu_name": "AMD EPYC 7452 32-Core Processor", + "cpu_processor_speed": { + "mhz": 2346 + }, + "identity": { + "user": { + "display_name": "Abbie Wilkins", + "id": "821809f5-0000-0000-0000-3b5136c0e777", + "tenant_id": "dc368399-474c-4d40-900c-6265431fd81f" + } + }, + "name": "machineName_1", + "user_agent": { + "header_value": "RTCC/7.0.0.0 UCWA/7.0.0.0 AndroidLync/6.25.0.27 (SM-G930U Android 8.0.0)", + "platform": "android", + "product_family": "skypeForBusiness" + } + }, + "end_date_time": "2020-02-25T18:52:46.7640013Z", + "id": "e523d2ed-2966-4b6b-925b-754a88034cc5", + "is_test": false, + "modalities": [ + "audio" + ], + "segments": { + "callee": { + "cpu_cores_count": 2, + "cpu_name": "Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz", + "identity": { + "user": { + "display_name": "Owen Franklin", + "id": "f69e2c00-0000-0000-0000-185e5f5f5d8a", + "tenant_id": "dc368399-474c-4d40-900c-6265431fd81f" + } + }, + "name": "machineName_2", + "user_agent": { + "header_value": "UCCAPI/16.0.12527.20122 OC/16.0.12527.20194 (Skype for Business)", + "platform": "windows", + "product_family": "skypeForBusiness" + } + }, + "caller": { + "cpu_cores_count": 8, + "cpu_name": "AMD EPYC 7452 32-Core Processor", + "cpu_processor_speed_in_mhz": 2346, + "identity": { + "user": { + "display_name": "Abbie Wilkins", + "id": "821809f5-0000-0000-0000-3b5136c0e777", + "tenant_id": "dc368399-474c-4d40-900c-6265431fd81f" + } + }, + "name": "machineName_1", + "user_agent": { + "header_value": "RTCC/7.0.0.0 UCWA/7.0.0.0 AndroidLync/6.25.0.27 (SM-G930U Android 8.0.0)", + "platform": "android", + "product_family": "skypeForBusiness" + } + }, + "end_date_time": "2020-02-25T18:52:46.7640013Z", + "id": "e523d2ed-2966-4b6b-925b-754a88034cc5", + "media": { + "callee_device": { + "capture_device_driver": "Microsoft: 5.0.8638.1100", + "capture_device_name": "Microphone (Microsoft Virtual Audio Device (Simple) (WDM))", + "initial_signal_level_root_mean_square": 146.7885, + "mic_glitch_rate": 143, + "received_noise_level": -86, + "received_signal_level": -14, + "render_device_driver": "Microsoft: 5.0.8638.1100", + "render_device_name": "Speakers (Microsoft Virtual Audio Device (Simple) (WDM))", + "speaker_glitch_rate": 182 + }, + "callee_network": { + "bandwidth_low_event_ratio": 0, + "connection_type": "wired", + "delay_event_ratio": 0, + "ip_address": "10.139.0.12", + "link_speed": 4294967295, + "mac_address": "00-00-00-00-00-00-00-00", + "port": 50011, + "received_quality_event_ratio": 0, + "reflexive_ip_address": "127.0.0.2", + "relay_ip_address": "52.114.188.102", + "relay_port": 52810, + "sent_quality_event_ratio": 0.31, + "subnet": "10.139.80.0" + }, + "caller_device": { + "capture_device_name": "Default input device", + "initial_signal_level_root_mean_square": 60.25816, + "mic_glitch_rate": 23, + "received_noise_level": -68, + "received_signal_level": -10, + "render_device_name": "Default output device", + "render_mute_event_ratio": 1, + "render_zero_volume_event_ratio": 1, + "speaker_glitch_rate": 3830 + }, + "caller_network": { + "bandwidth_low_event_ratio": 0, + "connection_type": "wifi", + "delay_event_ratio": 0, + "ip_address": "10.150.0.2", + "link_speed": 54000000, + "mac_address": "00-00-00-00-00-00", + "port": 27288, + "received_quality_event_ratio": 0.27, + "reflexive_ip_address": "127.0.0.2", + "relay_ip_address": "52.114.188.32", + "relay_port": 53889, + "sent_quality_event_ratio": 0, + "subnet": "10.150.0.0" + }, + "label": "main-audio", + "streams": [ + { + "average_audio_network_jitter": "PT0.043S", + "average_bandwidth_estimate": 9965083, + "average_jitter": "PT0.016S", + "average_packet_loss_rate": 0, + "average_round_trip_time": "PT0.061S", + "is_audio_forward_error_correction_used": true, + "max_audio_network_jitter": "PT0.046S", + "max_jitter": "PT0.021S", + "max_packet_loss_rate": 0, + "max_round_trip_time": "PT0.079S", + "packet_utilization": 67, + "stream_direction": "callerToCallee", + "stream_id": "1504545584", + "was_media_bypassed": false + }, + { + "average_audio_degradation": 1.160898, + "average_audio_network_jitter": "PT0.266S", + "average_bandwidth_estimate": 15644878, + "average_jitter": "PT0.007S", + "average_packet_loss_rate": 0.01381693, + "average_ratio_of_concealed_samples": 0.06233422, + "average_round_trip_time": "PT0.064S", + "is_audio_forward_error_correction_used": false, + "max_audio_network_jitter": "PT0.474S", + "max_jitter": "PT0.012S", + "max_packet_loss_rate": 0.03738318, + "max_ratio_of_concealed_samples": 0.07192807, + "max_round_trip_time": "PT0.106S", + "packet_utilization": 709, + "stream_direction": "calleeToCaller", + "stream_id": "1785122252", + "was_media_bypassed": false + } + ] + }, + "start_date_time": "2020-02-25T18:52:21.2169889Z" + }, + "start_date_time": "2020-02-25T18:52:21.2169889Z" + } + } + } + } + } + } + ] +} diff --git a/packages/o365_metrics/data_stream/teams_call_quality/agent/stream/cel.yml.hbs b/packages/o365_metrics/data_stream/teams_call_quality/agent/stream/cel.yml.hbs new file mode 100644 index 00000000000..66392448d27 --- /dev/null +++ b/packages/o365_metrics/data_stream/teams_call_quality/agent/stream/cel.yml.hbs @@ -0,0 +1,133 @@ +config_version: 2 +interval: {{interval}} +auth.oauth2: + client.id: {{client_id}} + client.secret: {{client_secret}} + provider: azure + scopes: +{{#each token_scopes as |token_scope|}} + - {{token_scope}} +{{/each}} + endpoint_params: + grant_type: client_credentials +{{#if token_url}} + token_url: {{token_url}}/{{azure_tenant_id}}/oauth2/v2.0/token +{{else if azure_tenant_id}} + azure.tenant_id: {{azure_tenant_id}} +{{/if}} + +resource.url: {{url}} +{{#if resource_ssl}} +resource.ssl: + {{resource_ssl}} +{{/if}} + +{{#if enable_request_tracer}} +resource.tracer.filename: "../../logs/cel/http-request-trace-*.ndjson" +{{/if}} + +tags: +{{#if preserve_original_event}} + - preserve_original_event +{{/if}} +{{#each tags as |tag|}} + - {{tag}} +{{/each}} +{{#contains "forwarded" tags}} +publisher_pipeline.disable_host: true +{{/contains}} +{{#if processors}} +processors: +{{processors}} +{{/if}} + +state: + want_more: false + base: + tenant_id: "{{azure_tenant_id}}" + period: "{{period}}" + +redact: + fields: + - base.tenant_id + +program: | + ( + has(state.worklist) && size(state.worklist) > 0 ? + state + : + state.with( + request( + "GET", + state.url.trim_right("/") + "/communications/callRecords" + ).do_request().as(resp, resp.StatusCode == 200 ? + bytes(resp.Body).decode_json().as(body, { + "worklist": body.value.collate("id"), + "next": 0, + }) + : + { + "events": { + "error": { + "code": string(resp.StatusCode), + "id": string(resp.Status), + "message": "GET /callRecords:"+ ( + size(resp.Body) != 0 ? + string(resp.Body) + : + string(resp.Status) + ' (' + string(resp.StatusCode) + ')' + ), + }, + }, + "want_more": false, + } + )) + ).as(state, state.with( + !has(state.worklist) ? state : // Exit early due to GET failure. + state.worklist[?state.?next.orValue(-1)].hasValue() ? + request( + "GET", + has(state.next_page) && state.next_page != "" ? + state.next_page + : + state.url + "/communications/callRecords/" + state.worklist[state.next] + "/sessions?$expand=segments" + ).do_request().as(resp, resp.StatusCode == 200 ? + bytes(resp.Body).decode_json().as(body,{ + "events": ( + has(body.value) && size(body.value) > 0 ? + body.value.map(e, { + "message": e.encode_json() + }) + : + [{"message":"retry"}] + ), + "worklist": int(state.next) + 1 < size(state.worklist) ? state.worklist : [], + "next": int(state.next) + 1 < size(state.worklist) ? (has(state.next_page) && state.next_page != "" ? int(state.next) : int(state.next) + 1) : 0, + "want_more": int(state.next) + 1 < size(state.worklist) || "@odata.nextLink" in body, + "next_page": "@odata.nextLink" in body ? body["@odata.nextLink"] : "", + }) + : + { + "events": { + "error": { + "code": string(resp.StatusCode), + "id": string(resp.Status), + "message": "GET /communications/callRecords/"+state.worklist[state.next].name+"/alerts:"+( + size(resp.Body) != 0 ? + string(resp.Body) + : + string(resp.Status) + ' (' + string(resp.StatusCode) + ')' + ), + }, + }, + "want_more": false, + } + ) + : + { + "events": [], + "want_more": false, + "next_page": {}, + } + ) + ) \ No newline at end of file diff --git a/packages/o365_metrics/data_stream/teams_call_quality/elasticsearch/ingest_pipeline/default.yml b/packages/o365_metrics/data_stream/teams_call_quality/elasticsearch/ingest_pipeline/default.yml new file mode 100644 index 00000000000..cc491908c85 --- /dev/null +++ b/packages/o365_metrics/data_stream/teams_call_quality/elasticsearch/ingest_pipeline/default.yml @@ -0,0 +1,182 @@ +--- +description: Pipeline for processing Teams Call Quality fields +processors: + - set: + field: ecs.version + value: "8.16.0" + + - set: + copy_from: message + field: event.original + ignore_empty_value: true + if: ctx.event?.original == null && (ctx.tags != null && (ctx.tags.contains('preserve_original_event'))) + - json: + field: message + target_field: o365.metrics.teams.call.quality + on_failure: + - append: + field: error.message + value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}' + +### Rename all fields to snake_case + - script: + lang: painless + ignore_failure: true + source: | + // Helper function to convert camelCase to snake_case + String camelToSnake(String str) { + def result = ""; + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (Character.isUpperCase(c)) { + if (i > 0) { + result += "_"; + } + result += Character.toLowerCase(c); + } else { + result += c; + } + } + return result; + } + + // Recursive function to handle nested fields + def convertToSnakeCase(def obj) { + if (obj instanceof Map) { + // Convert each key in the map + def newObj = [:]; + for (entry in obj.entrySet()) { + // Skip fields that contain '@' in their name + if (!entry.getKey().contains("@")) { + String newKey = camelToSnake(entry.getKey()); + newObj[newKey] = convertToSnakeCase(entry.getValue()); + } + } + return newObj; + } else if (obj instanceof List) { + // If it's a list, process each item recursively + def newList = []; + for (item in obj) { + newList.add(convertToSnakeCase(item)); + } + return newList; + } else { + return obj; + } + } + + // Apply conversion to the document's source + if (ctx.o365?.metrics?.teams?.call?.quality != null) { + ctx.o365.metrics.teams.call.quality = convertToSnakeCase(ctx.o365.metrics.teams.call.quality); + } + + - rename: + field: o365.metrics.teams.call.quality.callee.cpu_processor_speed_in_mhz + target_field: o365.metrics.teams.call.quality.callee.cpu_processor_speed.mhz + ignore_missing: true + - rename: + field: o365.metrics.teams.call.quality.callee.cpu_cores_count + target_field: o365.metrics.teams.call.quality.callee.cpu_cores.count + ignore_missing: true + - rename: + field: o365.metrics.teams.call.quality.caller.cpu_processor_speed_in_mhz + target_field: o365.metrics.teams.call.quality.caller.cpu_processor_speed.mhz + ignore_missing: true + - rename: + field: o365.metrics.teams.call.quality.caller.cpu_cores_count + target_field: o365.metrics.teams.call.quality.caller.cpu_cores.count + ignore_missing: true + - rename: + field: o365.metrics.teams.call.quality.segments.caller.cpu_processor_speed_in_mhz + target_field: o365.metrics.teams.call.quality.segments.caller.cpu_processor_speed.mhz + ignore_missing: true + + - script: + description: Keeps only the first item in segments the list and converts it to JSON + lang: painless + ignore_failure: true + source: > + if (ctx.o365?.metrics?.teams?.call?.quality?.segments instanceof List && ctx.o365.metrics.teams.call.quality.segments.size() > 0) { + ctx.o365.metrics.teams.call.quality.segments = ctx.o365.metrics.teams.call.quality.segments[0]; + } + + - script: + description: Keeps only the first item in the media list and converts it to JSON + lang: painless + ignore_failure: true + source: > + if (ctx.o365?.metrics?.teams?.call?.quality?.segments?.media instanceof List && ctx.o365.metrics.teams.call.quality.segments.media.size() > 0) { + ctx.o365.metrics.teams.call.quality.segments.media = ctx.o365.metrics.teams.call.quality.segments.media[0]; + } + +## Cleanup for snake_case renaming script + - rename: + field: o365.metrics.teams.call.quality.segments.media.callee_network.reflexive_i_p_address + target_field: o365.metrics.teams.call.quality.segments.media.callee_network.reflexive_ip_address + ignore_missing: true + - rename: + field: o365.metrics.teams.call.quality.segments.media.callee_network.relay_i_p_address + target_field: o365.metrics.teams.call.quality.segments.media.callee_network.relay_ip_address + ignore_missing: true + - rename: + field: o365.metrics.teams.call.quality.segments.media.caller_network.reflexive_i_p_address + target_field: o365.metrics.teams.call.quality.segments.media.caller_network.reflexive_ip_address + ignore_missing: true + - rename: + field: o365.metrics.teams.call.quality.segments.media.caller_network.relay_i_p_address + target_field: o365.metrics.teams.call.quality.segments.media.caller_network.relay_ip_address + ignore_missing: true + + + - script: + description: Drops null/empty values recursively. + ignore_failure: true + lang: painless + source: | + boolean drop(Object o) { + if (o == null || o == "") { + return true; + } else if (o instanceof Map) { + ((Map) o).values().removeIf(v -> drop(v)); + return (((Map) o).size() == 0); + } else if (o instanceof List) { + ((List) o).removeIf(v -> drop(v)); + return (((List) o).length == 0); + } + return false; + } + drop(ctx); + + + - fingerprint: + fields: + - o365.metrics.teams.call.quality.id + target_field: _id + + - set: + field: '@timestamp' + tag: set_timestamp_from_teams.call.quality.start_date_time + copy_from: o365.metrics.teams.call.quality.start_date_time + ignore_empty_value: true + + - remove: + if: ctx.message != null + field: message + ignore_missing: true + +on_failure: + - set: + field: error.message + value: 'Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}' + - append: + field: event.kind + value: pipeline_error + allow_duplicates: false + - append: + field: event.type + value: error + if: ctx.error?.message != null + - append: + field: tags + value: preserve_original_event + allow_duplicates: false \ No newline at end of file diff --git a/packages/o365_metrics/data_stream/teams_call_quality/fields/agent.yml b/packages/o365_metrics/data_stream/teams_call_quality/fields/agent.yml new file mode 100644 index 00000000000..2bc58530bac --- /dev/null +++ b/packages/o365_metrics/data_stream/teams_call_quality/fields/agent.yml @@ -0,0 +1,33 @@ +- name: cloud + title: Cloud + group: 2 + description: Fields related to the cloud or infrastructure the events are coming from. + footnote: 'Examples: If Metricbeat is running on an EC2 host and fetches data from its host, the cloud info contains the data about this machine. If Metricbeat runs on a remote machine outside the cloud and fetches data from a service running in the cloud, the field contains cloud data from the machine the service is running on.' + type: group + fields: + - name: image.id + type: keyword + description: Image ID for the cloud instance. +- name: host + title: Host + group: 2 + description: 'A host is defined as a general computing instance. ECS host.* fields should be populated with details about the host on which the event happened, or from which the measurement was taken. Host types include hardware, virtual machines, Docker containers, and Kubernetes nodes.' + type: group + fields: + - name: containerized + type: boolean + description: > + If the host is a container. + + - name: os.build + type: keyword + example: "18D109" + description: > + OS build information. + + - name: os.codename + type: keyword + example: "stretch" + description: > + OS codename, if any. + diff --git a/packages/o365_metrics/data_stream/teams_call_quality/fields/base-fields.yml b/packages/o365_metrics/data_stream/teams_call_quality/fields/base-fields.yml new file mode 100644 index 00000000000..71df896d68c --- /dev/null +++ b/packages/o365_metrics/data_stream/teams_call_quality/fields/base-fields.yml @@ -0,0 +1,15 @@ +- name: data_stream.type + type: constant_keyword + description: Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: Data stream namespace. +- name: input.type + type: keyword + description: Type of Filebeat input. +- name: '@timestamp' + type: date + description: Event timestamp. diff --git a/packages/o365_metrics/data_stream/teams_call_quality/fields/fields.yml b/packages/o365_metrics/data_stream/teams_call_quality/fields/fields.yml new file mode 100644 index 00000000000..fdd2fe5144e --- /dev/null +++ b/packages/o365_metrics/data_stream/teams_call_quality/fields/fields.yml @@ -0,0 +1,504 @@ +- name: o365.metrics.teams.call.quality + type: group + description: Teams Call Quality fields processing + fields: + - name: id + type: keyword + description: Unique identifier for the call quality record + - name: is_test + type: boolean + description: Indicates whether the call is a test call + - name: modalities + type: keyword + description: Types of communication used in the call (audio, video, etc.) + - name: start_date_time + type: date + description: The start date and time of the call + - name: end_date_time + type: date + description: The end date and time of the call + - name: caller + type: group + description: Information about the caller (initiator) + fields: + - name: name + type: keyword + description: The name of the caller + - name: user_agent + type: group + description: Information about the caller's user agent + fields: + - name: header_value + type: keyword + description: The header value of the user agent + - name: platform + type: keyword + description: The platform of the caller (e.g., Windows, macOS) + - name: product_family + type: keyword + description: The product family of the caller (e.g., Teams, Skype) + - name: cpu_cores.count + type: long + description: The number of CPU cores on the caller's device + - name: cpu_name + type: keyword + description: The name of the CPU on the caller's device + - name: cpu_processor_speed.mhz + type: long + description: The processor speed in MHz on the caller's CPU + - name: identity + type: group + description: Identity of the caller + fields: + - name: user + type: group + description: User information for the caller + fields: + - name: display_name + type: keyword + description: The display name of the caller + - name: id + type: keyword + description: The unique user ID for the caller + - name: tenant_id + type: keyword + description: The tenant ID of the caller's organization + - name: callee + type: group + description: Information about the callee (receiver) + fields: + - name: name + type: keyword + description: The name of the callee + - name: user_agent + type: group + description: Information about the callee's user agent + fields: + - name: header_value + type: keyword + description: The header value of the user agent + - name: platform + type: keyword + description: The platform of the callee (e.g., Windows, macOS) + - name: product_family + type: keyword + description: The product family of the callee (e.g., Teams, Skype) + - name: cpu_cores.count + type: long + description: The number of CPU cores on the callee's device + - name: cpu_name + type: keyword + description: The name of the CPU on the callee's device + - name: cpu_processor_speed.mhz + type: long + description: The processor speed in MHz on the callee's CPU + - name: feedback + type: group + description: Feedback provided by the callee during the call + fields: + - name: rating + type: keyword + description: The rating the callee gave for the call quality + - name: tokens + type: group + description: Feedback tokens from the callee + fields: + - name: distorted_sound + type: boolean + description: Whether distorted sound was reported by the callee + - name: echo + type: boolean + description: Whether echo was reported by the callee + - name: interruptions + type: boolean + description: Whether interruptions were reported by the callee + - name: low_volume + type: boolean + description: Whether low volume was reported by the callee + - name: no_sound + type: boolean + description: Whether no sound was reported by the callee + - name: noisy + type: boolean + description: Whether background noise was reported by the callee + - name: other_no_sound + type: boolean + description: Whether other no sound issues were reported by the callee + - name: stopped + type: boolean + description: Whether the call was stopped prematurely by the callee + - name: identity + type: group + description: Identity of the callee + fields: + - name: user + type: group + description: User information for the callee + fields: + - name: display_name + type: keyword + description: The display name of the callee + - name: id + type: keyword + description: The unique user ID for the callee + - name: tenant_id + type: keyword + description: The tenant ID of the callee's organization + - name: segments + type: group + description: Segments of the call quality + fields: + - name: id + type: keyword + description: Unique identifier for the segment + - name: start_date_time + type: date + description: Start time of the segment + - name: end_date_time + type: date + description: End time of the segment + - name: quality_score + type: float + description: Quality score of the call segment + - name: callee + type: group + description: Information about the callee (receiver) + fields: + - name: name + type: keyword + description: The name of the callee + - name: user_agent + type: group + description: Information about the callee's user agent + fields: + - name: header_value + type: keyword + description: The header value of the user agent + - name: platform + type: keyword + description: The platform of the callee (e.g., Windows, macOS) + - name: product_family + type: keyword + description: The product family of the callee (e.g., Teams, Skype) + - name: cpu_cores_count + type: long + description: The number of CPU cores on the callee's device + - name: cpu_name + type: keyword + description: The name of the CPU on the callee's device + - name: cpu_processor_speed_in_mhz + type: long + description: The processor speed in MHz on the callee's CPU + - name: feedback + type: group + description: Feedback provided by the callee during the call + fields: + - name: rating + type: keyword + description: The rating the callee gave for the call quality + - name: tokens + type: group + description: Feedback tokens from the callee + fields: + - name: distorted_sound + type: boolean + description: Whether distorted sound was reported by the callee + - name: echo + type: boolean + description: Whether echo was reported by the callee + - name: interruptions + type: boolean + description: Whether interruptions were reported by the callee + - name: low_volume + type: boolean + description: Whether low volume was reported by the callee + - name: no_sound + type: boolean + description: Whether no sound was reported by the callee + - name: noisy + type: boolean + description: Whether background noise was reported by the callee + - name: other_no_sound + type: boolean + description: Whether other no sound issues were reported by the callee + - name: stopped + type: boolean + description: Whether the call was stopped prematurely by the callee + - name: identity + type: group + description: Identity of the callee + fields: + - name: user + type: group + description: User information for the callee + fields: + - name: display_name + type: keyword + description: The display name of the callee + - name: id + type: keyword + description: The unique user ID for the callee + - name: tenant_id + type: keyword + description: The tenant ID of the callee's organization + - name: caller + type: group + description: Information about the caller (initiator) + fields: + - name: name + type: keyword + description: The name of the caller + - name: user_agent + type: group + description: Information about the caller's user agent + fields: + - name: header_value + type: keyword + description: The header value of the user agent + - name: platform + type: keyword + description: The platform of the caller (e.g., Windows, macOS) + - name: product_family + type: keyword + description: The product family of the caller (e.g., Teams, Skype) + - name: cpu_cores_count + type: long + description: The number of CPU cores on the caller's device + - name: cpu_name + type: keyword + description: The name of the CPU on the caller's device + - name: cpu_processor_speed_in_mhz + type: long + description: The processor speed in MHz on the caller's CPU + - name: identity + type: group + description: Identity of the caller + fields: + - name: user + type: group + description: User information for the caller + fields: + - name: display_name + type: keyword + description: The display name of the caller + - name: id + type: keyword + description: The unique user ID for the caller + - name: tenant_id + type: keyword + description: The tenant ID of the caller's organization + - name: media + type: group + description: Media data related to the segment (network and device quality) + fields: + - name: label + type: keyword + description: The label for the media stream (e.g., "main-audio") + - name: caller_network + type: group + description: Network details of the caller during the media stream + fields: + - name: ip_address + type: keyword + description: IP address of the caller's network + - name: subnet + type: keyword + description: Subnet of the caller's network + - name: link_speed + type: long + description: Link speed of the caller's network connection + - name: connection_type + type: keyword + description: Type of connection used (e.g., wifi, wired) + - name: port + type: long + description: Port used for the connection + - name: relay_port + type: long + description: Relay port + - name: mac_address + type: keyword + description: MAC address of the caller's device + - name: sent_quality_event_ratio + type: float + description: Quality event ratio related to the caller's network + - name: received_quality_event_ratio + type: float + description: Quality event ratio related to the received network quality + - name: bandwidth_low_event_ratio + type: float + description: The event ratio of low bandwidth for the caller's network + - name: delay_event_ratio + type: float + description: The event ratio of delay in the caller's network + - name: relay_ip_address + type: keyword + description: Relay IP address for the caller's network + - name: dns_suffix + type: keyword + description: DNS suffix for the caller's network + - name: reflexive_ip_address + type: keyword + description: Reflexive IP address for the caller's network + - name: callee_network + type: group + description: Network details of the callee during the media stream + fields: + - name: ip_address + type: keyword + description: IP address of the callee's network + - name: subnet + type: keyword + description: Subnet of the callee's network + - name: link_speed + type: long + description: Link speed of the callee's network connection + - name: connection_type + type: keyword + description: Type of connection used (e.g., wifi, wired) + - name: port + type: long + description: Port used for the connection + - name: relay_port + type: long + description: Relay port + - name: mac_address + type: keyword + description: MAC address of the callee's device + - name: sent_quality_event_ratio + type: float + description: Quality event ratio related to the callee's network + - name: received_quality_event_ratio + type: float + description: Quality event ratio related to the received network quality + - name: bandwidth_low_event_ratio + type: float + description: The event ratio of low bandwidth for the callee's network + - name: relay_ip_address + type: keyword + description: Relay IP address for the callee's network + - name: dns_suffix + type: keyword + description: DNS suffix for the callee's network + - name: reflexive_ip_address + type: keyword + description: Reflexive IP address for the callee's network + - name: delay_event_ratio + type: float + description: The event ratio of delay in the callee's network + - name: caller_device + type: group + description: Device details for the caller during the media stream + fields: + - name: capture_device_name + type: keyword + description: The name of the caller's capture device + - name: render_device_name + type: keyword + description: The name of the caller's render device + - name: received_signal_level + type: float + description: The received signal level on the caller's device + - name: received_noise_level + type: float + description: The received noise level on the caller's device + - name: initial_signal_level_root_mean_square + type: float + description: Initial RMS of the caller's signal level + - name: render_zero_volume_event_ratio + type: float + description: Ratio of zero volume events during rendering + - name: render_mute_event_ratio + type: float + description: Ratio of mute events during rendering + - name: mic_glitch_rate + type: float + description: The glitch rate for the caller's microphone + - name: speaker_glitch_rate + type: float + description: The glitch rate for the caller's speaker + - name: callee_device + type: group + description: Device details for the callee during the media stream + fields: + - name: capture_device_name + type: keyword + description: The name of the callee's capture device + - name: capture_device_driver + type: keyword + description: The name of the callee's capture device driver + - name: render_device_name + type: keyword + description: The name of the callee's render device + - name: render_device_driver + type: keyword + description: The name of the callee's render device driver + - name: received_signal_level + type: float + description: The received signal level on the callee's device + - name: received_noise_level + type: float + description: The received noise level on the callee's device + - name: initial_signal_level_root_mean_square + type: float + description: Initial RMS of the callee's signal level + - name: mic_glitch_rate + type: float + description: The glitch rate for the callee's microphone + - name: speaker_glitch_rate + type: float + description: The glitch rate for the callee's speaker + - name: streams + type: nested + description: Streams of the call + fields: + - name: stream_id + type: keyword + description: The stream ID + - name: stream_direction + type: keyword + description: Direction of the media stream + - name: average_packet_loss_rate + type: float + description: Average rate of packet loss + - name: max_packet_loss_rate + type: float + description: Maximum rate of packet loss + - name: average_round_trip_time + type: keyword + description: Average round trip time in milliseconds + - name: max_round_trip_time + type: keyword + description: Maximum round trip time in milliseconds + - name: packet_utilization + type: float + description: Utilization rate of packets + - name: was_media_bypassed + type: boolean + description: Indicates if media was bypassed + - name: is_audio_forward_error_correction_used + type: boolean + description: Indicates if audio forward error correction was used + - name: average_jitter + type: keyword + description: Average jitter in milliseconds + - name: max_jitter + type: keyword + description: Maximum jitter in milliseconds + - name: average_audio_network_jitter + type: keyword + description: Average audio network jitter in milliseconds + - name: max_audio_network_jitter + type: keyword + description: Maximum audio network jitter in milliseconds + - name: average_bandwidth_estimate + type: float + description: Average bandwidth estimate in bits per second + - name: max_ratio_of_concealed_samples + type: float + - name: average_audio_degradation + type: float + description: Average audio degradation metric + - name: average_ratio_of_concealed_samples + type: float + description: Average ratio of concealed samples \ No newline at end of file diff --git a/packages/o365_metrics/data_stream/teams_call_quality/manifest.yml b/packages/o365_metrics/data_stream/teams_call_quality/manifest.yml new file mode 100644 index 00000000000..3e0226bcec5 --- /dev/null +++ b/packages/o365_metrics/data_stream/teams_call_quality/manifest.yml @@ -0,0 +1,48 @@ +title: Microsoft 365 Teams Call Quality +type: metrics +streams: + - input: cel + title: Microsoft 365 Teams Call Quality metrics. + enabled: false + description: Collect Microsoft 365 Teams Call Quality metrics. + template_path: cel.yml.hbs + vars: + - name: interval + type: text + title: Interval + description: How often the API is polled, supports seconds, minutes and hours. + show_user: true + required: true + default: 12h + - name: processors + type: yaml + title: Processors + multi: false + required: false + show_user: false + description: > + Processors are used to reduce the number of fields in the exported event or to enhance the event with metadata. This executes in the agent before the logs are parsed. See [Processors](https://www.elastic.co/guide/en/fleet/current/elastic-agent-processor-configuration.html) for details. + - name: tags + type: text + title: Tags + multi: true + required: true + show_user: false + default: + - o365.metrics.teams.call.quality + - name: enable_request_tracer + type: bool + title: Enable request tracing + multi: false + required: false + show_user: false + description: >- + The request tracer logs HTTP requests and responses to the agent's local file-system for debugging configurations. Enabling this request tracing compromises security and should only be used for debugging. See [documentation](https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-input-cel.html#_resource_tracer_filename) for details. + - name: preserve_original_event + required: true + show_user: false + title: Preserve original event + description: Preserves a raw copy of the original event, added to the field `event.original` + type: bool + multi: false + default: false \ No newline at end of file diff --git a/packages/o365_metrics/data_stream/teams_call_quality/sample_event.json b/packages/o365_metrics/data_stream/teams_call_quality/sample_event.json new file mode 100644 index 00000000000..9aa69968445 --- /dev/null +++ b/packages/o365_metrics/data_stream/teams_call_quality/sample_event.json @@ -0,0 +1,258 @@ +{ + "o365": { + "metrics": { + "teams": { + "call": { + "quality": { + "callee": { + "cpu_cores": { + "count": 2 + }, + "cpu_name": "Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz", + "cpu_processor_speed": { + "mhz": 2594 + }, + "feedback": { + "rating": "poor", + "tokens": { + "distorted_sound": false, + "echo": false, + "interruptions": false, + "low_volume": false, + "no_sound": false, + "noisy": true, + "other_no_sound": false, + "stopped": false + } + }, + "identity": { + "user": { + "display_name": "Owen Franklin", + "id": "f69e2c00-0000-0000-0000-185e5f5f5d8a", + "tenant_id": "dc368399-474c-4d40-900c-6265431fd81f" + } + }, + "name": "machineName_2", + "user_agent": { + "header_value": "UCCAPI/16.0.12527.20122 OC/16.0.12527.20194 (Skype for Business)", + "platform": "windows", + "product_family": "skypeForBusiness" + } + }, + "caller": { + "cpu_cores": { + "count": 8 + }, + "cpu_name": "AMD EPYC 7452 32-Core Processor", + "cpu_processor_speed": { + "mhz": 2346 + }, + "identity": { + "user": { + "display_name": "Abbie Wilkins", + "id": "821809f5-0000-0000-0000-3b5136c0e777", + "tenant_id": "dc368399-474c-4d40-900c-6265431fd81f" + } + }, + "name": "machineName_1", + "user_agent": { + "header_value": "RTCC/7.0.0.0 UCWA/7.0.0.0 AndroidLync/6.25.0.27 (SM-G930U Android 8.0.0)", + "platform": "android", + "product_family": "skypeForBusiness" + } + }, + "end_date_time": "2020-02-25T18:52:46.7640013Z", + "id": "e523d2ed-2966-4b6b-925b-754a88034cc5", + "is_test": false, + "modalities": [ + "audio" + ], + "segments": { + "callee": { + "cpu_cores_count": 2, + "cpu_name": "Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz", + "identity": { + "user": { + "display_name": "Owen Franklin", + "id": "f69e2c00-0000-0000-0000-185e5f5f5d8a", + "tenant_id": "dc368399-474c-4d40-900c-6265431fd81f" + } + }, + "name": "machineName_2", + "user_agent": { + "header_value": "UCCAPI/16.0.12527.20122 OC/16.0.12527.20194 (Skype for Business)", + "platform": "windows", + "product_family": "skypeForBusiness" + } + }, + "caller": { + "cpu_cores_count": 8, + "cpu_name": "AMD EPYC 7452 32-Core Processor", + "cpu_processor_speed_in_mhz": 2346, + "identity": { + "user": { + "display_name": "Abbie Wilkins", + "id": "821809f5-0000-0000-0000-3b5136c0e777", + "tenant_id": "dc368399-474c-4d40-900c-6265431fd81f" + } + }, + "name": "machineName_1", + "user_agent": { + "header_value": "RTCC/7.0.0.0 UCWA/7.0.0.0 AndroidLync/6.25.0.27 (SM-G930U Android 8.0.0)", + "platform": "android", + "product_family": "skypeForBusiness" + } + }, + "end_date_time": "2020-02-25T18:52:46.7640013Z", + "id": "e523d2ed-2966-4b6b-925b-754a88034cc5", + "media": { + "callee_device": { + "capture_device_driver": "Microsoft: 5.0.8638.1100", + "capture_device_name": "Microphone (Microsoft Virtual Audio Device (Simple) (WDM))", + "initial_signal_level_root_mean_square": 146.7885, + "mic_glitch_rate": 143, + "received_noise_level": -86, + "received_signal_level": -14, + "render_device_driver": "Microsoft: 5.0.8638.1100", + "render_device_name": "Speakers (Microsoft Virtual Audio Device (Simple) (WDM))", + "speaker_glitch_rate": 182 + }, + "callee_network": { + "bandwidth_low_event_ratio": 0, + "connection_type": "wired", + "delay_event_ratio": 0, + "ip_address": "10.139.0.12", + "link_speed": 4294967295, + "mac_address": "00-00-00-00-00-00-00-00", + "port": 50011, + "received_quality_event_ratio": 0, + "reflexive_ip_address": "127.0.0.2", + "relay_ip_address": "52.114.188.102", + "relay_port": 52810, + "sent_quality_event_ratio": 0.31, + "subnet": "10.139.80.0" + }, + "caller_device": { + "capture_device_name": "Default input device", + "initial_signal_level_root_mean_square": 60.25816, + "mic_glitch_rate": 23, + "received_noise_level": -68, + "received_signal_level": -10, + "render_device_name": "Default output device", + "render_mute_event_ratio": 1, + "render_zero_volume_event_ratio": 1, + "speaker_glitch_rate": 3830 + }, + "caller_network": { + "bandwidth_low_event_ratio": 0, + "connection_type": "wifi", + "delay_event_ratio": 0, + "ip_address": "10.150.0.2", + "link_speed": 54000000, + "mac_address": "00-00-00-00-00-00", + "port": 27288, + "received_quality_event_ratio": 0.27, + "reflexive_ip_address": "127.0.0.2", + "relay_ip_address": "52.114.188.32", + "relay_port": 53889, + "sent_quality_event_ratio": 0, + "subnet": "10.150.0.0" + }, + "label": "main-audio", + "streams": [ + { + "average_audio_network_jitter": "PT0.043S", + "average_bandwidth_estimate": 9965083, + "average_jitter": "PT0.016S", + "average_packet_loss_rate": 0, + "average_round_trip_time": "PT0.061S", + "is_audio_forward_error_correction_used": true, + "max_audio_network_jitter": "PT0.046S", + "max_jitter": "PT0.021S", + "max_packet_loss_rate": 0, + "max_round_trip_time": "PT0.079S", + "packet_utilization": 67, + "stream_direction": "callerToCallee", + "stream_id": "1504545584", + "was_media_bypassed": false + }, + { + "average_audio_degradation": 1.160898, + "average_audio_network_jitter": "PT0.266S", + "average_bandwidth_estimate": 15644878, + "average_jitter": "PT0.007S", + "average_packet_loss_rate": 0.01381693, + "average_ratio_of_concealed_samples": 0.06233422, + "average_round_trip_time": "PT0.064S", + "is_audio_forward_error_correction_used": false, + "max_audio_network_jitter": "PT0.474S", + "max_jitter": "PT0.012S", + "max_packet_loss_rate": 0.03738318, + "max_ratio_of_concealed_samples": 0.07192807, + "max_round_trip_time": "PT0.106S", + "packet_utilization": 709, + "stream_direction": "calleeToCaller", + "stream_id": "1785122252", + "was_media_bypassed": false + } + ] + }, + "start_date_time": "2020-02-25T18:52:21.2169889Z" + }, + "start_date_time": "2020-02-25T18:52:21.2169889Z" + } + } + } + } + }, + "agent": { + "name": "docker-fleet-agent", + "id": "abf38fab-f7b6-4e1c-a3b3-a70a64f9e5db", + "ephemeral_id": "08417a8d-9698-4c62-b7dc-e1b048647626", + "type": "filebeat", + "version": "8.16.0" + }, + "@timestamp": "2025-01-29T12:36:44.408Z", + "ecs": { + "version": "8.16.0" + }, + "data_stream": { + "namespace": "default", + "type": "metrics", + "dataset": "o365_metrics.teams_call_quality" + }, + "host": { + "hostname": "docker-fleet-agent", + "os": { + "kernel": "5.10.104-linuxkit", + "name": "Wolfi", + "family": "", + "type": "linux", + "version": "20230201", + "platform": "wolfi" + }, + "ip": [ + "192.168.48.7" + ], + "containerized": false, + "name": "docker-fleet-agent", + "mac": [ + "02-42-C0-A8-30-07" + ], + "architecture": "aarch64" + }, + "elastic_agent": { + "id": "abf38fab-f7b6-4e1c-a3b3-a70a64f9e5db", + "version": "8.16.0", + "snapshot": false + }, + "event": { + "agent_id_status": "verified", + "ingested": "2025-01-29T12:35:44.48Z", + "dataset": "o365_metrics.teams_call_quality", + "original": "{ \"id\": \"e523d2ed-2966-4b6b-925b-754a88034cc5\", \"modalities\": [ \"audio\" ], \"startDateTime\": \"2020-02-25T18:52:21.2169889Z\", \"endDateTime\": \"2020-02-25T18:52:46.7640013Z\", \"isTest\": false, \"caller\": { \"@odata.type\": \"#microsoft.graph.callRecords.participantEndpoint\", \"name\": \"machineName_1\", \"cpuName\": \"AMD EPYC 7452 32-Core Processor\", \"cpuCoresCount\": 8, \"cpuProcessorSpeedInMhz\": 2346, \"userAgent\": { \"@odata.type\": \"#microsoft.graph.callRecords.clientUserAgent\", \"headerValue\": \"RTCC\/7.0.0.0 UCWA\/7.0.0.0 AndroidLync\/6.25.0.27 (SM-G930U Android 8.0.0)\", \"platform\": \"android\", \"productFamily\": \"skypeForBusiness\" }, \"identity\": { \"@odata.type\": \"#microsoft.graph.identitySet\", \"user\": { \"id\": \"821809f5-0000-0000-0000-3b5136c0e777\", \"displayName\": \"Abbie Wilkins\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\" } } }, \"callee\": { \"@odata.type\": \"#microsoft.graph.callRecords.participantEndpoint\", \"name\": \"machineName_2\", \"cpuName\": \"Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz\", \"cpuCoresCount\": 2, \"cpuProcessorSpeedInMhz\": 2594, \"userAgent\": { \"@odata.type\": \"#microsoft.graph.callRecords.clientUserAgent\", \"headerValue\": \"UCCAPI\/16.0.12527.20122 OC\/16.0.12527.20194 (Skype for Business)\", \"platform\": \"windows\", \"productFamily\": \"skypeForBusiness\" }, \"identity\": { \"user\": { \"id\": \"f69e2c00-0000-0000-0000-185e5f5f5d8a\", \"displayName\": \"Owen Franklin\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\" } }, \"feedback\": { \"rating\": \"poor\", \"tokens\": { \"NoSound\": false, \"OtherNoSound\": false, \"Echo\": false, \"Noisy\": true, \"LowVolume\": false, \"Stopped\": false, \"DistortedSound\": false, \"Interruptions\": false } } }, \"segments\": [ { \"startDateTime\": \"2020-02-25T18:52:21.2169889Z\", \"endDateTime\": \"2020-02-25T18:52:46.7640013Z\", \"id\": \"e523d2ed-2966-4b6b-925b-754a88034cc5\", \"caller\": { \"@odata.type\": \"#microsoft.graph.callRecords.participantEndpoint\", \"name\": \"machineName_1\", \"cpuName\": \"AMD EPYC 7452 32-Core Processor\", \"cpuCoresCount\": 8, \"cpuProcessorSpeedInMhz\": 2346, \"userAgent\": { \"@odata.type\": \"#microsoft.graph.callRecords.clientUserAgent\", \"headerValue\": \"RTCC\/7.0.0.0 UCWA\/7.0.0.0 AndroidLync\/6.25.0.27 (SM-G930U Android 8.0.0)\", \"platform\": \"android\", \"productFamily\": \"skypeForBusiness\" }, \"identity\": { \"user\": { \"id\": \"821809f5-0000-0000-0000-3b5136c0e777\", \"displayName\": \"Abbie Wilkins\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\" } } }, \"callee\": { \"@odata.type\": \"#microsoft.graph.callRecords.participantEndpoint\", \"name\": \"machineName_2\", \"cpuName\": \"Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz\", \"cpuCoresCount\": 2, \"userAgent\": { \"@odata.type\": \"#microsoft.graph.callRecords.clientUserAgent\", \"headerValue\": \"UCCAPI\/16.0.12527.20122 OC\/16.0.12527.20194 (Skype for Business)\", \"platform\": \"windows\", \"productFamily\": \"skypeForBusiness\" }, \"identity\": { \"user\": { \"id\": \"f69e2c00-0000-0000-0000-185e5f5f5d8a\", \"displayName\": \"Owen Franklin\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\" } } }, \"media\": [ { \"label\": \"main-audio\", \"callerNetwork\": { \"ipAddress\": \"10.150.0.2\", \"subnet\": \"10.150.0.0\", \"linkSpeed\": 54000000, \"connectionType\": \"wifi\", \"port\": 27288, \"reflexiveIPAddress\": \"127.0.0.2\", \"relayIPAddress\": \"52.114.188.32\", \"relayPort\": 53889, \"macAddress\": \"00-00-00-00-00-00\", \"dnsSuffix\": null, \"sentQualityEventRatio\": 0, \"receivedQualityEventRatio\": 0.27, \"delayEventRatio\": 0, \"bandwidthLowEventRatio\": 0 }, \"calleeNetwork\": { \"ipAddress\": \"10.139.0.12\", \"subnet\": \"10.139.80.0\", \"linkSpeed\": 4294967295, \"connectionType\": \"wired\", \"port\": 50011, \"reflexiveIPAddress\": \"127.0.0.2\", \"relayIPAddress\": \"52.114.188.102\", \"relayPort\": 52810, \"macAddress\": \"00-00-00-00-00-00-00-00\", \"dnsSuffix\": null, \"sentQualityEventRatio\": 0.31, \"receivedQualityEventRatio\": 0, \"delayEventRatio\": 0, \"bandwidthLowEventRatio\": 0 }, \"callerDevice\": { \"captureDeviceName\": \"Default input device\", \"renderDeviceName\": \"Default output device\", \"receivedSignalLevel\": -10, \"receivedNoiseLevel\": -68, \"initialSignalLevelRootMeanSquare\": 60.25816, \"renderZeroVolumeEventRatio\": 1, \"renderMuteEventRatio\": 1, \"micGlitchRate\": 23, \"speakerGlitchRate\": 3830 }, \"calleeDevice\": { \"captureDeviceName\": \"Microphone (Microsoft Virtual Audio Device (Simple) (WDM))\", \"captureDeviceDriver\": \"Microsoft: 5.0.8638.1100\", \"renderDeviceName\": \"Speakers (Microsoft Virtual Audio Device (Simple) (WDM))\", \"renderDeviceDriver\": \"Microsoft: 5.0.8638.1100\", \"receivedSignalLevel\": -14, \"receivedNoiseLevel\": -86, \"initialSignalLevelRootMeanSquare\": 146.7885, \"micGlitchRate\": 143, \"speakerGlitchRate\": 182 }, \"streams\": [ { \"streamId\": \"1504545584\", \"streamDirection\": \"callerToCallee\", \"averageAudioDegradation\": null, \"averageJitter\": \"PT0.016S\", \"maxJitter\": \"PT0.021S\", \"averagePacketLossRate\": 0, \"maxPacketLossRate\": 0, \"averageRatioOfConcealedSamples\": null, \"maxRatioOfConcealedSamples\": null, \"averageRoundTripTime\": \"PT0.061S\", \"maxRoundTripTime\": \"PT0.079S\", \"packetUtilization\": 67, \"averageBandwidthEstimate\": 9965083, \"wasMediaBypassed\": false, \"averageAudioNetworkJitter\": \"PT0.043S\", \"maxAudioNetworkJitter\": \"PT0.046S\", \"rmsFreezeDuration\": null, \"averageFreezeDuration\": null, \"isAudioForwardErrorCorrectionUsed\": true }, { \"streamId\": \"1785122252\", \"streamDirection\": \"calleeToCaller\", \"averageAudioDegradation\": 1.160898, \"averageJitter\": \"PT0.007S\", \"maxJitter\": \"PT0.012S\", \"averagePacketLossRate\": 0.01381693, \"maxPacketLossRate\": 0.03738318, \"averageRatioOfConcealedSamples\": 0.06233422, \"maxRatioOfConcealedSamples\": 0.07192807, \"averageRoundTripTime\": \"PT0.064S\", \"maxRoundTripTime\": \"PT0.106S\", \"packetUtilization\": 709, \"averageBandwidthEstimate\": 15644878, \"wasMediaBypassed\": false, \"averageAudioNetworkJitter\": \"PT0.266S\", \"maxAudioNetworkJitter\": \"PT0.474S\", \"rmsFreezeDuration\": null, \"averageFreezeDuration\": null, \"isAudioForwardErrorCorrectionUsed\": false } ] } ] } ] }" + }, + "tags": [ + "o365metrics-teams.call.quality" + ] +} \ No newline at end of file diff --git a/packages/o365_metrics/docs/README.md b/packages/o365_metrics/docs/README.md index bbe122c25d8..e8cc0af632a 100644 --- a/packages/o365_metrics/docs/README.md +++ b/packages/o365_metrics/docs/README.md @@ -8,24 +8,26 @@ Following Microsoft 365 Graph Reports can be collected by Microsoft Office 365 M | Report | API | Data-stream Name | Aggregation Level | |-----------------|-----|-------------|-------------------| -| [Microsoft 365 Active Users Service User Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/active-users-ww?view=o365-worldwide) | [reportRoot: getOffice365ServicesUserCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getoffice365servicesusercounts?view=graph-rest-1.0&tabs=http) | Office 365 Active Users metrics | `Period`-based | +| [Microsoft 365 Active Users Service User Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/active-users-ww?view=o365-worldwide) | [reportRoot: getOffice365ServicesUserCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getoffice365servicesusercounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 Active Users metrics | `Period`-based | | [Microsoft 365 Groups Activity Group Detail](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/office-365-groups-ww?view=o365-worldwide) | [reportRoot: getOffice365GroupsActivityDetail](https://learn.microsoft.com/en-us/graph/api/reportroot-getoffice365groupsactivitydetail?view=graph-rest-1.0&tabs=http) | Microsoft 365 Groups Activity Group Detail | `Day`-based | | [OneDrive Usage Account Detail](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/onedrive-for-business-usage-ww?view=o365-worldwide) | [reportRoot: getOneDriveUsageAccountDetail](https://learn.microsoft.com/en-us/graph/api/reportroot-getonedriveusageaccountdetail?view=graph-rest-1.0&tabs=http) | Microsoft 365 OneDrive Usage Account Detail | `Day`-based | -| [OneDrive Usage Account Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/onedrive-for-business-usage-ww?view=o365-worldwide) | [reportRoot: getOneDriveUsageAccountCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getonedriveusageaccountcounts?view=graph-rest-1.0&tabs=http) | Office 365 One Drive Usage metrics | `Period`-based | -| [OneDrive Usage File Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/onedrive-for-business-usage-ww?view=o365-worldwide) | [reportRoot: getOneDriveUsageFileCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getonedriveusagefilecounts?view=graph-rest-1.0&tabs=http) | Office 365 One Drive Usage metrics | `Period`-based | -| [OneDrive Usage Storage](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/onedrive-for-business-usage-ww?view=o365-worldwide) | [reportRoot: getOneDriveUsageStorage](https://learn.microsoft.com/en-us/graph/api/reportroot-getonedriveusagestorage?view=graph-rest-1.0&tabs=http) | Office 365 One Drive Usage metrics | `Period`-based | -| [Outlook Activity Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/email-activity-ww?view=o365-worldwide) | [reportRoot: getEmailActivityCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getemailactivitycounts?view=graph-rest-1.0&tabs=http) | Office 365 Outlook Activity metrics | `Period`-based | +| [OneDrive Usage Account Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/onedrive-for-business-usage-ww?view=o365-worldwide) | [reportRoot: getOneDriveUsageAccountCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getonedriveusageaccountcounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 One Drive Usage metrics | `Period`-based | +| [OneDrive Usage File Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/onedrive-for-business-usage-ww?view=o365-worldwide) | [reportRoot: getOneDriveUsageFileCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getonedriveusagefilecounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 One Drive Usage metrics | `Period`-based | +| [OneDrive Usage Storage](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/onedrive-for-business-usage-ww?view=o365-worldwide) | [reportRoot: getOneDriveUsageStorage](https://learn.microsoft.com/en-us/graph/api/reportroot-getonedriveusagestorage?view=graph-rest-1.0&tabs=http) | Microsoft 365 One Drive Usage metrics | `Period`-based | +| [Outlook Activity Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/email-activity-ww?view=o365-worldwide) | [reportRoot: getEmailActivityCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getemailactivitycounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 Outlook Activity metrics | `Period`-based | | [Outlook App Usage Version Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/email-apps-usage-ww?view=o365-worldwide) | [reportRoot: getEmailAppUsageVersionsUserCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getemailappusageversionsusercounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 Outlook App Usage Version Counts metrics | `Period`-based | | [Outlook Mailbox Usage Quota Status Mailbox Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/mailbox-usage?view=o365-worldwide) | [reportRoot: getMailboxUsageQuotaStatusMailboxCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getmailboxusagequotastatusmailboxcounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 mailbox usage quota status metrics | `Period`-based | | [Outlook Mailbox Usage Detail](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/mailbox-usage?view=o365-worldwide) | [reportRoot: getMailboxUsageDetail](https://learn.microsoft.com/en-us/graph/api/reportroot-getmailboxusagedetail?view=graph-rest-1.0&tabs=http) | Microsoft 365 mailbox usage detail metrics | `Period`-based | -| [SharePoint Site Usage Storage](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/sharepoint-site-usage-ww?view=o365-worldwide) | [reportRoot: getSharePointSiteUsageStorage](https://learn.microsoft.com/en-us/graph/api/reportroot-getsharepointsiteusagestorage?view=graph-rest-1.0&tabs=http) | Office 365 Sharepoint Site Usage metrics | `Period`-based | -| [SharePoint Site Usage Detail](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/sharepoint-site-usage-ww?view=o365-worldwide) | [reportRoot: getSharePointSiteUsageDetail](https://learn.microsoft.com/en-us/graph/api/reportroot-getsharepointsiteusagedetail?view=graph-rest-1.0&tabs=http) | Office 365 Sharepoint Site Usage metrics | `Period`-based | +| [SharePoint Site Usage Storage](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/sharepoint-site-usage-ww?view=o365-worldwide) | [reportRoot: getSharePointSiteUsageStorage](https://learn.microsoft.com/en-us/graph/api/reportroot-getsharepointsiteusagestorage?view=graph-rest-1.0&tabs=http) | Microsoft 365 Sharepoint Site Usage metrics | `Period`-based | +| [SharePoint Site Usage Detail](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/sharepoint-site-usage-ww?view=o365-worldwide) | [reportRoot: getSharePointSiteUsageDetail](https://learn.microsoft.com/en-us/graph/api/reportroot-getsharepointsiteusagedetail?view=graph-rest-1.0&tabs=http) | Microsoft 365 Sharepoint Site Usage metrics | `Period`-based | | [Teams Device Usage User Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/microsoft-teams-device-usage-preview?view=o365-worldwide) | [reportRoot: getTeamsDeviceUsageUserCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getteamsdeviceusageusercounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 Teams Device Usage User Counts metrics | `Period`-based | | [Teams User Activity User Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/microsoft-teams-user-activity-preview?view=o365-worldwide) | [reportRoot: getTeamsUserActivityUserCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getteamsuseractivityusercounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 Teams User Activity User Counts metrics | `Period`-based | | [Teams User Activity User Detail](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/microsoft-teams-user-activity-preview?view=o365-worldwide) | [reportRoot: getTeamsUserActivityUserDetail](https://learn.microsoft.com/en-us/graph/api/reportroot-getteamsuseractivityuserdetail?view=graph-rest-1.0&tabs=http) | Microsoft 365 Teams User Activity User Detail | `Day`-based | | [Viva Engage Groups Activity Group Detail](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/viva-engage-groups-activity-report-ww?view=o365-worldwide) | [reportRoot: getYammerGroupsActivityDetail](https://learn.microsoft.com/en-us/graph/api/reportroot-getyammergroupsactivitydetail?view=graph-rest-1.0&tabs=http) | Microsoft 365 Viva Engage Groups Activity | `Day`-based | | [Viva Engage Device Usage User Counts](https://learn.microsoft.com/en-us/microsoft-365/admin/activity-reports/viva-engage-device-usage-report-ww?view=o365-worldwide) | [reportRoot: getYammerDeviceUsageUserCounts](https://learn.microsoft.com/en-us/graph/api/reportroot-getyammerdeviceusageusercounts?view=graph-rest-1.0&tabs=http) | Microsoft 365 Viva Engage Device Usage User Counts metrics | `Period`-based | -| [Service Health](https://learn.microsoft.com/en-us/graph/service-communications-concept-overview?view=o365-worldwide) | [reportRoot: getServiceHealth](https://learn.microsoft.com/en-us/graph/api/servicehealth-get?view=graph-rest-1.0&tabs=http) | Office 365 Service Health metrics | No aggregation | +| [Service Health](https://learn.microsoft.com/en-us/graph/service-communications-concept-overview?view=o365-worldwide) | [reportRoot: getServiceHealth](https://learn.microsoft.com/en-us/graph/api/servicehealth-get?view=graph-rest-1.0&tabs=http) | Microsoft 365 Service Health metrics | No aggregation | +| [Subscriptions](https://learn.microsoft.com/en-us/graph/api/resources/subscribedsku?view=graph-rest-1.0?view=o365-worldwide) | [reportRoot: subscribedSkus](https://learn.microsoft.com/en-us/graph/api/subscribedsku-list?view=graph-rest-1.0&tabs=http) | Microsoft 365 Subscriptions metrics | No aggregation | +| [Teamms Call Quality](https://learn.microsoft.com/en-us/graph/api/resources/communications-api-overview?view=graph-rest-1.0?view=o365-worldwide) | [reportRoot: callRecords](https://learn.microsoft.com/en-us/graph/api/callrecords-callrecord-list-sessions?view=graph-rest-1.0&tabs=http) | Microsoft 365 Teams Call Quality metrics | No aggregation | ## Setup @@ -41,7 +43,7 @@ Once the application is registered, configure and/or note the following to setup - Navigate to `API permissions` page and click `Add a permission` - Select `Office 365 Management APIs` tile from the listed tiles. - Click `Application permissions`. - - If `User.Read` and `Reports.Read.All` permission under `Microsoft.Graph` tile is not added by default, add this permission. + - If `User.Read` and `Reports.Read.All` permission under `Microsoft.Graph` tile is not added by default, add this permission. Additional permissions, such as `ServiceHealth.Read.All` for data streams like Service Health may be required. Refer to the API documentation under the Permissions section to determine the necessary permissions. - After the permissions are added, the admin has to grant consent for these permissions. Once the secret is created and permissions are granted by admin, setup Elastic Agent's Microsoft O365 integration: @@ -2296,3 +2298,563 @@ Please refer to the following [document](https://www.elastic.co/guide/en/ecs/cur | o365.metrics.service.health.service | The service name. | keyword | | o365.metrics.service.health.status | Show the overall service health status (Eg. serviceOperational, serviceOperational etc.). | keyword | + + +### Subscriptions + +Get details about Subscriptions from [Microsoft Graph API](https://learn.microsoft.com/en-us/graph/api/subscribedsku-list?view=graph-rest-1.0&tabs=http). + +An example event for `subscriptions` looks as following: + +```json +{ + "o365": { + "metrics": { + "subscriptions": { + "account_id": "f97aeefc-af85-414d-8ae4-b457f90efc40", + "account_name": "Account1", + "applies_to": "User", + "capability_status": "Enabled", + "consumed_units": { + "count": 14 + }, + "id": "48a80680-7326-48cd-9935-b556b81d3a4e_c7df2760-2c81-4ef7-b578-5b5392b571df", + "prepaid_units": { + "enabled": { + "count": 25 + }, + "locked_out": { + "count": 5 + }, + "suspended": { + "count": 13 + }, + "warning": { + "count": 7 + } + }, + "service_plans": [ + { + "applies_to": "Company", + "provisioning_status": "Success", + "service_plan_id": "8c098270-9dd4-4350-9b30-ba4703f3b36b", + "service_plan_name": "ADALLOM_S_O365" + } + ], + "sku_id": "c7df2760-2c81-4ef7-b578-5b5392b571df", + "sku_part_number": "ENTERPRISEPREMIUM", + "subscription_ids": [ + "43d26afe-cb98-48b9-acc4-ae3ef2ac6c51" + ], + "surplus_units": { + "count": 11 + } + } + } + }, + "agent": { + "name": "docker-fleet-agent", + "id": "abf38fab-f7b6-4e1c-a3b3-a70a64f9e5db", + "ephemeral_id": "08417a8d-9698-4c62-b7dc-e1b048647626", + "type": "filebeat", + "version": "8.16.0" + }, + "@timestamp": "2025-01-29T12:36:44.408Z", + "ecs": { + "version": "8.16.0" + }, + "data_stream": { + "namespace": "default", + "type": "metrics", + "dataset": "o365_metrics.subscriptions" + }, + "host": { + "hostname": "docker-fleet-agent", + "os": { + "kernel": "5.10.104-linuxkit", + "name": "Wolfi", + "family": "", + "type": "linux", + "version": "20230201", + "platform": "wolfi" + }, + "ip": [ + "192.168.48.7" + ], + "containerized": false, + "name": "docker-fleet-agent", + "mac": [ + "02-42-C0-A8-30-07" + ], + "architecture": "aarch64" + }, + "elastic_agent": { + "id": "abf38fab-f7b6-4e1c-a3b3-a70a64f9e5db", + "version": "8.16.0", + "snapshot": false + }, + "event": { + "agent_id_status": "verified", + "ingested": "2025-01-29T12:35:44.48Z", + "dataset": "o365_metrics.subscriptions", + "original": "{\"accountName\":\"Account1\",\"accountId\":\"f97aeefc-af85-414d-8ae4-b457f90efc40\",\"appliesTo\":\"User\",\"capabilityStatus\":\"Enabled\",\"consumedUnits\":14,\"id\":\"48a80680-7326-48cd-9935-b556b81d3a4e_c7df2760-2c81-4ef7-b578-5b5392b571df\",\"prepaidUnits\":{\"enabled\":25,\"lockedOut\":5,\"suspended\":13,\"warning\":7},\"servicePlans\":[{\"servicePlanId\":\"8c098270-9dd4-4350-9b30-ba4703f3b36b\",\"servicePlanName\":\"ADALLOM_S_O365\",\"provisioningStatus\":\"Success\",\"appliesTo\":\"Company\"}],\"skuId\":\"c7df2760-2c81-4ef7-b578-5b5392b571df\",\"skuPartNumber\":\"ENTERPRISEPREMIUM\",\"subscriptionIds\":[\"43d26afe-cb98-48b9-acc4-ae3ef2ac6c51\"]}" + }, + "tags": [ + "o365metrics-subscriptions" + ] +} +``` + +**ECS Field Reference** + +Please refer to the following [document](https://www.elastic.co/guide/en/ecs/current/ecs-field-reference.html) for detailed information on ECS fields. + +**Exported fields** + +| Field | Description | Type | +|---|---|---| +| @timestamp | Event timestamp. | date | +| cloud.image.id | Image ID for the cloud instance. | keyword | +| data_stream.dataset | Data stream dataset. | constant_keyword | +| data_stream.namespace | Data stream namespace. | constant_keyword | +| data_stream.type | Data stream type. | constant_keyword | +| host.containerized | If the host is a container. | boolean | +| host.os.build | OS build information. | keyword | +| host.os.codename | OS codename, if any. | keyword | +| o365.metrics.subscriptions.account_id | Unique identifier for the account. | keyword | +| o365.metrics.subscriptions.account_name | Name of the account. | text | +| o365.metrics.subscriptions.applies_to | Type of entity the subscription applies to (e.g. User or Company). | keyword | +| o365.metrics.subscriptions.capability_status | Status of the capability (e.g. Enabled, Suspended). | keyword | +| o365.metrics.subscriptions.consumed_units.count | Number of consumed units. | long | +| o365.metrics.subscriptions.id | Unique identifier for the subscription entry. | keyword | +| o365.metrics.subscriptions.prepaid_units.enabled.count | Number of enabled prepaid units. | long | +| o365.metrics.subscriptions.prepaid_units.locked_out.count | Number of locked-out prepaid units. | long | +| o365.metrics.subscriptions.prepaid_units.suspended.count | Number of suspended prepaid units. | long | +| o365.metrics.subscriptions.prepaid_units.warning.count | Number of prepaid units in warning state. | long | +| o365.metrics.subscriptions.service_plans.applies_to | Type of entity the service plan applies to. | keyword | +| o365.metrics.subscriptions.service_plans.provisioning_status | Status of the service plan provisioning. | keyword | +| o365.metrics.subscriptions.service_plans.service_plan_id | Unique identifier for the service plan. | keyword | +| o365.metrics.subscriptions.service_plans.service_plan_name | Name of the service plan. | keyword | +| o365.metrics.subscriptions.sku_id | Unique identifier for the SKU. | keyword | +| o365.metrics.subscriptions.sku_part_number | SKU part number. | keyword | +| o365.metrics.subscriptions.subscription_ids | Array of subscription IDs. | keyword | +| o365.metrics.subscriptions.surplus_units.count | Number of unused units which indicates if you oversubscribed to any SKUs. | long | + + + +### Teams Call Quality + +Get details about Teams Call Quality from [Microsoft Graph API](https://learn.microsoft.com/en-us/graph/api/callrecords-callrecord-list-sessions?view=graph-rest-1.0&tabs=http). + +An example event for `teams_call_quality` looks as following: + +```json +{ + "o365": { + "metrics": { + "teams": { + "call": { + "quality": { + "callee": { + "cpu_cores": { + "count": 2 + }, + "cpu_name": "Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz", + "cpu_processor_speed": { + "mhz": 2594 + }, + "feedback": { + "rating": "poor", + "tokens": { + "distorted_sound": false, + "echo": false, + "interruptions": false, + "low_volume": false, + "no_sound": false, + "noisy": true, + "other_no_sound": false, + "stopped": false + } + }, + "identity": { + "user": { + "display_name": "Owen Franklin", + "id": "f69e2c00-0000-0000-0000-185e5f5f5d8a", + "tenant_id": "dc368399-474c-4d40-900c-6265431fd81f" + } + }, + "name": "machineName_2", + "user_agent": { + "header_value": "UCCAPI/16.0.12527.20122 OC/16.0.12527.20194 (Skype for Business)", + "platform": "windows", + "product_family": "skypeForBusiness" + } + }, + "caller": { + "cpu_cores": { + "count": 8 + }, + "cpu_name": "AMD EPYC 7452 32-Core Processor", + "cpu_processor_speed": { + "mhz": 2346 + }, + "identity": { + "user": { + "display_name": "Abbie Wilkins", + "id": "821809f5-0000-0000-0000-3b5136c0e777", + "tenant_id": "dc368399-474c-4d40-900c-6265431fd81f" + } + }, + "name": "machineName_1", + "user_agent": { + "header_value": "RTCC/7.0.0.0 UCWA/7.0.0.0 AndroidLync/6.25.0.27 (SM-G930U Android 8.0.0)", + "platform": "android", + "product_family": "skypeForBusiness" + } + }, + "end_date_time": "2020-02-25T18:52:46.7640013Z", + "id": "e523d2ed-2966-4b6b-925b-754a88034cc5", + "is_test": false, + "modalities": [ + "audio" + ], + "segments": { + "callee": { + "cpu_cores_count": 2, + "cpu_name": "Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz", + "identity": { + "user": { + "display_name": "Owen Franklin", + "id": "f69e2c00-0000-0000-0000-185e5f5f5d8a", + "tenant_id": "dc368399-474c-4d40-900c-6265431fd81f" + } + }, + "name": "machineName_2", + "user_agent": { + "header_value": "UCCAPI/16.0.12527.20122 OC/16.0.12527.20194 (Skype for Business)", + "platform": "windows", + "product_family": "skypeForBusiness" + } + }, + "caller": { + "cpu_cores_count": 8, + "cpu_name": "AMD EPYC 7452 32-Core Processor", + "cpu_processor_speed_in_mhz": 2346, + "identity": { + "user": { + "display_name": "Abbie Wilkins", + "id": "821809f5-0000-0000-0000-3b5136c0e777", + "tenant_id": "dc368399-474c-4d40-900c-6265431fd81f" + } + }, + "name": "machineName_1", + "user_agent": { + "header_value": "RTCC/7.0.0.0 UCWA/7.0.0.0 AndroidLync/6.25.0.27 (SM-G930U Android 8.0.0)", + "platform": "android", + "product_family": "skypeForBusiness" + } + }, + "end_date_time": "2020-02-25T18:52:46.7640013Z", + "id": "e523d2ed-2966-4b6b-925b-754a88034cc5", + "media": { + "callee_device": { + "capture_device_driver": "Microsoft: 5.0.8638.1100", + "capture_device_name": "Microphone (Microsoft Virtual Audio Device (Simple) (WDM))", + "initial_signal_level_root_mean_square": 146.7885, + "mic_glitch_rate": 143, + "received_noise_level": -86, + "received_signal_level": -14, + "render_device_driver": "Microsoft: 5.0.8638.1100", + "render_device_name": "Speakers (Microsoft Virtual Audio Device (Simple) (WDM))", + "speaker_glitch_rate": 182 + }, + "callee_network": { + "bandwidth_low_event_ratio": 0, + "connection_type": "wired", + "delay_event_ratio": 0, + "ip_address": "10.139.0.12", + "link_speed": 4294967295, + "mac_address": "00-00-00-00-00-00-00-00", + "port": 50011, + "received_quality_event_ratio": 0, + "reflexive_ip_address": "127.0.0.2", + "relay_ip_address": "52.114.188.102", + "relay_port": 52810, + "sent_quality_event_ratio": 0.31, + "subnet": "10.139.80.0" + }, + "caller_device": { + "capture_device_name": "Default input device", + "initial_signal_level_root_mean_square": 60.25816, + "mic_glitch_rate": 23, + "received_noise_level": -68, + "received_signal_level": -10, + "render_device_name": "Default output device", + "render_mute_event_ratio": 1, + "render_zero_volume_event_ratio": 1, + "speaker_glitch_rate": 3830 + }, + "caller_network": { + "bandwidth_low_event_ratio": 0, + "connection_type": "wifi", + "delay_event_ratio": 0, + "ip_address": "10.150.0.2", + "link_speed": 54000000, + "mac_address": "00-00-00-00-00-00", + "port": 27288, + "received_quality_event_ratio": 0.27, + "reflexive_ip_address": "127.0.0.2", + "relay_ip_address": "52.114.188.32", + "relay_port": 53889, + "sent_quality_event_ratio": 0, + "subnet": "10.150.0.0" + }, + "label": "main-audio", + "streams": [ + { + "average_audio_network_jitter": "PT0.043S", + "average_bandwidth_estimate": 9965083, + "average_jitter": "PT0.016S", + "average_packet_loss_rate": 0, + "average_round_trip_time": "PT0.061S", + "is_audio_forward_error_correction_used": true, + "max_audio_network_jitter": "PT0.046S", + "max_jitter": "PT0.021S", + "max_packet_loss_rate": 0, + "max_round_trip_time": "PT0.079S", + "packet_utilization": 67, + "stream_direction": "callerToCallee", + "stream_id": "1504545584", + "was_media_bypassed": false + }, + { + "average_audio_degradation": 1.160898, + "average_audio_network_jitter": "PT0.266S", + "average_bandwidth_estimate": 15644878, + "average_jitter": "PT0.007S", + "average_packet_loss_rate": 0.01381693, + "average_ratio_of_concealed_samples": 0.06233422, + "average_round_trip_time": "PT0.064S", + "is_audio_forward_error_correction_used": false, + "max_audio_network_jitter": "PT0.474S", + "max_jitter": "PT0.012S", + "max_packet_loss_rate": 0.03738318, + "max_ratio_of_concealed_samples": 0.07192807, + "max_round_trip_time": "PT0.106S", + "packet_utilization": 709, + "stream_direction": "calleeToCaller", + "stream_id": "1785122252", + "was_media_bypassed": false + } + ] + }, + "start_date_time": "2020-02-25T18:52:21.2169889Z" + }, + "start_date_time": "2020-02-25T18:52:21.2169889Z" + } + } + } + } + }, + "agent": { + "name": "docker-fleet-agent", + "id": "abf38fab-f7b6-4e1c-a3b3-a70a64f9e5db", + "ephemeral_id": "08417a8d-9698-4c62-b7dc-e1b048647626", + "type": "filebeat", + "version": "8.16.0" + }, + "@timestamp": "2025-01-29T12:36:44.408Z", + "ecs": { + "version": "8.16.0" + }, + "data_stream": { + "namespace": "default", + "type": "metrics", + "dataset": "o365_metrics.teams_call_quality" + }, + "host": { + "hostname": "docker-fleet-agent", + "os": { + "kernel": "5.10.104-linuxkit", + "name": "Wolfi", + "family": "", + "type": "linux", + "version": "20230201", + "platform": "wolfi" + }, + "ip": [ + "192.168.48.7" + ], + "containerized": false, + "name": "docker-fleet-agent", + "mac": [ + "02-42-C0-A8-30-07" + ], + "architecture": "aarch64" + }, + "elastic_agent": { + "id": "abf38fab-f7b6-4e1c-a3b3-a70a64f9e5db", + "version": "8.16.0", + "snapshot": false + }, + "event": { + "agent_id_status": "verified", + "ingested": "2025-01-29T12:35:44.48Z", + "dataset": "o365_metrics.teams_call_quality", + "original": "{ \"id\": \"e523d2ed-2966-4b6b-925b-754a88034cc5\", \"modalities\": [ \"audio\" ], \"startDateTime\": \"2020-02-25T18:52:21.2169889Z\", \"endDateTime\": \"2020-02-25T18:52:46.7640013Z\", \"isTest\": false, \"caller\": { \"@odata.type\": \"#microsoft.graph.callRecords.participantEndpoint\", \"name\": \"machineName_1\", \"cpuName\": \"AMD EPYC 7452 32-Core Processor\", \"cpuCoresCount\": 8, \"cpuProcessorSpeedInMhz\": 2346, \"userAgent\": { \"@odata.type\": \"#microsoft.graph.callRecords.clientUserAgent\", \"headerValue\": \"RTCC\/7.0.0.0 UCWA\/7.0.0.0 AndroidLync\/6.25.0.27 (SM-G930U Android 8.0.0)\", \"platform\": \"android\", \"productFamily\": \"skypeForBusiness\" }, \"identity\": { \"@odata.type\": \"#microsoft.graph.identitySet\", \"user\": { \"id\": \"821809f5-0000-0000-0000-3b5136c0e777\", \"displayName\": \"Abbie Wilkins\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\" } } }, \"callee\": { \"@odata.type\": \"#microsoft.graph.callRecords.participantEndpoint\", \"name\": \"machineName_2\", \"cpuName\": \"Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz\", \"cpuCoresCount\": 2, \"cpuProcessorSpeedInMhz\": 2594, \"userAgent\": { \"@odata.type\": \"#microsoft.graph.callRecords.clientUserAgent\", \"headerValue\": \"UCCAPI\/16.0.12527.20122 OC\/16.0.12527.20194 (Skype for Business)\", \"platform\": \"windows\", \"productFamily\": \"skypeForBusiness\" }, \"identity\": { \"user\": { \"id\": \"f69e2c00-0000-0000-0000-185e5f5f5d8a\", \"displayName\": \"Owen Franklin\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\" } }, \"feedback\": { \"rating\": \"poor\", \"tokens\": { \"NoSound\": false, \"OtherNoSound\": false, \"Echo\": false, \"Noisy\": true, \"LowVolume\": false, \"Stopped\": false, \"DistortedSound\": false, \"Interruptions\": false } } }, \"segments\": [ { \"startDateTime\": \"2020-02-25T18:52:21.2169889Z\", \"endDateTime\": \"2020-02-25T18:52:46.7640013Z\", \"id\": \"e523d2ed-2966-4b6b-925b-754a88034cc5\", \"caller\": { \"@odata.type\": \"#microsoft.graph.callRecords.participantEndpoint\", \"name\": \"machineName_1\", \"cpuName\": \"AMD EPYC 7452 32-Core Processor\", \"cpuCoresCount\": 8, \"cpuProcessorSpeedInMhz\": 2346, \"userAgent\": { \"@odata.type\": \"#microsoft.graph.callRecords.clientUserAgent\", \"headerValue\": \"RTCC\/7.0.0.0 UCWA\/7.0.0.0 AndroidLync\/6.25.0.27 (SM-G930U Android 8.0.0)\", \"platform\": \"android\", \"productFamily\": \"skypeForBusiness\" }, \"identity\": { \"user\": { \"id\": \"821809f5-0000-0000-0000-3b5136c0e777\", \"displayName\": \"Abbie Wilkins\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\" } } }, \"callee\": { \"@odata.type\": \"#microsoft.graph.callRecords.participantEndpoint\", \"name\": \"machineName_2\", \"cpuName\": \"Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz\", \"cpuCoresCount\": 2, \"userAgent\": { \"@odata.type\": \"#microsoft.graph.callRecords.clientUserAgent\", \"headerValue\": \"UCCAPI\/16.0.12527.20122 OC\/16.0.12527.20194 (Skype for Business)\", \"platform\": \"windows\", \"productFamily\": \"skypeForBusiness\" }, \"identity\": { \"user\": { \"id\": \"f69e2c00-0000-0000-0000-185e5f5f5d8a\", \"displayName\": \"Owen Franklin\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\" } } }, \"media\": [ { \"label\": \"main-audio\", \"callerNetwork\": { \"ipAddress\": \"10.150.0.2\", \"subnet\": \"10.150.0.0\", \"linkSpeed\": 54000000, \"connectionType\": \"wifi\", \"port\": 27288, \"reflexiveIPAddress\": \"127.0.0.2\", \"relayIPAddress\": \"52.114.188.32\", \"relayPort\": 53889, \"macAddress\": \"00-00-00-00-00-00\", \"dnsSuffix\": null, \"sentQualityEventRatio\": 0, \"receivedQualityEventRatio\": 0.27, \"delayEventRatio\": 0, \"bandwidthLowEventRatio\": 0 }, \"calleeNetwork\": { \"ipAddress\": \"10.139.0.12\", \"subnet\": \"10.139.80.0\", \"linkSpeed\": 4294967295, \"connectionType\": \"wired\", \"port\": 50011, \"reflexiveIPAddress\": \"127.0.0.2\", \"relayIPAddress\": \"52.114.188.102\", \"relayPort\": 52810, \"macAddress\": \"00-00-00-00-00-00-00-00\", \"dnsSuffix\": null, \"sentQualityEventRatio\": 0.31, \"receivedQualityEventRatio\": 0, \"delayEventRatio\": 0, \"bandwidthLowEventRatio\": 0 }, \"callerDevice\": { \"captureDeviceName\": \"Default input device\", \"renderDeviceName\": \"Default output device\", \"receivedSignalLevel\": -10, \"receivedNoiseLevel\": -68, \"initialSignalLevelRootMeanSquare\": 60.25816, \"renderZeroVolumeEventRatio\": 1, \"renderMuteEventRatio\": 1, \"micGlitchRate\": 23, \"speakerGlitchRate\": 3830 }, \"calleeDevice\": { \"captureDeviceName\": \"Microphone (Microsoft Virtual Audio Device (Simple) (WDM))\", \"captureDeviceDriver\": \"Microsoft: 5.0.8638.1100\", \"renderDeviceName\": \"Speakers (Microsoft Virtual Audio Device (Simple) (WDM))\", \"renderDeviceDriver\": \"Microsoft: 5.0.8638.1100\", \"receivedSignalLevel\": -14, \"receivedNoiseLevel\": -86, \"initialSignalLevelRootMeanSquare\": 146.7885, \"micGlitchRate\": 143, \"speakerGlitchRate\": 182 }, \"streams\": [ { \"streamId\": \"1504545584\", \"streamDirection\": \"callerToCallee\", \"averageAudioDegradation\": null, \"averageJitter\": \"PT0.016S\", \"maxJitter\": \"PT0.021S\", \"averagePacketLossRate\": 0, \"maxPacketLossRate\": 0, \"averageRatioOfConcealedSamples\": null, \"maxRatioOfConcealedSamples\": null, \"averageRoundTripTime\": \"PT0.061S\", \"maxRoundTripTime\": \"PT0.079S\", \"packetUtilization\": 67, \"averageBandwidthEstimate\": 9965083, \"wasMediaBypassed\": false, \"averageAudioNetworkJitter\": \"PT0.043S\", \"maxAudioNetworkJitter\": \"PT0.046S\", \"rmsFreezeDuration\": null, \"averageFreezeDuration\": null, \"isAudioForwardErrorCorrectionUsed\": true }, { \"streamId\": \"1785122252\", \"streamDirection\": \"calleeToCaller\", \"averageAudioDegradation\": 1.160898, \"averageJitter\": \"PT0.007S\", \"maxJitter\": \"PT0.012S\", \"averagePacketLossRate\": 0.01381693, \"maxPacketLossRate\": 0.03738318, \"averageRatioOfConcealedSamples\": 0.06233422, \"maxRatioOfConcealedSamples\": 0.07192807, \"averageRoundTripTime\": \"PT0.064S\", \"maxRoundTripTime\": \"PT0.106S\", \"packetUtilization\": 709, \"averageBandwidthEstimate\": 15644878, \"wasMediaBypassed\": false, \"averageAudioNetworkJitter\": \"PT0.266S\", \"maxAudioNetworkJitter\": \"PT0.474S\", \"rmsFreezeDuration\": null, \"averageFreezeDuration\": null, \"isAudioForwardErrorCorrectionUsed\": false } ] } ] } ] }" + }, + "tags": [ + "o365metrics-teams.call.quality" + ] +} +``` + +**ECS Field Reference** + +Please refer to the following [document](https://www.elastic.co/guide/en/ecs/current/ecs-field-reference.html) for detailed information on ECS fields. + +**Exported fields** + +| Field | Description | Type | +|---|---|---| +| @timestamp | Event timestamp. | date | +| cloud.image.id | Image ID for the cloud instance. | keyword | +| data_stream.dataset | Data stream dataset. | constant_keyword | +| data_stream.namespace | Data stream namespace. | constant_keyword | +| data_stream.type | Data stream type. | constant_keyword | +| host.containerized | If the host is a container. | boolean | +| host.os.build | OS build information. | keyword | +| host.os.codename | OS codename, if any. | keyword | +| input.type | Type of Filebeat input. | keyword | +| o365.metrics.teams.call.quality.callee.cpu_cores.count | The number of CPU cores on the callee's device | long | +| o365.metrics.teams.call.quality.callee.cpu_name | The name of the CPU on the callee's device | keyword | +| o365.metrics.teams.call.quality.callee.cpu_processor_speed.mhz | The processor speed in MHz on the callee's CPU | long | +| o365.metrics.teams.call.quality.callee.feedback.rating | The rating the callee gave for the call quality | keyword | +| o365.metrics.teams.call.quality.callee.feedback.tokens.distorted_sound | Whether distorted sound was reported by the callee | boolean | +| o365.metrics.teams.call.quality.callee.feedback.tokens.echo | Whether echo was reported by the callee | boolean | +| o365.metrics.teams.call.quality.callee.feedback.tokens.interruptions | Whether interruptions were reported by the callee | boolean | +| o365.metrics.teams.call.quality.callee.feedback.tokens.low_volume | Whether low volume was reported by the callee | boolean | +| o365.metrics.teams.call.quality.callee.feedback.tokens.no_sound | Whether no sound was reported by the callee | boolean | +| o365.metrics.teams.call.quality.callee.feedback.tokens.noisy | Whether background noise was reported by the callee | boolean | +| o365.metrics.teams.call.quality.callee.feedback.tokens.other_no_sound | Whether other no sound issues were reported by the callee | boolean | +| o365.metrics.teams.call.quality.callee.feedback.tokens.stopped | Whether the call was stopped prematurely by the callee | boolean | +| o365.metrics.teams.call.quality.callee.identity.user.display_name | The display name of the callee | keyword | +| o365.metrics.teams.call.quality.callee.identity.user.id | The unique user ID for the callee | keyword | +| o365.metrics.teams.call.quality.callee.identity.user.tenant_id | The tenant ID of the callee's organization | keyword | +| o365.metrics.teams.call.quality.callee.name | The name of the callee | keyword | +| o365.metrics.teams.call.quality.callee.user_agent.header_value | The header value of the user agent | keyword | +| o365.metrics.teams.call.quality.callee.user_agent.platform | The platform of the callee (e.g., Windows, macOS) | keyword | +| o365.metrics.teams.call.quality.callee.user_agent.product_family | The product family of the callee (e.g., Teams, Skype) | keyword | +| o365.metrics.teams.call.quality.caller.cpu_cores.count | The number of CPU cores on the caller's device | long | +| o365.metrics.teams.call.quality.caller.cpu_name | The name of the CPU on the caller's device | keyword | +| o365.metrics.teams.call.quality.caller.cpu_processor_speed.mhz | The processor speed in MHz on the caller's CPU | long | +| o365.metrics.teams.call.quality.caller.identity.user.display_name | The display name of the caller | keyword | +| o365.metrics.teams.call.quality.caller.identity.user.id | The unique user ID for the caller | keyword | +| o365.metrics.teams.call.quality.caller.identity.user.tenant_id | The tenant ID of the caller's organization | keyword | +| o365.metrics.teams.call.quality.caller.name | The name of the caller | keyword | +| o365.metrics.teams.call.quality.caller.user_agent.header_value | The header value of the user agent | keyword | +| o365.metrics.teams.call.quality.caller.user_agent.platform | The platform of the caller (e.g., Windows, macOS) | keyword | +| o365.metrics.teams.call.quality.caller.user_agent.product_family | The product family of the caller (e.g., Teams, Skype) | keyword | +| o365.metrics.teams.call.quality.end_date_time | The end date and time of the call | date | +| o365.metrics.teams.call.quality.id | Unique identifier for the call quality record | keyword | +| o365.metrics.teams.call.quality.is_test | Indicates whether the call is a test call | boolean | +| o365.metrics.teams.call.quality.modalities | Types of communication used in the call (audio, video, etc.) | keyword | +| o365.metrics.teams.call.quality.segments.callee.cpu_cores_count | The number of CPU cores on the callee's device | long | +| o365.metrics.teams.call.quality.segments.callee.cpu_name | The name of the CPU on the callee's device | keyword | +| o365.metrics.teams.call.quality.segments.callee.cpu_processor_speed_in_mhz | The processor speed in MHz on the callee's CPU | long | +| o365.metrics.teams.call.quality.segments.callee.feedback.rating | The rating the callee gave for the call quality | keyword | +| o365.metrics.teams.call.quality.segments.callee.feedback.tokens.distorted_sound | Whether distorted sound was reported by the callee | boolean | +| o365.metrics.teams.call.quality.segments.callee.feedback.tokens.echo | Whether echo was reported by the callee | boolean | +| o365.metrics.teams.call.quality.segments.callee.feedback.tokens.interruptions | Whether interruptions were reported by the callee | boolean | +| o365.metrics.teams.call.quality.segments.callee.feedback.tokens.low_volume | Whether low volume was reported by the callee | boolean | +| o365.metrics.teams.call.quality.segments.callee.feedback.tokens.no_sound | Whether no sound was reported by the callee | boolean | +| o365.metrics.teams.call.quality.segments.callee.feedback.tokens.noisy | Whether background noise was reported by the callee | boolean | +| o365.metrics.teams.call.quality.segments.callee.feedback.tokens.other_no_sound | Whether other no sound issues were reported by the callee | boolean | +| o365.metrics.teams.call.quality.segments.callee.feedback.tokens.stopped | Whether the call was stopped prematurely by the callee | boolean | +| o365.metrics.teams.call.quality.segments.callee.identity.user.display_name | The display name of the callee | keyword | +| o365.metrics.teams.call.quality.segments.callee.identity.user.id | The unique user ID for the callee | keyword | +| o365.metrics.teams.call.quality.segments.callee.identity.user.tenant_id | The tenant ID of the callee's organization | keyword | +| o365.metrics.teams.call.quality.segments.callee.name | The name of the callee | keyword | +| o365.metrics.teams.call.quality.segments.callee.user_agent.header_value | The header value of the user agent | keyword | +| o365.metrics.teams.call.quality.segments.callee.user_agent.platform | The platform of the callee (e.g., Windows, macOS) | keyword | +| o365.metrics.teams.call.quality.segments.callee.user_agent.product_family | The product family of the callee (e.g., Teams, Skype) | keyword | +| o365.metrics.teams.call.quality.segments.caller.cpu_cores_count | The number of CPU cores on the caller's device | long | +| o365.metrics.teams.call.quality.segments.caller.cpu_name | The name of the CPU on the caller's device | keyword | +| o365.metrics.teams.call.quality.segments.caller.cpu_processor_speed_in_mhz | The processor speed in MHz on the caller's CPU | long | +| o365.metrics.teams.call.quality.segments.caller.identity.user.display_name | The display name of the caller | keyword | +| o365.metrics.teams.call.quality.segments.caller.identity.user.id | The unique user ID for the caller | keyword | +| o365.metrics.teams.call.quality.segments.caller.identity.user.tenant_id | The tenant ID of the caller's organization | keyword | +| o365.metrics.teams.call.quality.segments.caller.name | The name of the caller | keyword | +| o365.metrics.teams.call.quality.segments.caller.user_agent.header_value | The header value of the user agent | keyword | +| o365.metrics.teams.call.quality.segments.caller.user_agent.platform | The platform of the caller (e.g., Windows, macOS) | keyword | +| o365.metrics.teams.call.quality.segments.caller.user_agent.product_family | The product family of the caller (e.g., Teams, Skype) | keyword | +| o365.metrics.teams.call.quality.segments.end_date_time | End time of the segment | date | +| o365.metrics.teams.call.quality.segments.id | Unique identifier for the segment | keyword | +| o365.metrics.teams.call.quality.segments.media.callee_device.capture_device_driver | The name of the callee's capture device driver | keyword | +| o365.metrics.teams.call.quality.segments.media.callee_device.capture_device_name | The name of the callee's capture device | keyword | +| o365.metrics.teams.call.quality.segments.media.callee_device.initial_signal_level_root_mean_square | Initial RMS of the callee's signal level | float | +| o365.metrics.teams.call.quality.segments.media.callee_device.mic_glitch_rate | The glitch rate for the callee's microphone | float | +| o365.metrics.teams.call.quality.segments.media.callee_device.received_noise_level | The received noise level on the callee's device | float | +| o365.metrics.teams.call.quality.segments.media.callee_device.received_signal_level | The received signal level on the callee's device | float | +| o365.metrics.teams.call.quality.segments.media.callee_device.render_device_driver | The name of the callee's render device driver | keyword | +| o365.metrics.teams.call.quality.segments.media.callee_device.render_device_name | The name of the callee's render device | keyword | +| o365.metrics.teams.call.quality.segments.media.callee_device.speaker_glitch_rate | The glitch rate for the callee's speaker | float | +| o365.metrics.teams.call.quality.segments.media.callee_network.bandwidth_low_event_ratio | The event ratio of low bandwidth for the callee's network | float | +| o365.metrics.teams.call.quality.segments.media.callee_network.connection_type | Type of connection used (e.g., wifi, wired) | keyword | +| o365.metrics.teams.call.quality.segments.media.callee_network.delay_event_ratio | The event ratio of delay in the callee's network | float | +| o365.metrics.teams.call.quality.segments.media.callee_network.dns_suffix | DNS suffix for the callee's network | keyword | +| o365.metrics.teams.call.quality.segments.media.callee_network.ip_address | IP address of the callee's network | keyword | +| o365.metrics.teams.call.quality.segments.media.callee_network.link_speed | Link speed of the callee's network connection | long | +| o365.metrics.teams.call.quality.segments.media.callee_network.mac_address | MAC address of the callee's device | keyword | +| o365.metrics.teams.call.quality.segments.media.callee_network.port | Port used for the connection | long | +| o365.metrics.teams.call.quality.segments.media.callee_network.received_quality_event_ratio | Quality event ratio related to the received network quality | float | +| o365.metrics.teams.call.quality.segments.media.callee_network.reflexive_ip_address | Reflexive IP address for the callee's network | keyword | +| o365.metrics.teams.call.quality.segments.media.callee_network.relay_ip_address | Relay IP address for the callee's network | keyword | +| o365.metrics.teams.call.quality.segments.media.callee_network.relay_port | Relay port | long | +| o365.metrics.teams.call.quality.segments.media.callee_network.sent_quality_event_ratio | Quality event ratio related to the callee's network | float | +| o365.metrics.teams.call.quality.segments.media.callee_network.subnet | Subnet of the callee's network | keyword | +| o365.metrics.teams.call.quality.segments.media.caller_device.capture_device_name | The name of the caller's capture device | keyword | +| o365.metrics.teams.call.quality.segments.media.caller_device.initial_signal_level_root_mean_square | Initial RMS of the caller's signal level | float | +| o365.metrics.teams.call.quality.segments.media.caller_device.mic_glitch_rate | The glitch rate for the caller's microphone | float | +| o365.metrics.teams.call.quality.segments.media.caller_device.received_noise_level | The received noise level on the caller's device | float | +| o365.metrics.teams.call.quality.segments.media.caller_device.received_signal_level | The received signal level on the caller's device | float | +| o365.metrics.teams.call.quality.segments.media.caller_device.render_device_name | The name of the caller's render device | keyword | +| o365.metrics.teams.call.quality.segments.media.caller_device.render_mute_event_ratio | Ratio of mute events during rendering | float | +| o365.metrics.teams.call.quality.segments.media.caller_device.render_zero_volume_event_ratio | Ratio of zero volume events during rendering | float | +| o365.metrics.teams.call.quality.segments.media.caller_device.speaker_glitch_rate | The glitch rate for the caller's speaker | float | +| o365.metrics.teams.call.quality.segments.media.caller_network.bandwidth_low_event_ratio | The event ratio of low bandwidth for the caller's network | float | +| o365.metrics.teams.call.quality.segments.media.caller_network.connection_type | Type of connection used (e.g., wifi, wired) | keyword | +| o365.metrics.teams.call.quality.segments.media.caller_network.delay_event_ratio | The event ratio of delay in the caller's network | float | +| o365.metrics.teams.call.quality.segments.media.caller_network.dns_suffix | DNS suffix for the caller's network | keyword | +| o365.metrics.teams.call.quality.segments.media.caller_network.ip_address | IP address of the caller's network | keyword | +| o365.metrics.teams.call.quality.segments.media.caller_network.link_speed | Link speed of the caller's network connection | long | +| o365.metrics.teams.call.quality.segments.media.caller_network.mac_address | MAC address of the caller's device | keyword | +| o365.metrics.teams.call.quality.segments.media.caller_network.port | Port used for the connection | long | +| o365.metrics.teams.call.quality.segments.media.caller_network.received_quality_event_ratio | Quality event ratio related to the received network quality | float | +| o365.metrics.teams.call.quality.segments.media.caller_network.reflexive_ip_address | Reflexive IP address for the caller's network | keyword | +| o365.metrics.teams.call.quality.segments.media.caller_network.relay_ip_address | Relay IP address for the caller's network | keyword | +| o365.metrics.teams.call.quality.segments.media.caller_network.relay_port | Relay port | long | +| o365.metrics.teams.call.quality.segments.media.caller_network.sent_quality_event_ratio | Quality event ratio related to the caller's network | float | +| o365.metrics.teams.call.quality.segments.media.caller_network.subnet | Subnet of the caller's network | keyword | +| o365.metrics.teams.call.quality.segments.media.label | The label for the media stream (e.g., "main-audio") | keyword | +| o365.metrics.teams.call.quality.segments.media.streams.average_audio_degradation | Average audio degradation metric | float | +| o365.metrics.teams.call.quality.segments.media.streams.average_audio_network_jitter | Average audio network jitter in milliseconds | keyword | +| o365.metrics.teams.call.quality.segments.media.streams.average_bandwidth_estimate | Average bandwidth estimate in bits per second | float | +| o365.metrics.teams.call.quality.segments.media.streams.average_jitter | Average jitter in milliseconds | keyword | +| o365.metrics.teams.call.quality.segments.media.streams.average_packet_loss_rate | Average rate of packet loss | float | +| o365.metrics.teams.call.quality.segments.media.streams.average_ratio_of_concealed_samples | Average ratio of concealed samples | float | +| o365.metrics.teams.call.quality.segments.media.streams.average_round_trip_time | Average round trip time in milliseconds | keyword | +| o365.metrics.teams.call.quality.segments.media.streams.is_audio_forward_error_correction_used | Indicates if audio forward error correction was used | boolean | +| o365.metrics.teams.call.quality.segments.media.streams.max_audio_network_jitter | Maximum audio network jitter in milliseconds | keyword | +| o365.metrics.teams.call.quality.segments.media.streams.max_jitter | Maximum jitter in milliseconds | keyword | +| o365.metrics.teams.call.quality.segments.media.streams.max_packet_loss_rate | Maximum rate of packet loss | float | +| o365.metrics.teams.call.quality.segments.media.streams.max_ratio_of_concealed_samples | | float | +| o365.metrics.teams.call.quality.segments.media.streams.max_round_trip_time | Maximum round trip time in milliseconds | keyword | +| o365.metrics.teams.call.quality.segments.media.streams.packet_utilization | Utilization rate of packets | float | +| o365.metrics.teams.call.quality.segments.media.streams.stream_direction | Direction of the media stream | keyword | +| o365.metrics.teams.call.quality.segments.media.streams.stream_id | The stream ID | keyword | +| o365.metrics.teams.call.quality.segments.media.streams.was_media_bypassed | Indicates if media was bypassed | boolean | +| o365.metrics.teams.call.quality.segments.quality_score | Quality score of the call segment | float | +| o365.metrics.teams.call.quality.segments.start_date_time | Start time of the segment | date | +| o365.metrics.teams.call.quality.start_date_time | The start date and time of the call | date | + diff --git a/packages/o365_metrics/manifest.yml b/packages/o365_metrics/manifest.yml index b843a938c7a..68cda6fe14d 100644 --- a/packages/o365_metrics/manifest.yml +++ b/packages/o365_metrics/manifest.yml @@ -1,6 +1,6 @@ name: o365_metrics title: Microsoft Office 365 Metrics -version: "0.4.0" +version: "0.5.0" description: Collect metrics from Microsoft Office 365 with Elastic Agent.(This integration is currently in development and not yet ready for general use) type: integration format_version: "3.0.2"