@oneuptime/common 14.0.10 → 14.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (837) hide show
  1. package/Models/DatabaseModels/AIConversation.ts +127 -1
  2. package/Models/DatabaseModels/CephCluster.ts +12 -0
  3. package/Models/DatabaseModels/CloudResource.ts +12 -0
  4. package/Models/DatabaseModels/DatabaseServer.ts +12 -0
  5. package/Models/DatabaseModels/DockerHost.ts +12 -0
  6. package/Models/DatabaseModels/DockerSwarmCluster.ts +12 -0
  7. package/Models/DatabaseModels/GlobalOidc.ts +0 -4
  8. package/Models/DatabaseModels/GlobalOidcProject.ts +0 -4
  9. package/Models/DatabaseModels/GlobalSso.ts +0 -4
  10. package/Models/DatabaseModels/GlobalSsoProject.ts +0 -4
  11. package/Models/DatabaseModels/Host.ts +12 -0
  12. package/Models/DatabaseModels/IncidentForm.ts +594 -0
  13. package/Models/DatabaseModels/IncidentFormSubmission.ts +283 -0
  14. package/Models/DatabaseModels/IncidentTemplate.ts +59 -0
  15. package/Models/DatabaseModels/Index.ts +14 -0
  16. package/Models/DatabaseModels/IoTFleet.ts +12 -0
  17. package/Models/DatabaseModels/KubernetesCluster.ts +12 -0
  18. package/Models/DatabaseModels/MessageQueue.ts +1102 -0
  19. package/Models/DatabaseModels/MessageQueueLabelRule.ts +553 -0
  20. package/Models/DatabaseModels/MessageQueueOwnerRule.ts +633 -0
  21. package/Models/DatabaseModels/MessageQueueOwnerTeam.ts +491 -0
  22. package/Models/DatabaseModels/MessageQueueOwnerUser.ts +490 -0
  23. package/Models/DatabaseModels/PodmanHost.ts +12 -0
  24. package/Models/DatabaseModels/Project.ts +59 -0
  25. package/Models/DatabaseModels/ProjectOidc.ts +0 -4
  26. package/Models/DatabaseModels/ProjectSso.ts +0 -4
  27. package/Models/DatabaseModels/ProxmoxCluster.ts +12 -0
  28. package/Models/DatabaseModels/RumApplication.ts +12 -0
  29. package/Models/DatabaseModels/ServerlessFunction.ts +12 -0
  30. package/Models/DatabaseModels/Service.ts +12 -0
  31. package/Models/DatabaseModels/StatusPageOidc.ts +0 -4
  32. package/Models/DatabaseModels/StatusPageSso.ts +0 -4
  33. package/Models/DatabaseModels/TeamComplianceSetting.ts +47 -2
  34. package/Models/DatabaseModels/VMwareVCenter.ts +12 -0
  35. package/Server/API/AIChatAPI.ts +13 -114
  36. package/Server/API/AIInvestigationAPI.ts +3 -3
  37. package/Server/API/AIInvestigationConversationAPI.ts +266 -0
  38. package/Server/API/IncidentFormAPI.ts +376 -0
  39. package/Server/API/ProjectOIDC.ts +16 -25
  40. package/Server/API/ProjectSSO.ts +16 -24
  41. package/Server/API/StatusPageAPI.ts +42 -77
  42. package/Server/Enterprise/EnterpriseEdition.ts +93 -28
  43. package/Server/Enterprise/EnterpriseFeature.ts +25 -3
  44. package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +1 -1
  45. package/Server/Enterprise/EnterpriseServerModule.ts +4 -1
  46. package/Server/EnvironmentConfig.ts +1 -1
  47. package/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.ts +129 -0
  48. package/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.ts +52 -0
  49. package/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.ts +75 -0
  50. package/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.ts +477 -0
  51. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  52. package/Server/Middleware/IncidentFormRateLimit.ts +847 -0
  53. package/Server/Middleware/UserAuthorization.ts +16 -38
  54. package/Server/Services/AIService.ts +10 -13
  55. package/Server/Services/IncidentCustomFieldService.ts +112 -2
  56. package/Server/Services/IncidentEpisodeMemberService.ts +24 -4
  57. package/Server/Services/IncidentEpisodeService.ts +10 -1
  58. package/Server/Services/IncidentFormService.ts +1566 -0
  59. package/Server/Services/IncidentFormSubmissionService.ts +97 -0
  60. package/Server/Services/IncidentGroupingEngineService.ts +45 -8
  61. package/Server/Services/IncidentService.ts +123 -5
  62. package/Server/Services/IncidentTemplateService.ts +22 -0
  63. package/Server/Services/Index.ts +14 -0
  64. package/Server/Services/MessageQueueLabelRuleEngineService.ts +321 -0
  65. package/Server/Services/MessageQueueLabelRuleService.ts +14 -0
  66. package/Server/Services/MessageQueueOwnerRuleEngineService.ts +412 -0
  67. package/Server/Services/MessageQueueOwnerRuleService.ts +14 -0
  68. package/Server/Services/MessageQueueOwnerTeamService.ts +62 -0
  69. package/Server/Services/MessageQueueOwnerUserService.ts +62 -0
  70. package/Server/Services/MessageQueueService.ts +1463 -0
  71. package/Server/Services/OpenTelemetryIngestService.ts +37 -4
  72. package/Server/Services/ProjectService.ts +0 -59
  73. package/Server/Services/StatusPagePrivateUserService.ts +1 -4
  74. package/Server/Services/StatusPageService.ts +1 -51
  75. package/Server/Services/TeamComplianceSettingService.ts +163 -42
  76. package/Server/Services/UserNotificationRuleService.ts +8 -1
  77. package/Server/Services/WorkspaceNotificationSummaryService.ts +12 -3
  78. package/Server/Types/Database/Permissions/CreatePermission.ts +17 -3
  79. package/Server/Types/Database/Permissions/EditionPermission.ts +140 -38
  80. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +16 -0
  81. package/Server/Types/Database/Permissions/TablePermission.ts +3 -3
  82. package/Server/Types/Database/Permissions/UpdatePermission.ts +20 -6
  83. package/Server/Utils/AI/Chat/AgentContextCompactor.ts +200 -0
  84. package/Server/Utils/AI/Chat/ChatAgentRunner.ts +307 -48
  85. package/Server/Utils/AI/Chat/ChatRunCancellation.ts +156 -0
  86. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +78 -18
  87. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
  88. package/Server/Utils/AI/Chat/ToolOutputPager.ts +322 -0
  89. package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +88 -30
  90. package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +13 -1
  91. package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +0 -32
  92. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +27 -25
  93. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +7 -1
  94. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +34 -14
  95. package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +69 -24
  96. package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +9 -0
  97. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +53 -10
  98. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +27 -10
  99. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +27 -10
  100. package/Server/Utils/AI/SRE/InvestigationQueue.ts +16 -19
  101. package/Server/Utils/AI/SRE/InvestigationThread.ts +646 -0
  102. package/Server/Utils/AI/SRE/InvestigationThreadService.ts +715 -0
  103. package/Server/Utils/AI/Toolbox/Serializer.ts +10 -3
  104. package/Server/Utils/EditionEnforcement.ts +19 -202
  105. package/Server/Utils/LLM/LLMService.ts +259 -63
  106. package/Server/Utils/RelaxedScimTeamLocksReport.ts +245 -0
  107. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
  108. package/Server/Utils/SameOriginRequest.ts +203 -0
  109. package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
  110. package/Server/Utils/Telemetry/EntityRegistry.ts +4 -1
  111. package/Server/Utils/Telemetry/MessageQueueDiscovery.ts +1402 -0
  112. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +4 -1
  113. package/Server/Utils/VendorAssets.ts +3 -3
  114. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +3 -1
  115. package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +3 -1
  116. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +10 -1
  117. package/Tests/App/Accounts/IncidentFormPage.test.tsx +2036 -0
  118. package/Tests/App/Accounts/IncidentFormServerMessages.test.ts +119 -0
  119. package/Tests/App/Accounts/IncidentFormUtils.test.ts +1157 -0
  120. package/Tests/App/Accounts/LoginPasskey.test.tsx +6 -4
  121. package/Tests/App/Accounts/LoginSso.test.tsx +724 -0
  122. package/Tests/App/AdminDashboard/AdminAuthenticationRequireSso.test.tsx +338 -0
  123. package/Tests/App/AdminDashboard/AdminAuthenticationSsoCardLocales.test.tsx +331 -0
  124. package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +47 -33
  125. package/Tests/App/AdminDashboard/GlobalSsoOidcPages.test.tsx +1021 -0
  126. package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +876 -78
  127. package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +20 -3
  128. package/Tests/App/Dashboard/CephProxmoxVMwareDocumentationCards.test.tsx +359 -0
  129. package/Tests/App/Dashboard/CephSetupGuide.test.ts +961 -0
  130. package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +381 -95
  131. package/Tests/App/Dashboard/CloudSetupGuide.test.ts +1463 -0
  132. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +174 -12
  133. package/Tests/App/Dashboard/ContainerSetupGuideCards.test.tsx +345 -0
  134. package/Tests/App/Dashboard/CoreListEmptyStates.test.tsx +501 -0
  135. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +0 -1
  136. package/Tests/App/Dashboard/DatabaseDocumentationCard.test.tsx +400 -0
  137. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +5 -0
  138. package/Tests/App/Dashboard/DatabaseSetupGuide.test.ts +1869 -0
  139. package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +44 -0
  140. package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +50 -9
  141. package/Tests/App/Dashboard/DockerSetupGuide.test.ts +899 -0
  142. package/Tests/App/Dashboard/DockerSwarmSetupGuide.test.ts +964 -0
  143. package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +141 -7
  144. package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +52 -39
  145. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +7 -1
  146. package/Tests/App/Dashboard/GettingStartedTaskRoutes.test.tsx +331 -0
  147. package/Tests/App/Dashboard/HomeOverviewStatsFirstRun.test.tsx +925 -0
  148. package/Tests/App/Dashboard/HostDocumentationCard.test.tsx +225 -0
  149. package/Tests/App/Dashboard/HostSetupGuide.test.ts +1183 -0
  150. package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +69 -45
  151. package/Tests/App/Dashboard/IncidentCreateTemplateCustomFieldSettings.test.tsx +745 -0
  152. package/Tests/App/Dashboard/IncidentCreateTemplateOwners.test.tsx +414 -0
  153. package/Tests/App/Dashboard/IncidentCustomFieldCreateSettingsForm.test.ts +1042 -0
  154. package/Tests/App/Dashboard/IncidentCustomFieldSettingsCard.test.tsx +1816 -0
  155. package/Tests/App/Dashboard/IncidentFormPlan.test.ts +89 -0
  156. package/Tests/App/Dashboard/IncidentFormShareLinkCard.test.tsx +846 -0
  157. package/Tests/App/Dashboard/IncidentFormsPages.test.tsx +1324 -0
  158. package/Tests/App/Dashboard/IncidentTemplateCustomFieldSettings.test.tsx +630 -0
  159. package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +13 -0
  160. package/Tests/App/Dashboard/IncomingEmailMonitorLinkVerifyHint.test.tsx +104 -0
  161. package/Tests/App/Dashboard/InvestigationConversation.test.tsx +1107 -0
  162. package/Tests/App/Dashboard/InvestigationConversationData.test.ts +546 -0
  163. package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +170 -5
  164. package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +207 -2
  165. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +729 -34
  166. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +9 -21
  167. package/Tests/App/Dashboard/InvestigationReportView.test.tsx +274 -37
  168. package/Tests/App/Dashboard/InvestigationStatusBadge.test.tsx +130 -0
  169. package/Tests/App/Dashboard/IoTDocumentationCard.test.tsx +218 -0
  170. package/Tests/App/Dashboard/IoTSetupGuide.test.ts +1124 -0
  171. package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +20 -6
  172. package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +107 -83
  173. package/Tests/App/Dashboard/KubernetesSetupGuide.test.ts +787 -0
  174. package/Tests/App/Dashboard/MessageQueueBreadcrumbs.test.tsx +228 -0
  175. package/Tests/App/Dashboard/MessageQueueBrokerHealth.test.tsx +1538 -0
  176. package/Tests/App/Dashboard/MessageQueueBrokerHealthMetricChart.test.tsx +969 -0
  177. package/Tests/App/Dashboard/MessageQueueBrokerHealthReads.test.ts +889 -0
  178. package/Tests/App/Dashboard/MessageQueueBrokerMetricsReach.test.ts +236 -0
  179. package/Tests/App/Dashboard/MessageQueueDocumentationCard.test.tsx +479 -0
  180. package/Tests/App/Dashboard/MessageQueueListPages.test.tsx +1232 -0
  181. package/Tests/App/Dashboard/MessageQueueMetricDescriptions.test.ts +244 -0
  182. package/Tests/App/Dashboard/MessageQueueMonitorLink.test.ts +952 -0
  183. package/Tests/App/Dashboard/MessageQueueMonitorLinkMonitorCreate.test.tsx +859 -0
  184. package/Tests/App/Dashboard/MessageQueueOverview.test.tsx +1773 -0
  185. package/Tests/App/Dashboard/MessageQueueOverviewPresentation.test.ts +196 -0
  186. package/Tests/App/Dashboard/MessageQueuePresentation.test.ts +799 -0
  187. package/Tests/App/Dashboard/MessageQueueProducersConsumers.test.tsx +680 -0
  188. package/Tests/App/Dashboard/MessageQueueRoutes.test.tsx +383 -0
  189. package/Tests/App/Dashboard/MessageQueueRulePages.test.tsx +278 -0
  190. package/Tests/App/Dashboard/MessageQueueSetupGuide.test.ts +2778 -0
  191. package/Tests/App/Dashboard/MessageQueueSideMenus.test.tsx +273 -0
  192. package/Tests/App/Dashboard/MessageQueueSpanPopulations.test.ts +930 -0
  193. package/Tests/App/Dashboard/MessageQueueSpanStore.ts +351 -0
  194. package/Tests/App/Dashboard/MessageQueueTelemetryScope.test.ts +375 -0
  195. package/Tests/App/Dashboard/MessageQueueTelemetryScopeTabs.test.tsx +668 -0
  196. package/Tests/App/Dashboard/MessageQueueViewPages.test.tsx +685 -0
  197. package/Tests/App/Dashboard/MonitorAndHomeNotOperationalMenus.test.tsx +342 -0
  198. package/Tests/App/Dashboard/MonitorCreateFirstRunDefaults.test.tsx +623 -0
  199. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +442 -0
  200. package/Tests/App/Dashboard/MonitorLogsPageViewSummary.test.tsx +814 -0
  201. package/Tests/App/Dashboard/MonitorSetupCardBodies.test.tsx +246 -0
  202. package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +8 -0
  203. package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +27 -12
  204. package/Tests/App/Dashboard/PlanGatedPage.test.tsx +292 -0
  205. package/Tests/App/Dashboard/PodmanSetupGuide.test.ts +948 -0
  206. package/Tests/App/Dashboard/ProductOrientation.test.tsx +5 -4
  207. package/Tests/App/Dashboard/ProductSettingsSectionCollapsed.test.tsx +266 -0
  208. package/Tests/App/Dashboard/ProxmoxSetupGuide.test.ts +1318 -0
  209. package/Tests/App/Dashboard/ResourceAiAgentAttentionServerParity.test.ts +555 -0
  210. package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +298 -9
  211. package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +453 -0
  212. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +16 -0
  213. package/Tests/App/Dashboard/ResourceConnectionGuideCard.test.tsx +444 -0
  214. package/Tests/App/Dashboard/ResourceConnectionGuideOverviewsInfra.test.tsx +798 -0
  215. package/Tests/App/Dashboard/ResourceConnectionGuideOverviewsPlatforms.test.tsx +717 -0
  216. package/Tests/App/Dashboard/ResourceConnectionGuides.test.ts +981 -0
  217. package/Tests/App/Dashboard/ResourceConnectionState.test.ts +132 -0
  218. package/Tests/App/Dashboard/RumDocumentationCard.test.tsx +293 -0
  219. package/Tests/App/Dashboard/RumSessionReplayRetentionSettings.test.tsx +467 -0
  220. package/Tests/App/Dashboard/RumSetupGuide.test.ts +758 -0
  221. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +25 -0
  222. package/Tests/App/Dashboard/ServerlessDocumentationCard.test.tsx +254 -0
  223. package/Tests/App/Dashboard/ServerlessSetupGuide.test.ts +1074 -0
  224. package/Tests/App/Dashboard/SetupGuide.test.ts +246 -0
  225. package/Tests/App/Dashboard/SetupGuideCard.test.tsx +756 -0
  226. package/Tests/App/Dashboard/SloListSideMenu.test.tsx +120 -0
  227. package/Tests/App/Dashboard/SsoPages.test.tsx +833 -0
  228. package/Tests/App/Dashboard/TelemetryDocumentation.test.tsx +253 -0
  229. package/Tests/App/Dashboard/TelemetryRetentionShells.test.tsx +730 -0
  230. package/Tests/App/Dashboard/VMwareSetupGuide.test.ts +1033 -0
  231. package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +87 -7
  232. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +28 -9
  233. package/Tests/Models/DatabaseModels/IncidentFormModel.test.ts +1250 -0
  234. package/Tests/Models/DatabaseModels/MessageQueueModels.test.ts +1983 -0
  235. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
  236. package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +190 -14
  237. package/Tests/Models/IncidentTemplateCustomFieldSettingsColumn.test.ts +291 -0
  238. package/Tests/Server/API/AIInvestigationConversationAPI.test.ts +412 -0
  239. package/Tests/Server/API/GlobalConfigLicense.test.ts +38 -9
  240. package/Tests/Server/API/IncidentFormAPI.test.ts +942 -0
  241. package/Tests/Server/API/IncidentFormPublicRoutes.test.ts +1653 -0
  242. package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -1
  243. package/Tests/Server/API/{SsoProviderListingsEdition.test.ts → SsoProviderListings.test.ts} +164 -110
  244. package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +76 -54
  245. package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +125 -42
  246. package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +36 -10
  247. package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +51 -9
  248. package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +13 -8
  249. package/Tests/Server/Enterprise/SsoInCommunityEdition.test.ts +540 -0
  250. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
  251. package/Tests/Server/Infrastructure/Postgres/AddIncidentFormsMigration.test.ts +438 -0
  252. package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleNotificationChannelsMigration.test.ts +255 -0
  253. package/Tests/Server/Infrastructure/Postgres/MessageQueueTablesMigration.test.ts +637 -0
  254. package/Tests/Server/Middleware/IncidentFormRateLimit.test.ts +1630 -0
  255. package/Tests/Server/Middleware/UserAuthorization.test.ts +16 -17
  256. package/Tests/Server/Middleware/UserAuthorizationSsoEnforcement.test.ts +544 -0
  257. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +37 -8
  258. package/Tests/Server/Services/IncidentCreatedFeedTitle.test.ts +212 -0
  259. package/Tests/Server/Services/IncidentCustomFieldDeleteFormQuestions.test.ts +297 -0
  260. package/Tests/Server/Services/IncidentFormOwnersCreatedNotification.test.ts +497 -0
  261. package/Tests/Server/Services/IncidentFormPostgres.test.ts +958 -0
  262. package/Tests/Server/Services/IncidentFormPublicForm.test.ts +1260 -0
  263. package/Tests/Server/Services/IncidentFormPublicSubmission.test.ts +2520 -0
  264. package/Tests/Server/Services/IncidentFormRegistration.test.ts +159 -0
  265. package/Tests/Server/Services/IncidentFormService.test.ts +663 -0
  266. package/Tests/Server/Services/IncidentFormSubmissionService.test.ts +430 -0
  267. package/Tests/Server/Services/IncidentFormSubmissionTemplateBranch.test.ts +473 -0
  268. package/Tests/Server/Services/IncidentGroupingTemplateSubstitution.test.ts +81 -0
  269. package/Tests/Server/Services/IncidentTemplateCustomFieldSettings.test.ts +262 -0
  270. package/Tests/Server/Services/IncidentTemplateOwnersOnDeclare.test.ts +566 -0
  271. package/Tests/Server/Services/IncidentTitleMarkdownSinks.test.ts +640 -0
  272. package/Tests/Server/Services/LlmLogServiceTokenAggregateParams.test.ts +3 -3
  273. package/Tests/Server/Services/MessageQueueOwnerServices.test.ts +440 -0
  274. package/Tests/Server/Services/MessageQueueRegistries.test.ts +577 -0
  275. package/Tests/Server/Services/MessageQueueRuleEngines.test.ts +900 -0
  276. package/Tests/Server/Services/MessageQueueService.test.ts +2210 -0
  277. package/Tests/Server/Services/MessageQueueSqlPostgres.test.ts +1271 -0
  278. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +28 -1
  279. package/Tests/Server/Services/OpenTelemetryRetentionOverrideEdition.test.ts +474 -0
  280. package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +21 -0
  281. package/Tests/Server/Services/OwnerRowUniqueness.test.ts +3 -0
  282. package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +0 -1
  283. package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +56 -6
  284. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +30 -1
  285. package/Tests/Server/Services/SsoRequirementReads.test.ts +454 -0
  286. package/Tests/Server/Services/SsoRequirementWrites.test.ts +529 -0
  287. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
  288. package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +107 -89
  289. package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +1068 -176
  290. package/Tests/Server/Services/TeamComplianceSettingService.test.ts +1962 -200
  291. package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +654 -297
  292. package/Tests/Server/Types/Database/Permissions/RetentionOverrideColumns.test.ts +784 -0
  293. package/Tests/Server/Types/Database/Permissions/SsoScalePlanGate.test.ts +418 -0
  294. package/Tests/Server/Utils/AI/AIAlertGating.test.ts +0 -1
  295. package/Tests/Server/Utils/AI/AIInvestigationEngineRunLimits.test.ts +136 -0
  296. package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +15 -14
  297. package/Tests/Server/Utils/AI/AgentContextCompactor.test.ts +351 -0
  298. package/Tests/Server/Utils/AI/ChatAgentRunnerSharedThread.test.ts +842 -0
  299. package/Tests/Server/Utils/AI/ChatRunCancellation.test.ts +195 -0
  300. package/Tests/Server/Utils/AI/CodeFixReadiness.test.ts +10 -57
  301. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +20 -24
  302. package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +7 -30
  303. package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +225 -29
  304. package/Tests/Server/Utils/AI/InvestigationInfrastructureAccessWiring.test.ts +266 -25
  305. package/Tests/Server/Utils/AI/InvestigationThread.test.ts +580 -0
  306. package/Tests/Server/Utils/AI/InvestigationThreadService.test.ts +801 -0
  307. package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +525 -43
  308. package/Tests/Server/Utils/AI/KubectlJobRunner.test.ts +4 -2
  309. package/Tests/Server/Utils/AI/LLMServiceUnreachableProvider.test.ts +435 -0
  310. package/Tests/Server/Utils/AI/ObservabilityAssistantLimits.test.ts +462 -0
  311. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +14 -25
  312. package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +2 -0
  313. package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +297 -15
  314. package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +10 -6
  315. package/Tests/Server/Utils/AI/ToolOutputPager.test.ts +382 -0
  316. package/Tests/Server/Utils/AI/ToolResultSerializer.test.ts +23 -4
  317. package/Tests/Server/Utils/AI/Toolbox/LogTools.test.ts +25 -6
  318. package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +14 -3
  319. package/Tests/Server/Utils/EditionEnforcement.test.ts +107 -147
  320. package/Tests/Server/Utils/{CommunityEditionSsoReport.test.ts → RelaxedScimTeamLocksReport.test.ts} +212 -208
  321. package/Tests/Server/Utils/SameOriginRequest.test.ts +372 -0
  322. package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +20 -0
  323. package/Tests/Server/Utils/Telemetry/MessageQueueDiscovery.test.ts +2590 -0
  324. package/Tests/Server/Utils/Telemetry/MessageQueueSpanQueryTwin.ts +246 -0
  325. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +23 -0
  326. package/Tests/Types/AI/AIAgentRunLimits.test.ts +255 -0
  327. package/Tests/Types/Code/JsonSyntax.test.ts +1300 -0
  328. package/Tests/Types/CustomField/CustomFieldCreateSettings.test.ts +1113 -0
  329. package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +91 -0
  330. package/Tests/Types/CustomField/CustomFieldValueValidator.test.ts +30 -0
  331. package/Tests/Types/Incident/IncidentFormIpAllowlist.test.ts +227 -0
  332. package/Tests/Types/Incident/IncidentFormPublic.test.ts +1916 -0
  333. package/Tests/Types/MessageQueue/MessageQueueEntityKey.test.ts +916 -0
  334. package/Tests/Types/MessageQueue/MessageQueueIdentity.test.ts +567 -0
  335. package/Tests/Types/MessageQueue/MessageQueueManualIdentity.test.ts +686 -0
  336. package/Tests/Types/MessageQueue/MessageQueueMetricCatalog.test.ts +1726 -0
  337. package/Tests/Types/MessageQueue/MessageQueueMetricResolution.test.ts +1758 -0
  338. package/Tests/Types/MessageQueue/MessagingInstrumentationFixtures.test.ts +4686 -0
  339. package/Tests/Types/MessageQueue/MessagingSystem.test.ts +840 -0
  340. package/Tests/Types/MessageQueue/MessagingTelemetryFixtures.ts +3287 -0
  341. package/Tests/Types/MessageQueue/MessagingTelemetryResolver.test.ts +2966 -0
  342. package/Tests/Types/Monitor/MessageQueueAlertTemplates.test.ts +5401 -0
  343. package/Tests/Types/Monitor/MetricEngineFold.ts +154 -0
  344. package/Tests/Types/ResourceAiAgent/ResourceAiAccess.test.ts +5 -3
  345. package/Tests/Types/Team/ComplianceRule.test.ts +588 -37
  346. package/Tests/Types/Team/TeamComplianceStatus.test.ts +64 -11
  347. package/Tests/Types/XML.test.ts +51 -0
  348. package/Tests/UI/Components/CodeEditor/CodeEditor.test.tsx +2362 -0
  349. package/Tests/UI/Components/CodeEditor/CodeEditorCommands.test.ts +810 -0
  350. package/Tests/UI/Components/CodeEditor/CodeEditorHighlight.test.ts +338 -0
  351. package/Tests/UI/Components/CodeEditor/CodeEditorLanguages.test.ts +222 -0
  352. package/Tests/UI/Components/CodeEditor/CodeEditorStyles.test.ts +807 -0
  353. package/Tests/UI/Components/CodeEditor/NoMonaco.test.ts +245 -0
  354. package/Tests/UI/Components/CodeEditor/YamlEditor.test.tsx +729 -0
  355. package/Tests/UI/Components/CopyTextButton.test.tsx +76 -0
  356. package/Tests/UI/Components/EditionLabelLapseCopy.ts +51 -14
  357. package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +131 -23
  358. package/Tests/UI/Components/ErrorMessageAction.test.tsx +142 -0
  359. package/Tests/UI/Components/FacetSidebarInScope.test.tsx +459 -0
  360. package/Tests/UI/Components/FacetValuesInScope.test.ts +270 -0
  361. package/Tests/UI/Components/Forms/FormFieldCodeEditors.test.tsx +294 -0
  362. package/Tests/UI/Components/Forms/FormFieldMarkdown.test.tsx +126 -0
  363. package/Tests/UI/Components/Forms/FormFieldYaml.test.tsx +22 -75
  364. package/Tests/UI/Components/Forms/ModelFormOnBeforeCreateMiscData.test.tsx +254 -0
  365. package/Tests/UI/Components/Icon.test.tsx +32 -0
  366. package/Tests/UI/Components/Input.test.tsx +31 -0
  367. package/Tests/UI/Components/LockedFilterChipScope.test.tsx +501 -0
  368. package/Tests/UI/Components/MarkdownConverters.test.ts +253 -1
  369. package/Tests/UI/Components/MarkdownEditor.test.tsx +2785 -2
  370. package/Tests/UI/Components/MarkdownEditorHistory.test.ts +243 -0
  371. package/Tests/UI/Components/MarkdownListEditing.test.ts +1118 -0
  372. package/Tests/UI/Components/MarkdownPaste.test.ts +1180 -0
  373. package/Tests/UI/Components/MarkdownViewerCopy.test.tsx +466 -0
  374. package/Tests/UI/Components/MarkdownVisualEditing.test.ts +1089 -0
  375. package/Tests/UI/Components/ModelTable/BaseModelTableEmptyStateAction.test.tsx +623 -0
  376. package/Tests/UI/Components/ResetObjectID.test.tsx +282 -0
  377. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  378. package/Tests/UI/Components/Table/EmptyTableMessage.test.ts +439 -0
  379. package/Tests/UI/Components/Table/TableEmptyState.test.tsx +352 -0
  380. package/Tests/UI/Components/TableRowMobileTitles.test.tsx +78 -0
  381. package/Tests/UI/Components/TextArea.test.tsx +19 -0
  382. package/Tests/UI/Components/Workflow/ModelColumnEditor.render.test.tsx +12 -29
  383. package/Tests/UI/Components/fixtures/MarkdownPasteFixtures.ts +460 -0
  384. package/Tests/UI/EsbuildConfig.test.ts +115 -39
  385. package/Tests/UI/EsbuildEnterpriseAlias.test.ts +4 -4
  386. package/Tests/UI/Monitor/MonitorLogSummaryRender.test.tsx +377 -0
  387. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +81 -1
  388. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +17 -0
  389. package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
  390. package/Tests/Utils/Markdown/DashboardMarkdownRenderer.ts +81 -0
  391. package/Tests/Utils/Markdown/UntrustedMarkdown.test.ts +1339 -0
  392. package/Tests/Utils/Monitor/MonitorLogSummaryUtil.test.ts +862 -0
  393. package/Types/AI/AIAgentRunLimits.ts +146 -0
  394. package/Types/Code/CodeType.ts +2 -0
  395. package/Types/Code/JsonSyntax.ts +923 -0
  396. package/Types/CustomField/CustomFieldCreateSettings.ts +549 -0
  397. package/Types/CustomField/CustomFieldMappingCatalog.ts +77 -0
  398. package/Types/CustomField/CustomFieldValueValidator.ts +10 -7
  399. package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +1 -1
  400. package/Types/Icon/IconProp.ts +2 -0
  401. package/Types/Incident/IncidentFormIpAllowlist.ts +206 -0
  402. package/Types/Incident/IncidentFormPublic.ts +1145 -0
  403. package/Types/Kubernetes/KubernetesClusterAiAccess.ts +10 -3
  404. package/Types/MessageQueue/MessageQueueIdentity.ts +256 -0
  405. package/Types/MessageQueue/MessageQueueManualIdentity.ts +325 -0
  406. package/Types/MessageQueue/MessageQueueMetricCatalog.ts +1357 -0
  407. package/Types/MessageQueue/MessagingSystem.ts +518 -0
  408. package/Types/MessageQueue/MessagingTelemetryResolver.ts +2311 -0
  409. package/Types/Monitor/MessageQueueAlertTemplates.ts +2128 -0
  410. package/Types/Permission.ts +310 -0
  411. package/Types/ResourceAiAgent/ResourceAiAccess.ts +10 -4
  412. package/Types/Rules/RuleCriteriaFieldRegistry.ts +12 -0
  413. package/Types/Rules/RuleRun.ts +4 -0
  414. package/Types/Team/ComplianceNotificationChannel.ts +4 -3
  415. package/Types/Team/ComplianceRule.ts +71 -18
  416. package/Types/Team/ComplianceRuleType.ts +2 -2
  417. package/Types/Team/TeamComplianceStatus.ts +6 -2
  418. package/Types/Telemetry/EntityType.ts +16 -0
  419. package/Types/Telemetry/LockedFilterDetail.ts +22 -0
  420. package/Types/XML.ts +26 -0
  421. package/UI/Components/CodeEditor/CodeEditor.css +379 -0
  422. package/UI/Components/CodeEditor/CodeEditor.tsx +1128 -294
  423. package/UI/Components/CodeEditor/CodeEditorCommands.ts +774 -0
  424. package/UI/Components/CodeEditor/CodeEditorHighlight.ts +106 -0
  425. package/UI/Components/CodeEditor/CodeEditorLanguages.ts +164 -0
  426. package/UI/Components/CodeEditor/YamlEditor.tsx +28 -326
  427. package/UI/Components/CopyTextButton/CopyTextButton.tsx +5 -1
  428. package/UI/Components/CustomFields/CustomFieldModelFormFields.tsx +6 -25
  429. package/UI/Components/EditionLabel/EditionLabel.tsx +14 -13
  430. package/UI/Components/ErrorMessage/ErrorMessage.tsx +11 -1
  431. package/UI/Components/Forms/Fields/FormField.tsx +8 -0
  432. package/UI/Components/Forms/Types/Field.ts +8 -0
  433. package/UI/Components/Icon/Icon.tsx +18 -0
  434. package/UI/Components/Input/Input.tsx +11 -4
  435. package/UI/Components/LogsViewer/LogsViewer.tsx +4 -0
  436. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +21 -3
  437. package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
  438. package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +877 -79
  439. package/UI/Components/Markdown.tsx/MarkdownEditorHistory.ts +284 -0
  440. package/UI/Components/Markdown.tsx/MarkdownListEditing.ts +1362 -0
  441. package/UI/Components/Markdown.tsx/MarkdownPaste.ts +1326 -0
  442. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +106 -10
  443. package/UI/Components/Markdown.tsx/MarkdownVisualEditing.ts +1032 -0
  444. package/UI/Components/ModelTable/BaseModelTable.tsx +85 -7
  445. package/UI/Components/ResetObjectID/ResetObjectID.tsx +35 -9
  446. package/UI/Components/Table/EmptyTableMessage.ts +81 -0
  447. package/UI/Components/Table/Table.tsx +50 -21
  448. package/UI/Components/Table/TableRow.tsx +9 -1
  449. package/UI/Components/TelemetryViewer/FacetVisibility.ts +97 -2
  450. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +13 -0
  451. package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +214 -7
  452. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +21 -3
  453. package/UI/Components/TextArea/TextArea.tsx +9 -2
  454. package/UI/Components/Workflow/ModelFieldPicker.tsx +10 -12
  455. package/UI/Styles/Theme.css +8 -0
  456. package/UI/esbuild-config.js +2 -32
  457. package/Utils/LabelRuleImportExport.ts +2 -0
  458. package/Utils/Markdown/UntrustedMarkdown.ts +1513 -0
  459. package/Utils/Monitor/IncomingEmailMonitorRequestUtil.ts +41 -0
  460. package/Utils/Monitor/MonitorLogSummaryUtil.ts +212 -0
  461. package/Utils/Telemetry/EntityKey.ts +48 -0
  462. package/build/dist/Models/DatabaseModels/AIConversation.js +125 -1
  463. package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -1
  464. package/build/dist/Models/DatabaseModels/CephCluster.js +12 -0
  465. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
  466. package/build/dist/Models/DatabaseModels/CloudResource.js +12 -0
  467. package/build/dist/Models/DatabaseModels/CloudResource.js.map +1 -1
  468. package/build/dist/Models/DatabaseModels/DatabaseServer.js +12 -0
  469. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
  470. package/build/dist/Models/DatabaseModels/DockerHost.js +12 -0
  471. package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
  472. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +12 -0
  473. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js.map +1 -1
  474. package/build/dist/Models/DatabaseModels/GlobalOidc.js +0 -4
  475. package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
  476. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +0 -4
  477. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
  478. package/build/dist/Models/DatabaseModels/GlobalSso.js +0 -4
  479. package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
  480. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +0 -4
  481. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
  482. package/build/dist/Models/DatabaseModels/Host.js +12 -0
  483. package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
  484. package/build/dist/Models/DatabaseModels/IncidentForm.js +605 -0
  485. package/build/dist/Models/DatabaseModels/IncidentForm.js.map +1 -0
  486. package/build/dist/Models/DatabaseModels/IncidentFormSubmission.js +299 -0
  487. package/build/dist/Models/DatabaseModels/IncidentFormSubmission.js.map +1 -0
  488. package/build/dist/Models/DatabaseModels/IncidentTemplate.js +60 -0
  489. package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
  490. package/build/dist/Models/DatabaseModels/Index.js +14 -0
  491. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  492. package/build/dist/Models/DatabaseModels/IoTFleet.js +12 -0
  493. package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
  494. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +12 -0
  495. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  496. package/build/dist/Models/DatabaseModels/MessageQueue.js +1106 -0
  497. package/build/dist/Models/DatabaseModels/MessageQueue.js.map +1 -0
  498. package/build/dist/Models/DatabaseModels/MessageQueueLabelRule.js +562 -0
  499. package/build/dist/Models/DatabaseModels/MessageQueueLabelRule.js.map +1 -0
  500. package/build/dist/Models/DatabaseModels/MessageQueueOwnerRule.js +643 -0
  501. package/build/dist/Models/DatabaseModels/MessageQueueOwnerRule.js.map +1 -0
  502. package/build/dist/Models/DatabaseModels/MessageQueueOwnerTeam.js +506 -0
  503. package/build/dist/Models/DatabaseModels/MessageQueueOwnerTeam.js.map +1 -0
  504. package/build/dist/Models/DatabaseModels/MessageQueueOwnerUser.js +505 -0
  505. package/build/dist/Models/DatabaseModels/MessageQueueOwnerUser.js.map +1 -0
  506. package/build/dist/Models/DatabaseModels/PodmanHost.js +12 -0
  507. package/build/dist/Models/DatabaseModels/PodmanHost.js.map +1 -1
  508. package/build/dist/Models/DatabaseModels/Project.js +61 -0
  509. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  510. package/build/dist/Models/DatabaseModels/ProjectOidc.js +0 -4
  511. package/build/dist/Models/DatabaseModels/ProjectOidc.js.map +1 -1
  512. package/build/dist/Models/DatabaseModels/ProjectSso.js +0 -4
  513. package/build/dist/Models/DatabaseModels/ProjectSso.js.map +1 -1
  514. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +12 -0
  515. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
  516. package/build/dist/Models/DatabaseModels/RumApplication.js +12 -0
  517. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  518. package/build/dist/Models/DatabaseModels/ServerlessFunction.js +12 -0
  519. package/build/dist/Models/DatabaseModels/ServerlessFunction.js.map +1 -1
  520. package/build/dist/Models/DatabaseModels/Service.js +12 -0
  521. package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
  522. package/build/dist/Models/DatabaseModels/StatusPageOidc.js +0 -4
  523. package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
  524. package/build/dist/Models/DatabaseModels/StatusPageSso.js +0 -4
  525. package/build/dist/Models/DatabaseModels/StatusPageSso.js.map +1 -1
  526. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +49 -3
  527. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
  528. package/build/dist/Models/DatabaseModels/VMwareVCenter.js +12 -0
  529. package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -1
  530. package/build/dist/Server/API/AIChatAPI.js +9 -103
  531. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  532. package/build/dist/Server/API/AIInvestigationAPI.js +3 -3
  533. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  534. package/build/dist/Server/API/AIInvestigationConversationAPI.js +162 -0
  535. package/build/dist/Server/API/AIInvestigationConversationAPI.js.map +1 -0
  536. package/build/dist/Server/API/IncidentFormAPI.js +245 -0
  537. package/build/dist/Server/API/IncidentFormAPI.js.map +1 -0
  538. package/build/dist/Server/API/ProjectOIDC.js +16 -24
  539. package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
  540. package/build/dist/Server/API/ProjectSSO.js +16 -24
  541. package/build/dist/Server/API/ProjectSSO.js.map +1 -1
  542. package/build/dist/Server/API/StatusPageAPI.js +42 -75
  543. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  544. package/build/dist/Server/Enterprise/EnterpriseEdition.js +79 -25
  545. package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -1
  546. package/build/dist/Server/Enterprise/EnterpriseFeature.js +24 -3
  547. package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -1
  548. package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +1 -1
  549. package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -1
  550. package/build/dist/Server/EnvironmentConfig.js +1 -1
  551. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.js +63 -0
  552. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.js.map +1 -0
  553. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.js +41 -0
  554. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.js.map +1 -0
  555. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.js +40 -0
  556. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.js.map +1 -0
  557. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.js +183 -0
  558. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.js.map +1 -0
  559. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  560. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  561. package/build/dist/Server/Middleware/IncidentFormRateLimit.js +559 -0
  562. package/build/dist/Server/Middleware/IncidentFormRateLimit.js.map +1 -0
  563. package/build/dist/Server/Middleware/UserAuthorization.js +11 -30
  564. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  565. package/build/dist/Server/Services/AIService.js +10 -13
  566. package/build/dist/Server/Services/AIService.js.map +1 -1
  567. package/build/dist/Server/Services/IncidentCustomFieldService.js +83 -0
  568. package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
  569. package/build/dist/Server/Services/IncidentEpisodeMemberService.js +8 -4
  570. package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
  571. package/build/dist/Server/Services/IncidentEpisodeService.js +10 -1
  572. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  573. package/build/dist/Server/Services/IncidentFormService.js +1202 -0
  574. package/build/dist/Server/Services/IncidentFormService.js.map +1 -0
  575. package/build/dist/Server/Services/IncidentFormSubmissionService.js +91 -0
  576. package/build/dist/Server/Services/IncidentFormSubmissionService.js.map +1 -0
  577. package/build/dist/Server/Services/IncidentGroupingEngineService.js +20 -8
  578. package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
  579. package/build/dist/Server/Services/IncidentService.js +106 -4
  580. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  581. package/build/dist/Server/Services/IncidentTemplateService.js +18 -0
  582. package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
  583. package/build/dist/Server/Services/Index.js +14 -0
  584. package/build/dist/Server/Services/Index.js.map +1 -1
  585. package/build/dist/Server/Services/MessageQueueLabelRuleEngineService.js +262 -0
  586. package/build/dist/Server/Services/MessageQueueLabelRuleEngineService.js.map +1 -0
  587. package/build/dist/Server/Services/MessageQueueLabelRuleService.js +13 -0
  588. package/build/dist/Server/Services/MessageQueueLabelRuleService.js.map +1 -0
  589. package/build/dist/Server/Services/MessageQueueOwnerRuleEngineService.js +334 -0
  590. package/build/dist/Server/Services/MessageQueueOwnerRuleEngineService.js.map +1 -0
  591. package/build/dist/Server/Services/MessageQueueOwnerRuleService.js +13 -0
  592. package/build/dist/Server/Services/MessageQueueOwnerRuleService.js.map +1 -0
  593. package/build/dist/Server/Services/MessageQueueOwnerTeamService.js +62 -0
  594. package/build/dist/Server/Services/MessageQueueOwnerTeamService.js.map +1 -0
  595. package/build/dist/Server/Services/MessageQueueOwnerUserService.js +62 -0
  596. package/build/dist/Server/Services/MessageQueueOwnerUserService.js.map +1 -0
  597. package/build/dist/Server/Services/MessageQueueService.js +1140 -0
  598. package/build/dist/Server/Services/MessageQueueService.js.map +1 -0
  599. package/build/dist/Server/Services/OpenTelemetryIngestService.js +25 -4
  600. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  601. package/build/dist/Server/Services/ProjectService.js +0 -54
  602. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  603. package/build/dist/Server/Services/StatusPagePrivateUserService.js +1 -4
  604. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  605. package/build/dist/Server/Services/StatusPageService.js +0 -46
  606. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  607. package/build/dist/Server/Services/TeamComplianceSettingService.js +120 -31
  608. package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
  609. package/build/dist/Server/Services/UserNotificationRuleService.js +8 -1
  610. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  611. package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js +12 -3
  612. package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js.map +1 -1
  613. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +6 -3
  614. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
  615. package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +109 -37
  616. package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
  617. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +16 -0
  618. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  619. package/build/dist/Server/Types/Database/Permissions/TablePermission.js +3 -3
  620. package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +9 -6
  621. package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
  622. package/build/dist/Server/Utils/AI/Chat/AgentContextCompactor.js +128 -0
  623. package/build/dist/Server/Utils/AI/Chat/AgentContextCompactor.js.map +1 -0
  624. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +192 -50
  625. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
  626. package/build/dist/Server/Utils/AI/Chat/ChatRunCancellation.js +133 -0
  627. package/build/dist/Server/Utils/AI/Chat/ChatRunCancellation.js.map +1 -0
  628. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +53 -13
  629. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  630. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
  631. package/build/dist/Server/Utils/AI/Chat/ToolOutputPager.js +206 -0
  632. package/build/dist/Server/Utils/AI/Chat/ToolOutputPager.js.map +1 -0
  633. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +53 -26
  634. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
  635. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +4 -2
  636. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
  637. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +1 -29
  638. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
  639. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +24 -24
  640. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  641. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +7 -2
  642. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  643. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +29 -14
  644. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  645. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +38 -14
  646. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -1
  647. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +2 -0
  648. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -1
  649. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +40 -10
  650. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  651. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +19 -7
  652. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  653. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +19 -7
  654. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  655. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +15 -18
  656. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
  657. package/build/dist/Server/Utils/AI/SRE/InvestigationThread.js +412 -0
  658. package/build/dist/Server/Utils/AI/SRE/InvestigationThread.js.map +1 -0
  659. package/build/dist/Server/Utils/AI/SRE/InvestigationThreadService.js +495 -0
  660. package/build/dist/Server/Utils/AI/SRE/InvestigationThreadService.js.map +1 -0
  661. package/build/dist/Server/Utils/AI/Toolbox/Serializer.js +10 -3
  662. package/build/dist/Server/Utils/AI/Toolbox/Serializer.js.map +1 -1
  663. package/build/dist/Server/Utils/EditionEnforcement.js +20 -158
  664. package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -1
  665. package/build/dist/Server/Utils/LLM/LLMService.js +193 -54
  666. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  667. package/build/dist/Server/Utils/RelaxedScimTeamLocksReport.js +160 -0
  668. package/build/dist/Server/Utils/RelaxedScimTeamLocksReport.js.map +1 -0
  669. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
  670. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
  671. package/build/dist/Server/Utils/SameOriginRequest.js +151 -0
  672. package/build/dist/Server/Utils/SameOriginRequest.js.map +1 -0
  673. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
  674. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
  675. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +4 -1
  676. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  677. package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js +1015 -0
  678. package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js.map +1 -0
  679. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +4 -1
  680. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
  681. package/build/dist/Server/Utils/VendorAssets.js +3 -3
  682. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +3 -1
  683. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  684. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +3 -1
  685. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
  686. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +10 -1
  687. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  688. package/build/dist/Types/AI/AIAgentRunLimits.js +91 -0
  689. package/build/dist/Types/AI/AIAgentRunLimits.js.map +1 -0
  690. package/build/dist/Types/Code/CodeType.js +2 -0
  691. package/build/dist/Types/Code/CodeType.js.map +1 -1
  692. package/build/dist/Types/Code/JsonSyntax.js +604 -0
  693. package/build/dist/Types/Code/JsonSyntax.js.map +1 -0
  694. package/build/dist/Types/CustomField/CustomFieldCreateSettings.js +310 -0
  695. package/build/dist/Types/CustomField/CustomFieldCreateSettings.js.map +1 -0
  696. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +38 -0
  697. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -1
  698. package/build/dist/Types/CustomField/CustomFieldValueValidator.js +10 -7
  699. package/build/dist/Types/CustomField/CustomFieldValueValidator.js.map +1 -1
  700. package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +1 -1
  701. package/build/dist/Types/Icon/IconProp.js +2 -0
  702. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  703. package/build/dist/Types/Incident/IncidentFormIpAllowlist.js +119 -0
  704. package/build/dist/Types/Incident/IncidentFormIpAllowlist.js.map +1 -0
  705. package/build/dist/Types/Incident/IncidentFormPublic.js +678 -0
  706. package/build/dist/Types/Incident/IncidentFormPublic.js.map +1 -0
  707. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +10 -3
  708. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
  709. package/build/dist/Types/MessageQueue/MessageQueueIdentity.js +184 -0
  710. package/build/dist/Types/MessageQueue/MessageQueueIdentity.js.map +1 -0
  711. package/build/dist/Types/MessageQueue/MessageQueueManualIdentity.js +190 -0
  712. package/build/dist/Types/MessageQueue/MessageQueueManualIdentity.js.map +1 -0
  713. package/build/dist/Types/MessageQueue/MessageQueueMetricCatalog.js +1057 -0
  714. package/build/dist/Types/MessageQueue/MessageQueueMetricCatalog.js.map +1 -0
  715. package/build/dist/Types/MessageQueue/MessagingSystem.js +394 -0
  716. package/build/dist/Types/MessageQueue/MessagingSystem.js.map +1 -0
  717. package/build/dist/Types/MessageQueue/MessagingTelemetryResolver.js +1768 -0
  718. package/build/dist/Types/MessageQueue/MessagingTelemetryResolver.js.map +1 -0
  719. package/build/dist/Types/Monitor/MessageQueueAlertTemplates.js +1207 -0
  720. package/build/dist/Types/Monitor/MessageQueueAlertTemplates.js.map +1 -0
  721. package/build/dist/Types/Permission.js +274 -0
  722. package/build/dist/Types/Permission.js.map +1 -1
  723. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +10 -4
  724. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -1
  725. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +12 -0
  726. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  727. package/build/dist/Types/Rules/RuleRun.js +4 -0
  728. package/build/dist/Types/Rules/RuleRun.js.map +1 -1
  729. package/build/dist/Types/Team/ComplianceNotificationChannel.js +4 -3
  730. package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -1
  731. package/build/dist/Types/Team/ComplianceRule.js +48 -14
  732. package/build/dist/Types/Team/ComplianceRule.js.map +1 -1
  733. package/build/dist/Types/Team/ComplianceRuleType.js +2 -2
  734. package/build/dist/Types/Telemetry/EntityType.js +16 -0
  735. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  736. package/build/dist/Types/XML.js +23 -0
  737. package/build/dist/Types/XML.js.map +1 -1
  738. package/build/dist/UI/Components/CodeEditor/CodeEditor.js +641 -266
  739. package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
  740. package/build/dist/UI/Components/CodeEditor/CodeEditorCommands.js +464 -0
  741. package/build/dist/UI/Components/CodeEditor/CodeEditorCommands.js.map +1 -0
  742. package/build/dist/UI/Components/CodeEditor/CodeEditorHighlight.js +69 -0
  743. package/build/dist/UI/Components/CodeEditor/CodeEditorHighlight.js.map +1 -0
  744. package/build/dist/UI/Components/CodeEditor/CodeEditorLanguages.js +108 -0
  745. package/build/dist/UI/Components/CodeEditor/CodeEditorLanguages.js.map +1 -0
  746. package/build/dist/UI/Components/CodeEditor/YamlEditor.js +14 -186
  747. package/build/dist/UI/Components/CodeEditor/YamlEditor.js.map +1 -1
  748. package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js +5 -1
  749. package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js.map +1 -1
  750. package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js +5 -14
  751. package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js.map +1 -1
  752. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +14 -13
  753. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  754. package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js +1 -1
  755. package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js.map +1 -1
  756. package/build/dist/UI/Components/Forms/Fields/FormField.js +8 -3
  757. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  758. package/build/dist/UI/Components/Icon/Icon.js +8 -0
  759. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  760. package/build/dist/UI/Components/Input/Input.js +11 -3
  761. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  762. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +2 -1
  763. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  764. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +14 -4
  765. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  766. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
  767. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
  768. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +710 -65
  769. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
  770. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditorHistory.js +238 -0
  771. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditorHistory.js.map +1 -0
  772. package/build/dist/UI/Components/Markdown.tsx/MarkdownListEditing.js +1028 -0
  773. package/build/dist/UI/Components/Markdown.tsx/MarkdownListEditing.js.map +1 -0
  774. package/build/dist/UI/Components/Markdown.tsx/MarkdownPaste.js +1088 -0
  775. package/build/dist/UI/Components/Markdown.tsx/MarkdownPaste.js.map +1 -0
  776. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +70 -10
  777. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  778. package/build/dist/UI/Components/Markdown.tsx/MarkdownVisualEditing.js +887 -0
  779. package/build/dist/UI/Components/Markdown.tsx/MarkdownVisualEditing.js.map +1 -0
  780. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +57 -6
  781. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  782. package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js +7 -5
  783. package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js.map +1 -1
  784. package/build/dist/UI/Components/Table/EmptyTableMessage.js +51 -0
  785. package/build/dist/UI/Components/Table/EmptyTableMessage.js.map +1 -0
  786. package/build/dist/UI/Components/Table/Table.js +30 -11
  787. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  788. package/build/dist/UI/Components/Table/TableRow.js +9 -2
  789. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  790. package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js +63 -1
  791. package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js.map +1 -1
  792. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +4 -2
  793. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  794. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +91 -10
  795. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -1
  796. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +14 -4
  797. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  798. package/build/dist/UI/Components/TextArea/TextArea.js +9 -3
  799. package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
  800. package/build/dist/UI/Components/Workflow/ModelFieldPicker.js +1 -2
  801. package/build/dist/UI/Components/Workflow/ModelFieldPicker.js.map +1 -1
  802. package/build/dist/Utils/LabelRuleImportExport.js +2 -0
  803. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
  804. package/build/dist/Utils/Markdown/UntrustedMarkdown.js +988 -0
  805. package/build/dist/Utils/Markdown/UntrustedMarkdown.js.map +1 -0
  806. package/build/dist/Utils/Monitor/IncomingEmailMonitorRequestUtil.js +34 -0
  807. package/build/dist/Utils/Monitor/IncomingEmailMonitorRequestUtil.js.map +1 -0
  808. package/build/dist/Utils/Monitor/MonitorLogSummaryUtil.js +148 -0
  809. package/build/dist/Utils/Monitor/MonitorLogSummaryUtil.js.map +1 -0
  810. package/build/dist/Utils/Telemetry/EntityKey.js +36 -0
  811. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  812. package/package.json +1 -3
  813. package/Server/Utils/CommunityEditionSsoReport.ts +0 -361
  814. package/Tests/App/Accounts/LoginSsoEdition.test.tsx +0 -616
  815. package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +0 -217
  816. package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +0 -271
  817. package/Tests/App/Dashboard/CloudDocumentationMarkdown.test.ts +0 -215
  818. package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +0 -784
  819. package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +0 -518
  820. package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +0 -419
  821. package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +0 -769
  822. package/Tests/UI/Components/CodeEditor.test.tsx +0 -638
  823. package/Tests/UI/Components/MonacoLoader.test.ts +0 -67
  824. package/Tests/UI/Components/MonacoRuntime.test.ts +0 -121
  825. package/Tests/UI/Components/Telemetry/TelemetryRetentionConfigForm.test.tsx +0 -329
  826. package/Tests/UI/Components/YamlEditor.test.tsx +0 -847
  827. package/UI/Components/CodeEditor/MonacoLoader.ts +0 -36
  828. package/UI/Components/Telemetry/TelemetryRetentionConfigForm.tsx +0 -319
  829. package/UI/Components/Telemetry/TelemetryRetentionConfigSummary.tsx +0 -223
  830. package/build/dist/Server/Utils/CommunityEditionSsoReport.js +0 -223
  831. package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +0 -1
  832. package/build/dist/UI/Components/CodeEditor/MonacoLoader.js +0 -34
  833. package/build/dist/UI/Components/CodeEditor/MonacoLoader.js.map +0 -1
  834. package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js +0 -171
  835. package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js.map +0 -1
  836. package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigSummary.js +0 -119
  837. package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigSummary.js.map +0 -1
@@ -0,0 +1,4686 @@
1
+ import {
2
+ AttributeGetter,
3
+ MESSAGING_METRIC_RESOLVER_INPUT_ATTRIBUTES,
4
+ MESSAGING_RESOLVER_INPUT_ATTRIBUTES,
5
+ ResolvedMessagingDestination,
6
+ resolveMessagingMetricDatapoint,
7
+ resolveMessagingSpan,
8
+ } from "../../../Types/MessageQueue/MessagingTelemetryResolver";
9
+ import {
10
+ buildMessageQueueIdentifier,
11
+ MessageQueueIdentity,
12
+ toMessageQueueIdentity,
13
+ } from "../../../Types/MessageQueue/MessageQueueIdentity";
14
+ import { keyForMessageQueue } from "../../../Utils/Telemetry/EntityKey";
15
+ import { describe, expect, test } from "@jest/globals";
16
+
17
+ /*
18
+ * Messaging telemetry exactly as each instrumentation and each broker-metrics
19
+ * receiver emits it — attribute for attribute, per-message values included so
20
+ * the resolver is proven to ignore them — with the queue OneUptime must find
21
+ * in it. The attribute sets are rebuilt from the instrumentations' and
22
+ * receivers' source and from live captures against real brokers (research:
23
+ * messaging-semconv.md, broker-metrics-selfhosted.md, broker-metrics-azure.md,
24
+ * broker-metrics-aws-gcp.md and the upstream files they cite). Every
25
+ * expectation follows the research's rules, never the resolver's output.
26
+ *
27
+ * Spans carry the exported attribute map and the stored SpanKind string.
28
+ * Datapoints carry the STORED flattened map: datapoint keys bare, resource
29
+ * keys with the `resource.` prefix, a kvlist flattened to `<key>.<nestedKey>`
30
+ * (CloudWatch's `Dimensions.QueueName`).
31
+ *
32
+ * The last block is the point of it all: a span of an application using a
33
+ * queue and a broker metric describing the same queue must land on one
34
+ * identity, one identifier and one entity key — otherwise the broker's health
35
+ * never attaches to the queue its producers and consumers use.
36
+ */
37
+
38
+ type Attributes = Record<string, unknown>;
39
+
40
+ interface SpanFixture {
41
+ id: string;
42
+ // The instrumentation, its version or mode, and the operation.
43
+ source: string;
44
+ kind: string | null;
45
+ attributes: Attributes;
46
+ expected: ResolvedMessagingDestination | null;
47
+ }
48
+
49
+ interface DatapointFixture {
50
+ id: string;
51
+ // The receiver or SDK that emits it, and its configuration.
52
+ source: string;
53
+ metricName: string;
54
+ attributes: Attributes;
55
+ expected: ResolvedMessagingDestination | null;
56
+ }
57
+
58
+ interface SameQueuePair {
59
+ queue: string;
60
+ spanId: string;
61
+ datapointId: string;
62
+ identity: MessageQueueIdentity;
63
+ }
64
+
65
+ interface QueueKeys {
66
+ identity: MessageQueueIdentity;
67
+ identifier: string | null;
68
+ entityKey: string;
69
+ }
70
+
71
+ const PRODUCER: string = "SPAN_KIND_PRODUCER";
72
+ const CONSUMER: string = "SPAN_KIND_CONSUMER";
73
+ const CLIENT: string = "SPAN_KIND_CLIENT";
74
+ const INTERNAL: string = "SPAN_KIND_INTERNAL";
75
+ const SERVER: string = "SPAN_KIND_SERVER";
76
+
77
+ const PROJECT_ID: string = "8c2f0d6e-3b1a-4c5d-9e7f-0a1b2c3d4e5f";
78
+
79
+ // A resolution, with the fields a fixture does not state at their defaults.
80
+ function queue(
81
+ partial: Partial<ResolvedMessagingDestination> & {
82
+ system: string;
83
+ destination: string;
84
+ },
85
+ ): ResolvedMessagingDestination {
86
+ return {
87
+ brokerScope: "",
88
+ brokerAddress: null,
89
+ direction: "unknown",
90
+ consumerGroup: null,
91
+ isDeadLetter: false,
92
+ ...partial,
93
+ };
94
+ }
95
+
96
+ // ---- shared values --------------------------------------------------------
97
+
98
+ const SERVICE_BUS_HOST: string = "billing-prod.servicebus.windows.net";
99
+ const EVENT_HUBS_HOST: string = "telemetry-prod.servicebus.windows.net";
100
+ const AZURE_SUBSCRIPTION_ID: string = "0f6a1c2b-3d4e-4f60-8a7b-9c0d1e2f3a4b";
101
+ const AZURE_TENANT_ID: string = "72f988bf-86f1-41af-91ab-2d7cd011db47";
102
+ const AZURE_SCHEMA_URL: string = "https://opentelemetry.io/schemas/1.23.0";
103
+
104
+ const SQS_QUEUE_URL: string =
105
+ "https://sqs.eu-west-1.amazonaws.com/123456789012/payment-events";
106
+ const SQS_HOST: string = "sqs.eu-west-1.amazonaws.com";
107
+ const SNS_TOPIC_ARN: string =
108
+ "arn:aws:sns:eu-west-1:123456789012:payment-notifications";
109
+ const SNS_ENDPOINT_RESOURCE: string =
110
+ "endpoint/GCM/billing-app/5e3e9847-3183-3f18-a7e8-671c3a57d4b3";
111
+
112
+ const UUID_TOPIC: string = "tenant-3f2b9c1e-8d3a-4b6f-9c0d-1e2f3a4b5c6d-events";
113
+ const UUID_TOPIC_TEMPLATED: string = "tenant-{uuid}-events";
114
+
115
+ // amqplib's connection attributes (url password censored by the library).
116
+ const AMQPLIB_CONNECTION: Attributes = {
117
+ "messaging.protocol_version": "0.9.1",
118
+ "messaging.url": "amqp://billing:***@rabbitmq.internal:5672/billing",
119
+ "messaging.protocol": "AMQP",
120
+ "server.address": "rabbitmq.internal",
121
+ "server.port": 5672,
122
+ "messaging.system": "rabbitmq",
123
+ };
124
+
125
+ // RabbitMQ.Client .NET v7 CreationTags.
126
+ const RABBITMQ_DOTNET_CREATION_TAGS: Attributes = {
127
+ "messaging.system": "rabbitmq",
128
+ "network.protocol.name": "amqp",
129
+ "network.protocol.version": "0.9.1",
130
+ };
131
+
132
+ // azure_monitor: resource attributes on by default in the code.
133
+ const AZURE_MONITOR_RESOURCE: Attributes = {
134
+ "resource.azuremonitor.subscription_id": AZURE_SUBSCRIPTION_ID,
135
+ "resource.azuremonitor.tenant_id": AZURE_TENANT_ID,
136
+ };
137
+
138
+ const SERVICE_BUS_DATAPOINT: Attributes = {
139
+ ...AZURE_MONITOR_RESOURCE,
140
+ "azuremonitor.resource_id": `/subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/billing-rg/providers/Microsoft.ServiceBus/namespaces/billing-prod`,
141
+ location: "westeurope",
142
+ name: "billing-prod",
143
+ resource_group: "billing-rg",
144
+ type: "Microsoft.ServiceBus/namespaces",
145
+ };
146
+
147
+ const EVENT_HUBS_DATAPOINT: Attributes = {
148
+ ...AZURE_MONITOR_RESOURCE,
149
+ "azuremonitor.resource_id": `/subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/telemetry-rg/providers/Microsoft.EventHub/namespaces/telemetry-prod`,
150
+ location: "westeurope",
151
+ name: "telemetry-prod",
152
+ resource_group: "telemetry-rg",
153
+ timegrain: "PT1M",
154
+ type: "Microsoft.EventHub/namespaces",
155
+ };
156
+
157
+ // Metric Stream (OpenTelemetry 1.0 format) / aws_cloudwatch resource.
158
+ const CLOUDWATCH_OTEL_RESOURCE: Attributes = {
159
+ "resource.cloud.provider": "aws",
160
+ "resource.cloud.account.id": "123456789012",
161
+ "resource.cloud.region": "eu-west-1",
162
+ "resource.aws.exporter.arn":
163
+ "arn:aws:cloudwatch:eu-west-1:123456789012:metric-stream/oneuptime",
164
+ };
165
+
166
+ // Metric Stream (JSON format) resource for an AWS/<service> namespace.
167
+ function cloudWatchJsonResource(service: string): Attributes {
168
+ return {
169
+ "resource.aws.cloudwatch.metric_stream_name": "oneuptime",
170
+ "resource.cloud.account.id": "123456789012",
171
+ "resource.cloud.provider": "aws",
172
+ "resource.cloud.region": "eu-west-1",
173
+ "resource.service.name": service,
174
+ "resource.service.namespace": "AWS",
175
+ };
176
+ }
177
+
178
+ // The JMX Scraper's SDK resource (captured live, jmx-scraper 1.60.0-alpha).
179
+ const JMX_SCRAPER_RESOURCE: Attributes = {
180
+ "resource.service.instance.id": "174b52e6-c976-3dfd-8e52-bfb13115009a",
181
+ "resource.service.name": "activemq-prod",
182
+ "resource.telemetry.sdk.language": "java",
183
+ "resource.telemetry.sdk.name": "opentelemetry",
184
+ "resource.telemetry.sdk.version": "1.65.0",
185
+ };
186
+
187
+ // The prometheus receiver's resource for a scrape target.
188
+ function prometheusResource(
189
+ job: string,
190
+ host: string,
191
+ port: string,
192
+ ): Attributes {
193
+ return {
194
+ "resource.server.address": host,
195
+ "resource.server.port": port,
196
+ "resource.service.instance.id": `${host}:${port}`,
197
+ "resource.service.name": job,
198
+ "resource.url.scheme": "http",
199
+ };
200
+ }
201
+
202
+ const PULSAR_RESOURCE: Attributes = prometheusResource(
203
+ "pulsar-broker",
204
+ "pulsar-broker-0.pulsar-broker",
205
+ "8080",
206
+ );
207
+ const PULSAR_BROKER_ADDRESS: string = "pulsar-broker-0.pulsar-broker:8080";
208
+
209
+ const ROCKETMQ_RESOURCE: Attributes = prometheusResource(
210
+ "rocketmq-broker",
211
+ "rocketmq-broker-a",
212
+ "5557",
213
+ );
214
+ const ROCKETMQ_BROKER_ADDRESS: string = "rocketmq-broker-a:5557";
215
+
216
+ const RABBITMQ_QUEUE_RESOURCE: (queueName: string) => Attributes = (
217
+ queueName: string,
218
+ ): Attributes => {
219
+ return {
220
+ "resource.rabbitmq.queue.name": queueName,
221
+ "resource.rabbitmq.vhost.name": "/",
222
+ "resource.rabbitmq.node.name": "rabbit@rabbitmq-0",
223
+ };
224
+ };
225
+
226
+ // ---- spans ----------------------------------------------------------------
227
+
228
+ const KAFKA_SPANS: ReadonlyArray<SpanFixture> = [
229
+ {
230
+ id: "kafka.java-agent.default.send",
231
+ source: "Java agent 2.x kafka-clients send, default (pre-1.28) conventions",
232
+ kind: PRODUCER,
233
+ attributes: {
234
+ "messaging.system": "kafka",
235
+ "messaging.destination.name": "payments",
236
+ "messaging.operation": "publish",
237
+ "messaging.client_id": "producer-1",
238
+ "messaging.destination.partition.id": "2",
239
+ "messaging.kafka.message.key": "order-10042",
240
+ "messaging.kafka.message.offset": 4711,
241
+ },
242
+ expected: queue({
243
+ system: "kafka",
244
+ destination: "payments",
245
+ direction: "publish",
246
+ }),
247
+ },
248
+ {
249
+ id: "kafka.java-agent.default.process",
250
+ source: "Java agent 2.x kafka-clients process, default conventions",
251
+ kind: CONSUMER,
252
+ attributes: {
253
+ "messaging.system": "kafka",
254
+ "messaging.destination.name": "payments",
255
+ "messaging.operation": "process",
256
+ "messaging.client_id": "consumer-billing-1",
257
+ "messaging.kafka.consumer.group": "billing",
258
+ "messaging.destination.partition.id": "0",
259
+ "messaging.kafka.message.offset": 17,
260
+ "messaging.kafka.message.key": "order-10042",
261
+ "messaging.message.body.size": 512,
262
+ },
263
+ expected: queue({
264
+ system: "kafka",
265
+ destination: "payments",
266
+ direction: "consume",
267
+ consumerGroup: "billing",
268
+ }),
269
+ },
270
+ {
271
+ id: "kafka.java-agent.opt-in.process",
272
+ source:
273
+ "Java agent kafka-clients process, OTEL_SEMCONV_STABILITY_OPT_IN=messaging",
274
+ kind: CONSUMER,
275
+ attributes: {
276
+ "messaging.system": "kafka",
277
+ "messaging.destination.name": "payments",
278
+ "messaging.operation.name": "process",
279
+ "messaging.operation.type": "process",
280
+ "messaging.consumer.group.name": "billing",
281
+ "messaging.client.id": "consumer-billing-1",
282
+ "messaging.destination.partition.id": "0",
283
+ "messaging.kafka.offset": 17,
284
+ "messaging.kafka.message.key": "order-10042",
285
+ "messaging.message.body.size": 512,
286
+ },
287
+ expected: queue({
288
+ system: "kafka",
289
+ destination: "payments",
290
+ direction: "consume",
291
+ consumerGroup: "billing",
292
+ }),
293
+ },
294
+ {
295
+ id: "kafka.java-agent.dup.poll",
296
+ source:
297
+ "Java agent kafka-clients poll, OTEL_SEMCONV_STABILITY_OPT_IN=messaging/dup (old and new keys)",
298
+ kind: CLIENT,
299
+ attributes: {
300
+ "messaging.system": "kafka",
301
+ "messaging.destination.name": "payments",
302
+ "messaging.operation": "receive",
303
+ "messaging.operation.name": "poll",
304
+ "messaging.operation.type": "receive",
305
+ "messaging.kafka.consumer.group": "billing",
306
+ "messaging.consumer.group.name": "billing",
307
+ "messaging.client_id": "consumer-billing-1",
308
+ "messaging.client.id": "consumer-billing-1",
309
+ "messaging.batch.message_count": 25,
310
+ },
311
+ expected: queue({
312
+ system: "kafka",
313
+ destination: "payments",
314
+ direction: "consume",
315
+ consumerGroup: "billing",
316
+ }),
317
+ },
318
+ {
319
+ id: "kafka.java-agent.default.send.uuid-topic",
320
+ source: "Java agent kafka-clients send to a per-tenant topic named by UUID",
321
+ kind: PRODUCER,
322
+ attributes: {
323
+ "messaging.system": "kafka",
324
+ "messaging.destination.name": UUID_TOPIC,
325
+ "messaging.operation": "publish",
326
+ "messaging.client_id": "producer-3",
327
+ "messaging.destination.partition.id": "5",
328
+ },
329
+ expected: queue({
330
+ system: "kafka",
331
+ destination: UUID_TOPIC_TEMPLATED,
332
+ direction: "publish",
333
+ }),
334
+ },
335
+ {
336
+ id: "kafka.confluent-dotnet.send",
337
+ source: "OpenTelemetry.Instrumentation.ConfluentKafka (.NET) produce",
338
+ kind: PRODUCER,
339
+ attributes: {
340
+ "messaging.destination.name": "payments",
341
+ "messaging.operation.name": "send",
342
+ "messaging.operation.type": "send",
343
+ "messaging.system": "kafka",
344
+ "messaging.destination.partition.id": "1",
345
+ "messaging.client.id": "rdkafka#producer-1",
346
+ "messaging.kafka.message.key": "order-10042",
347
+ "messaging.kafka.cluster.id": "lkc-7yq8z",
348
+ },
349
+ expected: queue({
350
+ system: "kafka",
351
+ destination: "payments",
352
+ direction: "publish",
353
+ }),
354
+ },
355
+ {
356
+ id: "kafka.confluent-dotnet.poll",
357
+ source: "OpenTelemetry.Instrumentation.ConfluentKafka (.NET) poll",
358
+ kind: CLIENT,
359
+ attributes: {
360
+ "messaging.operation.name": "poll",
361
+ "messaging.operation.type": "receive",
362
+ "messaging.system": "kafka",
363
+ "messaging.consumer.group.name": "billing",
364
+ "messaging.destination.name": "payments",
365
+ "messaging.destination.partition.id": "0",
366
+ "messaging.client.id": "rdkafka#consumer-2",
367
+ "messaging.kafka.offset": 17,
368
+ "messaging.kafka.cluster.id": "lkc-7yq8z",
369
+ },
370
+ expected: queue({
371
+ system: "kafka",
372
+ destination: "payments",
373
+ direction: "consume",
374
+ consumerGroup: "billing",
375
+ }),
376
+ },
377
+ {
378
+ id: "kafka.kafkajs.process",
379
+ source: "@opentelemetry/instrumentation-kafkajs 0.9+ eachMessage",
380
+ kind: CONSUMER,
381
+ attributes: {
382
+ "messaging.destination.partition.id": "0",
383
+ "messaging.system": "kafka",
384
+ "messaging.destination.name": "payments",
385
+ "messaging.operation.type": "process",
386
+ "messaging.operation.name": "process",
387
+ "messaging.kafka.message.key": "order-10042",
388
+ "messaging.kafka.offset": "17",
389
+ "messaging.kafka.cluster.id": "5L6g3nShT-eMCtK--X86sw",
390
+ },
391
+ expected: queue({
392
+ system: "kafka",
393
+ destination: "payments",
394
+ direction: "consume",
395
+ }),
396
+ },
397
+ {
398
+ id: "kafka.kafkajs-0.7.receive",
399
+ source:
400
+ "@opentelemetry/instrumentation-kafkajs before 0.9 (pre-1.17 destination key)",
401
+ kind: CONSUMER,
402
+ attributes: {
403
+ "messaging.system": "kafka",
404
+ "messaging.destination": "payments",
405
+ "messaging.operation": "receive",
406
+ },
407
+ expected: queue({
408
+ system: "kafka",
409
+ destination: "payments",
410
+ direction: "consume",
411
+ }),
412
+ },
413
+ {
414
+ id: "kafka.confluent-kafka-python.v0.62.produce",
415
+ source:
416
+ "opentelemetry-instrumentation-confluent-kafka up to v0.62b1: operation 'receive' on its PRODUCER span",
417
+ kind: PRODUCER,
418
+ attributes: {
419
+ "messaging.system": "kafka",
420
+ "messaging.destination": "payments",
421
+ "messaging.destination_kind": "queue",
422
+ "messaging.operation": "receive",
423
+ "messaging.kafka.partition": 2,
424
+ "server.address": "kafka-0.kafka-headless.data.svc",
425
+ "server.port": 9092,
426
+ },
427
+ expected: queue({
428
+ system: "kafka",
429
+ destination: "payments",
430
+ direction: "publish",
431
+ brokerAddress: "kafka-0.kafka-headless.data.svc:9092",
432
+ }),
433
+ },
434
+ {
435
+ id: "kafka.confluent-kafka-python.v0.63.produce",
436
+ source:
437
+ "opentelemetry-instrumentation-confluent-kafka v0.63b0+: operation fixed to 'publish'",
438
+ kind: PRODUCER,
439
+ attributes: {
440
+ "messaging.system": "kafka",
441
+ "messaging.destination": "payments",
442
+ "messaging.destination_kind": "queue",
443
+ "messaging.operation": "publish",
444
+ "messaging.kafka.partition": 2,
445
+ "server.address": "kafka-0.kafka-headless.data.svc",
446
+ "server.port": 9092,
447
+ },
448
+ expected: queue({
449
+ system: "kafka",
450
+ destination: "payments",
451
+ direction: "publish",
452
+ brokerAddress: "kafka-0.kafka-headless.data.svc:9092",
453
+ }),
454
+ },
455
+ {
456
+ id: "kafka.aiokafka.getone",
457
+ source:
458
+ "opentelemetry-instrumentation-aiokafka getone (bootstrap servers as a JSON list in server.address)",
459
+ kind: CONSUMER,
460
+ attributes: {
461
+ "messaging.system": "kafka",
462
+ "messaging.destination.name": "payments",
463
+ "messaging.operation.name": "receive",
464
+ "messaging.operation.type": "receive",
465
+ "messaging.consumer.group.name": "billing",
466
+ "messaging.client.id": "aiokafka-1",
467
+ "messaging.destination.partition.id": "0",
468
+ "messaging.kafka.message.offset": 17,
469
+ "messaging.kafka.message.key": "order-10042",
470
+ "server.address": '["kafka-0:9092", "kafka-1:9092", "kafka-2:9092"]',
471
+ },
472
+ expected: queue({
473
+ system: "kafka",
474
+ destination: "payments",
475
+ direction: "consume",
476
+ consumerGroup: "billing",
477
+ brokerAddress: "kafka-0:9092",
478
+ }),
479
+ },
480
+ ];
481
+
482
+ const RABBITMQ_SPANS: ReadonlyArray<SpanFixture> = [
483
+ {
484
+ id: "rabbitmq.java-agent.default.publish.named-exchange",
485
+ source:
486
+ "Java agent rabbitmq-2.7 basic.publish, default mode (the destination is the EXCHANGE)",
487
+ kind: PRODUCER,
488
+ attributes: {
489
+ "messaging.system": "rabbitmq",
490
+ "messaging.destination.name": "orders.topic",
491
+ "messaging.operation": "publish",
492
+ "messaging.rabbitmq.destination.routing_key": "orders.eu.created",
493
+ "messaging.message.body.size": 512,
494
+ "network.peer.address": "10.0.3.17",
495
+ "network.peer.port": 5672,
496
+ "network.type": "ipv4",
497
+ },
498
+ expected: queue({
499
+ system: "rabbitmq",
500
+ destination: "orders.topic",
501
+ direction: "publish",
502
+ brokerAddress: "10.0.3.17:5672",
503
+ }),
504
+ },
505
+ {
506
+ id: "rabbitmq.java-agent.default.process.default-exchange",
507
+ source:
508
+ "Java agent rabbitmq-2.7 delivery, default mode, through the default exchange ('<default>' + routing key = queue)",
509
+ kind: CONSUMER,
510
+ attributes: {
511
+ "messaging.system": "rabbitmq",
512
+ "messaging.destination.name": "<default>",
513
+ "messaging.operation": "process",
514
+ "messaging.rabbitmq.destination.routing_key": "invoices",
515
+ "messaging.message.body.size": 128,
516
+ "network.peer.address": "10.0.3.17",
517
+ "network.peer.port": 5672,
518
+ },
519
+ expected: queue({
520
+ system: "rabbitmq",
521
+ destination: "invoices",
522
+ direction: "consume",
523
+ brokerAddress: "10.0.3.17:5672",
524
+ }),
525
+ },
526
+ {
527
+ id: "rabbitmq.java-agent.default.receive.server-named-queue",
528
+ source:
529
+ "Java agent rabbitmq-2.7 basic.get from a server-named queue (amq.gen-), default mode",
530
+ kind: CONSUMER,
531
+ attributes: {
532
+ "messaging.system": "rabbitmq",
533
+ "messaging.destination.name": "<default>",
534
+ "messaging.operation": "receive",
535
+ "messaging.rabbitmq.destination.routing_key":
536
+ "amq.gen-JzTY20BRgKO-HjmUJj0wLg",
537
+ "network.peer.address": "10.0.3.17",
538
+ "network.peer.port": 5672,
539
+ },
540
+ expected: null,
541
+ },
542
+ {
543
+ /*
544
+ * semconv rabbitmq.yaml (consumer spans): '{exchange}:{routing key}:{queue}',
545
+ * empty parts omitted, and "when {routing key} and {queue} are equal, only
546
+ * one of them SHOULD be used, e.g. {exchange}:{routing key}" — the Java
547
+ * agent's consumerDestinationName does exactly that. So on a consumer,
548
+ * `direct_logs:warning` is exchange direct_logs, queue warning.
549
+ */
550
+ id: "rabbitmq.java-agent.opt-in.process.routing-key-is-queue",
551
+ source:
552
+ "Java agent rabbitmq-2.7 delivery, opt-in: 'direct_logs:warning' (routing key == queue, so the queue part is omitted)",
553
+ kind: CONSUMER,
554
+ attributes: {
555
+ "messaging.system": "rabbitmq",
556
+ "messaging.destination.name": "direct_logs:warning",
557
+ "messaging.operation.name": "process",
558
+ "messaging.operation.type": "process",
559
+ "messaging.rabbitmq.destination.routing_key": "warning",
560
+ "messaging.rabbitmq.message.delivery_tag": 7,
561
+ "messaging.message.body.size": 64,
562
+ "network.peer.address": "10.0.3.17",
563
+ "network.peer.port": 5672,
564
+ },
565
+ expected: queue({
566
+ system: "rabbitmq",
567
+ destination: "warning",
568
+ direction: "consume",
569
+ brokerAddress: "10.0.3.17:5672",
570
+ }),
571
+ },
572
+ {
573
+ /*
574
+ * A fanout exchange has an empty routing key: the Java agent omits it
575
+ * from the name and does not set the routing-key attribute, leaving
576
+ * '{exchange}:{queue}'.
577
+ */
578
+ id: "rabbitmq.java-agent.opt-in.process.fanout-empty-routing-key",
579
+ source:
580
+ "Java agent rabbitmq-2.7 delivery, opt-in, from a fanout exchange: 'logs:logs-audit' (empty routing key omitted)",
581
+ kind: CONSUMER,
582
+ attributes: {
583
+ "messaging.system": "rabbitmq",
584
+ "messaging.destination.name": "logs:logs-audit",
585
+ "messaging.operation.name": "process",
586
+ "messaging.operation.type": "process",
587
+ "messaging.rabbitmq.message.delivery_tag": 3,
588
+ "messaging.message.body.size": 256,
589
+ },
590
+ expected: queue({
591
+ system: "rabbitmq",
592
+ destination: "logs-audit",
593
+ direction: "consume",
594
+ }),
595
+ },
596
+ {
597
+ id: "rabbitmq.java-agent.opt-in.settle.three-parts",
598
+ source:
599
+ "Java agent rabbitmq-2.7 basic.ack, opt-in: '{exchange}:{routing key}:{queue}'",
600
+ kind: CLIENT,
601
+ attributes: {
602
+ "messaging.system": "rabbitmq",
603
+ "messaging.destination.name": "orders.topic:orders.eu.created:orders-eu",
604
+ "messaging.operation.name": "ack",
605
+ "messaging.operation.type": "settle",
606
+ "messaging.rabbitmq.message.delivery_tag": 9,
607
+ },
608
+ expected: queue({
609
+ system: "rabbitmq",
610
+ destination: "orders-eu",
611
+ direction: "settle",
612
+ }),
613
+ },
614
+ {
615
+ id: "rabbitmq.java-agent.opt-in.publish.exchange-and-routing-key",
616
+ source:
617
+ "Java agent rabbitmq-2.7 basic.publish, opt-in: '{exchange}:{routing key}' (a publisher names no queue)",
618
+ kind: PRODUCER,
619
+ attributes: {
620
+ "messaging.system": "rabbitmq",
621
+ "messaging.destination.name": "orders.topic:orders.eu.created",
622
+ "messaging.operation.name": "publish",
623
+ "messaging.operation.type": "send",
624
+ "messaging.rabbitmq.destination.routing_key": "orders.eu.created",
625
+ "messaging.message.body.size": 512,
626
+ "server.address": "rabbitmq.internal",
627
+ "server.port": 5672,
628
+ "network.peer.address": "10.0.3.17",
629
+ "network.peer.port": 5672,
630
+ },
631
+ expected: queue({
632
+ system: "rabbitmq",
633
+ destination: "orders.topic",
634
+ direction: "publish",
635
+ brokerAddress: "rabbitmq.internal:5672",
636
+ }),
637
+ },
638
+ {
639
+ id: "rabbitmq.java-agent.opt-in.publish.default-exchange",
640
+ source:
641
+ "Java agent rabbitmq-2.7 basic.publish, opt-in, through the default exchange (exchange omitted: the routing key alone)",
642
+ kind: PRODUCER,
643
+ attributes: {
644
+ "messaging.system": "rabbitmq",
645
+ "messaging.destination.name": "invoices",
646
+ "messaging.operation.name": "publish",
647
+ "messaging.operation.type": "send",
648
+ "messaging.rabbitmq.destination.routing_key": "invoices",
649
+ "server.address": "rabbitmq.internal",
650
+ "server.port": 5672,
651
+ },
652
+ expected: queue({
653
+ system: "rabbitmq",
654
+ destination: "invoices",
655
+ direction: "publish",
656
+ brokerAddress: "rabbitmq.internal:5672",
657
+ }),
658
+ },
659
+ {
660
+ id: "rabbitmq.dotnet-v7.deliver.default-exchange",
661
+ source:
662
+ "RabbitMQ.Client .NET v7 native tracing: deliver through the default exchange (amq.default + routing key)",
663
+ kind: CONSUMER,
664
+ attributes: {
665
+ ...RABBITMQ_DOTNET_CREATION_TAGS,
666
+ "messaging.operation.type": "process",
667
+ "messaging.operation.name": "deliver",
668
+ "messaging.destination.name": "amq.default",
669
+ "messaging.rabbitmq.destination.routing_key": "invoices",
670
+ "messaging.message.body.size": 342,
671
+ "messaging.rabbitmq.delivery_tag": 12,
672
+ "messaging.message.id": "inv-2026-0042",
673
+ "messaging.message.conversation_id": "corr-77",
674
+ },
675
+ expected: queue({
676
+ system: "rabbitmq",
677
+ destination: "invoices",
678
+ direction: "consume",
679
+ }),
680
+ },
681
+ {
682
+ id: "rabbitmq.dotnet-v7.publish.topic-exchange",
683
+ source:
684
+ "RabbitMQ.Client .NET v7 native tracing: publish to a topic exchange (network tags from the frame handler)",
685
+ kind: PRODUCER,
686
+ attributes: {
687
+ ...RABBITMQ_DOTNET_CREATION_TAGS,
688
+ "messaging.operation.type": "send",
689
+ "messaging.operation.name": "publish",
690
+ "messaging.destination.name": "orders.topic",
691
+ "messaging.rabbitmq.destination.routing_key": "orders.eu.created",
692
+ "messaging.message.body.size": 512,
693
+ "network.type": "ipv4",
694
+ "server.address": "rabbitmq.internal",
695
+ "server.port": 5672,
696
+ "network.peer.address": "10.0.3.17",
697
+ "network.peer.port": 5672,
698
+ "client.address": "10.0.9.4",
699
+ "client.port": 51234,
700
+ "network.local.address": "10.0.9.4",
701
+ },
702
+ expected: queue({
703
+ system: "rabbitmq",
704
+ destination: "orders.topic",
705
+ direction: "publish",
706
+ brokerAddress: "rabbitmq.internal:5672",
707
+ }),
708
+ },
709
+ {
710
+ id: "rabbitmq.dotnet-v7.fetch-empty",
711
+ source:
712
+ "RabbitMQ.Client .NET v7 basic.get that found nothing ('fetch (empty) {queue}': the queue is only in the span name)",
713
+ kind: CONSUMER,
714
+ attributes: {
715
+ ...RABBITMQ_DOTNET_CREATION_TAGS,
716
+ "messaging.operation.type": "receive",
717
+ "messaging.operation.name": "fetch (empty)",
718
+ "messaging.destination.name": "amq.default",
719
+ },
720
+ expected: null,
721
+ },
722
+ {
723
+ id: "rabbitmq.dotnet-v7.publish.direct-reply-to",
724
+ source:
725
+ "RabbitMQ.Client .NET v7 RPC reply through direct reply-to (default exchange, amq.rabbitmq.reply-to.<opaque>)",
726
+ kind: PRODUCER,
727
+ attributes: {
728
+ ...RABBITMQ_DOTNET_CREATION_TAGS,
729
+ "messaging.operation.type": "send",
730
+ "messaging.operation.name": "publish",
731
+ "messaging.destination.name": "amq.default",
732
+ "messaging.rabbitmq.destination.routing_key":
733
+ "amq.rabbitmq.reply-to.g1h2AA5yZXBseUAxMjM0NTY3OAAAB2EAAAAAZvhZzA==",
734
+ "messaging.message.body.size": 96,
735
+ },
736
+ expected: null,
737
+ },
738
+ {
739
+ /*
740
+ * MassTransit names each message type's exchange '<Namespace>:<Type>' and
741
+ * publishes with an EMPTY routing key. The .NET client puts the exchange
742
+ * alone in messaging.destination.name, and semconv's producer rule says
743
+ * '{exchange}:{routing key}' only "when both values are present and
744
+ * non-empty" — so a producer name with ':' and no routing key is one
745
+ * exchange name.
746
+ */
747
+ id: "rabbitmq.dotnet-v7.publish.masstransit-exchange",
748
+ source:
749
+ "RabbitMQ.Client .NET v7 publish from MassTransit to a message-type exchange ('Namespace:Type', empty routing key)",
750
+ kind: PRODUCER,
751
+ attributes: {
752
+ ...RABBITMQ_DOTNET_CREATION_TAGS,
753
+ "messaging.operation.type": "send",
754
+ "messaging.operation.name": "publish",
755
+ "messaging.destination.name": "Contoso.Billing.Contracts:InvoiceIssued",
756
+ "messaging.rabbitmq.destination.routing_key": "",
757
+ "messaging.message.body.size": 1024,
758
+ "server.address": "rabbitmq.internal",
759
+ "server.port": 5672,
760
+ },
761
+ expected: queue({
762
+ system: "rabbitmq",
763
+ destination: "Contoso.Billing.Contracts:InvoiceIssued",
764
+ direction: "publish",
765
+ brokerAddress: "rabbitmq.internal:5672",
766
+ }),
767
+ },
768
+ {
769
+ /*
770
+ * The consuming side of the same exchange: the .NET client's deliver span
771
+ * names the exchange the message was published to (never the joined
772
+ * '{exchange}:{routing key}:{queue}' form), so the ':' is still part of
773
+ * the exchange name here — unlike the Java agent's opt-in consumer names.
774
+ */
775
+ id: "rabbitmq.dotnet-v7.deliver.masstransit-exchange",
776
+ source:
777
+ "RabbitMQ.Client .NET v7 deliver of a message published to a MassTransit message-type exchange ('Namespace:Type', empty routing key)",
778
+ kind: CONSUMER,
779
+ attributes: {
780
+ ...RABBITMQ_DOTNET_CREATION_TAGS,
781
+ "messaging.operation.type": "process",
782
+ "messaging.operation.name": "deliver",
783
+ "messaging.destination.name": "Contoso.Billing.Contracts:InvoiceIssued",
784
+ "messaging.rabbitmq.destination.routing_key": "",
785
+ "messaging.message.body.size": 1024,
786
+ "messaging.rabbitmq.delivery_tag": 5,
787
+ },
788
+ expected: queue({
789
+ system: "rabbitmq",
790
+ destination: "Contoso.Billing.Contracts:InvoiceIssued",
791
+ direction: "consume",
792
+ }),
793
+ },
794
+ {
795
+ /*
796
+ * RabbitMqMessageNameFormatter ("::", "--", ":", "-") writes a generic
797
+ * type's argument after "--" in its own `Namespace:Type`, so the
798
+ * Fault<T> MassTransit publishes on every consumer fault goes to an
799
+ * exchange with TWO colons — still one exchange, published to with an
800
+ * empty routing key. Semconv joins three parts on a consumer only.
801
+ */
802
+ id: "rabbitmq.dotnet-v7.publish.masstransit-fault-exchange",
803
+ source:
804
+ "RabbitMQ.Client .NET v7 publish from MassTransit of a Fault<T> ('MassTransit:Fault--Namespace:Type--', empty routing key)",
805
+ kind: PRODUCER,
806
+ attributes: {
807
+ ...RABBITMQ_DOTNET_CREATION_TAGS,
808
+ "messaging.operation.type": "send",
809
+ "messaging.operation.name": "publish",
810
+ "messaging.destination.name":
811
+ "MassTransit:Fault--Contoso.Billing.Contracts:InvoiceIssued--",
812
+ "messaging.rabbitmq.destination.routing_key": "",
813
+ "messaging.message.body.size": 2048,
814
+ "server.address": "rabbitmq.internal",
815
+ "server.port": 5672,
816
+ },
817
+ expected: queue({
818
+ system: "rabbitmq",
819
+ destination:
820
+ "MassTransit:Fault--Contoso.Billing.Contracts:InvoiceIssued--",
821
+ direction: "publish",
822
+ brokerAddress: "rabbitmq.internal:5672",
823
+ }),
824
+ },
825
+ {
826
+ /*
827
+ * The Java agent's opt-in consumer of a MassTransit exchange: the
828
+ * exchange's own colon, the empty routing key left out (and no
829
+ * routing-key attribute), then the queue.
830
+ */
831
+ id: "rabbitmq.java-agent.opt-in.process.masstransit-exchange",
832
+ source:
833
+ "Java agent rabbitmq-2.7 delivery, opt-in, from a MassTransit exchange: 'Namespace:Type:{queue}' (empty routing key omitted)",
834
+ kind: CONSUMER,
835
+ attributes: {
836
+ "messaging.system": "rabbitmq",
837
+ "messaging.destination.name":
838
+ "Contoso.Billing.Contracts:InvoiceIssued:invoice-issued",
839
+ "messaging.operation.name": "process",
840
+ "messaging.operation.type": "process",
841
+ "messaging.rabbitmq.message.delivery_tag": 4,
842
+ "messaging.message.body.size": 1024,
843
+ },
844
+ expected: queue({
845
+ system: "rabbitmq",
846
+ destination: "invoice-issued",
847
+ direction: "consume",
848
+ }),
849
+ },
850
+ {
851
+ id: "rabbitmq.amqplib.publish.default-exchange",
852
+ source:
853
+ "@opentelemetry/instrumentation-amqplib publish to the default exchange ('' exchange, routing key = queue)",
854
+ kind: PRODUCER,
855
+ attributes: {
856
+ ...AMQPLIB_CONNECTION,
857
+ "messaging.destination": "",
858
+ "messaging.destination_kind": "topic",
859
+ "messaging.rabbitmq.routing_key": "invoices",
860
+ "messaging.message_id": "inv-2026-0042",
861
+ "messaging.conversation_id": "corr-77",
862
+ },
863
+ expected: queue({
864
+ system: "rabbitmq",
865
+ destination: "invoices",
866
+ direction: "publish",
867
+ brokerAddress: "rabbitmq.internal:5672",
868
+ }),
869
+ },
870
+ {
871
+ id: "rabbitmq.amqplib.consume.named-exchange",
872
+ source:
873
+ "@opentelemetry/instrumentation-amqplib consume of a message routed by a named exchange",
874
+ kind: CONSUMER,
875
+ attributes: {
876
+ ...AMQPLIB_CONNECTION,
877
+ "messaging.destination": "orders.topic",
878
+ "messaging.destination_kind": "topic",
879
+ "messaging.rabbitmq.routing_key": "orders.eu.created",
880
+ "messaging.operation": "process",
881
+ "messaging.message_id": "ord-1",
882
+ },
883
+ expected: queue({
884
+ system: "rabbitmq",
885
+ destination: "orders.topic",
886
+ direction: "consume",
887
+ brokerAddress: "rabbitmq.internal:5672",
888
+ }),
889
+ },
890
+ {
891
+ id: "rabbitmq.amqplib.consume.server-named-queue",
892
+ source:
893
+ "@opentelemetry/instrumentation-amqplib consume from a server-named queue via the default exchange",
894
+ kind: CONSUMER,
895
+ attributes: {
896
+ ...AMQPLIB_CONNECTION,
897
+ "messaging.destination": "",
898
+ "messaging.destination_kind": "topic",
899
+ "messaging.rabbitmq.routing_key": "amq.gen-Xa2bE9nqT0y5Pq1wR7uVcA",
900
+ "messaging.operation": "process",
901
+ },
902
+ expected: null,
903
+ },
904
+ {
905
+ id: "rabbitmq.pika.publish.default-exchange",
906
+ source:
907
+ "opentelemetry-instrumentation-pika basic_publish (sets messaging.temp_destination on every publish)",
908
+ kind: PRODUCER,
909
+ attributes: {
910
+ "messaging.system": "rabbitmq",
911
+ "messaging.temp_destination": true,
912
+ "messaging.destination": "invoices",
913
+ "messaging.message.id": "inv-2026-0042",
914
+ "messaging.conversation_id": "corr-77",
915
+ "net.peer.name": "rabbitmq.internal",
916
+ "net.peer.port": 5672,
917
+ },
918
+ expected: queue({
919
+ system: "rabbitmq",
920
+ destination: "invoices",
921
+ direction: "publish",
922
+ brokerAddress: "rabbitmq.internal:5672",
923
+ }),
924
+ },
925
+ {
926
+ id: "rabbitmq.pika.consume.named-exchange",
927
+ source: "opentelemetry-instrumentation-pika consumer callback",
928
+ kind: CONSUMER,
929
+ attributes: {
930
+ "messaging.system": "rabbitmq",
931
+ "messaging.operation": "receive",
932
+ "messaging.destination": "orders.topic",
933
+ "net.peer.name": "rabbitmq.internal",
934
+ "net.peer.port": 5672,
935
+ },
936
+ expected: queue({
937
+ system: "rabbitmq",
938
+ destination: "orders.topic",
939
+ direction: "consume",
940
+ brokerAddress: "rabbitmq.internal:5672",
941
+ }),
942
+ },
943
+ {
944
+ id: "rabbitmq.aio-pika.publish.named-exchange",
945
+ source:
946
+ "opentelemetry-instrumentation-aio-pika publish ('{exchange},{routing key}', comma-joined)",
947
+ kind: PRODUCER,
948
+ attributes: {
949
+ "messaging.system": "rabbitmq",
950
+ "messaging.destination": "orders.topic,orders.eu.created",
951
+ "net.peer.name": "rabbitmq.internal",
952
+ "net.peer.port": 5672,
953
+ "messaging.message.id": "ord-1",
954
+ "messaging.temp_destination": true,
955
+ },
956
+ expected: queue({
957
+ system: "rabbitmq",
958
+ destination: "orders.topic",
959
+ direction: "publish",
960
+ brokerAddress: "rabbitmq.internal:5672",
961
+ }),
962
+ },
963
+ {
964
+ id: "rabbitmq.aio-pika.publish.default-exchange",
965
+ source:
966
+ "opentelemetry-instrumentation-aio-pika publish on the default exchange (',{routing key}')",
967
+ kind: PRODUCER,
968
+ attributes: {
969
+ "messaging.system": "rabbitmq",
970
+ "messaging.destination": ",invoices",
971
+ "net.peer.name": "rabbitmq.internal",
972
+ "net.peer.port": 5672,
973
+ "messaging.temp_destination": true,
974
+ },
975
+ expected: queue({
976
+ system: "rabbitmq",
977
+ destination: "invoices",
978
+ direction: "publish",
979
+ brokerAddress: "rabbitmq.internal:5672",
980
+ }),
981
+ },
982
+ {
983
+ id: "rabbitmq.aio-pika.consume.default-exchange",
984
+ source:
985
+ "opentelemetry-instrumentation-aio-pika consume (exchange or routing key)",
986
+ kind: CONSUMER,
987
+ attributes: {
988
+ "messaging.system": "rabbitmq",
989
+ "messaging.operation": "receive",
990
+ "messaging.destination": "invoices",
991
+ "net.peer.name": "rabbitmq.internal",
992
+ "net.peer.port": 5672,
993
+ },
994
+ expected: queue({
995
+ system: "rabbitmq",
996
+ destination: "invoices",
997
+ direction: "consume",
998
+ brokerAddress: "rabbitmq.internal:5672",
999
+ }),
1000
+ },
1001
+ ];
1002
+
1003
+ const JMS_SPANS: ReadonlyArray<SpanFixture> = [
1004
+ {
1005
+ id: "jms.java-agent.default.send",
1006
+ source: "Java agent jms-1.1 send to an ActiveMQ queue, default conventions",
1007
+ kind: PRODUCER,
1008
+ attributes: {
1009
+ "messaging.system": "jms",
1010
+ "messaging.destination.name": "orders",
1011
+ "messaging.operation": "publish",
1012
+ "messaging.message.id": "ID:app-1-38493-1727690000000-1:1:1:1:1",
1013
+ "messaging.message.conversation_id": "corr-77",
1014
+ },
1015
+ expected: queue({
1016
+ system: "jms",
1017
+ destination: "orders",
1018
+ direction: "publish",
1019
+ }),
1020
+ },
1021
+ {
1022
+ id: "jms.java-agent.default.process.dead-letter",
1023
+ source:
1024
+ "Java agent jms-1.1 listener on ActiveMQ's shared dead-letter queue",
1025
+ kind: CONSUMER,
1026
+ attributes: {
1027
+ "messaging.system": "jms",
1028
+ "messaging.destination.name": "ActiveMQ.DLQ",
1029
+ "messaging.operation": "process",
1030
+ "messaging.message.id": "ID:app-1-38493-1727690000000-1:1:1:1:9",
1031
+ },
1032
+ expected: queue({
1033
+ system: "jms",
1034
+ destination: "ActiveMQ.DLQ",
1035
+ direction: "consume",
1036
+ isDeadLetter: true,
1037
+ }),
1038
+ },
1039
+ {
1040
+ id: "jms.java-agent.opt-in.receive.temporary",
1041
+ source: "Java agent jms-1.1 receive on a TemporaryQueue, opt-in",
1042
+ kind: CLIENT,
1043
+ attributes: {
1044
+ "messaging.system": "jms",
1045
+ "messaging.destination.name": "(temporary)",
1046
+ "messaging.destination.temporary": true,
1047
+ "messaging.operation.name": "receive",
1048
+ "messaging.operation.type": "receive",
1049
+ },
1050
+ expected: null,
1051
+ },
1052
+ {
1053
+ id: "activemq.manual.send",
1054
+ source:
1055
+ "A hand-instrumented ActiveMQ client using the semconv system value (destination printed with its queue:// prefix)",
1056
+ kind: PRODUCER,
1057
+ attributes: {
1058
+ "messaging.system": "activemq",
1059
+ "messaging.destination.name": "queue://orders",
1060
+ "messaging.operation.type": "send",
1061
+ "messaging.operation.name": "send",
1062
+ "server.address": "activemq.internal",
1063
+ "server.port": 61616,
1064
+ },
1065
+ expected: queue({
1066
+ system: "activemq",
1067
+ destination: "orders",
1068
+ direction: "publish",
1069
+ brokerAddress: "activemq.internal:61616",
1070
+ }),
1071
+ },
1072
+ ];
1073
+
1074
+ const SQS_SPANS: ReadonlyArray<SpanFixture> = [
1075
+ {
1076
+ id: "sqs.java-agent.default.send",
1077
+ source: "Java agent aws-sdk-2.2 SQS SendMessage (agent 2.4+, aws_sqs)",
1078
+ kind: PRODUCER,
1079
+ attributes: {
1080
+ "rpc.system": "aws-api",
1081
+ "rpc.service": "Sqs",
1082
+ "rpc.method": "SendMessage",
1083
+ "http.request.method": "POST",
1084
+ "http.response.status_code": 200,
1085
+ "server.address": SQS_HOST,
1086
+ "server.port": 443,
1087
+ "url.full": `https://${SQS_HOST}`,
1088
+ "aws.agent": "java-aws-sdk",
1089
+ "aws.request_id": "7a62c49f-347e-4fc4-9331-6e8e7a96aa73",
1090
+ "aws.sqs.queue.url": SQS_QUEUE_URL,
1091
+ "messaging.destination.name": "payment-events",
1092
+ "messaging.message.id": "5fea7756-0ea4-451a-a703-a558b933e274",
1093
+ "messaging.system": "aws_sqs",
1094
+ "messaging.operation": "publish",
1095
+ },
1096
+ expected: queue({
1097
+ system: "aws_sqs",
1098
+ destination: "payment-events",
1099
+ direction: "publish",
1100
+ brokerAddress: `${SQS_HOST}:443`,
1101
+ }),
1102
+ },
1103
+ {
1104
+ id: "sqs.java-agent.2.3.receive",
1105
+ source: "Java agent aws-sdk-2.2 SQS ReceiveMessage up to 2.3.0 (AmazonSQS)",
1106
+ kind: CONSUMER,
1107
+ attributes: {
1108
+ "rpc.system": "aws-api",
1109
+ "rpc.service": "Sqs",
1110
+ "rpc.method": "ReceiveMessage",
1111
+ "http.request.method": "POST",
1112
+ "http.response.status_code": 200,
1113
+ "server.address": SQS_HOST,
1114
+ "server.port": 443,
1115
+ "aws.sqs.queue.url": SQS_QUEUE_URL,
1116
+ "messaging.destination.name": "payment-events",
1117
+ "messaging.system": "AmazonSQS",
1118
+ "messaging.operation": "receive",
1119
+ },
1120
+ expected: queue({
1121
+ system: "aws_sqs",
1122
+ destination: "payment-events",
1123
+ direction: "consume",
1124
+ brokerAddress: `${SQS_HOST}:443`,
1125
+ }),
1126
+ },
1127
+ {
1128
+ id: "sqs.java-agent.opt-in.lambda-event",
1129
+ source:
1130
+ "Java agent aws-lambda SQS event, opt-in (queue name derived from the event source ARN)",
1131
+ kind: CONSUMER,
1132
+ attributes: {
1133
+ "messaging.system": "aws_sqs",
1134
+ "messaging.destination.name": "payment-events",
1135
+ "messaging.operation.name": "process",
1136
+ "messaging.operation.type": "process",
1137
+ "messaging.message.id": "059f36b4-87a3-44ab-83d2-661975830a7d",
1138
+ },
1139
+ expected: queue({
1140
+ system: "aws_sqs",
1141
+ destination: "payment-events",
1142
+ direction: "consume",
1143
+ }),
1144
+ },
1145
+ {
1146
+ id: "sqs.aws-sdk-js.0.58.receive",
1147
+ source:
1148
+ "@opentelemetry/instrumentation-aws-sdk 0.58+ SQS ReceiveMessage (aws_sqs, queue URL in url.full)",
1149
+ kind: CONSUMER,
1150
+ attributes: {
1151
+ "rpc.system": "aws-api",
1152
+ "rpc.method": "ReceiveMessage",
1153
+ "rpc.service": "SQS",
1154
+ "cloud.region": "eu-west-1",
1155
+ "messaging.system": "aws_sqs",
1156
+ "messaging.destination.name": "payment-events",
1157
+ "url.full": SQS_QUEUE_URL,
1158
+ "messaging.operation.type": "receive",
1159
+ },
1160
+ expected: queue({
1161
+ system: "aws_sqs",
1162
+ destination: "payment-events",
1163
+ direction: "consume",
1164
+ }),
1165
+ },
1166
+ {
1167
+ id: "sqs.boto3sqs.process",
1168
+ source:
1169
+ "opentelemetry-instrumentation-boto3sqs processing span (aws.sqs, queue URL in messaging.url)",
1170
+ kind: CONSUMER,
1171
+ attributes: {
1172
+ "messaging.system": "aws.sqs",
1173
+ "messaging.destination": "payment-events",
1174
+ "messaging.destination_kind": "queue",
1175
+ "messaging.url": SQS_QUEUE_URL,
1176
+ "messaging.operation": "process",
1177
+ "messaging.message.id": "5fea7756-0ea4-451a-a703-a558b933e274",
1178
+ },
1179
+ expected: queue({
1180
+ system: "aws_sqs",
1181
+ destination: "payment-events",
1182
+ direction: "consume",
1183
+ brokerAddress: SQS_HOST,
1184
+ }),
1185
+ },
1186
+ {
1187
+ id: "sqs.botocore.send-message",
1188
+ source:
1189
+ "opentelemetry-instrumentation-botocore SQS SendMessage (a CLIENT span: the operation is in rpc.method)",
1190
+ kind: CLIENT,
1191
+ attributes: {
1192
+ "rpc.system": "aws-api",
1193
+ "rpc.service": "SQS",
1194
+ "rpc.method": "SendMessage",
1195
+ "aws.region": "eu-west-1",
1196
+ "cloud.region": "eu-west-1",
1197
+ retry_attempts: 0,
1198
+ "aws.request_id": "b8c2d4e6-1a3b-4c5d-8e7f-9a0b1c2d3e4f",
1199
+ "http.status_code": 200,
1200
+ "aws.queue_url": SQS_QUEUE_URL,
1201
+ "messaging.system": "aws.sqs",
1202
+ "messaging.url": SQS_QUEUE_URL,
1203
+ "messaging.destination": "payment-events",
1204
+ "messaging.message.id": "5fea7756-0ea4-451a-a703-a558b933e274",
1205
+ },
1206
+ expected: queue({
1207
+ system: "aws_sqs",
1208
+ destination: "payment-events",
1209
+ direction: "publish",
1210
+ brokerAddress: SQS_HOST,
1211
+ }),
1212
+ },
1213
+ {
1214
+ id: "sqs.go-otelaws.send-message",
1215
+ source:
1216
+ "Go otelaws v0.62+ SQS SendMessage (the full queue URL in server.address, no destination key)",
1217
+ kind: CLIENT,
1218
+ attributes: {
1219
+ "rpc.system.name": "aws-api",
1220
+ "rpc.method": "SQS/SendMessage",
1221
+ "aws.region": "eu-west-1",
1222
+ "messaging.system": "aws_sqs",
1223
+ "server.address": SQS_QUEUE_URL,
1224
+ "aws.request_id": "0c7d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
1225
+ "http.response.status_code": 200,
1226
+ },
1227
+ expected: queue({
1228
+ system: "aws_sqs",
1229
+ destination: "payment-events",
1230
+ direction: "publish",
1231
+ brokerAddress: SQS_HOST,
1232
+ }),
1233
+ },
1234
+ {
1235
+ id: "sqs.go-otelaws.get-queue-attributes",
1236
+ source:
1237
+ "Go otelaws v0.62+ SQS GetQueueAttributes (same attributes, no direction)",
1238
+ kind: CLIENT,
1239
+ attributes: {
1240
+ "rpc.system.name": "aws-api",
1241
+ "rpc.method": "SQS/GetQueueAttributes",
1242
+ "aws.region": "eu-west-1",
1243
+ "messaging.system": "aws_sqs",
1244
+ "server.address": SQS_QUEUE_URL,
1245
+ "http.response.status_code": 200,
1246
+ },
1247
+ expected: queue({
1248
+ system: "aws_sqs",
1249
+ destination: "payment-events",
1250
+ brokerAddress: SQS_HOST,
1251
+ }),
1252
+ },
1253
+ {
1254
+ id: "sqs.go-otelaws-0.61.receive",
1255
+ source:
1256
+ "Go otelaws up to v0.61 SQS ReceiveMessage (AmazonSQS, queue URL in net.peer.name)",
1257
+ kind: CLIENT,
1258
+ attributes: {
1259
+ "rpc.system": "aws-api",
1260
+ "rpc.service": "SQS",
1261
+ "rpc.method": "ReceiveMessage",
1262
+ "aws.region": "eu-west-1",
1263
+ "messaging.system": "AmazonSQS",
1264
+ "net.peer.name": SQS_QUEUE_URL,
1265
+ },
1266
+ expected: queue({
1267
+ system: "aws_sqs",
1268
+ destination: "payment-events",
1269
+ direction: "consume",
1270
+ brokerAddress: SQS_HOST,
1271
+ }),
1272
+ },
1273
+ {
1274
+ id: "sqs.dotnet-aws.semconv-1.40.send",
1275
+ source:
1276
+ "OpenTelemetry.Instrumentation.AWS (.NET), semconv 1.40 mode, SendMessage",
1277
+ kind: CLIENT,
1278
+ attributes: {
1279
+ "rpc.system.name": "aws-api",
1280
+ "messaging.system": "aws_sqs",
1281
+ "aws.sqs.queue.url": SQS_QUEUE_URL,
1282
+ "server.address": SQS_HOST,
1283
+ "messaging.destination.name": "payment-events",
1284
+ "messaging.operation.name": "SendMessage",
1285
+ "messaging.operation.type": "send",
1286
+ "cloud.region": "eu-west-1",
1287
+ },
1288
+ expected: queue({
1289
+ system: "aws_sqs",
1290
+ destination: "payment-events",
1291
+ direction: "publish",
1292
+ brokerAddress: SQS_HOST,
1293
+ }),
1294
+ },
1295
+ {
1296
+ id: "sqs.dotnet-aws.legacy.receive",
1297
+ source:
1298
+ "OpenTelemetry.Instrumentation.AWS (.NET), legacy mode (no messaging.system, aws.queue_url)",
1299
+ kind: CLIENT,
1300
+ attributes: {
1301
+ "rpc.system": "aws-api",
1302
+ "aws.queue_url": SQS_QUEUE_URL,
1303
+ "cloud.region": "eu-west-1",
1304
+ },
1305
+ expected: queue({
1306
+ system: "aws_sqs",
1307
+ destination: "payment-events",
1308
+ }),
1309
+ },
1310
+ ];
1311
+
1312
+ const SNS_SPANS: ReadonlyArray<SpanFixture> = [
1313
+ {
1314
+ id: "sns.java-agent.publish",
1315
+ source:
1316
+ "Java agent aws-sdk-2.2 SNS Publish (an RPC span: no messaging.system, the topic ARN as destination)",
1317
+ kind: CLIENT,
1318
+ attributes: {
1319
+ "rpc.system": "aws-api",
1320
+ "rpc.service": "Sns",
1321
+ "rpc.method": "Publish",
1322
+ "http.request.method": "POST",
1323
+ "http.response.status_code": 200,
1324
+ "server.address": "sns.eu-west-1.amazonaws.com",
1325
+ "server.port": 443,
1326
+ "url.full": "https://sns.eu-west-1.amazonaws.com",
1327
+ "aws.agent": "java-aws-sdk",
1328
+ "aws.request_id": "f1e2d3c4-b5a6-4978-8a9b-0c1d2e3f4a5b",
1329
+ "messaging.destination.name": SNS_TOPIC_ARN,
1330
+ "aws.sns.topic.arn": SNS_TOPIC_ARN,
1331
+ },
1332
+ expected: queue({
1333
+ system: "aws.sns",
1334
+ destination: "payment-notifications",
1335
+ direction: "publish",
1336
+ brokerAddress: "sns.eu-west-1.amazonaws.com:443",
1337
+ }),
1338
+ },
1339
+ {
1340
+ id: "sns.java-agent.publish.platform-endpoint",
1341
+ source:
1342
+ "Java agent aws-sdk-2.2 SNS Publish to a mobile push endpoint (TargetArn: one per device, not a topic)",
1343
+ kind: CLIENT,
1344
+ attributes: {
1345
+ "rpc.system": "aws-api",
1346
+ "rpc.service": "Sns",
1347
+ "rpc.method": "Publish",
1348
+ "server.address": "sns.eu-west-1.amazonaws.com",
1349
+ "server.port": 443,
1350
+ "messaging.destination.name": `arn:aws:sns:eu-west-1:123456789012:${SNS_ENDPOINT_RESOURCE}`,
1351
+ },
1352
+ expected: null,
1353
+ },
1354
+ {
1355
+ id: "sns.go-otelaws.publish.topic",
1356
+ source:
1357
+ "Go otelaws v0.62+ SNS Publish (aws_sns, short topic name, operation name publish_input)",
1358
+ kind: CLIENT,
1359
+ attributes: {
1360
+ "rpc.system.name": "aws-api",
1361
+ "rpc.method": "SNS/Publish",
1362
+ "aws.region": "eu-west-1",
1363
+ "messaging.system": "aws_sns",
1364
+ "messaging.destination.name": "payment-notifications",
1365
+ "messaging.operation.type": "send",
1366
+ "messaging.operation.name": "publish_input",
1367
+ "aws.request_id": "d4e5f6a7-b8c9-4d0e-8f1a-2b3c4d5e6f7a",
1368
+ "http.response.status_code": 200,
1369
+ },
1370
+ expected: queue({
1371
+ system: "aws.sns",
1372
+ destination: "payment-notifications",
1373
+ direction: "publish",
1374
+ }),
1375
+ },
1376
+ {
1377
+ /*
1378
+ * Go otelaws's extractDestinationName keeps the text after the last ':'
1379
+ * of TopicArn OR TargetArn — for a mobile push endpoint that is
1380
+ * 'endpoint/<platform>/<app>/<device id>'. SNS topic names cannot contain
1381
+ * '/', and a device endpoint is never a topic (the same endpoint as a
1382
+ * full ARN resolves to no queue).
1383
+ */
1384
+ id: "sns.go-otelaws.publish.platform-endpoint",
1385
+ source:
1386
+ "Go otelaws v0.62+ SNS Publish to a mobile push endpoint (TargetArn cut after its last ':')",
1387
+ kind: CLIENT,
1388
+ attributes: {
1389
+ "rpc.system.name": "aws-api",
1390
+ "rpc.method": "SNS/Publish",
1391
+ "aws.region": "eu-west-1",
1392
+ "messaging.system": "aws_sns",
1393
+ "messaging.destination.name": SNS_ENDPOINT_RESOURCE,
1394
+ "messaging.operation.type": "send",
1395
+ "messaging.operation.name": "publish_input",
1396
+ },
1397
+ expected: null,
1398
+ },
1399
+ {
1400
+ id: "sns.go-otelaws.publish-batch",
1401
+ source: "Go otelaws v0.62+ SNS PublishBatch",
1402
+ kind: CLIENT,
1403
+ attributes: {
1404
+ "rpc.system.name": "aws-api",
1405
+ "rpc.method": "SNS/PublishBatch",
1406
+ "aws.region": "eu-west-1",
1407
+ "messaging.system": "aws_sns",
1408
+ "messaging.destination.name": "payment-notifications",
1409
+ "messaging.operation.type": "send",
1410
+ "messaging.operation.name": "publish_batch_input",
1411
+ "messaging.batch.message_count": 10,
1412
+ },
1413
+ expected: queue({
1414
+ system: "aws.sns",
1415
+ destination: "payment-notifications",
1416
+ direction: "publish",
1417
+ }),
1418
+ },
1419
+ {
1420
+ id: "sns.aws-sdk-js.publish",
1421
+ source:
1422
+ "@opentelemetry/instrumentation-aws-sdk SNS Publish (short name in messaging.destination, ARN in messaging.destination.name)",
1423
+ kind: PRODUCER,
1424
+ attributes: {
1425
+ "rpc.system": "aws-api",
1426
+ "rpc.method": "Publish",
1427
+ "rpc.service": "SNS",
1428
+ "cloud.region": "eu-west-1",
1429
+ "messaging.system": "aws.sns",
1430
+ "messaging.destination_kind": "topic",
1431
+ "messaging.destination": "payment-notifications",
1432
+ "messaging.destination.name": SNS_TOPIC_ARN,
1433
+ "aws.sns.topic.arn": SNS_TOPIC_ARN,
1434
+ },
1435
+ expected: queue({
1436
+ system: "aws.sns",
1437
+ destination: "payment-notifications",
1438
+ direction: "publish",
1439
+ }),
1440
+ },
1441
+ {
1442
+ id: "sns.aws-sdk-js.publish.platform-endpoint",
1443
+ source:
1444
+ "@opentelemetry/instrumentation-aws-sdk SNS Publish to a mobile push endpoint (TargetArn)",
1445
+ kind: PRODUCER,
1446
+ attributes: {
1447
+ "rpc.system": "aws-api",
1448
+ "rpc.method": "Publish",
1449
+ "rpc.service": "SNS",
1450
+ "messaging.system": "aws.sns",
1451
+ "messaging.destination_kind": "topic",
1452
+ "messaging.destination": SNS_ENDPOINT_RESOURCE,
1453
+ "messaging.destination.name": `arn:aws:sns:eu-west-1:123456789012:${SNS_ENDPOINT_RESOURCE}`,
1454
+ },
1455
+ expected: null,
1456
+ },
1457
+ {
1458
+ id: "sns.botocore.publish-batch",
1459
+ source:
1460
+ "opentelemetry-instrumentation-botocore SNS PublishBatch (full ARN in both destination keys)",
1461
+ kind: PRODUCER,
1462
+ attributes: {
1463
+ "rpc.system": "aws-api",
1464
+ "rpc.service": "SNS",
1465
+ "rpc.method": "PublishBatch",
1466
+ "aws.region": "eu-west-1",
1467
+ "messaging.system": "aws.sns",
1468
+ "messaging.destination_kind": "topic",
1469
+ "messaging.destination": SNS_TOPIC_ARN,
1470
+ "messaging.destination.name": SNS_TOPIC_ARN,
1471
+ "aws.sns.topic.arn": SNS_TOPIC_ARN,
1472
+ },
1473
+ expected: queue({
1474
+ system: "aws.sns",
1475
+ destination: "payment-notifications",
1476
+ direction: "publish",
1477
+ }),
1478
+ },
1479
+ {
1480
+ id: "sns.botocore.publish.sms",
1481
+ source:
1482
+ "opentelemetry-instrumentation-botocore SNS Publish of an SMS (phone number censored)",
1483
+ kind: PRODUCER,
1484
+ attributes: {
1485
+ "rpc.system": "aws-api",
1486
+ "rpc.service": "SNS",
1487
+ "rpc.method": "Publish",
1488
+ "messaging.system": "aws.sns",
1489
+ "messaging.destination_kind": "topic",
1490
+ "messaging.destination": "phone_number:**",
1491
+ "messaging.destination.name": "phone_number:**",
1492
+ },
1493
+ expected: null,
1494
+ },
1495
+ ];
1496
+
1497
+ const PUBSUB_SPANS: ReadonlyArray<SpanFixture> = [
1498
+ {
1499
+ id: "pubsub.node.create",
1500
+ source: "@google-cloud/pubsub (Node) '{topicId} create' span",
1501
+ kind: PRODUCER,
1502
+ attributes: {
1503
+ "messaging.system": "gcp_pubsub",
1504
+ "messaging.destination.name": "orders",
1505
+ "gcp.project_id": "shop-prod",
1506
+ "code.function": "Topic.publishMessage",
1507
+ "messaging.message.envelope.size": 184,
1508
+ "messaging.operation": "create",
1509
+ },
1510
+ expected: queue({
1511
+ system: "gcp_pubsub",
1512
+ destination: "orders",
1513
+ direction: "publish",
1514
+ }),
1515
+ },
1516
+ {
1517
+ id: "pubsub.node.publish-rpc",
1518
+ source:
1519
+ "@google-cloud/pubsub (Node) publish RPC span ('{projects/p/topics/t} send': the short id in the attribute)",
1520
+ kind: PRODUCER,
1521
+ attributes: {
1522
+ "messaging.system": "gcp_pubsub",
1523
+ "messaging.destination.name": "orders",
1524
+ "gcp.project_id": "shop-prod",
1525
+ "code.function": "Publisher.publish",
1526
+ "messaging.batch.message_count": 12,
1527
+ },
1528
+ expected: queue({
1529
+ system: "gcp_pubsub",
1530
+ destination: "orders",
1531
+ direction: "publish",
1532
+ }),
1533
+ },
1534
+ {
1535
+ id: "pubsub.node.subscribe",
1536
+ source:
1537
+ "@google-cloud/pubsub (Node) '{subId} subscribe' span: the destination is the SUBSCRIPTION",
1538
+ kind: CONSUMER,
1539
+ attributes: {
1540
+ "messaging.system": "gcp_pubsub",
1541
+ "messaging.destination.name": "orders-billing",
1542
+ "gcp.project_id": "shop-prod",
1543
+ "code.function": "Subscription.emit",
1544
+ "messaging.message.envelope.size": 184,
1545
+ "messaging.gcp_pubsub.message.ack_id":
1546
+ "RkhRNxkIaFEOT14jPzUgKEUXAggUBXx9dEFBX1pnHwxQ",
1547
+ "messaging.operation": "receive",
1548
+ },
1549
+ expected: queue({
1550
+ system: "gcp_pubsub",
1551
+ destination: "orders-billing",
1552
+ direction: "consume",
1553
+ consumerGroup: "orders-billing",
1554
+ }),
1555
+ },
1556
+ {
1557
+ id: "pubsub.node.ack-rpc",
1558
+ source:
1559
+ "@google-cloud/pubsub (Node) '{subId} ack' RPC span (no operation attribute: nothing but the span name says ack)",
1560
+ kind: CLIENT,
1561
+ attributes: {
1562
+ "messaging.system": "gcp_pubsub",
1563
+ "messaging.destination.name": "orders-billing",
1564
+ "gcp.project_id": "shop-prod",
1565
+ "code.function": "AckQueue.flush",
1566
+ "messaging.batch.message_count": 3,
1567
+ },
1568
+ expected: queue({
1569
+ system: "gcp_pubsub",
1570
+ destination: "orders-billing",
1571
+ }),
1572
+ },
1573
+ {
1574
+ /*
1575
+ * The Java client writes the RPC's operation NAME ("ack", "modack",
1576
+ * "nack") into the legacy messaging.operation key; messaging-semconv.md
1577
+ * lists ack / nack / modack as settlement.
1578
+ */
1579
+ id: "pubsub.java.ack-rpc",
1580
+ source:
1581
+ "google-cloud-pubsub (Java) '{sub} ack' RPC span (messaging.operation 'ack')",
1582
+ kind: CLIENT,
1583
+ attributes: {
1584
+ "messaging.system": "gcp_pubsub",
1585
+ "messaging.destination.name": "orders-billing",
1586
+ "gcp.project_id": "shop-prod",
1587
+ "code.function": "sendAckOperations",
1588
+ "messaging.operation": "ack",
1589
+ "messaging.batch.message_count": 3,
1590
+ },
1591
+ expected: queue({
1592
+ system: "gcp_pubsub",
1593
+ destination: "orders-billing",
1594
+ direction: "settle",
1595
+ consumerGroup: "orders-billing",
1596
+ }),
1597
+ },
1598
+ {
1599
+ id: "pubsub.java.publish-rpc",
1600
+ source: "google-cloud-pubsub (Java) '{topic} publish' RPC span",
1601
+ kind: CLIENT,
1602
+ attributes: {
1603
+ "messaging.system": "gcp_pubsub",
1604
+ "messaging.destination.name": "orders",
1605
+ "gcp.project_id": "shop-prod",
1606
+ "code.function": "publishOutstandingBatch",
1607
+ "messaging.operation": "publish",
1608
+ "messaging.batch.message_count": 12,
1609
+ },
1610
+ expected: queue({
1611
+ system: "gcp_pubsub",
1612
+ destination: "orders",
1613
+ direction: "publish",
1614
+ }),
1615
+ },
1616
+ {
1617
+ id: "pubsub.go-v2.process",
1618
+ source:
1619
+ "cloud.google.com/go/pubsub/v2 '{sub} process' span (gcp.resource.name holds the full resource name)",
1620
+ kind: CONSUMER,
1621
+ attributes: {
1622
+ "gcp.project_id": "shop-prod",
1623
+ "gcp.resource.name": "projects/shop-prod/subscriptions/orders-billing",
1624
+ "messaging.system": "gcp_pubsub",
1625
+ "messaging.destination.name": "orders-billing",
1626
+ "messaging.message.id": "12345678901234567",
1627
+ "messaging.message.body.size": 184,
1628
+ "messaging.gcp_pubsub.message.ordering_key": "",
1629
+ "messaging.gcp_pubsub.message.delivery_attempt": 1,
1630
+ "messaging.operation.type": "process",
1631
+ },
1632
+ expected: queue({
1633
+ system: "gcp_pubsub",
1634
+ destination: "orders-billing",
1635
+ direction: "consume",
1636
+ consumerGroup: "orders-billing",
1637
+ }),
1638
+ },
1639
+ {
1640
+ id: "pubsub.python.modack",
1641
+ source: "google-cloud-pubsub (Python) '{sub} modack' span",
1642
+ kind: CLIENT,
1643
+ attributes: {
1644
+ "messaging.system": "gcp_pubsub",
1645
+ "messaging.batch.message_count": 3,
1646
+ "messaging.gcp_pubsub.message.ack_deadline": 60,
1647
+ "messaging.destination.name": "orders-billing",
1648
+ "gcp.project_id": "shop-prod",
1649
+ "messaging.operation.name": "modack",
1650
+ "code.function": "modify_ack_deadline",
1651
+ },
1652
+ expected: queue({
1653
+ system: "gcp_pubsub",
1654
+ destination: "orders-billing",
1655
+ direction: "settle",
1656
+ consumerGroup: "orders-billing",
1657
+ }),
1658
+ },
1659
+ {
1660
+ id: "pubsub.python.publish",
1661
+ source: "google-cloud-pubsub (Python) '{topic} publish' batch commit span",
1662
+ kind: CLIENT,
1663
+ attributes: {
1664
+ "messaging.system": "gcp_pubsub",
1665
+ "messaging.destination.name": "orders",
1666
+ "gcp.project_id": "shop-prod",
1667
+ "messaging.batch.message_count": 5,
1668
+ "messaging.operation": "publish",
1669
+ "code.function": "_commit",
1670
+ },
1671
+ expected: queue({
1672
+ system: "gcp_pubsub",
1673
+ destination: "orders",
1674
+ direction: "publish",
1675
+ }),
1676
+ },
1677
+ ];
1678
+
1679
+ const SERVICE_BUS_SPANS: ReadonlyArray<SpanFixture> = [
1680
+ {
1681
+ id: "servicebus.dotnet.activity-source.send",
1682
+ source:
1683
+ "Azure.Messaging.ServiceBus (.NET) ServiceBusSender.Send, ActivitySource switch on",
1684
+ kind: CLIENT,
1685
+ attributes: {
1686
+ "az.namespace": "Microsoft.ServiceBus",
1687
+ "az.schema_url": AZURE_SCHEMA_URL,
1688
+ "messaging.system": "servicebus",
1689
+ "messaging.operation": "publish",
1690
+ "server.address": SERVICE_BUS_HOST,
1691
+ "messaging.destination.name": "invoices",
1692
+ "messaging.batch.message_count": 2,
1693
+ },
1694
+ expected: queue({
1695
+ system: "servicebus",
1696
+ destination: "invoices",
1697
+ brokerScope: "billing-prod",
1698
+ direction: "publish",
1699
+ brokerAddress: SERVICE_BUS_HOST,
1700
+ }),
1701
+ },
1702
+ {
1703
+ id: "servicebus.dotnet.activity-source.message",
1704
+ source:
1705
+ "Azure.Messaging.ServiceBus (.NET) per-message 'Message' PRODUCER span, ActivitySource switch on",
1706
+ kind: PRODUCER,
1707
+ attributes: {
1708
+ "az.namespace": "Microsoft.ServiceBus",
1709
+ "az.schema_url": AZURE_SCHEMA_URL,
1710
+ "messaging.system": "servicebus",
1711
+ "server.address": SERVICE_BUS_HOST,
1712
+ "messaging.destination.name": "invoices",
1713
+ },
1714
+ expected: queue({
1715
+ system: "servicebus",
1716
+ destination: "invoices",
1717
+ brokerScope: "billing-prod",
1718
+ direction: "publish",
1719
+ brokerAddress: SERVICE_BUS_HOST,
1720
+ }),
1721
+ },
1722
+ {
1723
+ id: "servicebus.dotnet.activity-source.process.subscription",
1724
+ source:
1725
+ "Azure.Messaging.ServiceBus (.NET) ServiceBusProcessor.ProcessMessage on a topic subscription ('{topic}/Subscriptions/{sub}')",
1726
+ kind: CONSUMER,
1727
+ attributes: {
1728
+ "az.namespace": "Microsoft.ServiceBus",
1729
+ "az.schema_url": AZURE_SCHEMA_URL,
1730
+ "messaging.system": "servicebus",
1731
+ "messaging.operation": "process",
1732
+ "server.address": SERVICE_BUS_HOST,
1733
+ "messaging.destination.name": "invoice-events/Subscriptions/ledger",
1734
+ },
1735
+ expected: queue({
1736
+ system: "servicebus",
1737
+ destination: "invoice-events",
1738
+ brokerScope: "billing-prod",
1739
+ direction: "consume",
1740
+ consumerGroup: "ledger",
1741
+ brokerAddress: SERVICE_BUS_HOST,
1742
+ }),
1743
+ },
1744
+ {
1745
+ id: "servicebus.dotnet.activity-source.complete",
1746
+ source: "Azure.Messaging.ServiceBus (.NET) ServiceBusReceiver.Complete",
1747
+ kind: CLIENT,
1748
+ attributes: {
1749
+ "az.namespace": "Microsoft.ServiceBus",
1750
+ "az.schema_url": AZURE_SCHEMA_URL,
1751
+ "messaging.system": "servicebus",
1752
+ "messaging.operation": "settle",
1753
+ "server.address": SERVICE_BUS_HOST,
1754
+ "messaging.destination.name": "invoices",
1755
+ },
1756
+ expected: queue({
1757
+ system: "servicebus",
1758
+ destination: "invoices",
1759
+ brokerScope: "billing-prod",
1760
+ direction: "settle",
1761
+ brokerAddress: SERVICE_BUS_HOST,
1762
+ }),
1763
+ },
1764
+ {
1765
+ id: "servicebus.dotnet.activity-source.renew-lock",
1766
+ source:
1767
+ "Azure.Messaging.ServiceBus (.NET) ServiceBusReceiver.RenewMessageLock (no operation)",
1768
+ kind: CLIENT,
1769
+ attributes: {
1770
+ "az.namespace": "Microsoft.ServiceBus",
1771
+ "az.schema_url": AZURE_SCHEMA_URL,
1772
+ "messaging.system": "servicebus",
1773
+ "server.address": SERVICE_BUS_HOST,
1774
+ "messaging.destination.name": "invoices",
1775
+ },
1776
+ expected: queue({
1777
+ system: "servicebus",
1778
+ destination: "invoices",
1779
+ brokerScope: "billing-prod",
1780
+ brokerAddress: SERVICE_BUS_HOST,
1781
+ }),
1782
+ },
1783
+ {
1784
+ id: "servicebus.dotnet.activity-source.send.mixed-case-namespace",
1785
+ source:
1786
+ "Azure.Messaging.ServiceBus (.NET) send, connection string spelling the namespace and entity in mixed case",
1787
+ kind: CLIENT,
1788
+ attributes: {
1789
+ "az.namespace": "Microsoft.ServiceBus",
1790
+ "az.schema_url": AZURE_SCHEMA_URL,
1791
+ "messaging.system": "servicebus",
1792
+ "messaging.operation": "publish",
1793
+ "server.address": "Billing-Prod.servicebus.windows.net",
1794
+ "messaging.destination.name": "Invoices",
1795
+ },
1796
+ expected: queue({
1797
+ system: "servicebus",
1798
+ destination: "Invoices",
1799
+ brokerScope: "billing-prod",
1800
+ direction: "publish",
1801
+ brokerAddress: "Billing-Prod.servicebus.windows.net",
1802
+ }),
1803
+ },
1804
+ {
1805
+ id: "servicebus.dotnet.diagnostic-source.send",
1806
+ source:
1807
+ "Azure.Messaging.ServiceBus (.NET) send WITHOUT the ActivitySource switch (legacy DiagnosticSource: component, peer.address, message_bus.destination; kind only as a tag)",
1808
+ kind: INTERNAL,
1809
+ attributes: {
1810
+ "az.namespace": "Microsoft.ServiceBus",
1811
+ kind: "client",
1812
+ component: "servicebus",
1813
+ "peer.address": SERVICE_BUS_HOST,
1814
+ "message_bus.destination": "invoices",
1815
+ },
1816
+ expected: queue({
1817
+ system: "servicebus",
1818
+ destination: "invoices",
1819
+ brokerScope: "billing-prod",
1820
+ brokerAddress: SERVICE_BUS_HOST,
1821
+ }),
1822
+ },
1823
+ {
1824
+ id: "servicebus.dotnet.diagnostic-source.receive.dead-letter",
1825
+ source:
1826
+ "Azure.Messaging.ServiceBus (.NET) legacy DiagnosticSource receive from the dead-letter sub-queue",
1827
+ kind: INTERNAL,
1828
+ attributes: {
1829
+ "az.namespace": "Microsoft.ServiceBus",
1830
+ kind: "client",
1831
+ component: "servicebus",
1832
+ "peer.address": SERVICE_BUS_HOST,
1833
+ "message_bus.destination": "invoices/$DeadLetterQueue",
1834
+ },
1835
+ expected: queue({
1836
+ system: "servicebus",
1837
+ destination: "invoices",
1838
+ brokerScope: "billing-prod",
1839
+ brokerAddress: SERVICE_BUS_HOST,
1840
+ isDeadLetter: true,
1841
+ }),
1842
+ },
1843
+ {
1844
+ id: "servicebus.dotnet.diagnostic-source.process.subscription-dead-letter",
1845
+ source:
1846
+ "Azure.Messaging.ServiceBus (.NET) legacy DiagnosticSource processor on a subscription's dead-letter queue",
1847
+ kind: INTERNAL,
1848
+ attributes: {
1849
+ "az.namespace": "Microsoft.ServiceBus",
1850
+ kind: "consumer",
1851
+ component: "servicebus",
1852
+ "peer.address": SERVICE_BUS_HOST,
1853
+ "message_bus.destination":
1854
+ "invoice-events/Subscriptions/ledger/$DeadLetterQueue",
1855
+ },
1856
+ expected: queue({
1857
+ system: "servicebus",
1858
+ destination: "invoice-events",
1859
+ brokerScope: "billing-prod",
1860
+ consumerGroup: "ledger",
1861
+ brokerAddress: SERVICE_BUS_HOST,
1862
+ isDeadLetter: true,
1863
+ }),
1864
+ },
1865
+ {
1866
+ id: "servicebus.java.process.subscription",
1867
+ source:
1868
+ "azure-messaging-servicebus (Java) ServiceBus.process ('{topic}/subscriptions/{sub}', both namespace keys)",
1869
+ kind: CONSUMER,
1870
+ attributes: {
1871
+ "messaging.system": "servicebus",
1872
+ "messaging.destination.name": "invoice-events/subscriptions/ledger",
1873
+ "server.address": SERVICE_BUS_HOST,
1874
+ "messaging.operation": "process",
1875
+ "az.namespace": "Microsoft.ServiceBus",
1876
+ "azure.resource_provider.namespace": "Microsoft.ServiceBus",
1877
+ "messaging.servicebus.message.enqueued_time": 1727690000,
1878
+ },
1879
+ expected: queue({
1880
+ system: "servicebus",
1881
+ destination: "invoice-events",
1882
+ brokerScope: "billing-prod",
1883
+ direction: "consume",
1884
+ consumerGroup: "ledger",
1885
+ brokerAddress: SERVICE_BUS_HOST,
1886
+ }),
1887
+ },
1888
+ {
1889
+ id: "servicebus.java.receive.transfer-dead-letter",
1890
+ source:
1891
+ "azure-messaging-servicebus (Java) ServiceBus.receive from the transfer dead-letter queue ('/$Transfer/$deadletterqueue')",
1892
+ kind: CLIENT,
1893
+ attributes: {
1894
+ "messaging.system": "servicebus",
1895
+ "messaging.destination.name": "invoices/$Transfer/$deadletterqueue",
1896
+ "server.address": SERVICE_BUS_HOST,
1897
+ "messaging.operation": "receive",
1898
+ "messaging.batch.message_count": 4,
1899
+ "az.namespace": "Microsoft.ServiceBus",
1900
+ "azure.resource_provider.namespace": "Microsoft.ServiceBus",
1901
+ },
1902
+ expected: queue({
1903
+ system: "servicebus",
1904
+ destination: "invoices",
1905
+ brokerScope: "billing-prod",
1906
+ direction: "consume",
1907
+ brokerAddress: SERVICE_BUS_HOST,
1908
+ isDeadLetter: true,
1909
+ }),
1910
+ },
1911
+ {
1912
+ id: "servicebus.js.receive.subscription",
1913
+ source:
1914
+ "@azure/service-bus (JS) receive (messaging.source.name, net.peer.name)",
1915
+ kind: CLIENT,
1916
+ attributes: {
1917
+ "messaging.system": "servicebus",
1918
+ "messaging.source.name": "invoice-events/Subscriptions/ledger",
1919
+ "messaging.operation": "receive",
1920
+ "net.peer.name": SERVICE_BUS_HOST,
1921
+ "az.namespace": "Microsoft.ServiceBus",
1922
+ },
1923
+ expected: queue({
1924
+ system: "servicebus",
1925
+ destination: "invoice-events",
1926
+ brokerScope: "billing-prod",
1927
+ direction: "consume",
1928
+ consumerGroup: "ledger",
1929
+ brokerAddress: SERVICE_BUS_HOST,
1930
+ }),
1931
+ },
1932
+ {
1933
+ id: "servicebus.js.complete",
1934
+ source: "@azure/service-bus (JS) ServicebusReceiver.complete",
1935
+ kind: CLIENT,
1936
+ attributes: {
1937
+ "messaging.system": "servicebus",
1938
+ "messaging.destination.name": "invoices",
1939
+ "messaging.operation": "settle",
1940
+ "net.peer.name": SERVICE_BUS_HOST,
1941
+ "az.namespace": "Microsoft.ServiceBus",
1942
+ },
1943
+ expected: queue({
1944
+ system: "servicebus",
1945
+ destination: "invoices",
1946
+ brokerScope: "billing-prod",
1947
+ direction: "settle",
1948
+ brokerAddress: SERVICE_BUS_HOST,
1949
+ }),
1950
+ },
1951
+ {
1952
+ id: "servicebus.python.send",
1953
+ source:
1954
+ "azure-servicebus (Python) ServiceBus.send (legacy message_bus.destination + peer.address only)",
1955
+ kind: CLIENT,
1956
+ attributes: {
1957
+ "az.namespace": "Microsoft.ServiceBus",
1958
+ "messaging.system": "servicebus",
1959
+ "messaging.operation": "publish",
1960
+ "messaging.batch.message_count": 3,
1961
+ "message_bus.destination": "invoices",
1962
+ "peer.address": SERVICE_BUS_HOST,
1963
+ },
1964
+ expected: queue({
1965
+ system: "servicebus",
1966
+ destination: "invoices",
1967
+ brokerScope: "billing-prod",
1968
+ direction: "publish",
1969
+ brokerAddress: SERVICE_BUS_HOST,
1970
+ }),
1971
+ },
1972
+ {
1973
+ id: "servicebus.python.complete",
1974
+ source:
1975
+ "azure-servicebus (Python) settle span (messaging.destination.name + net.peer.name)",
1976
+ kind: CLIENT,
1977
+ attributes: {
1978
+ "az.namespace": "Microsoft.ServiceBus",
1979
+ "messaging.system": "servicebus",
1980
+ "messaging.operation": "settle",
1981
+ "net.peer.name": SERVICE_BUS_HOST,
1982
+ "messaging.destination.name": "invoices",
1983
+ },
1984
+ expected: queue({
1985
+ system: "servicebus",
1986
+ destination: "invoices",
1987
+ brokerScope: "billing-prod",
1988
+ direction: "settle",
1989
+ brokerAddress: SERVICE_BUS_HOST,
1990
+ }),
1991
+ },
1992
+ ];
1993
+
1994
+ const EVENT_HUBS_SPANS: ReadonlyArray<SpanFixture> = [
1995
+ {
1996
+ id: "eventhubs.dotnet.activity-source.send",
1997
+ source:
1998
+ "Azure.Messaging.EventHubs (.NET) EventHubProducerClient.Send, ActivitySource switch on",
1999
+ kind: CLIENT,
2000
+ attributes: {
2001
+ "az.namespace": "Microsoft.EventHub",
2002
+ "az.schema_url": AZURE_SCHEMA_URL,
2003
+ "messaging.system": "eventhubs",
2004
+ "messaging.operation": "publish",
2005
+ "server.address": EVENT_HUBS_HOST,
2006
+ "messaging.destination.name": "device-telemetry",
2007
+ "messaging.batch.message_count": 50,
2008
+ },
2009
+ expected: queue({
2010
+ system: "eventhubs",
2011
+ destination: "device-telemetry",
2012
+ brokerScope: "telemetry-prod",
2013
+ direction: "publish",
2014
+ brokerAddress: EVENT_HUBS_HOST,
2015
+ }),
2016
+ },
2017
+ {
2018
+ id: "eventhubs.dotnet.activity-source.process",
2019
+ source: "Azure.Messaging.EventHubs (.NET) EventProcessor.Process",
2020
+ kind: CONSUMER,
2021
+ attributes: {
2022
+ "az.namespace": "Microsoft.EventHub",
2023
+ "az.schema_url": AZURE_SCHEMA_URL,
2024
+ "messaging.system": "eventhubs",
2025
+ "messaging.operation": "process",
2026
+ "server.address": EVENT_HUBS_HOST,
2027
+ "messaging.destination.name": "device-telemetry",
2028
+ "messaging.batch.message_count": 10,
2029
+ },
2030
+ expected: queue({
2031
+ system: "eventhubs",
2032
+ destination: "device-telemetry",
2033
+ brokerScope: "telemetry-prod",
2034
+ direction: "consume",
2035
+ brokerAddress: EVENT_HUBS_HOST,
2036
+ }),
2037
+ },
2038
+ {
2039
+ id: "eventhubs.dotnet.activity-source.checkpoint",
2040
+ source:
2041
+ "Azure.Messaging.EventHubs (.NET) EventProcessor.Checkpoint (INTERNAL, no operation)",
2042
+ kind: INTERNAL,
2043
+ attributes: {
2044
+ "az.namespace": "Microsoft.EventHub",
2045
+ "az.schema_url": AZURE_SCHEMA_URL,
2046
+ "messaging.system": "eventhubs",
2047
+ "server.address": EVENT_HUBS_HOST,
2048
+ "messaging.destination.name": "device-telemetry",
2049
+ },
2050
+ expected: queue({
2051
+ system: "eventhubs",
2052
+ destination: "device-telemetry",
2053
+ brokerScope: "telemetry-prod",
2054
+ brokerAddress: EVENT_HUBS_HOST,
2055
+ }),
2056
+ },
2057
+ {
2058
+ id: "eventhubs.dotnet.diagnostic-source.send",
2059
+ source:
2060
+ "Azure.Messaging.EventHubs (.NET) send WITHOUT the ActivitySource switch (legacy DiagnosticSource keys)",
2061
+ kind: INTERNAL,
2062
+ attributes: {
2063
+ "az.namespace": "Microsoft.EventHub",
2064
+ kind: "client",
2065
+ component: "eventhubs",
2066
+ "peer.address": EVENT_HUBS_HOST,
2067
+ "message_bus.destination": "device-telemetry",
2068
+ },
2069
+ expected: queue({
2070
+ system: "eventhubs",
2071
+ destination: "device-telemetry",
2072
+ brokerScope: "telemetry-prod",
2073
+ brokerAddress: EVENT_HUBS_HOST,
2074
+ }),
2075
+ },
2076
+ {
2077
+ id: "eventhubs.java.process",
2078
+ source:
2079
+ "azure-messaging-eventhubs (Java) 'process device-telemetry' (operation name + type, consumer group, partition)",
2080
+ kind: CONSUMER,
2081
+ attributes: {
2082
+ "messaging.system": "eventhubs",
2083
+ "messaging.destination.name": "device-telemetry",
2084
+ "server.address": EVENT_HUBS_HOST,
2085
+ "messaging.operation.name": "process",
2086
+ "messaging.consumer.group.name": "$Default",
2087
+ "messaging.destination.partition.id": "3",
2088
+ "messaging.operation.type": "process",
2089
+ "messaging.eventhubs.message.enqueued_time": 1727690000,
2090
+ "az.namespace": "Microsoft.EventHub",
2091
+ "azure.resource_provider.namespace": "Microsoft.EventHub",
2092
+ },
2093
+ expected: queue({
2094
+ system: "eventhubs",
2095
+ destination: "device-telemetry",
2096
+ brokerScope: "telemetry-prod",
2097
+ direction: "consume",
2098
+ consumerGroup: "$Default",
2099
+ brokerAddress: EVENT_HUBS_HOST,
2100
+ }),
2101
+ },
2102
+ {
2103
+ id: "eventhubs.java.checkpoint",
2104
+ source:
2105
+ "azure-messaging-eventhubs (Java) 'checkpoint device-telemetry' (settle)",
2106
+ kind: CLIENT,
2107
+ attributes: {
2108
+ "messaging.system": "eventhubs",
2109
+ "messaging.destination.name": "device-telemetry",
2110
+ "server.address": EVENT_HUBS_HOST,
2111
+ "messaging.operation.name": "checkpoint",
2112
+ "messaging.consumer.group.name": "$Default",
2113
+ "messaging.destination.partition.id": "3",
2114
+ "messaging.operation.type": "settle",
2115
+ },
2116
+ expected: queue({
2117
+ system: "eventhubs",
2118
+ destination: "device-telemetry",
2119
+ brokerScope: "telemetry-prod",
2120
+ direction: "settle",
2121
+ consumerGroup: "$Default",
2122
+ brokerAddress: EVENT_HUBS_HOST,
2123
+ }),
2124
+ },
2125
+ {
2126
+ id: "eventhubs.python.receive",
2127
+ source:
2128
+ "azure-eventhub (Python) EventHubs.receive (new keys: messaging.destination.name + net.peer.name)",
2129
+ kind: CLIENT,
2130
+ attributes: {
2131
+ "az.namespace": "Microsoft.EventHub",
2132
+ "messaging.system": "eventhubs",
2133
+ "messaging.operation": "receive",
2134
+ "messaging.batch.message_count": 10,
2135
+ "net.peer.name": EVENT_HUBS_HOST,
2136
+ "messaging.destination.name": "device-telemetry",
2137
+ },
2138
+ expected: queue({
2139
+ system: "eventhubs",
2140
+ destination: "device-telemetry",
2141
+ brokerScope: "telemetry-prod",
2142
+ direction: "consume",
2143
+ brokerAddress: EVENT_HUBS_HOST,
2144
+ }),
2145
+ },
2146
+ {
2147
+ id: "eventhubs.python.process",
2148
+ source:
2149
+ "azure-eventhub (Python) EventHubs.process (legacy message_bus.destination + peer.address)",
2150
+ kind: CONSUMER,
2151
+ attributes: {
2152
+ "az.namespace": "Microsoft.EventHub",
2153
+ "messaging.system": "eventhubs",
2154
+ "messaging.operation": "process",
2155
+ "message_bus.destination": "device-telemetry",
2156
+ "peer.address": EVENT_HUBS_HOST,
2157
+ },
2158
+ expected: queue({
2159
+ system: "eventhubs",
2160
+ destination: "device-telemetry",
2161
+ brokerScope: "telemetry-prod",
2162
+ direction: "consume",
2163
+ brokerAddress: EVENT_HUBS_HOST,
2164
+ }),
2165
+ },
2166
+ {
2167
+ id: "eventhubs.js.receive",
2168
+ source:
2169
+ "@azure/event-hubs (JS) receive (messaging.source.name, net.peer.name)",
2170
+ kind: CLIENT,
2171
+ attributes: {
2172
+ "messaging.system": "eventhubs",
2173
+ "messaging.source.name": "device-telemetry",
2174
+ "net.peer.name": EVENT_HUBS_HOST,
2175
+ "messaging.operation": "receive",
2176
+ "az.namespace": "Microsoft.EventHub",
2177
+ },
2178
+ expected: queue({
2179
+ system: "eventhubs",
2180
+ destination: "device-telemetry",
2181
+ brokerScope: "telemetry-prod",
2182
+ direction: "consume",
2183
+ brokerAddress: EVENT_HUBS_HOST,
2184
+ }),
2185
+ },
2186
+ ];
2187
+
2188
+ const PULSAR_ROCKETMQ_NATS_SPANS: ReadonlyArray<SpanFixture> = [
2189
+ {
2190
+ id: "pulsar.java-agent.default.send.short-name",
2191
+ source:
2192
+ "Java agent pulsar-2.8 send, default mode (the topic as the producer was created with: a short name)",
2193
+ kind: PRODUCER,
2194
+ attributes: {
2195
+ "messaging.system": "pulsar",
2196
+ "messaging.destination.name": "payments",
2197
+ "messaging.operation": "publish",
2198
+ "messaging.message.id": "12:3:1",
2199
+ "messaging.message.body.size": 64,
2200
+ "server.address": "pulsar-broker-0.pulsar-broker",
2201
+ "server.port": 6650,
2202
+ },
2203
+ expected: queue({
2204
+ system: "pulsar",
2205
+ destination: "persistent://public/default/payments",
2206
+ direction: "publish",
2207
+ brokerAddress: "pulsar-broker-0.pulsar-broker:6650",
2208
+ }),
2209
+ },
2210
+ {
2211
+ id: "pulsar.java-agent.default.process.partition",
2212
+ source:
2213
+ "Java agent pulsar-2.8 process, default mode (a partition of a partitioned topic)",
2214
+ kind: CONSUMER,
2215
+ attributes: {
2216
+ "messaging.system": "pulsar",
2217
+ "messaging.destination.name":
2218
+ "persistent://public/default/payments-partition-1",
2219
+ "messaging.operation": "process",
2220
+ "messaging.message.id": "12:4:1:0",
2221
+ "server.address": "pulsar-broker-0.pulsar-broker",
2222
+ "server.port": 6650,
2223
+ },
2224
+ expected: queue({
2225
+ system: "pulsar",
2226
+ destination: "persistent://public/default/payments",
2227
+ direction: "consume",
2228
+ brokerAddress: "pulsar-broker-0.pulsar-broker:6650",
2229
+ }),
2230
+ },
2231
+ {
2232
+ id: "pulsar.java-agent.opt-in.receive",
2233
+ source:
2234
+ "Java agent pulsar-2.8 receive, opt-in (fully-qualified topic, partition id and subscription apart)",
2235
+ kind: CLIENT,
2236
+ attributes: {
2237
+ "messaging.system": "pulsar",
2238
+ "messaging.destination.name": "persistent://public/default/payments",
2239
+ "messaging.destination.partition.id": "0",
2240
+ "messaging.destination.subscription.name": "ledger",
2241
+ "messaging.operation.name": "receive",
2242
+ "messaging.operation.type": "receive",
2243
+ "server.address": "pulsar-broker-0.pulsar-broker",
2244
+ "server.port": 6650,
2245
+ },
2246
+ expected: queue({
2247
+ system: "pulsar",
2248
+ destination: "persistent://public/default/payments",
2249
+ direction: "consume",
2250
+ consumerGroup: "ledger",
2251
+ brokerAddress: "pulsar-broker-0.pulsar-broker:6650",
2252
+ }),
2253
+ },
2254
+ {
2255
+ id: "rocketmq.java-agent.5.process",
2256
+ source:
2257
+ "Java agent rocketmq-client-5.0 process, default mode (legacy consumer group key; keys as an array)",
2258
+ kind: CONSUMER,
2259
+ attributes: {
2260
+ "messaging.system": "rocketmq",
2261
+ "messaging.destination.name": "order-topic",
2262
+ "messaging.operation": "process",
2263
+ "messaging.rocketmq.client_group": "order-consumer-group",
2264
+ "messaging.rocketmq.message.tag": "TagA",
2265
+ "messaging.rocketmq.message.keys": ["order-10042"],
2266
+ "messaging.message.id": "01AC1E0A2D4C5D6E7F8090A1B2C3D4E5",
2267
+ "messaging.message.body.size": 64,
2268
+ },
2269
+ expected: queue({
2270
+ system: "rocketmq",
2271
+ destination: "order-topic",
2272
+ direction: "consume",
2273
+ consumerGroup: "order-consumer-group",
2274
+ }),
2275
+ },
2276
+ {
2277
+ id: "rocketmq.java-agent.4.send",
2278
+ source: "Java agent rocketmq-client-4.8 send, default mode",
2279
+ kind: PRODUCER,
2280
+ attributes: {
2281
+ "messaging.system": "rocketmq",
2282
+ "messaging.destination.name": "order-topic",
2283
+ "messaging.operation": "publish",
2284
+ "messaging.rocketmq.message.tag": "TagA",
2285
+ "messaging.message.id": "0A0004155E8418B4AAC2A1F3B2E10000",
2286
+ },
2287
+ expected: queue({
2288
+ system: "rocketmq",
2289
+ destination: "order-topic",
2290
+ direction: "publish",
2291
+ }),
2292
+ },
2293
+ {
2294
+ id: "nats.java-agent.default.publish",
2295
+ source: "Java agent nats-2.17 publish, default mode (the subject)",
2296
+ kind: PRODUCER,
2297
+ attributes: {
2298
+ "messaging.system": "nats",
2299
+ "messaging.destination.name": "orders.created",
2300
+ "messaging.operation": "publish",
2301
+ "messaging.client_id": "7",
2302
+ "messaging.message.body.size": 48,
2303
+ },
2304
+ expected: queue({
2305
+ system: "nats",
2306
+ destination: "orders.created",
2307
+ direction: "publish",
2308
+ }),
2309
+ },
2310
+ {
2311
+ id: "nats.java-agent.opt-in.process",
2312
+ source: "Java agent nats-2.17 subscription dispatch, opt-in",
2313
+ kind: CONSUMER,
2314
+ attributes: {
2315
+ "messaging.system": "nats",
2316
+ "messaging.destination.name": "orders.created",
2317
+ "messaging.operation.name": "process",
2318
+ "messaging.operation.type": "process",
2319
+ "messaging.client.id": "7",
2320
+ "messaging.message.body.size": 48,
2321
+ },
2322
+ expected: queue({
2323
+ system: "nats",
2324
+ destination: "orders.created",
2325
+ direction: "consume",
2326
+ }),
2327
+ },
2328
+ {
2329
+ id: "nats.java-agent.request-reply-inbox",
2330
+ source:
2331
+ "Java agent nats-2.17 reply on a request inbox (template = inbox prefix, temporary flag)",
2332
+ kind: CONSUMER,
2333
+ attributes: {
2334
+ "messaging.system": "nats",
2335
+ "messaging.destination.name": "_INBOX.k2Hw7dP1cPU9fC4tZ8fKDq.1",
2336
+ "messaging.destination.template": "_INBOX.",
2337
+ "messaging.destination.temporary": true,
2338
+ "messaging.operation": "process",
2339
+ "messaging.client_id": "7",
2340
+ },
2341
+ expected: null,
2342
+ },
2343
+ {
2344
+ id: "nats.java-agent.jetstream-ack",
2345
+ source:
2346
+ "Java agent nats-2.17 JetStream acknowledgement ($JS.ACK subject, templated as $JS.ACK)",
2347
+ kind: PRODUCER,
2348
+ attributes: {
2349
+ "messaging.system": "nats",
2350
+ "messaging.destination.name":
2351
+ "$JS.ACK.ORDERS.billing.1.12.12.1727690000000000000.0",
2352
+ "messaging.destination.template": "$JS.ACK",
2353
+ "messaging.operation": "publish",
2354
+ "messaging.client_id": "7",
2355
+ },
2356
+ expected: null,
2357
+ },
2358
+ ];
2359
+
2360
+ const OTHER_SPANS: ReadonlyArray<SpanFixture> = [
2361
+ {
2362
+ id: "oneuptime.worker-job.root-span",
2363
+ source:
2364
+ "OneUptime's own BullMQ worker job root span (TelemetryContext keys, no messaging keys)",
2365
+ kind: INTERNAL,
2366
+ attributes: {
2367
+ queueName: "Worker",
2368
+ jobName: "ProcessMonitorEvaluation",
2369
+ "oneuptime.unit_of_work": "worker-job",
2370
+ "oneuptime.component": "worker",
2371
+ projectId: "6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
2372
+ },
2373
+ expected: null,
2374
+ },
2375
+ {
2376
+ id: "celery.run-task",
2377
+ source:
2378
+ "opentelemetry-instrumentation-celery 'run/{task}' (no messaging.system: the broker is unknown)",
2379
+ kind: CONSUMER,
2380
+ attributes: {
2381
+ "celery.action": "run",
2382
+ "celery.state": "SUCCESS",
2383
+ "celery.task_name": "billing.tasks.charge",
2384
+ "celery.hostname": "celery@worker-1",
2385
+ "messaging.destination": "celery",
2386
+ "messaging.destination_kind": "queue",
2387
+ "messaging.message.id": "b6c7d8e9-f0a1-4b2c-8d3e-4f5a6b7c8d9e",
2388
+ "messaging.conversation_id": "b6c7d8e9-f0a1-4b2c-8d3e-4f5a6b7c8d9e",
2389
+ },
2390
+ expected: null,
2391
+ },
2392
+ {
2393
+ id: "http.server.pubsub-push-endpoint",
2394
+ source:
2395
+ "An HTTP SERVER span of a Pub/Sub push endpoint enriched with messaging keys (a messaging operation is never served)",
2396
+ kind: SERVER,
2397
+ attributes: {
2398
+ "messaging.system": "gcp_pubsub",
2399
+ "messaging.destination.name": "orders-push",
2400
+ "http.request.method": "POST",
2401
+ "url.path": "/pubsub/push",
2402
+ "http.response.status_code": 204,
2403
+ },
2404
+ expected: null,
2405
+ },
2406
+ ];
2407
+
2408
+ const SPANS: ReadonlyArray<SpanFixture> = [
2409
+ ...KAFKA_SPANS,
2410
+ ...RABBITMQ_SPANS,
2411
+ ...JMS_SPANS,
2412
+ ...SQS_SPANS,
2413
+ ...SNS_SPANS,
2414
+ ...PUBSUB_SPANS,
2415
+ ...SERVICE_BUS_SPANS,
2416
+ ...EVENT_HUBS_SPANS,
2417
+ ...PULSAR_ROCKETMQ_NATS_SPANS,
2418
+ ...OTHER_SPANS,
2419
+ ];
2420
+
2421
+ // ---- datapoints (stored shape) --------------------------------------------
2422
+
2423
+ const KAFKA_DATAPOINTS: ReadonlyArray<DatapointFixture> = [
2424
+ {
2425
+ id: "kafka_metrics.lag_sum",
2426
+ source:
2427
+ "kafka_metrics consumers scraper, cluster alias and id enabled as resource attributes (live capture, Kafka 4.1)",
2428
+ metricName: "kafka.consumer_group.lag_sum",
2429
+ attributes: {
2430
+ group: "billing",
2431
+ topic: "payments",
2432
+ "resource.kafka.cluster.alias": "prod-kafka",
2433
+ "resource.kafka.cluster.id": "5L6g3nShT-eMCtK--X86sw",
2434
+ },
2435
+ expected: queue({ system: "kafka", destination: "payments" }),
2436
+ },
2437
+ {
2438
+ id: "kafka_metrics.lag_sum.no-resource",
2439
+ source:
2440
+ "kafka_metrics on 0.161.0 with only cluster_alias set: no resource attributes at all (live capture)",
2441
+ metricName: "kafka.consumer_group.lag_sum",
2442
+ attributes: {
2443
+ group: "billing",
2444
+ topic: "payments",
2445
+ },
2446
+ expected: queue({ system: "kafka", destination: "payments" }),
2447
+ },
2448
+ {
2449
+ id: "kafka_metrics.lag",
2450
+ source: "kafka_metrics per-partition lag (partition is an int)",
2451
+ metricName: "kafka.consumer_group.lag",
2452
+ attributes: {
2453
+ group: "billing",
2454
+ topic: "payments",
2455
+ partition: 0,
2456
+ },
2457
+ expected: queue({ system: "kafka", destination: "payments" }),
2458
+ },
2459
+ {
2460
+ id: "kafka_metrics.offset_sum",
2461
+ source: "kafka_metrics committed offsets summed over partitions",
2462
+ metricName: "kafka.consumer_group.offset_sum",
2463
+ attributes: {
2464
+ group: "billing",
2465
+ topic: "payments",
2466
+ },
2467
+ expected: queue({
2468
+ system: "kafka",
2469
+ destination: "payments",
2470
+ direction: "consume",
2471
+ }),
2472
+ },
2473
+ {
2474
+ id: "kafka_metrics.current_offset",
2475
+ source: "kafka_metrics topics scraper log-end offset",
2476
+ metricName: "kafka.partition.current_offset",
2477
+ attributes: {
2478
+ topic: "payments",
2479
+ partition: 2,
2480
+ },
2481
+ expected: queue({
2482
+ system: "kafka",
2483
+ destination: "payments",
2484
+ direction: "publish",
2485
+ }),
2486
+ },
2487
+ {
2488
+ id: "kafka_metrics.members",
2489
+ source: "kafka_metrics group members (names a group, not a topic)",
2490
+ metricName: "kafka.consumer_group.members",
2491
+ attributes: {
2492
+ group: "billing",
2493
+ },
2494
+ expected: null,
2495
+ },
2496
+ {
2497
+ id: "kafka_metrics.lag_sum.uuid-topic",
2498
+ source: "kafka_metrics lag on a per-tenant topic named by UUID",
2499
+ metricName: "kafka.consumer_group.lag_sum",
2500
+ attributes: {
2501
+ group: "tenant-worker",
2502
+ topic: UUID_TOPIC,
2503
+ },
2504
+ expected: queue({ system: "kafka", destination: UUID_TOPIC_TEMPLATED }),
2505
+ },
2506
+ ];
2507
+
2508
+ const RABBITMQ_DATAPOINTS: ReadonlyArray<DatapointFixture> = [
2509
+ {
2510
+ id: "rabbitmq.message.current.ready",
2511
+ source:
2512
+ "rabbitmq receiver queue depth, ready series (one resource per queue; live capture, RabbitMQ 4.3)",
2513
+ metricName: "rabbitmq.message.current",
2514
+ attributes: {
2515
+ state: "ready",
2516
+ ...RABBITMQ_QUEUE_RESOURCE("invoices"),
2517
+ },
2518
+ expected: queue({ system: "rabbitmq", destination: "invoices" }),
2519
+ },
2520
+ {
2521
+ id: "rabbitmq.message.current.unacknowledged",
2522
+ source: "rabbitmq receiver queue depth, unacknowledged series",
2523
+ metricName: "rabbitmq.message.current",
2524
+ attributes: {
2525
+ state: "unacknowledged",
2526
+ ...RABBITMQ_QUEUE_RESOURCE("invoices"),
2527
+ },
2528
+ expected: queue({ system: "rabbitmq", destination: "invoices" }),
2529
+ },
2530
+ {
2531
+ id: "rabbitmq.message.published",
2532
+ source: "rabbitmq receiver message_stats.publish",
2533
+ metricName: "rabbitmq.message.published",
2534
+ attributes: {
2535
+ ...RABBITMQ_QUEUE_RESOURCE("invoices"),
2536
+ },
2537
+ expected: queue({
2538
+ system: "rabbitmq",
2539
+ destination: "invoices",
2540
+ direction: "publish",
2541
+ }),
2542
+ },
2543
+ {
2544
+ id: "rabbitmq.message.delivered",
2545
+ source: "rabbitmq receiver message_stats.deliver",
2546
+ metricName: "rabbitmq.message.delivered",
2547
+ attributes: {
2548
+ ...RABBITMQ_QUEUE_RESOURCE("invoices"),
2549
+ },
2550
+ expected: queue({
2551
+ system: "rabbitmq",
2552
+ destination: "invoices",
2553
+ direction: "consume",
2554
+ }),
2555
+ },
2556
+ {
2557
+ id: "rabbitmq.message.acknowledged",
2558
+ source: "rabbitmq receiver message_stats.ack",
2559
+ metricName: "rabbitmq.message.acknowledged",
2560
+ attributes: {
2561
+ ...RABBITMQ_QUEUE_RESOURCE("invoices"),
2562
+ },
2563
+ expected: queue({
2564
+ system: "rabbitmq",
2565
+ destination: "invoices",
2566
+ direction: "consume",
2567
+ }),
2568
+ },
2569
+ {
2570
+ id: "rabbitmq.message.dropped",
2571
+ source: "rabbitmq receiver message_stats.drop_unroutable",
2572
+ metricName: "rabbitmq.message.dropped",
2573
+ attributes: {
2574
+ ...RABBITMQ_QUEUE_RESOURCE("invoices"),
2575
+ },
2576
+ expected: queue({ system: "rabbitmq", destination: "invoices" }),
2577
+ },
2578
+ {
2579
+ id: "rabbitmq.consumer.count",
2580
+ source: "rabbitmq receiver consumers (live capture: value 0)",
2581
+ metricName: "rabbitmq.consumer.count",
2582
+ attributes: {
2583
+ ...RABBITMQ_QUEUE_RESOURCE("invoices"),
2584
+ },
2585
+ expected: queue({ system: "rabbitmq", destination: "invoices" }),
2586
+ },
2587
+ {
2588
+ id: "rabbitmq.message.current.warning",
2589
+ source: "rabbitmq receiver queue depth of the 'warning' queue",
2590
+ metricName: "rabbitmq.message.current",
2591
+ attributes: {
2592
+ state: "ready",
2593
+ ...RABBITMQ_QUEUE_RESOURCE("warning"),
2594
+ },
2595
+ expected: queue({ system: "rabbitmq", destination: "warning" }),
2596
+ },
2597
+ {
2598
+ id: "rabbitmq.message.current.logs-audit",
2599
+ source: "rabbitmq receiver queue depth of the 'logs-audit' queue",
2600
+ metricName: "rabbitmq.message.current",
2601
+ attributes: {
2602
+ state: "ready",
2603
+ ...RABBITMQ_QUEUE_RESOURCE("logs-audit"),
2604
+ },
2605
+ expected: queue({ system: "rabbitmq", destination: "logs-audit" }),
2606
+ },
2607
+ {
2608
+ id: "rabbitmq.message.current.server-named",
2609
+ source: "rabbitmq receiver queue depth of a server-named queue",
2610
+ metricName: "rabbitmq.message.current",
2611
+ attributes: {
2612
+ state: "ready",
2613
+ ...RABBITMQ_QUEUE_RESOURCE("amq.gen-JzTY20BRgKO-HjmUJj0wLg"),
2614
+ },
2615
+ expected: null,
2616
+ },
2617
+ {
2618
+ id: "rabbitmq.message.current.invoice-issued",
2619
+ source: "rabbitmq receiver queue depth of the 'invoice-issued' queue",
2620
+ metricName: "rabbitmq.message.current",
2621
+ attributes: {
2622
+ state: "ready",
2623
+ ...RABBITMQ_QUEUE_RESOURCE("invoice-issued"),
2624
+ },
2625
+ expected: queue({ system: "rabbitmq", destination: "invoice-issued" }),
2626
+ },
2627
+ {
2628
+ /*
2629
+ * MassTransit's bus endpoint (DefaultEndpointNameFormatter
2630
+ * .GetTemporaryQueueName("bus")): `{machine}_{process}_bus_{NewId}`, a
2631
+ * new one for every process; the receiver lists it like any queue.
2632
+ */
2633
+ id: "rabbitmq.message.current.masstransit-bus-endpoint",
2634
+ source:
2635
+ "rabbitmq receiver queue depth of a MassTransit bus endpoint (one per process)",
2636
+ metricName: "rabbitmq.message.current",
2637
+ attributes: {
2638
+ state: "ready",
2639
+ ...RABBITMQ_QUEUE_RESOURCE(
2640
+ "billingapi5f7c9d8b6q2wzt_BillingApi_bus_3ibyyjnrydpynkcybdxt6fndr7",
2641
+ ),
2642
+ },
2643
+ expected: null,
2644
+ },
2645
+ {
2646
+ id: "rabbitmq.node.mem_alarm",
2647
+ source: "rabbitmq receiver node metric (node resource only, opt-in)",
2648
+ metricName: "rabbitmq.node.mem_alarm",
2649
+ attributes: {
2650
+ "resource.rabbitmq.node.name": "rabbit@rabbitmq-0",
2651
+ },
2652
+ expected: null,
2653
+ },
2654
+ ];
2655
+
2656
+ const ACTIVEMQ_DATAPOINTS: ReadonlyArray<DatapointFixture> = [
2657
+ {
2658
+ id: "jmx.activemq.message.queue.size",
2659
+ source:
2660
+ "OpenTelemetry JMX Scraper 1.53+ (instrumentation rules) queue size (live capture, ActiveMQ Classic 6.2)",
2661
+ metricName: "activemq.message.queue.size",
2662
+ attributes: {
2663
+ "activemq.broker.name": "localhost",
2664
+ "activemq.destination.type": "queue",
2665
+ "messaging.destination.name": "orders",
2666
+ ...JMX_SCRAPER_RESOURCE,
2667
+ },
2668
+ expected: queue({ system: "activemq", destination: "orders" }),
2669
+ },
2670
+ {
2671
+ id: "jmx.activemq.message.current.legacy",
2672
+ source:
2673
+ "OpenTelemetry JMX Scraper legacy rules (1.52 and older, or OTEL_JMX_TARGET_SOURCE=legacy) queue size",
2674
+ metricName: "activemq.message.current",
2675
+ attributes: {
2676
+ broker: "localhost",
2677
+ destination: "orders",
2678
+ ...JMX_SCRAPER_RESOURCE,
2679
+ },
2680
+ expected: queue({ system: "activemq", destination: "orders" }),
2681
+ },
2682
+ {
2683
+ id: "jmx.activemq.message.enqueued",
2684
+ source: "OpenTelemetry JMX Scraper 1.53+ enqueued",
2685
+ metricName: "activemq.message.enqueued",
2686
+ attributes: {
2687
+ "activemq.broker.name": "localhost",
2688
+ "activemq.destination.type": "queue",
2689
+ "messaging.destination.name": "orders",
2690
+ ...JMX_SCRAPER_RESOURCE,
2691
+ },
2692
+ expected: queue({
2693
+ system: "activemq",
2694
+ destination: "orders",
2695
+ direction: "publish",
2696
+ }),
2697
+ },
2698
+ {
2699
+ id: "jmx.activemq.message.enqueued.legacy",
2700
+ source: "OpenTelemetry JMX Scraper legacy enqueued",
2701
+ metricName: "activemq.message.enqueued",
2702
+ attributes: {
2703
+ broker: "localhost",
2704
+ destination: "orders",
2705
+ ...JMX_SCRAPER_RESOURCE,
2706
+ },
2707
+ expected: queue({
2708
+ system: "activemq",
2709
+ destination: "orders",
2710
+ direction: "publish",
2711
+ }),
2712
+ },
2713
+ {
2714
+ id: "jmx.activemq.message.dequeued",
2715
+ source: "OpenTelemetry JMX Scraper 1.53+ dequeued",
2716
+ metricName: "activemq.message.dequeued",
2717
+ attributes: {
2718
+ "activemq.broker.name": "localhost",
2719
+ "activemq.destination.type": "queue",
2720
+ "messaging.destination.name": "orders",
2721
+ ...JMX_SCRAPER_RESOURCE,
2722
+ },
2723
+ expected: queue({
2724
+ system: "activemq",
2725
+ destination: "orders",
2726
+ direction: "consume",
2727
+ }),
2728
+ },
2729
+ {
2730
+ id: "jmx.activemq.message.dequeued.legacy",
2731
+ source: "OpenTelemetry JMX Scraper legacy dequeued",
2732
+ metricName: "activemq.message.dequeued",
2733
+ attributes: {
2734
+ broker: "localhost",
2735
+ destination: "orders",
2736
+ ...JMX_SCRAPER_RESOURCE,
2737
+ },
2738
+ expected: queue({
2739
+ system: "activemq",
2740
+ destination: "orders",
2741
+ direction: "consume",
2742
+ }),
2743
+ },
2744
+ {
2745
+ id: "jmx.activemq.message.expired",
2746
+ source: "OpenTelemetry JMX Scraper 1.53+ expired",
2747
+ metricName: "activemq.message.expired",
2748
+ attributes: {
2749
+ "activemq.broker.name": "localhost",
2750
+ "activemq.destination.type": "queue",
2751
+ "messaging.destination.name": "orders",
2752
+ ...JMX_SCRAPER_RESOURCE,
2753
+ },
2754
+ expected: queue({ system: "activemq", destination: "orders" }),
2755
+ },
2756
+ {
2757
+ id: "jmx.activemq.consumer.count",
2758
+ source: "OpenTelemetry JMX Scraper 1.53+ consumer count",
2759
+ metricName: "activemq.consumer.count",
2760
+ attributes: {
2761
+ "activemq.broker.name": "localhost",
2762
+ "activemq.destination.type": "queue",
2763
+ "messaging.destination.name": "orders",
2764
+ ...JMX_SCRAPER_RESOURCE,
2765
+ },
2766
+ expected: queue({ system: "activemq", destination: "orders" }),
2767
+ },
2768
+ {
2769
+ id: "jmx.activemq.message.enqueue.average_duration",
2770
+ source: "OpenTelemetry JMX Scraper 1.53+ average time in queue (seconds)",
2771
+ metricName: "activemq.message.enqueue.average_duration",
2772
+ attributes: {
2773
+ "activemq.broker.name": "localhost",
2774
+ "activemq.destination.type": "queue",
2775
+ "messaging.destination.name": "orders",
2776
+ ...JMX_SCRAPER_RESOURCE,
2777
+ },
2778
+ expected: queue({ system: "activemq", destination: "orders" }),
2779
+ },
2780
+ {
2781
+ id: "jmx.activemq.message.wait_time.avg.legacy",
2782
+ source: "OpenTelemetry JMX Scraper legacy average wait time (ms)",
2783
+ metricName: "activemq.message.wait_time.avg",
2784
+ attributes: {
2785
+ broker: "localhost",
2786
+ destination: "orders",
2787
+ ...JMX_SCRAPER_RESOURCE,
2788
+ },
2789
+ expected: queue({ system: "activemq", destination: "orders" }),
2790
+ },
2791
+ {
2792
+ id: "jmx.activemq.message.queue.size.dead-letter",
2793
+ source: "OpenTelemetry JMX Scraper 1.53+ depth of the shared ActiveMQ.DLQ",
2794
+ metricName: "activemq.message.queue.size",
2795
+ attributes: {
2796
+ "activemq.broker.name": "localhost",
2797
+ "activemq.destination.type": "queue",
2798
+ "messaging.destination.name": "ActiveMQ.DLQ",
2799
+ ...JMX_SCRAPER_RESOURCE,
2800
+ },
2801
+ expected: queue({
2802
+ system: "activemq",
2803
+ destination: "ActiveMQ.DLQ",
2804
+ isDeadLetter: true,
2805
+ }),
2806
+ },
2807
+ {
2808
+ id: "jmx.activemq.message.queue.size.advisory",
2809
+ source:
2810
+ "OpenTelemetry JMX Scraper 1.53+ advisory topic (captured live next to the real queue)",
2811
+ metricName: "activemq.message.queue.size",
2812
+ attributes: {
2813
+ "activemq.broker.name": "localhost",
2814
+ "activemq.destination.type": "topic",
2815
+ "messaging.destination.name": "ActiveMQ.Advisory.Connection",
2816
+ ...JMX_SCRAPER_RESOURCE,
2817
+ },
2818
+ expected: null,
2819
+ },
2820
+ {
2821
+ id: "jmx.activemq.consumer.count.legacy-advisory",
2822
+ source:
2823
+ "OpenTelemetry JMX Scraper legacy consumer count of a producer advisory topic (live capture)",
2824
+ metricName: "activemq.consumer.count",
2825
+ attributes: {
2826
+ broker: "localhost",
2827
+ destination: "ActiveMQ.Advisory.Producer.Queue.orders",
2828
+ ...JMX_SCRAPER_RESOURCE,
2829
+ },
2830
+ expected: null,
2831
+ },
2832
+ ];
2833
+
2834
+ const SERVICE_BUS_DATAPOINTS: ReadonlyArray<DatapointFixture> = [
2835
+ {
2836
+ id: "azure_monitor.servicebus.activemessages",
2837
+ source:
2838
+ "azure_monitor ActiveMessages (Average), dimension key as Azure returns it (lowercase)",
2839
+ metricName: "azure_activemessages_average",
2840
+ attributes: {
2841
+ ...SERVICE_BUS_DATAPOINT,
2842
+ metadata_entityname: "invoices",
2843
+ },
2844
+ expected: queue({
2845
+ system: "servicebus",
2846
+ destination: "invoices",
2847
+ brokerScope: "billing-prod",
2848
+ }),
2849
+ },
2850
+ {
2851
+ id: "azure_monitor.servicebus.deadletteredmessages",
2852
+ source:
2853
+ "azure_monitor DeadletteredMessages (Average), dimension key as the docs spell it and the ARM resource type casing",
2854
+ metricName: "azure_deadletteredmessages_average",
2855
+ attributes: {
2856
+ ...SERVICE_BUS_DATAPOINT,
2857
+ type: "Microsoft.ServiceBus/Namespaces",
2858
+ metadata_EntityName: "invoices",
2859
+ },
2860
+ expected: queue({
2861
+ system: "servicebus",
2862
+ destination: "invoices",
2863
+ brokerScope: "billing-prod",
2864
+ }),
2865
+ },
2866
+ {
2867
+ id: "azure_monitor.servicebus.incomingmessages",
2868
+ source:
2869
+ "azure_monitor IncomingMessages (Total) on a Service Bus namespace (v0.162 adds timegrain)",
2870
+ metricName: "azure_incomingmessages_total",
2871
+ attributes: {
2872
+ ...SERVICE_BUS_DATAPOINT,
2873
+ timegrain: "PT1M",
2874
+ metadata_entityname: "invoices",
2875
+ },
2876
+ expected: queue({
2877
+ system: "servicebus",
2878
+ destination: "invoices",
2879
+ brokerScope: "billing-prod",
2880
+ direction: "publish",
2881
+ }),
2882
+ },
2883
+ {
2884
+ id: "azure_monitor.servicebus.outgoingmessages",
2885
+ source: "azure_monitor OutgoingMessages (Total) on a Service Bus namespace",
2886
+ metricName: "azure_outgoingmessages_total",
2887
+ attributes: {
2888
+ ...SERVICE_BUS_DATAPOINT,
2889
+ metadata_entityname: "invoices",
2890
+ },
2891
+ expected: queue({
2892
+ system: "servicebus",
2893
+ destination: "invoices",
2894
+ brokerScope: "billing-prod",
2895
+ direction: "consume",
2896
+ }),
2897
+ },
2898
+ {
2899
+ id: "azure_monitor.servicebus.completemessage",
2900
+ source: "azure_monitor CompleteMessage (Total)",
2901
+ metricName: "azure_completemessage_total",
2902
+ attributes: {
2903
+ ...SERVICE_BUS_DATAPOINT,
2904
+ metadata_entityname: "invoices",
2905
+ },
2906
+ expected: queue({
2907
+ system: "servicebus",
2908
+ destination: "invoices",
2909
+ brokerScope: "billing-prod",
2910
+ direction: "consume",
2911
+ }),
2912
+ },
2913
+ {
2914
+ id: "azure_monitor.servicebus.abandonmessage",
2915
+ source: "azure_monitor AbandonMessage (Total)",
2916
+ metricName: "azure_abandonmessage_total",
2917
+ attributes: {
2918
+ ...SERVICE_BUS_DATAPOINT,
2919
+ metadata_entityname: "invoices",
2920
+ },
2921
+ expected: queue({
2922
+ system: "servicebus",
2923
+ destination: "invoices",
2924
+ brokerScope: "billing-prod",
2925
+ }),
2926
+ },
2927
+ {
2928
+ id: "azure_monitor.servicebus.servererrors",
2929
+ source:
2930
+ "azure_monitor ServerErrors (Total) split by EntityName and OperationResult",
2931
+ metricName: "azure_servererrors_total",
2932
+ attributes: {
2933
+ ...SERVICE_BUS_DATAPOINT,
2934
+ metadata_entityname: "invoice-events",
2935
+ metadata_operationresult: "serverbusy",
2936
+ },
2937
+ expected: queue({
2938
+ system: "servicebus",
2939
+ destination: "invoice-events",
2940
+ brokerScope: "billing-prod",
2941
+ }),
2942
+ },
2943
+ {
2944
+ id: "azure_monitor.servicebus.throttledrequests",
2945
+ source:
2946
+ "azure_monitor ThrottledRequests (Total) split by EntityName, OperationResult and MessagingErrorSubCode",
2947
+ metricName: "azure_throttledrequests_total",
2948
+ attributes: {
2949
+ ...SERVICE_BUS_DATAPOINT,
2950
+ metadata_entityname: "invoices",
2951
+ metadata_operationresult: "serverbusy",
2952
+ metadata_messagingerrorsubcode: "CPU",
2953
+ },
2954
+ expected: queue({
2955
+ system: "servicebus",
2956
+ destination: "invoices",
2957
+ brokerScope: "billing-prod",
2958
+ }),
2959
+ },
2960
+ {
2961
+ id: "azure_monitor.servicebus.activemessages.namespace-only",
2962
+ source:
2963
+ "azure_monitor ActiveMessages for the namespace itself (EntityName '-NamespaceOnlyMetric-')",
2964
+ metricName: "azure_activemessages_average",
2965
+ attributes: {
2966
+ ...SERVICE_BUS_DATAPOINT,
2967
+ metadata_entityname: "-NamespaceOnlyMetric-",
2968
+ },
2969
+ expected: null,
2970
+ },
2971
+ {
2972
+ id: "azure_monitor.servicebus.activemessages.mixed-case",
2973
+ source:
2974
+ "azure_monitor ActiveMessages of a namespace and entity created in mixed case",
2975
+ metricName: "azure_activemessages_average",
2976
+ attributes: {
2977
+ ...SERVICE_BUS_DATAPOINT,
2978
+ name: "Billing-Prod",
2979
+ metadata_entityname: "Invoices",
2980
+ },
2981
+ expected: queue({
2982
+ system: "servicebus",
2983
+ destination: "Invoices",
2984
+ brokerScope: "billing-prod",
2985
+ }),
2986
+ },
2987
+ {
2988
+ /*
2989
+ * azure-messaging-servicebus's own meter (research brokerMetrics): its
2990
+ * attributes are renamed by azure-core-metrics-opentelemetry —
2991
+ * hostName → server.address, entityName → messaging.destination.name —
2992
+ * and it sets no messaging.system; the metric name says Service Bus.
2993
+ */
2994
+ id: "azure-sdk-java.servicebus.messages.sent",
2995
+ source:
2996
+ "azure-messaging-servicebus (Java) messaging.servicebus.messages.sent (entity name + namespace host, no messaging.system)",
2997
+ metricName: "messaging.servicebus.messages.sent",
2998
+ attributes: {
2999
+ "server.address": SERVICE_BUS_HOST,
3000
+ "messaging.destination.name": "invoices",
3001
+ "resource.service.name": "billing-worker",
3002
+ "resource.telemetry.sdk.language": "java",
3003
+ },
3004
+ expected: queue({
3005
+ system: "servicebus",
3006
+ destination: "invoices",
3007
+ brokerScope: "billing-prod",
3008
+ direction: "publish",
3009
+ brokerAddress: SERVICE_BUS_HOST,
3010
+ }),
3011
+ },
3012
+ ];
3013
+
3014
+ const EVENT_HUBS_DATAPOINTS: ReadonlyArray<DatapointFixture> = [
3015
+ {
3016
+ id: "azure_monitor.eventhubs.incomingmessages",
3017
+ source:
3018
+ "azure_monitor IncomingMessages (Total) on an Event Hubs namespace (the same name as Service Bus's)",
3019
+ metricName: "azure_incomingmessages_total",
3020
+ attributes: {
3021
+ ...EVENT_HUBS_DATAPOINT,
3022
+ metadata_entityname: "device-telemetry",
3023
+ },
3024
+ expected: queue({
3025
+ system: "eventhubs",
3026
+ destination: "device-telemetry",
3027
+ brokerScope: "telemetry-prod",
3028
+ direction: "publish",
3029
+ }),
3030
+ },
3031
+ {
3032
+ id: "azure_monitor.eventhubs.outgoingmessages",
3033
+ source:
3034
+ "azure_monitor OutgoingMessages (Total), PascalCase dimension key and ARM type casing",
3035
+ metricName: "azure_outgoingmessages_total",
3036
+ attributes: {
3037
+ ...EVENT_HUBS_DATAPOINT,
3038
+ type: "Microsoft.EventHub/Namespaces",
3039
+ metadata_EntityName: "device-telemetry",
3040
+ },
3041
+ expected: queue({
3042
+ system: "eventhubs",
3043
+ destination: "device-telemetry",
3044
+ brokerScope: "telemetry-prod",
3045
+ direction: "consume",
3046
+ }),
3047
+ },
3048
+ {
3049
+ id: "azure_monitor.eventhubs.throttledrequests",
3050
+ source:
3051
+ "azure_monitor ThrottledRequests (Total) on an Event Hubs namespace",
3052
+ metricName: "azure_throttledrequests_total",
3053
+ attributes: {
3054
+ ...EVENT_HUBS_DATAPOINT,
3055
+ metadata_entityname: "device-telemetry",
3056
+ metadata_operationresult: "serverbusy",
3057
+ },
3058
+ expected: queue({
3059
+ system: "eventhubs",
3060
+ destination: "device-telemetry",
3061
+ brokerScope: "telemetry-prod",
3062
+ }),
3063
+ },
3064
+ {
3065
+ id: "azure_monitor.eventhubs.quotaexceedederrors",
3066
+ source: "azure_monitor QuotaExceededErrors (Total)",
3067
+ metricName: "azure_quotaexceedederrors_total",
3068
+ attributes: {
3069
+ ...EVENT_HUBS_DATAPOINT,
3070
+ metadata_entityname: "device-telemetry",
3071
+ metadata_operationresult: "quotaexceeded",
3072
+ },
3073
+ expected: queue({
3074
+ system: "eventhubs",
3075
+ destination: "device-telemetry",
3076
+ brokerScope: "telemetry-prod",
3077
+ }),
3078
+ },
3079
+ {
3080
+ id: "azure_monitor.eventhubs.usererrors",
3081
+ source: "azure_monitor UserErrors (Total) on an Event Hubs namespace",
3082
+ metricName: "azure_usererrors_total",
3083
+ attributes: {
3084
+ ...EVENT_HUBS_DATAPOINT,
3085
+ metadata_entityname: "device-telemetry",
3086
+ metadata_operationresult: "clienterror",
3087
+ },
3088
+ expected: queue({
3089
+ system: "eventhubs",
3090
+ destination: "device-telemetry",
3091
+ brokerScope: "telemetry-prod",
3092
+ }),
3093
+ },
3094
+ {
3095
+ id: "azure-sdk-java.eventhubs.consumer.lag",
3096
+ source:
3097
+ "azure-messaging-eventhubs (Java) messaging.eventhubs.consumer.lag histogram (carries messaging.system)",
3098
+ metricName: "messaging.eventhubs.consumer.lag",
3099
+ attributes: {
3100
+ "messaging.system": "eventhubs",
3101
+ "server.address": EVENT_HUBS_HOST,
3102
+ "messaging.destination.name": "device-telemetry",
3103
+ "messaging.consumer.group.name": "$Default",
3104
+ "messaging.destination.partition.id": "3",
3105
+ },
3106
+ expected: queue({
3107
+ system: "eventhubs",
3108
+ destination: "device-telemetry",
3109
+ brokerScope: "telemetry-prod",
3110
+ consumerGroup: "$Default",
3111
+ brokerAddress: EVENT_HUBS_HOST,
3112
+ }),
3113
+ },
3114
+ {
3115
+ id: "azure-sdk-java.eventhubs.client.published.messages",
3116
+ source:
3117
+ "azure-messaging-eventhubs (Java) messaging.client.published.messages (the pre-1.28 metric name)",
3118
+ metricName: "messaging.client.published.messages",
3119
+ attributes: {
3120
+ "messaging.system": "eventhubs",
3121
+ "server.address": EVENT_HUBS_HOST,
3122
+ "messaging.destination.name": "device-telemetry",
3123
+ "messaging.operation.type": "publish",
3124
+ "messaging.operation.name": "send",
3125
+ "messaging.destination.partition.id": "3",
3126
+ },
3127
+ expected: queue({
3128
+ system: "eventhubs",
3129
+ destination: "device-telemetry",
3130
+ brokerScope: "telemetry-prod",
3131
+ direction: "publish",
3132
+ brokerAddress: EVENT_HUBS_HOST,
3133
+ }),
3134
+ },
3135
+ {
3136
+ id: "azure-sdk-java.eventhubs.client.consumed.messages",
3137
+ source:
3138
+ "azure-messaging-eventhubs (Java) messaging.client.consumed.messages from a processor",
3139
+ metricName: "messaging.client.consumed.messages",
3140
+ attributes: {
3141
+ "messaging.system": "eventhubs",
3142
+ "server.address": EVENT_HUBS_HOST,
3143
+ "messaging.destination.name": "device-telemetry",
3144
+ "messaging.consumer.group.name": "$Default",
3145
+ "messaging.operation.type": "receive",
3146
+ "messaging.operation.name": "receive",
3147
+ "messaging.destination.partition.id": "3",
3148
+ },
3149
+ expected: queue({
3150
+ system: "eventhubs",
3151
+ destination: "device-telemetry",
3152
+ brokerScope: "telemetry-prod",
3153
+ direction: "consume",
3154
+ consumerGroup: "$Default",
3155
+ brokerAddress: EVENT_HUBS_HOST,
3156
+ }),
3157
+ },
3158
+ ];
3159
+
3160
+ const AWS_DATAPOINTS: ReadonlyArray<DatapointFixture> = [
3161
+ {
3162
+ id: "cloudwatch-otel1.sqs.messages-visible",
3163
+ source:
3164
+ "awsfirehose + awscloudwatchmetricstreams_encoding (opentelemetry1.0): Dimensions kvlist flattened",
3165
+ metricName: "amazonaws.com/aws/sqs/approximatenumberofmessagesvisible",
3166
+ attributes: {
3167
+ Namespace: "AWS/SQS",
3168
+ MetricName: "ApproximateNumberOfMessagesVisible",
3169
+ "Dimensions.QueueName": "payment-events",
3170
+ ...CLOUDWATCH_OTEL_RESOURCE,
3171
+ },
3172
+ expected: queue({ system: "aws_sqs", destination: "payment-events" }),
3173
+ },
3174
+ {
3175
+ id: "aws_cloudwatch.sqs.age-of-oldest-message.stat",
3176
+ source:
3177
+ "aws_cloudwatch pull receiver with `stats` configured (a Gauge per statistic, tagged with `stat`)",
3178
+ metricName: "amazonaws.com/aws/sqs/approximateageofoldestmessage",
3179
+ attributes: {
3180
+ Namespace: "AWS/SQS",
3181
+ MetricName: "ApproximateAgeOfOldestMessage",
3182
+ "Dimensions.QueueName": "payment-events",
3183
+ stat: "Maximum",
3184
+ "resource.cloud.provider": "aws",
3185
+ "resource.cloud.region": "eu-west-1",
3186
+ },
3187
+ expected: queue({ system: "aws_sqs", destination: "payment-events" }),
3188
+ },
3189
+ {
3190
+ id: "cloudwatch-otel1.sqs.messages-sent",
3191
+ source: "Metric Stream (opentelemetry1.0) NumberOfMessagesSent",
3192
+ metricName: "amazonaws.com/aws/sqs/numberofmessagessent",
3193
+ attributes: {
3194
+ Namespace: "AWS/SQS",
3195
+ MetricName: "NumberOfMessagesSent",
3196
+ "Dimensions.QueueName": "payment-events",
3197
+ ...CLOUDWATCH_OTEL_RESOURCE,
3198
+ },
3199
+ expected: queue({
3200
+ system: "aws_sqs",
3201
+ destination: "payment-events",
3202
+ direction: "publish",
3203
+ }),
3204
+ },
3205
+ {
3206
+ id: "cloudwatch-otel1.sqs.messages-deleted",
3207
+ source: "Metric Stream (opentelemetry1.0) NumberOfMessagesDeleted",
3208
+ metricName: "amazonaws.com/aws/sqs/numberofmessagesdeleted",
3209
+ attributes: {
3210
+ Namespace: "AWS/SQS",
3211
+ MetricName: "NumberOfMessagesDeleted",
3212
+ "Dimensions.QueueName": "payment-events",
3213
+ ...CLOUDWATCH_OTEL_RESOURCE,
3214
+ },
3215
+ expected: queue({
3216
+ system: "aws_sqs",
3217
+ destination: "payment-events",
3218
+ direction: "consume",
3219
+ }),
3220
+ },
3221
+ {
3222
+ id: "cloudwatch-json.sqs.messages-visible",
3223
+ source:
3224
+ "awsfirehose + encoding (json): the bare CloudWatch name, plain QueueName, service.name=SQS on the resource",
3225
+ metricName: "approximatenumberofmessagesvisible",
3226
+ attributes: {
3227
+ QueueName: "payment-events",
3228
+ ...cloudWatchJsonResource("SQS"),
3229
+ },
3230
+ expected: queue({ system: "aws_sqs", destination: "payment-events" }),
3231
+ },
3232
+ {
3233
+ id: "cloudwatch-json.sqs.messages-received",
3234
+ source: "Metric Stream (json) NumberOfMessagesReceived",
3235
+ metricName: "numberofmessagesreceived",
3236
+ attributes: {
3237
+ QueueName: "payment-events",
3238
+ ...cloudWatchJsonResource("SQS"),
3239
+ },
3240
+ expected: queue({
3241
+ system: "aws_sqs",
3242
+ destination: "payment-events",
3243
+ direction: "consume",
3244
+ }),
3245
+ },
3246
+ {
3247
+ id: "cloudwatch-json.sqs.messages-not-visible",
3248
+ source: "Metric Stream (json) ApproximateNumberOfMessagesNotVisible",
3249
+ metricName: "approximatenumberofmessagesnotvisible",
3250
+ attributes: {
3251
+ QueueName: "payment-events",
3252
+ ...cloudWatchJsonResource("SQS"),
3253
+ },
3254
+ expected: queue({ system: "aws_sqs", destination: "payment-events" }),
3255
+ },
3256
+ {
3257
+ id: "cloudwatch-json.sqs.dead-letter-queue",
3258
+ source:
3259
+ "Metric Stream (json) ApproximateNumberOfMessagesVisible of a DLQ (an ordinary queue: no DLQ dimension)",
3260
+ metricName: "approximatenumberofmessagesvisible",
3261
+ attributes: {
3262
+ QueueName: "payment-events-dlq",
3263
+ ...cloudWatchJsonResource("SQS"),
3264
+ },
3265
+ expected: queue({ system: "aws_sqs", destination: "payment-events-dlq" }),
3266
+ },
3267
+ {
3268
+ id: "cloudwatch-otel1.sns.messages-published",
3269
+ source: "Metric Stream (opentelemetry1.0) SNS NumberOfMessagesPublished",
3270
+ metricName: "amazonaws.com/aws/sns/numberofmessagespublished",
3271
+ attributes: {
3272
+ Namespace: "AWS/SNS",
3273
+ MetricName: "NumberOfMessagesPublished",
3274
+ "Dimensions.TopicName": "payment-notifications",
3275
+ ...CLOUDWATCH_OTEL_RESOURCE,
3276
+ },
3277
+ expected: queue({
3278
+ system: "aws.sns",
3279
+ destination: "payment-notifications",
3280
+ direction: "publish",
3281
+ }),
3282
+ },
3283
+ {
3284
+ id: "cloudwatch-otel1.sns.notifications-failed",
3285
+ source: "Metric Stream (opentelemetry1.0) SNS NumberOfNotificationsFailed",
3286
+ metricName: "amazonaws.com/aws/sns/numberofnotificationsfailed",
3287
+ attributes: {
3288
+ Namespace: "AWS/SNS",
3289
+ MetricName: "NumberOfNotificationsFailed",
3290
+ "Dimensions.TopicName": "payment-notifications",
3291
+ ...CLOUDWATCH_OTEL_RESOURCE,
3292
+ },
3293
+ expected: queue({
3294
+ system: "aws.sns",
3295
+ destination: "payment-notifications",
3296
+ }),
3297
+ },
3298
+ {
3299
+ id: "cloudwatch-json.sns.notifications-delivered",
3300
+ source:
3301
+ "Metric Stream (json) SNS NumberOfNotificationsDelivered (service.name=SNS)",
3302
+ metricName: "numberofnotificationsdelivered",
3303
+ attributes: {
3304
+ TopicName: "payment-notifications",
3305
+ ...cloudWatchJsonResource("SNS"),
3306
+ },
3307
+ expected: queue({
3308
+ system: "aws.sns",
3309
+ destination: "payment-notifications",
3310
+ direction: "consume",
3311
+ }),
3312
+ },
3313
+ {
3314
+ id: "cloudwatch-json.sns.redriven-to-dlq",
3315
+ source: "Metric Stream (json) SNS NumberOfNotificationsRedrivenToDlq",
3316
+ metricName: "numberofnotificationsredriventodlq",
3317
+ attributes: {
3318
+ TopicName: "payment-notifications",
3319
+ ...cloudWatchJsonResource("SNS"),
3320
+ },
3321
+ expected: queue({
3322
+ system: "aws.sns",
3323
+ destination: "payment-notifications",
3324
+ }),
3325
+ },
3326
+ {
3327
+ id: "cloudwatch-otel1.sns.mobile-push-dimensions",
3328
+ source:
3329
+ "Metric Stream (opentelemetry1.0) SNS NumberOfNotificationsDelivered for a push application (Application/Platform dimensions, no TopicName)",
3330
+ metricName: "amazonaws.com/aws/sns/numberofnotificationsdelivered",
3331
+ attributes: {
3332
+ Namespace: "AWS/SNS",
3333
+ MetricName: "NumberOfNotificationsDelivered",
3334
+ "Dimensions.Application": "billing-app",
3335
+ "Dimensions.Platform": "GCM",
3336
+ ...CLOUDWATCH_OTEL_RESOURCE,
3337
+ },
3338
+ expected: null,
3339
+ },
3340
+ ];
3341
+
3342
+ const PUBSUB_DATAPOINTS: ReadonlyArray<DatapointFixture> = [
3343
+ {
3344
+ id: "googlecloudmonitoring.subscription.num-undelivered",
3345
+ source:
3346
+ "googlecloudmonitoring num_undelivered_messages (monitored-resource labels on the resource)",
3347
+ metricName: "pubsub.googleapis.com/subscription/num_undelivered_messages",
3348
+ attributes: {
3349
+ "resource.gcp.resource_type": "pubsub_subscription",
3350
+ "resource.project_id": "shop-prod",
3351
+ "resource.subscription_id": "orders-billing",
3352
+ },
3353
+ expected: queue({ system: "gcp_pubsub", destination: "orders-billing" }),
3354
+ },
3355
+ {
3356
+ id: "googlecloudmonitoring.subscription.oldest-unacked-age",
3357
+ source: "googlecloudmonitoring oldest_unacked_message_age",
3358
+ metricName: "pubsub.googleapis.com/subscription/oldest_unacked_message_age",
3359
+ attributes: {
3360
+ "resource.gcp.resource_type": "pubsub_subscription",
3361
+ "resource.project_id": "shop-prod",
3362
+ "resource.subscription_id": "orders-billing",
3363
+ },
3364
+ expected: queue({ system: "gcp_pubsub", destination: "orders-billing" }),
3365
+ },
3366
+ {
3367
+ id: "googlecloudmonitoring.subscription.dead-letter-count",
3368
+ source:
3369
+ "googlecloudmonitoring dead_letter_message_count (collector 0.137+: response_code on the datapoint)",
3370
+ metricName: "pubsub.googleapis.com/subscription/dead_letter_message_count",
3371
+ attributes: {
3372
+ response_code: "success",
3373
+ "resource.gcp.resource_type": "pubsub_subscription",
3374
+ "resource.project_id": "shop-prod",
3375
+ "resource.subscription_id": "orders-billing",
3376
+ },
3377
+ expected: queue({ system: "gcp_pubsub", destination: "orders-billing" }),
3378
+ },
3379
+ {
3380
+ id: "googlecloudmonitoring.subscription.ack-count.resource-labels",
3381
+ source:
3382
+ "googlecloudmonitoring ack_message_count from collector 0.116-0.136 (metric label on the RESOURCE)",
3383
+ metricName: "pubsub.googleapis.com/subscription/ack_message_count",
3384
+ attributes: {
3385
+ "resource.delivery_type": "pull",
3386
+ "resource.gcp.resource_type": "pubsub_subscription",
3387
+ "resource.project_id": "shop-prod",
3388
+ "resource.subscription_id": "orders-billing",
3389
+ },
3390
+ expected: queue({
3391
+ system: "gcp_pubsub",
3392
+ destination: "orders-billing",
3393
+ direction: "consume",
3394
+ }),
3395
+ },
3396
+ {
3397
+ id: "googlecloudmonitoring.topic.send-request-count",
3398
+ source:
3399
+ "googlecloudmonitoring topic send_request_count (pubsub_topic resource)",
3400
+ metricName: "pubsub.googleapis.com/topic/send_request_count",
3401
+ attributes: {
3402
+ response_class: "success",
3403
+ response_code: "OK",
3404
+ "resource.gcp.resource_type": "pubsub_topic",
3405
+ "resource.project_id": "shop-prod",
3406
+ "resource.topic_id": "orders",
3407
+ },
3408
+ expected: queue({
3409
+ system: "gcp_pubsub",
3410
+ destination: "orders",
3411
+ direction: "publish",
3412
+ }),
3413
+ },
3414
+ ];
3415
+
3416
+ const PULSAR_ROCKETMQ_NATS_DATAPOINTS: ReadonlyArray<DatapointFixture> = [
3417
+ {
3418
+ id: "prometheus.pulsar_msg_backlog",
3419
+ source:
3420
+ "prometheus receiver scraping a Pulsar broker's /metrics/ (a partition of a partitioned topic; live capture, Pulsar 4.2)",
3421
+ metricName: "pulsar_msg_backlog",
3422
+ attributes: {
3423
+ cluster: "pulsar-prod",
3424
+ namespace: "public/default",
3425
+ topic: "persistent://public/default/payments-partition-1",
3426
+ ...PULSAR_RESOURCE,
3427
+ },
3428
+ expected: queue({
3429
+ system: "pulsar",
3430
+ destination: "persistent://public/default/payments",
3431
+ brokerAddress: PULSAR_BROKER_ADDRESS,
3432
+ }),
3433
+ },
3434
+ {
3435
+ id: "prometheus.pulsar_msg_backlog.split-partition-label",
3436
+ source:
3437
+ "Pulsar with splitTopicAndPartitionLabelInPrometheus=true (partition in its own label)",
3438
+ metricName: "pulsar_msg_backlog",
3439
+ attributes: {
3440
+ cluster: "pulsar-prod",
3441
+ namespace: "public/default",
3442
+ topic: "persistent://public/default/payments",
3443
+ partition: "1",
3444
+ ...PULSAR_RESOURCE,
3445
+ },
3446
+ expected: queue({
3447
+ system: "pulsar",
3448
+ destination: "persistent://public/default/payments",
3449
+ brokerAddress: PULSAR_BROKER_ADDRESS,
3450
+ }),
3451
+ },
3452
+ {
3453
+ id: "prometheus.pulsar_subscription_back_log",
3454
+ source: "Pulsar subscription backlog (topic + subscription labels)",
3455
+ metricName: "pulsar_subscription_back_log",
3456
+ attributes: {
3457
+ cluster: "pulsar-prod",
3458
+ namespace: "public/default",
3459
+ subscription: "ledger",
3460
+ topic: "persistent://public/default/payments-partition-0",
3461
+ ...PULSAR_RESOURCE,
3462
+ },
3463
+ expected: queue({
3464
+ system: "pulsar",
3465
+ destination: "persistent://public/default/payments",
3466
+ brokerAddress: PULSAR_BROKER_ADDRESS,
3467
+ }),
3468
+ },
3469
+ {
3470
+ id: "prometheus.pulsar_storage_backlog_age_seconds",
3471
+ source: "Pulsar backlog age (-1 while unknown)",
3472
+ metricName: "pulsar_storage_backlog_age_seconds",
3473
+ attributes: {
3474
+ cluster: "pulsar-prod",
3475
+ namespace: "public/default",
3476
+ topic: "persistent://public/default/orders",
3477
+ ...PULSAR_RESOURCE,
3478
+ },
3479
+ expected: queue({
3480
+ system: "pulsar",
3481
+ destination: "persistent://public/default/orders",
3482
+ brokerAddress: PULSAR_BROKER_ADDRESS,
3483
+ }),
3484
+ },
3485
+ {
3486
+ id: "prometheus.pulsar_in_messages_total",
3487
+ source:
3488
+ "Pulsar messages in (declared `# TYPE gauge`, holds a running total)",
3489
+ metricName: "pulsar_in_messages_total",
3490
+ attributes: {
3491
+ cluster: "pulsar-prod",
3492
+ namespace: "public/default",
3493
+ topic: "persistent://public/default/orders",
3494
+ ...PULSAR_RESOURCE,
3495
+ },
3496
+ expected: queue({
3497
+ system: "pulsar",
3498
+ destination: "persistent://public/default/orders",
3499
+ direction: "publish",
3500
+ brokerAddress: PULSAR_BROKER_ADDRESS,
3501
+ }),
3502
+ },
3503
+ {
3504
+ id: "prometheus.pulsar_out_messages_total",
3505
+ source: "Pulsar messages out, per subscription",
3506
+ metricName: "pulsar_out_messages_total",
3507
+ attributes: {
3508
+ cluster: "pulsar-prod",
3509
+ namespace: "public/default",
3510
+ subscription: "billing",
3511
+ topic: "persistent://public/default/orders",
3512
+ ...PULSAR_RESOURCE,
3513
+ },
3514
+ expected: queue({
3515
+ system: "pulsar",
3516
+ destination: "persistent://public/default/orders",
3517
+ direction: "consume",
3518
+ brokerAddress: PULSAR_BROKER_ADDRESS,
3519
+ }),
3520
+ },
3521
+ {
3522
+ id: "prometheus.pulsar_subscription_back_log.system-topic",
3523
+ source:
3524
+ "Pulsar compaction subscription on the __change_events system topic (live capture)",
3525
+ metricName: "pulsar_subscription_back_log",
3526
+ attributes: {
3527
+ cluster: "pulsar-prod",
3528
+ namespace: "public/default",
3529
+ subscription: "__compaction",
3530
+ topic: "persistent://public/default/__change_events",
3531
+ ...PULSAR_RESOURCE,
3532
+ },
3533
+ expected: null,
3534
+ },
3535
+ {
3536
+ id: "prometheus.rocketmq_consumer_lag_messages",
3537
+ source:
3538
+ "prometheus receiver scraping a RocketMQ 5 broker (metricsExporterType=PROM, :5557)",
3539
+ metricName: "rocketmq_consumer_lag_messages",
3540
+ attributes: {
3541
+ topic: "order-topic",
3542
+ consumer_group: "order-consumer-group",
3543
+ is_retry: "false",
3544
+ is_system: "false",
3545
+ cluster: "DefaultCluster",
3546
+ node_type: "broker",
3547
+ node_id: "broker-a",
3548
+ ...ROCKETMQ_RESOURCE,
3549
+ },
3550
+ expected: queue({
3551
+ system: "rocketmq",
3552
+ destination: "order-topic",
3553
+ brokerAddress: ROCKETMQ_BROKER_ADDRESS,
3554
+ }),
3555
+ },
3556
+ {
3557
+ id: "prometheus.rocketmq_consumer_ready_messages",
3558
+ source: "RocketMQ 5 broker ready messages",
3559
+ metricName: "rocketmq_consumer_ready_messages",
3560
+ attributes: {
3561
+ topic: "order-topic",
3562
+ consumer_group: "order-consumer-group",
3563
+ is_retry: "false",
3564
+ is_system: "false",
3565
+ cluster: "DefaultCluster",
3566
+ node_type: "broker",
3567
+ node_id: "broker-a",
3568
+ ...ROCKETMQ_RESOURCE,
3569
+ },
3570
+ expected: queue({
3571
+ system: "rocketmq",
3572
+ destination: "order-topic",
3573
+ brokerAddress: ROCKETMQ_BROKER_ADDRESS,
3574
+ }),
3575
+ },
3576
+ {
3577
+ id: "prometheus.rocketmq_send_to_dlq_messages_total",
3578
+ source:
3579
+ "RocketMQ 5 broker messages sent to a group's DLQ, counted under the ORIGIN topic",
3580
+ metricName: "rocketmq_send_to_dlq_messages_total",
3581
+ attributes: {
3582
+ topic: "order-topic",
3583
+ consumer_group: "order-consumer-group",
3584
+ is_system: "false",
3585
+ cluster: "DefaultCluster",
3586
+ node_type: "broker",
3587
+ node_id: "broker-a",
3588
+ ...ROCKETMQ_RESOURCE,
3589
+ },
3590
+ expected: queue({
3591
+ system: "rocketmq",
3592
+ destination: "order-topic",
3593
+ brokerAddress: ROCKETMQ_BROKER_ADDRESS,
3594
+ }),
3595
+ },
3596
+ {
3597
+ id: "prometheus.rocketmq_messages_in_total",
3598
+ source: "RocketMQ 5 broker messages in",
3599
+ metricName: "rocketmq_messages_in_total",
3600
+ attributes: {
3601
+ topic: "order-topic",
3602
+ message_type: "Normal",
3603
+ is_system: "false",
3604
+ cluster: "DefaultCluster",
3605
+ node_type: "broker",
3606
+ node_id: "broker-a",
3607
+ ...ROCKETMQ_RESOURCE,
3608
+ },
3609
+ expected: queue({
3610
+ system: "rocketmq",
3611
+ destination: "order-topic",
3612
+ direction: "publish",
3613
+ brokerAddress: ROCKETMQ_BROKER_ADDRESS,
3614
+ }),
3615
+ },
3616
+ {
3617
+ id: "prometheus.rocketmq_consumer_lag_messages.dead-letter-topic",
3618
+ source:
3619
+ "RocketMQ 5 broker lag on a consumer group's dead-letter topic (%DLQ%<group>)",
3620
+ metricName: "rocketmq_consumer_lag_messages",
3621
+ attributes: {
3622
+ topic: "%DLQ%order-consumer-group",
3623
+ consumer_group: "order-dlq-drainer",
3624
+ is_retry: "false",
3625
+ is_system: "false",
3626
+ cluster: "DefaultCluster",
3627
+ node_type: "broker",
3628
+ node_id: "broker-a",
3629
+ ...ROCKETMQ_RESOURCE,
3630
+ },
3631
+ expected: queue({
3632
+ system: "rocketmq",
3633
+ destination: "%DLQ%order-consumer-group",
3634
+ brokerAddress: ROCKETMQ_BROKER_ADDRESS,
3635
+ isDeadLetter: true,
3636
+ }),
3637
+ },
3638
+ {
3639
+ id: "prometheus.jetstream_consumer_num_pending",
3640
+ source:
3641
+ "prometheus-nats-exporter JetStream consumer pending (per stream and consumer, not per subject; live capture)",
3642
+ metricName: "jetstream_consumer_num_pending",
3643
+ attributes: {
3644
+ account: "$G",
3645
+ account_id: "$G",
3646
+ account_name: "$G",
3647
+ consumer_name: "billing",
3648
+ is_consumer_leader: "true",
3649
+ is_meta_leader: "true",
3650
+ is_stream_leader: "true",
3651
+ server_id: "http://nats-0.nats:8222",
3652
+ server_name: "NBGQRQA4BN5NA7ADQLKR3AS5EEBBLIMUPAXQ3SIHW7UH3DQPJX5OMAR4",
3653
+ stream_leader: "NBGQRQA4BN5NA7ADQLKR3AS5EEBBLIMUPAXQ3SIHW7UH3DQPJX5OMAR4",
3654
+ stream_name: "ORDERS",
3655
+ ...prometheusResource("nats", "nats-exporter", "7777"),
3656
+ },
3657
+ expected: null,
3658
+ },
3659
+ ];
3660
+
3661
+ const CLIENT_AND_APPLICATION_DATAPOINTS: ReadonlyArray<DatapointFixture> = [
3662
+ {
3663
+ id: "kafkajs.client.sent.messages",
3664
+ source:
3665
+ "@opentelemetry/instrumentation-kafkajs messaging.client.sent.messages",
3666
+ metricName: "messaging.client.sent.messages",
3667
+ attributes: {
3668
+ "messaging.system": "kafka",
3669
+ "messaging.operation.name": "send",
3670
+ "messaging.destination.name": "payments",
3671
+ "messaging.destination.partition.id": "1",
3672
+ },
3673
+ expected: queue({
3674
+ system: "kafka",
3675
+ destination: "payments",
3676
+ direction: "publish",
3677
+ }),
3678
+ },
3679
+ {
3680
+ id: "kafkajs.client.consumed.messages",
3681
+ source:
3682
+ "@opentelemetry/instrumentation-kafkajs messaging.client.consumed.messages",
3683
+ metricName: "messaging.client.consumed.messages",
3684
+ attributes: {
3685
+ "messaging.system": "kafka",
3686
+ "messaging.operation.name": "process",
3687
+ "messaging.destination.name": "payments",
3688
+ "messaging.destination.partition.id": "0",
3689
+ },
3690
+ expected: queue({
3691
+ system: "kafka",
3692
+ destination: "payments",
3693
+ direction: "consume",
3694
+ }),
3695
+ },
3696
+ {
3697
+ id: "kafkajs.process.duration",
3698
+ source: "@opentelemetry/instrumentation-kafkajs messaging.process.duration",
3699
+ metricName: "messaging.process.duration",
3700
+ attributes: {
3701
+ "messaging.system": "kafka",
3702
+ "messaging.operation.name": "process",
3703
+ "messaging.destination.name": "payments",
3704
+ "messaging.destination.partition.id": "0",
3705
+ },
3706
+ expected: queue({
3707
+ system: "kafka",
3708
+ destination: "payments",
3709
+ direction: "consume",
3710
+ }),
3711
+ },
3712
+ {
3713
+ id: "kafkajs.client.operation.duration.request",
3714
+ source:
3715
+ "@opentelemetry/instrumentation-kafkajs request duration (broker API name, no topic)",
3716
+ metricName: "messaging.client.operation.duration",
3717
+ attributes: {
3718
+ "messaging.system": "kafka",
3719
+ "messaging.operation.name": "Fetch",
3720
+ "server.address": "kafka-0.kafka-headless",
3721
+ "server.port": 9092,
3722
+ },
3723
+ expected: null,
3724
+ },
3725
+ {
3726
+ id: "java-agent.default.publish.duration",
3727
+ source:
3728
+ "Java agent default mode messaging.publish.duration (deprecated name; no address for Kafka)",
3729
+ metricName: "messaging.publish.duration",
3730
+ attributes: {
3731
+ "messaging.system": "kafka",
3732
+ "messaging.destination.name": "payments",
3733
+ "messaging.operation": "publish",
3734
+ "messaging.destination.partition.id": "2",
3735
+ },
3736
+ expected: queue({
3737
+ system: "kafka",
3738
+ destination: "payments",
3739
+ direction: "publish",
3740
+ }),
3741
+ },
3742
+ {
3743
+ id: "java-agent.default.receive.messages",
3744
+ source: "Java agent default mode messaging.receive.messages",
3745
+ metricName: "messaging.receive.messages",
3746
+ attributes: {
3747
+ "messaging.system": "kafka",
3748
+ "messaging.destination.name": "payments",
3749
+ "messaging.operation": "receive",
3750
+ "messaging.destination.partition.id": "0",
3751
+ },
3752
+ expected: queue({
3753
+ system: "kafka",
3754
+ destination: "payments",
3755
+ direction: "consume",
3756
+ }),
3757
+ },
3758
+ /*
3759
+ * The Java agent's opt-in client metrics keep what MessagingMetricsAdvice
3760
+ * lists for each instrument: the operation NAME on all four, the
3761
+ * operation type on messaging.client.operation.duration alone, never a
3762
+ * routing key.
3763
+ */
3764
+ {
3765
+ id: "java-agent.opt-in.client.consumed.messages",
3766
+ source:
3767
+ "Java agent opt-in messaging.client.consumed.messages (consumer group on the datapoint)",
3768
+ metricName: "messaging.client.consumed.messages",
3769
+ attributes: {
3770
+ "messaging.operation.name": "process",
3771
+ "messaging.system": "kafka",
3772
+ "messaging.consumer.group.name": "billing",
3773
+ "messaging.destination.name": "payments",
3774
+ "messaging.destination.partition.id": "0",
3775
+ },
3776
+ expected: queue({
3777
+ system: "kafka",
3778
+ destination: "payments",
3779
+ direction: "consume",
3780
+ consumerGroup: "billing",
3781
+ }),
3782
+ },
3783
+ {
3784
+ id: "java-agent.opt-in.client.sent.messages.nats-inbox",
3785
+ source:
3786
+ "Java agent opt-in messaging.client.sent.messages to a NATS inbox (the advice drops the name, keeps the template)",
3787
+ metricName: "messaging.client.sent.messages",
3788
+ attributes: {
3789
+ "messaging.operation.name": "publish",
3790
+ "messaging.system": "nats",
3791
+ "messaging.destination.template": "_INBOX.",
3792
+ },
3793
+ expected: null,
3794
+ },
3795
+ {
3796
+ id: "java-agent.opt-in.client.operation.duration.rabbitmq-publish",
3797
+ source:
3798
+ "Java agent opt-in messaging.client.operation.duration of a RabbitMQ publish (no routing-key key on metrics)",
3799
+ metricName: "messaging.client.operation.duration",
3800
+ attributes: {
3801
+ "messaging.operation.name": "publish",
3802
+ "messaging.system": "rabbitmq",
3803
+ "messaging.destination.name": "orders.topic:orders.eu.created",
3804
+ "messaging.operation.type": "send",
3805
+ "server.address": "rabbitmq.internal",
3806
+ "server.port": 5672,
3807
+ },
3808
+ expected: queue({
3809
+ system: "rabbitmq",
3810
+ destination: "orders.topic",
3811
+ direction: "publish",
3812
+ brokerAddress: "rabbitmq.internal:5672",
3813
+ }),
3814
+ },
3815
+ {
3816
+ id: "java-agent.opt-in.client.sent.messages.rabbitmq-publish",
3817
+ source:
3818
+ "Java agent opt-in messaging.client.sent.messages of the same RabbitMQ publish (the operation name, no operation type)",
3819
+ metricName: "messaging.client.sent.messages",
3820
+ attributes: {
3821
+ "messaging.operation.name": "publish",
3822
+ "messaging.system": "rabbitmq",
3823
+ "messaging.destination.name": "orders.topic:orders.eu.created",
3824
+ "server.address": "rabbitmq.internal",
3825
+ "server.port": 5672,
3826
+ },
3827
+ expected: queue({
3828
+ system: "rabbitmq",
3829
+ destination: "orders.topic",
3830
+ direction: "publish",
3831
+ brokerAddress: "rabbitmq.internal:5672",
3832
+ }),
3833
+ },
3834
+ {
3835
+ id: "java-agent.opt-in.process.duration.rabbitmq-consumer",
3836
+ source:
3837
+ "Java agent opt-in messaging.process.duration of a RabbitMQ consumer ('direct_logs:warning': routing key == queue; the operation name, no operation type)",
3838
+ metricName: "messaging.process.duration",
3839
+ attributes: {
3840
+ "messaging.operation.name": "process",
3841
+ "messaging.system": "rabbitmq",
3842
+ "messaging.destination.name": "direct_logs:warning",
3843
+ },
3844
+ expected: queue({
3845
+ system: "rabbitmq",
3846
+ destination: "warning",
3847
+ direction: "consume",
3848
+ }),
3849
+ },
3850
+ {
3851
+ id: "java-agent.opt-in.client.consumed.messages.rabbitmq-fanout",
3852
+ source:
3853
+ "Java agent opt-in messaging.client.consumed.messages of a RabbitMQ delivery from a fanout exchange ('logs:logs-audit': the empty routing key left out)",
3854
+ metricName: "messaging.client.consumed.messages",
3855
+ attributes: {
3856
+ "messaging.operation.name": "process",
3857
+ "messaging.system": "rabbitmq",
3858
+ "messaging.destination.name": "logs:logs-audit",
3859
+ },
3860
+ expected: queue({
3861
+ system: "rabbitmq",
3862
+ destination: "logs-audit",
3863
+ direction: "consume",
3864
+ }),
3865
+ },
3866
+ {
3867
+ id: "oneuptime.queue.size.waiting",
3868
+ source:
3869
+ "OneUptime's own BullMQ queue.size observable gauge (Queue.ts), waiting jobs",
3870
+ metricName: "queue.size",
3871
+ attributes: {
3872
+ "messaging.system": "bullmq",
3873
+ "messaging.destination.name": "Worker",
3874
+ state: "waiting",
3875
+ "resource.service.name": "app",
3876
+ },
3877
+ expected: queue({ system: "bullmq", destination: "Worker" }),
3878
+ },
3879
+ {
3880
+ id: "oneuptime.queue.size.failed",
3881
+ source: "OneUptime's own BullMQ queue.size, failed jobs",
3882
+ metricName: "queue.size",
3883
+ attributes: {
3884
+ "messaging.system": "bullmq",
3885
+ "messaging.destination.name": "Worker",
3886
+ state: "failed",
3887
+ "resource.service.name": "app",
3888
+ },
3889
+ expected: queue({ system: "bullmq", destination: "Worker" }),
3890
+ },
3891
+ {
3892
+ id: "oneuptime.worker.job.count",
3893
+ source:
3894
+ "OneUptime's own worker.job.count (QueueWorker.ts: job name in messaging.operation.name, outcome)",
3895
+ metricName: "worker.job.count",
3896
+ attributes: {
3897
+ "messaging.system": "bullmq",
3898
+ "messaging.destination.name": "Telemetry",
3899
+ "messaging.operation.name": "IngestTelemetryBatch",
3900
+ outcome: "success",
3901
+ "resource.service.name": "app",
3902
+ },
3903
+ expected: queue({ system: "bullmq", destination: "Telemetry" }),
3904
+ },
3905
+ {
3906
+ id: "oneuptime.worker.job.duration",
3907
+ source: "OneUptime's own worker.job.duration of a failed Workflow job",
3908
+ metricName: "worker.job.duration",
3909
+ attributes: {
3910
+ "messaging.system": "bullmq",
3911
+ "messaging.destination.name": "Workflow",
3912
+ "messaging.operation.name": "RunWorkflow",
3913
+ outcome: "failure",
3914
+ "resource.service.name": "app",
3915
+ },
3916
+ expected: queue({ system: "bullmq", destination: "Workflow" }),
3917
+ },
3918
+ {
3919
+ id: "oneuptime.worker.job.active",
3920
+ source: "OneUptime's own worker.job.active up-down counter",
3921
+ metricName: "worker.job.active",
3922
+ attributes: {
3923
+ "messaging.system": "bullmq",
3924
+ "messaging.destination.name": "Runbook",
3925
+ "messaging.operation.name": "ExecuteRunbook",
3926
+ "resource.service.name": "app",
3927
+ },
3928
+ expected: queue({ system: "bullmq", destination: "Runbook" }),
3929
+ },
3930
+ ];
3931
+
3932
+ const DATAPOINTS: ReadonlyArray<DatapointFixture> = [
3933
+ ...KAFKA_DATAPOINTS,
3934
+ ...RABBITMQ_DATAPOINTS,
3935
+ ...ACTIVEMQ_DATAPOINTS,
3936
+ ...SERVICE_BUS_DATAPOINTS,
3937
+ ...EVENT_HUBS_DATAPOINTS,
3938
+ ...AWS_DATAPOINTS,
3939
+ ...PUBSUB_DATAPOINTS,
3940
+ ...PULSAR_ROCKETMQ_NATS_DATAPOINTS,
3941
+ ...CLIENT_AND_APPLICATION_DATAPOINTS,
3942
+ ];
3943
+
3944
+ // ---- the same queue seen by an application and by its broker -------------
3945
+
3946
+ const SAME_QUEUE_PAIRS: ReadonlyArray<SameQueuePair> = [
3947
+ {
3948
+ queue: "Kafka topic, Java agent consumer vs kafka_metrics lag",
3949
+ spanId: "kafka.java-agent.default.process",
3950
+ datapointId: "kafka_metrics.lag_sum",
3951
+ identity: { system: "kafka", brokerScope: "", destination: "payments" },
3952
+ },
3953
+ {
3954
+ queue:
3955
+ "Kafka topic, Confluent .NET poll vs kafka_metrics lag (no resource)",
3956
+ spanId: "kafka.confluent-dotnet.poll",
3957
+ datapointId: "kafka_metrics.lag_sum.no-resource",
3958
+ identity: { system: "kafka", brokerScope: "", destination: "payments" },
3959
+ },
3960
+ {
3961
+ queue: "Kafka topic, Confluent .NET send vs log-end offset",
3962
+ spanId: "kafka.confluent-dotnet.send",
3963
+ datapointId: "kafka_metrics.current_offset",
3964
+ identity: { system: "kafka", brokerScope: "", destination: "payments" },
3965
+ },
3966
+ {
3967
+ queue: "Kafka topic named by UUID, templated on both sides",
3968
+ spanId: "kafka.java-agent.default.send.uuid-topic",
3969
+ datapointId: "kafka_metrics.lag_sum.uuid-topic",
3970
+ identity: {
3971
+ system: "kafka",
3972
+ brokerScope: "",
3973
+ destination: UUID_TOPIC_TEMPLATED,
3974
+ },
3975
+ },
3976
+ {
3977
+ queue: "RabbitMQ queue, Java agent default-exchange delivery vs depth",
3978
+ spanId: "rabbitmq.java-agent.default.process.default-exchange",
3979
+ datapointId: "rabbitmq.message.current.ready",
3980
+ identity: { system: "rabbitmq", brokerScope: "", destination: "invoices" },
3981
+ },
3982
+ {
3983
+ queue:
3984
+ "RabbitMQ queue, Java agent opt-in default-exchange publish vs depth",
3985
+ spanId: "rabbitmq.java-agent.opt-in.publish.default-exchange",
3986
+ datapointId: "rabbitmq.message.current.unacknowledged",
3987
+ identity: { system: "rabbitmq", brokerScope: "", destination: "invoices" },
3988
+ },
3989
+ {
3990
+ queue: "RabbitMQ queue, .NET v7 deliver vs acknowledged",
3991
+ spanId: "rabbitmq.dotnet-v7.deliver.default-exchange",
3992
+ datapointId: "rabbitmq.message.acknowledged",
3993
+ identity: { system: "rabbitmq", brokerScope: "", destination: "invoices" },
3994
+ },
3995
+ {
3996
+ queue: "RabbitMQ queue, amqplib default-exchange publish vs published",
3997
+ spanId: "rabbitmq.amqplib.publish.default-exchange",
3998
+ datapointId: "rabbitmq.message.published",
3999
+ identity: { system: "rabbitmq", brokerScope: "", destination: "invoices" },
4000
+ },
4001
+ {
4002
+ queue: "RabbitMQ queue, pika publish vs published",
4003
+ spanId: "rabbitmq.pika.publish.default-exchange",
4004
+ datapointId: "rabbitmq.message.published",
4005
+ identity: { system: "rabbitmq", brokerScope: "", destination: "invoices" },
4006
+ },
4007
+ {
4008
+ queue: "RabbitMQ queue, aio-pika consume vs delivered",
4009
+ spanId: "rabbitmq.aio-pika.consume.default-exchange",
4010
+ datapointId: "rabbitmq.message.delivered",
4011
+ identity: { system: "rabbitmq", brokerScope: "", destination: "invoices" },
4012
+ },
4013
+ {
4014
+ queue:
4015
+ "RabbitMQ queue, Java agent opt-in consumer 'direct_logs:warning' vs the 'warning' queue's depth",
4016
+ spanId: "rabbitmq.java-agent.opt-in.process.routing-key-is-queue",
4017
+ datapointId: "rabbitmq.message.current.warning",
4018
+ identity: { system: "rabbitmq", brokerScope: "", destination: "warning" },
4019
+ },
4020
+ {
4021
+ queue:
4022
+ "RabbitMQ queue, Java agent opt-in fanout consumer 'logs:logs-audit' vs the 'logs-audit' queue's depth",
4023
+ spanId: "rabbitmq.java-agent.opt-in.process.fanout-empty-routing-key",
4024
+ datapointId: "rabbitmq.message.current.logs-audit",
4025
+ identity: {
4026
+ system: "rabbitmq",
4027
+ brokerScope: "",
4028
+ destination: "logs-audit",
4029
+ },
4030
+ },
4031
+ {
4032
+ queue:
4033
+ "RabbitMQ queue, Java agent opt-in consumer of a MassTransit exchange 'Namespace:Type:invoice-issued' vs the 'invoice-issued' queue's depth",
4034
+ spanId: "rabbitmq.java-agent.opt-in.process.masstransit-exchange",
4035
+ datapointId: "rabbitmq.message.current.invoice-issued",
4036
+ identity: {
4037
+ system: "rabbitmq",
4038
+ brokerScope: "",
4039
+ destination: "invoice-issued",
4040
+ },
4041
+ },
4042
+ {
4043
+ /*
4044
+ * ActiveMQ is keyed on the JMS family (MessagingSystem identityFamily),
4045
+ * so its identity says "jms" whichever side named the queue.
4046
+ */
4047
+ queue: "ActiveMQ queue vs JMX Scraper (1.53+ names)",
4048
+ spanId: "activemq.manual.send",
4049
+ datapointId: "jmx.activemq.message.queue.size",
4050
+ identity: { system: "jms", brokerScope: "", destination: "orders" },
4051
+ },
4052
+ {
4053
+ queue: "ActiveMQ queue vs JMX Scraper (legacy names)",
4054
+ spanId: "activemq.manual.send",
4055
+ datapointId: "jmx.activemq.message.current.legacy",
4056
+ identity: { system: "jms", brokerScope: "", destination: "orders" },
4057
+ },
4058
+ {
4059
+ // The everyday case: Java agent JMS spans against ActiveMQ's own metrics.
4060
+ queue: "JMS client (Java agent) vs ActiveMQ JMX Scraper",
4061
+ spanId: "jms.java-agent.default.send",
4062
+ datapointId: "jmx.activemq.message.queue.size",
4063
+ identity: { system: "jms", brokerScope: "", destination: "orders" },
4064
+ },
4065
+ {
4066
+ queue: "JMS client (Java agent) vs ActiveMQ JMX Scraper (legacy names)",
4067
+ spanId: "jms.java-agent.default.send",
4068
+ datapointId: "jmx.activemq.message.current.legacy",
4069
+ identity: { system: "jms", brokerScope: "", destination: "orders" },
4070
+ },
4071
+ {
4072
+ queue: "SQS queue, Java agent vs Metric Stream (opentelemetry1.0)",
4073
+ spanId: "sqs.java-agent.default.send",
4074
+ datapointId: "cloudwatch-otel1.sqs.messages-visible",
4075
+ identity: {
4076
+ system: "aws_sqs",
4077
+ brokerScope: "",
4078
+ destination: "payment-events",
4079
+ },
4080
+ },
4081
+ {
4082
+ queue:
4083
+ "SQS queue, Go otelaws (URL in server.address) vs Metric Stream (json)",
4084
+ spanId: "sqs.go-otelaws.send-message",
4085
+ datapointId: "cloudwatch-json.sqs.messages-visible",
4086
+ identity: {
4087
+ system: "aws_sqs",
4088
+ brokerScope: "",
4089
+ destination: "payment-events",
4090
+ },
4091
+ },
4092
+ {
4093
+ queue: "SQS queue, boto3sqs vs aws_cloudwatch pull with stats",
4094
+ spanId: "sqs.boto3sqs.process",
4095
+ datapointId: "aws_cloudwatch.sqs.age-of-oldest-message.stat",
4096
+ identity: {
4097
+ system: "aws_sqs",
4098
+ brokerScope: "",
4099
+ destination: "payment-events",
4100
+ },
4101
+ },
4102
+ {
4103
+ queue: "SQS queue, .NET AWS legacy mode vs NumberOfMessagesSent",
4104
+ spanId: "sqs.dotnet-aws.legacy.receive",
4105
+ datapointId: "cloudwatch-otel1.sqs.messages-sent",
4106
+ identity: {
4107
+ system: "aws_sqs",
4108
+ brokerScope: "",
4109
+ destination: "payment-events",
4110
+ },
4111
+ },
4112
+ {
4113
+ queue:
4114
+ "SNS topic, Java agent RPC span (ARN) vs Metric Stream (opentelemetry1.0)",
4115
+ spanId: "sns.java-agent.publish",
4116
+ datapointId: "cloudwatch-otel1.sns.messages-published",
4117
+ identity: {
4118
+ system: "aws.sns",
4119
+ brokerScope: "",
4120
+ destination: "payment-notifications",
4121
+ },
4122
+ },
4123
+ {
4124
+ queue:
4125
+ "SNS topic, Go otelaws (aws_sns, short name) vs Metric Stream (json)",
4126
+ spanId: "sns.go-otelaws.publish.topic",
4127
+ datapointId: "cloudwatch-json.sns.notifications-delivered",
4128
+ identity: {
4129
+ system: "aws.sns",
4130
+ brokerScope: "",
4131
+ destination: "payment-notifications",
4132
+ },
4133
+ },
4134
+ {
4135
+ queue: "SNS topic, JS aws-sdk vs NumberOfNotificationsFailed",
4136
+ spanId: "sns.aws-sdk-js.publish",
4137
+ datapointId: "cloudwatch-otel1.sns.notifications-failed",
4138
+ identity: {
4139
+ system: "aws.sns",
4140
+ brokerScope: "",
4141
+ destination: "payment-notifications",
4142
+ },
4143
+ },
4144
+ {
4145
+ queue: "Pub/Sub subscription, Node subscriber vs num_undelivered_messages",
4146
+ spanId: "pubsub.node.subscribe",
4147
+ datapointId: "googlecloudmonitoring.subscription.num-undelivered",
4148
+ identity: {
4149
+ system: "gcp_pubsub",
4150
+ brokerScope: "",
4151
+ destination: "orders-billing",
4152
+ },
4153
+ },
4154
+ {
4155
+ queue: "Pub/Sub subscription, Go process vs ack_message_count",
4156
+ spanId: "pubsub.go-v2.process",
4157
+ datapointId: "googlecloudmonitoring.subscription.ack-count.resource-labels",
4158
+ identity: {
4159
+ system: "gcp_pubsub",
4160
+ brokerScope: "",
4161
+ destination: "orders-billing",
4162
+ },
4163
+ },
4164
+ {
4165
+ queue: "Pub/Sub topic, Node publisher vs send_request_count",
4166
+ spanId: "pubsub.node.create",
4167
+ datapointId: "googlecloudmonitoring.topic.send-request-count",
4168
+ identity: { system: "gcp_pubsub", brokerScope: "", destination: "orders" },
4169
+ },
4170
+ {
4171
+ queue: "Service Bus queue, .NET (ActivitySource) vs ActiveMessages",
4172
+ spanId: "servicebus.dotnet.activity-source.send",
4173
+ datapointId: "azure_monitor.servicebus.activemessages",
4174
+ identity: {
4175
+ system: "servicebus",
4176
+ brokerScope: "billing-prod",
4177
+ destination: "invoices",
4178
+ },
4179
+ },
4180
+ {
4181
+ queue:
4182
+ "Service Bus queue, .NET without the ActivitySource switch vs DeadletteredMessages (PascalCase key)",
4183
+ spanId: "servicebus.dotnet.diagnostic-source.send",
4184
+ datapointId: "azure_monitor.servicebus.deadletteredmessages",
4185
+ identity: {
4186
+ system: "servicebus",
4187
+ brokerScope: "billing-prod",
4188
+ destination: "invoices",
4189
+ },
4190
+ },
4191
+ {
4192
+ queue:
4193
+ "Service Bus queue, a dead-letter sub-queue receive vs DeadletteredMessages",
4194
+ spanId: "servicebus.dotnet.diagnostic-source.receive.dead-letter",
4195
+ datapointId: "azure_monitor.servicebus.deadletteredmessages",
4196
+ identity: {
4197
+ system: "servicebus",
4198
+ brokerScope: "billing-prod",
4199
+ destination: "invoices",
4200
+ },
4201
+ },
4202
+ {
4203
+ queue: "Service Bus topic, .NET subscription processor vs ServerErrors",
4204
+ spanId: "servicebus.dotnet.activity-source.process.subscription",
4205
+ datapointId: "azure_monitor.servicebus.servererrors",
4206
+ identity: {
4207
+ system: "servicebus",
4208
+ brokerScope: "billing-prod",
4209
+ destination: "invoice-events",
4210
+ },
4211
+ },
4212
+ {
4213
+ queue: "Service Bus topic, Java subscription processor vs ServerErrors",
4214
+ spanId: "servicebus.java.process.subscription",
4215
+ datapointId: "azure_monitor.servicebus.servererrors",
4216
+ identity: {
4217
+ system: "servicebus",
4218
+ brokerScope: "billing-prod",
4219
+ destination: "invoice-events",
4220
+ },
4221
+ },
4222
+ {
4223
+ queue:
4224
+ "Service Bus topic, JS receiver (messaging.source.name) vs ServerErrors",
4225
+ spanId: "servicebus.js.receive.subscription",
4226
+ datapointId: "azure_monitor.servicebus.servererrors",
4227
+ identity: {
4228
+ system: "servicebus",
4229
+ brokerScope: "billing-prod",
4230
+ destination: "invoice-events",
4231
+ },
4232
+ },
4233
+ {
4234
+ queue: "Service Bus queue, Python (legacy keys) vs IncomingMessages",
4235
+ spanId: "servicebus.python.send",
4236
+ datapointId: "azure_monitor.servicebus.incomingmessages",
4237
+ identity: {
4238
+ system: "servicebus",
4239
+ brokerScope: "billing-prod",
4240
+ destination: "invoices",
4241
+ },
4242
+ },
4243
+ {
4244
+ queue: "Service Bus queue spelled in mixed case on both sides",
4245
+ spanId: "servicebus.dotnet.activity-source.send.mixed-case-namespace",
4246
+ datapointId: "azure_monitor.servicebus.activemessages.mixed-case",
4247
+ identity: {
4248
+ system: "servicebus",
4249
+ brokerScope: "billing-prod",
4250
+ destination: "invoices",
4251
+ },
4252
+ },
4253
+ {
4254
+ queue:
4255
+ "Service Bus queue, .NET send vs the Java SDK's own messages.sent metric",
4256
+ spanId: "servicebus.dotnet.activity-source.send",
4257
+ datapointId: "azure-sdk-java.servicebus.messages.sent",
4258
+ identity: {
4259
+ system: "servicebus",
4260
+ brokerScope: "billing-prod",
4261
+ destination: "invoices",
4262
+ },
4263
+ },
4264
+ {
4265
+ queue: "Event hub, .NET (ActivitySource) vs IncomingMessages",
4266
+ spanId: "eventhubs.dotnet.activity-source.send",
4267
+ datapointId: "azure_monitor.eventhubs.incomingmessages",
4268
+ identity: {
4269
+ system: "eventhubs",
4270
+ brokerScope: "telemetry-prod",
4271
+ destination: "device-telemetry",
4272
+ },
4273
+ },
4274
+ {
4275
+ queue:
4276
+ "Event hub, .NET without the ActivitySource switch vs IncomingMessages",
4277
+ spanId: "eventhubs.dotnet.diagnostic-source.send",
4278
+ datapointId: "azure_monitor.eventhubs.incomingmessages",
4279
+ identity: {
4280
+ system: "eventhubs",
4281
+ brokerScope: "telemetry-prod",
4282
+ destination: "device-telemetry",
4283
+ },
4284
+ },
4285
+ {
4286
+ queue: "Event hub, Java processor vs OutgoingMessages (PascalCase key)",
4287
+ spanId: "eventhubs.java.process",
4288
+ datapointId: "azure_monitor.eventhubs.outgoingmessages",
4289
+ identity: {
4290
+ system: "eventhubs",
4291
+ brokerScope: "telemetry-prod",
4292
+ destination: "device-telemetry",
4293
+ },
4294
+ },
4295
+ {
4296
+ queue: "Event hub, Python receive (net.peer.name) vs ThrottledRequests",
4297
+ spanId: "eventhubs.python.receive",
4298
+ datapointId: "azure_monitor.eventhubs.throttledrequests",
4299
+ identity: {
4300
+ system: "eventhubs",
4301
+ brokerScope: "telemetry-prod",
4302
+ destination: "device-telemetry",
4303
+ },
4304
+ },
4305
+ {
4306
+ queue: "Event hub, JS receive (messaging.source.name) vs UserErrors",
4307
+ spanId: "eventhubs.js.receive",
4308
+ datapointId: "azure_monitor.eventhubs.usererrors",
4309
+ identity: {
4310
+ system: "eventhubs",
4311
+ brokerScope: "telemetry-prod",
4312
+ destination: "device-telemetry",
4313
+ },
4314
+ },
4315
+ {
4316
+ queue: "Event hub, .NET processor vs the Java SDK's consumer lag metric",
4317
+ spanId: "eventhubs.dotnet.activity-source.process",
4318
+ datapointId: "azure-sdk-java.eventhubs.consumer.lag",
4319
+ identity: {
4320
+ system: "eventhubs",
4321
+ brokerScope: "telemetry-prod",
4322
+ destination: "device-telemetry",
4323
+ },
4324
+ },
4325
+ {
4326
+ queue: "Pulsar topic, short-named producer vs a partition's backlog",
4327
+ spanId: "pulsar.java-agent.default.send.short-name",
4328
+ datapointId: "prometheus.pulsar_msg_backlog",
4329
+ identity: {
4330
+ system: "pulsar",
4331
+ brokerScope: "",
4332
+ destination: "persistent://public/default/payments",
4333
+ },
4334
+ },
4335
+ {
4336
+ queue: "Pulsar topic, partition consumer vs the split partition label",
4337
+ spanId: "pulsar.java-agent.default.process.partition",
4338
+ datapointId: "prometheus.pulsar_msg_backlog.split-partition-label",
4339
+ identity: {
4340
+ system: "pulsar",
4341
+ brokerScope: "",
4342
+ destination: "persistent://public/default/payments",
4343
+ },
4344
+ },
4345
+ {
4346
+ queue: "Pulsar topic, opt-in receive vs subscription backlog",
4347
+ spanId: "pulsar.java-agent.opt-in.receive",
4348
+ datapointId: "prometheus.pulsar_subscription_back_log",
4349
+ identity: {
4350
+ system: "pulsar",
4351
+ brokerScope: "",
4352
+ destination: "persistent://public/default/payments",
4353
+ },
4354
+ },
4355
+ {
4356
+ queue: "RocketMQ topic, Java agent consumer vs consumer lag",
4357
+ spanId: "rocketmq.java-agent.5.process",
4358
+ datapointId: "prometheus.rocketmq_consumer_lag_messages",
4359
+ identity: {
4360
+ system: "rocketmq",
4361
+ brokerScope: "",
4362
+ destination: "order-topic",
4363
+ },
4364
+ },
4365
+ {
4366
+ queue: "RocketMQ topic, Java agent producer vs messages in",
4367
+ spanId: "rocketmq.java-agent.4.send",
4368
+ datapointId: "prometheus.rocketmq_messages_in_total",
4369
+ identity: {
4370
+ system: "rocketmq",
4371
+ brokerScope: "",
4372
+ destination: "order-topic",
4373
+ },
4374
+ },
4375
+ ];
4376
+
4377
+ // ---- the same queue seen by a span and by its own client metrics ---------
4378
+
4379
+ /*
4380
+ * The Java agent records RabbitMQ client metrics in its opt-in mode only,
4381
+ * with the span's joined name but none of its routing key: each metric of
4382
+ * an operation must still key the queue its span does.
4383
+ */
4384
+ const SPAN_AND_CLIENT_METRIC_PAIRS: ReadonlyArray<SameQueuePair> = [
4385
+ {
4386
+ queue:
4387
+ "RabbitMQ exchange, Java agent opt-in publish vs its operation duration",
4388
+ spanId: "rabbitmq.java-agent.opt-in.publish.exchange-and-routing-key",
4389
+ datapointId: "java-agent.opt-in.client.operation.duration.rabbitmq-publish",
4390
+ identity: {
4391
+ system: "rabbitmq",
4392
+ brokerScope: "",
4393
+ destination: "orders.topic",
4394
+ },
4395
+ },
4396
+ {
4397
+ queue: "RabbitMQ exchange, Java agent opt-in publish vs its sent messages",
4398
+ spanId: "rabbitmq.java-agent.opt-in.publish.exchange-and-routing-key",
4399
+ datapointId: "java-agent.opt-in.client.sent.messages.rabbitmq-publish",
4400
+ identity: {
4401
+ system: "rabbitmq",
4402
+ brokerScope: "",
4403
+ destination: "orders.topic",
4404
+ },
4405
+ },
4406
+ {
4407
+ queue:
4408
+ "RabbitMQ queue, Java agent opt-in delivery ('direct_logs:warning') vs its process duration",
4409
+ spanId: "rabbitmq.java-agent.opt-in.process.routing-key-is-queue",
4410
+ datapointId: "java-agent.opt-in.process.duration.rabbitmq-consumer",
4411
+ identity: { system: "rabbitmq", brokerScope: "", destination: "warning" },
4412
+ },
4413
+ {
4414
+ queue:
4415
+ "RabbitMQ queue, Java agent opt-in delivery from a fanout exchange vs its consumed messages",
4416
+ spanId: "rabbitmq.java-agent.opt-in.process.fanout-empty-routing-key",
4417
+ datapointId: "java-agent.opt-in.client.consumed.messages.rabbitmq-fanout",
4418
+ identity: {
4419
+ system: "rabbitmq",
4420
+ brokerScope: "",
4421
+ destination: "logs-audit",
4422
+ },
4423
+ },
4424
+ ];
4425
+
4426
+ // ---- helpers --------------------------------------------------------------
4427
+
4428
+ function getterOver(attributes: Attributes): AttributeGetter {
4429
+ return (key: string): unknown => {
4430
+ return Object.prototype.hasOwnProperty.call(attributes, key)
4431
+ ? attributes[key]
4432
+ : undefined;
4433
+ };
4434
+ }
4435
+
4436
+ /*
4437
+ * The row the discovery cron reads back from ClickHouse: exactly `keys`,
4438
+ * each value as the Map(String, String) column holds it — a number or
4439
+ * boolean as its text, an array as its JSON — and a missing key as ''.
4440
+ */
4441
+ function storedRow(
4442
+ attributes: Attributes,
4443
+ keys: ReadonlyArray<string>,
4444
+ ): Attributes {
4445
+ const row: Attributes = {};
4446
+ for (const key of keys) {
4447
+ const value: unknown = Object.prototype.hasOwnProperty.call(attributes, key)
4448
+ ? attributes[key]
4449
+ : undefined;
4450
+ if (typeof value === "string") {
4451
+ row[key] = value;
4452
+ } else if (typeof value === "number" || typeof value === "boolean") {
4453
+ row[key] = String(value);
4454
+ } else if (Array.isArray(value)) {
4455
+ row[key] = JSON.stringify(value);
4456
+ } else {
4457
+ row[key] = "";
4458
+ }
4459
+ }
4460
+ return row;
4461
+ }
4462
+
4463
+ function resolveSpanFixture(
4464
+ fixture: SpanFixture,
4465
+ ): ResolvedMessagingDestination | null {
4466
+ return resolveMessagingSpan({
4467
+ getAttribute: getterOver(fixture.attributes),
4468
+ kind: fixture.kind,
4469
+ });
4470
+ }
4471
+
4472
+ function resolveDatapointFixture(
4473
+ fixture: DatapointFixture,
4474
+ ): ResolvedMessagingDestination | null {
4475
+ return resolveMessagingMetricDatapoint({
4476
+ metricName: fixture.metricName,
4477
+ getAttribute: getterOver(fixture.attributes),
4478
+ });
4479
+ }
4480
+
4481
+ /*
4482
+ * What a resolution keys the queue by: its canonical identity, the row
4483
+ * identifier the discovery cron creates it under, and the entity key ingest
4484
+ * stamps on the span or datapoint.
4485
+ */
4486
+ function queueKeysOf(
4487
+ resolved: ResolvedMessagingDestination | null,
4488
+ ): QueueKeys | null {
4489
+ const identity: MessageQueueIdentity | null = resolved
4490
+ ? toMessageQueueIdentity(resolved)
4491
+ : null;
4492
+ if (!identity) {
4493
+ return null;
4494
+ }
4495
+ return {
4496
+ identity,
4497
+ identifier: buildMessageQueueIdentifier(identity),
4498
+ entityKey: keyForMessageQueue(PROJECT_ID, identity),
4499
+ };
4500
+ }
4501
+
4502
+ // The same, built from the expected identity by the documented formats.
4503
+ function expectedQueueKeys(identity: MessageQueueIdentity): QueueKeys {
4504
+ return {
4505
+ identity,
4506
+ identifier: `${identity.system}|${identity.brokerScope}|${identity.destination}`,
4507
+ entityKey: keyForMessageQueue(PROJECT_ID, identity),
4508
+ };
4509
+ }
4510
+
4511
+ function testName(fixture: { id: string; source: string }): string {
4512
+ return `${fixture.id} — ${fixture.source}`;
4513
+ }
4514
+
4515
+ const SPAN_BY_ID: ReadonlyMap<string, SpanFixture> = new Map<
4516
+ string,
4517
+ SpanFixture
4518
+ >(
4519
+ SPANS.map((fixture: SpanFixture): [string, SpanFixture] => {
4520
+ return [fixture.id, fixture];
4521
+ }),
4522
+ );
4523
+
4524
+ const DATAPOINT_BY_ID: ReadonlyMap<string, DatapointFixture> = new Map<
4525
+ string,
4526
+ DatapointFixture
4527
+ >(
4528
+ DATAPOINTS.map((fixture: DatapointFixture): [string, DatapointFixture] => {
4529
+ return [fixture.id, fixture];
4530
+ }),
4531
+ );
4532
+
4533
+ // ---- tests ----------------------------------------------------------------
4534
+
4535
+ describe("the fixture corpus", () => {
4536
+ test("covers at least 60 fixtures, with unique ids", () => {
4537
+ expect(SPANS.length + DATAPOINTS.length).toBeGreaterThanOrEqual(60);
4538
+ expect(SPAN_BY_ID.size).toBe(SPANS.length);
4539
+ expect(DATAPOINT_BY_ID.size).toBe(DATAPOINTS.length);
4540
+ });
4541
+
4542
+ test("every same-queue pair names a span and a datapoint that exist", () => {
4543
+ for (const pair of [...SAME_QUEUE_PAIRS, ...SPAN_AND_CLIENT_METRIC_PAIRS]) {
4544
+ expect(SPAN_BY_ID.has(pair.spanId)).toBe(true);
4545
+ expect(DATAPOINT_BY_ID.has(pair.datapointId)).toBe(true);
4546
+ }
4547
+ });
4548
+
4549
+ test("every expected queue is one an identity can be built from", () => {
4550
+ const expectations: Array<ResolvedMessagingDestination> = [
4551
+ ...SPANS.map(
4552
+ (fixture: SpanFixture): ResolvedMessagingDestination | null => {
4553
+ return fixture.expected;
4554
+ },
4555
+ ),
4556
+ ...DATAPOINTS.map(
4557
+ (fixture: DatapointFixture): ResolvedMessagingDestination | null => {
4558
+ return fixture.expected;
4559
+ },
4560
+ ),
4561
+ ].filter(
4562
+ (
4563
+ expected: ResolvedMessagingDestination | null,
4564
+ ): expected is ResolvedMessagingDestination => {
4565
+ return expected !== null;
4566
+ },
4567
+ );
4568
+ for (const expected of expectations) {
4569
+ expect(toMessageQueueIdentity(expected)).not.toBeNull();
4570
+ }
4571
+ });
4572
+ });
4573
+
4574
+ describe("messaging spans, attribute for attribute", () => {
4575
+ test.each(
4576
+ SPANS.map((fixture: SpanFixture): [string, SpanFixture] => {
4577
+ return [testName(fixture), fixture];
4578
+ }),
4579
+ )("%s", (_name: string, fixture: SpanFixture) => {
4580
+ expect(resolveSpanFixture(fixture)).toEqual(fixture.expected);
4581
+ });
4582
+
4583
+ test.each(
4584
+ SPANS.map((fixture: SpanFixture): [string, SpanFixture] => {
4585
+ return [testName(fixture), fixture];
4586
+ }),
4587
+ )(
4588
+ "%s — resolves the same read back from ClickHouse",
4589
+ (_name: string, fixture: SpanFixture) => {
4590
+ /*
4591
+ * The discovery cron groups stored spans by exactly
4592
+ * MESSAGING_RESOLVER_INPUT_ATTRIBUTES and hands each row back to the
4593
+ * resolver: it must land where the ingest-time stamp did.
4594
+ */
4595
+ const row: Attributes = storedRow(
4596
+ fixture.attributes,
4597
+ MESSAGING_RESOLVER_INPUT_ATTRIBUTES,
4598
+ );
4599
+ expect(
4600
+ resolveMessagingSpan({
4601
+ getAttribute: getterOver(row),
4602
+ kind: fixture.kind,
4603
+ }),
4604
+ ).toEqual(resolveSpanFixture(fixture));
4605
+ },
4606
+ );
4607
+ });
4608
+
4609
+ describe("broker and client metric datapoints, in the stored shape", () => {
4610
+ test.each(
4611
+ DATAPOINTS.map((fixture: DatapointFixture): [string, DatapointFixture] => {
4612
+ return [testName(fixture), fixture];
4613
+ }),
4614
+ )("%s", (_name: string, fixture: DatapointFixture) => {
4615
+ expect(resolveDatapointFixture(fixture)).toEqual(fixture.expected);
4616
+ });
4617
+
4618
+ test.each(
4619
+ DATAPOINTS.map((fixture: DatapointFixture): [string, DatapointFixture] => {
4620
+ return [testName(fixture), fixture];
4621
+ }),
4622
+ )(
4623
+ "%s — resolves the same read back from ClickHouse",
4624
+ (_name: string, fixture: DatapointFixture) => {
4625
+ const row: Attributes = storedRow(
4626
+ fixture.attributes,
4627
+ MESSAGING_METRIC_RESOLVER_INPUT_ATTRIBUTES,
4628
+ );
4629
+ expect(
4630
+ resolveMessagingMetricDatapoint({
4631
+ metricName: fixture.metricName,
4632
+ getAttribute: getterOver(row),
4633
+ }),
4634
+ ).toEqual(resolveDatapointFixture(fixture));
4635
+ },
4636
+ );
4637
+ });
4638
+
4639
+ function pairCases(
4640
+ pairs: ReadonlyArray<SameQueuePair>,
4641
+ ): Array<[string, SameQueuePair]> {
4642
+ return pairs.map((pair: SameQueuePair): [string, SameQueuePair] => {
4643
+ return [`${pair.queue} (${pair.spanId} ↔ ${pair.datapointId})`, pair];
4644
+ });
4645
+ }
4646
+
4647
+ // The pair's span and datapoint key the pair's queue, and so each other's.
4648
+ function expectOneQueue(pair: SameQueuePair): void {
4649
+ const span: SpanFixture | undefined = SPAN_BY_ID.get(pair.spanId);
4650
+ const datapoint: DatapointFixture | undefined = DATAPOINT_BY_ID.get(
4651
+ pair.datapointId,
4652
+ );
4653
+ expect(span).toBeDefined();
4654
+ expect(datapoint).toBeDefined();
4655
+ if (!span || !datapoint) {
4656
+ return;
4657
+ }
4658
+
4659
+ const fromSpan: QueueKeys | null = queueKeysOf(resolveSpanFixture(span));
4660
+ const fromDatapoint: QueueKeys | null = queueKeysOf(
4661
+ resolveDatapointFixture(datapoint),
4662
+ );
4663
+ const expected: QueueKeys = expectedQueueKeys(pair.identity);
4664
+
4665
+ expect(fromSpan).toEqual(expected);
4666
+ expect(fromDatapoint).toEqual(expected);
4667
+ expect(fromSpan).toEqual(fromDatapoint);
4668
+ }
4669
+
4670
+ describe("a span and a broker metric of the same queue share one identity and one entity key", () => {
4671
+ test.each(pairCases(SAME_QUEUE_PAIRS))(
4672
+ "%s",
4673
+ (_name: string, pair: SameQueuePair) => {
4674
+ expectOneQueue(pair);
4675
+ },
4676
+ );
4677
+ });
4678
+
4679
+ describe("a span and the client metrics of its own operation share one identity and one entity key", () => {
4680
+ test.each(pairCases(SPAN_AND_CLIENT_METRIC_PAIRS))(
4681
+ "%s",
4682
+ (_name: string, pair: SameQueuePair) => {
4683
+ expectOneQueue(pair);
4684
+ },
4685
+ );
4686
+ });