@oneuptime/common 10.8.1 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (772) hide show
  1. package/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.ts +16 -18
  2. package/Models/AnalyticsModels/AuditLog.ts +3 -1
  3. package/Models/AnalyticsModels/ExceptionInstance.ts +200 -82
  4. package/Models/AnalyticsModels/Index.ts +7 -2
  5. package/Models/AnalyticsModels/Log.ts +197 -81
  6. package/Models/AnalyticsModels/Metric.ts +199 -86
  7. package/Models/AnalyticsModels/MetricBaselineHourly.ts +44 -25
  8. package/Models/AnalyticsModels/MetricItemAggMV1m.ts +23 -20
  9. package/Models/AnalyticsModels/{MetricItemAggMV1mByHost.ts → MetricItemAggMV1mByHostV2.ts} +58 -47
  10. package/Models/AnalyticsModels/MonitorLog.ts +5 -1
  11. package/Models/AnalyticsModels/Profile.ts +206 -85
  12. package/Models/AnalyticsModels/ProfileSample.ts +196 -83
  13. package/Models/AnalyticsModels/Span.ts +218 -85
  14. package/Models/DatabaseModels/CloudResourceInstance.ts +1 -2
  15. package/Models/DatabaseModels/CloudResourceOwnerTeam.ts +1 -2
  16. package/Models/DatabaseModels/CloudResourceOwnerUser.ts +1 -2
  17. package/Models/DatabaseModels/Index.ts +4 -0
  18. package/Models/DatabaseModels/Service.ts +29 -0
  19. package/Models/DatabaseModels/TelemetryEntity.ts +393 -0
  20. package/Models/DatabaseModels/TelemetryEntityRelationship.ts +294 -0
  21. package/Models/DatabaseModels/TelemetryException.ts +13 -12
  22. package/Models/DatabaseModels/TelemetryUsageBilling.ts +5 -5
  23. package/Server/API/AIAgentDataAPI.ts +13 -12
  24. package/Server/API/DashboardAPI.ts +2 -2
  25. package/Server/API/TelemetryAPI.ts +656 -141
  26. package/Server/API/TelemetryExceptionAPI.ts +2 -2
  27. package/Server/Infrastructure/ClickhouseConfig.ts +12 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1780931863719-AddTelemetryResourceMetadataColumns.ts +1 -3
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1780933132562-AddServerlessFunctionTables.ts +6 -2
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1780935387827-AddCloudResourceTables.ts +18 -6
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1781011482945-MigrationName.ts +2317 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1781100000001-RenameTelemetryServiceIdToPrimaryEntityId.ts +48 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1781200000000-AddTelemetryEntityTable.ts +70 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1781200000001-AddTelemetryEntityRelationshipTable.ts +57 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1781250074195-MigrationName.ts +207 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/1781300000000-AddTelemetryEntityLabels.ts +24 -0
  37. package/Server/Infrastructure/Postgres/SchemaMigrations/1781400000000-AddServiceTelemetrySdkLanguage.ts +25 -0
  38. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -0
  39. package/Server/Infrastructure/Queue.ts +36 -3
  40. package/Server/Middleware/TelemetryIngest.ts +27 -22
  41. package/Server/Services/AlertService.ts +9 -9
  42. package/Server/Services/AnalyticsDatabaseService.ts +204 -35
  43. package/Server/Services/CloudResourceLabelRuleEngineService.ts +4 -1
  44. package/Server/Services/CloudResourceOwnerRuleEngineService.ts +4 -1
  45. package/Server/Services/ExceptionAggregationService.ts +41 -18
  46. package/Server/Services/HostService.ts +2 -1
  47. package/Server/Services/IncidentService.ts +19 -19
  48. package/Server/Services/Index.ts +6 -2
  49. package/Server/Services/LogAggregationService.ts +116 -43
  50. package/Server/Services/MetricAggregationService.ts +29 -14
  51. package/Server/Services/MetricBaselineService.ts +34 -34
  52. package/Server/Services/MetricItemAggMV1mByHostV2Service.ts +30 -0
  53. package/Server/Services/MetricService.ts +119 -31
  54. package/Server/Services/OpenTelemetryIngestService.ts +189 -51
  55. package/Server/Services/ProfileAggregationService.ts +904 -126
  56. package/Server/Services/RumApplicationLabelRuleEngineService.ts +4 -1
  57. package/Server/Services/RumApplicationOwnerRuleEngineService.ts +4 -1
  58. package/Server/Services/ServerlessFunctionInstanceService.ts +4 -2
  59. package/Server/Services/ServerlessFunctionLabelRuleEngineService.ts +7 -2
  60. package/Server/Services/ServerlessFunctionOwnerRuleEngineService.ts +7 -2
  61. package/Server/Services/ServiceService.ts +6 -0
  62. package/Server/Services/SpanService.ts +274 -14
  63. package/Server/Services/TelemetryEntityRelationshipService.ts +71 -0
  64. package/Server/Services/TelemetryEntityService.ts +246 -0
  65. package/Server/Services/TelemetryExceptionService.ts +27 -23
  66. package/Server/Services/TelemetryUsageBillingService.ts +38 -31
  67. package/Server/Services/TraceAggregationService.ts +875 -43
  68. package/Server/Types/AnalyticsDatabase/ModelPermission.ts +43 -2
  69. package/Server/Types/Database/Permissions/AccessControlPermission.ts +47 -2
  70. package/Server/Types/Database/Permissions/BasePermission.ts +37 -1
  71. package/Server/Types/Database/Permissions/OwnedScopePermission.ts +21 -3
  72. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +1 -0
  73. package/Server/Types/Database/QueryHelper.ts +41 -0
  74. package/Server/Utils/Alert/AlertPrivacyFilter.ts +9 -2
  75. package/Server/Utils/AlertEpisode/AlertEpisodePrivacyFilter.ts +9 -2
  76. package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +95 -0
  77. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +133 -0
  78. package/Server/Utils/Incident/IncidentPrivacyFilter.ts +9 -2
  79. package/Server/Utils/IncidentEpisode/IncidentEpisodePrivacyFilter.ts +9 -2
  80. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +1 -1
  81. package/Server/Utils/Monitor/MonitorLogUtil.ts +1 -2
  82. package/Server/Utils/Monitor/MonitorMetricUtil.ts +3 -4
  83. package/Server/Utils/PrivacyFilterUtil.ts +72 -0
  84. package/Server/Utils/Profile/PprofEncoder.ts +135 -11
  85. package/Server/Utils/Telemetry/EntityRegistry.ts +316 -0
  86. package/Server/Utils/Telemetry/ResourceFacetResolver.ts +9 -3
  87. package/Server/Utils/Telemetry/TelemetryEntity.ts +783 -0
  88. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +79 -4
  89. package/Tests/Server/Services/LogAggregationService.test.ts +7 -2
  90. package/Tests/Server/Services/ProfileAggregationService.test.ts +280 -0
  91. package/Tests/Server/Services/ProfileBreakdown.test.ts +161 -0
  92. package/Tests/Server/Services/ProfileFunctionFocus.test.ts +349 -0
  93. package/Tests/Server/Services/TelemetryAttributeService.test.ts +1 -1
  94. package/Tests/Server/Services/TraceAggregationService.test.ts +403 -0
  95. package/Tests/Server/Types/AnalyticsDatabase/ModelPermissionOwnedScope.test.ts +114 -0
  96. package/Tests/Server/Types/Database/Permissions/AccessControlPermission.test.ts +189 -0
  97. package/Tests/Server/Types/Database/Permissions/BasePermission.test.ts +118 -0
  98. package/Tests/Server/Types/Database/Permissions/OwnedScopePermission.test.ts +159 -0
  99. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +275 -8
  100. package/Tests/Server/Utils/PrivacyFilterUtil.test.ts +177 -0
  101. package/Tests/Server/Utils/Profile/PprofEncoder.test.ts +276 -0
  102. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +761 -0
  103. package/Tests/Types/Monitor/MonitorStepEntityScope.test.ts +275 -0
  104. package/Tests/Types/Text.test.ts +52 -0
  105. package/Tests/Utils/Telemetry/EntityKey.test.ts +150 -0
  106. package/Tests/Utils/Telemetry/EntityKeySqlParity.test.ts +40 -0
  107. package/Tests/Utils/Telemetry/EntityRelationship.test.ts +150 -0
  108. package/Tests/Utils/UUID.test.ts +47 -0
  109. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +14 -9
  110. package/Types/AnalyticsDatabase/TableColumnType.ts +1 -0
  111. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  112. package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +37 -0
  113. package/Types/Dashboard/DashboardTemplates.ts +4 -5
  114. package/Types/Log/LogQueryParser.ts +2 -2
  115. package/Types/Log/LogQueryToFilter.ts +2 -2
  116. package/Types/Monitor/MonitorStepExceptionMonitor.ts +19 -1
  117. package/Types/Monitor/MonitorStepLogMonitor.ts +20 -1
  118. package/Types/Monitor/MonitorStepMetricMonitor.ts +27 -0
  119. package/Types/Monitor/MonitorStepProfileMonitor.ts +19 -1
  120. package/Types/Monitor/MonitorStepTraceMonitor.ts +18 -1
  121. package/Types/Monitor/MonitorType.ts +8 -1
  122. package/Types/ObjectID.ts +10 -0
  123. package/Types/Permission.ts +4 -2
  124. package/Types/Telemetry/EntityRelationshipType.ts +31 -0
  125. package/Types/Telemetry/EntityType.ts +33 -0
  126. package/Types/Telemetry/TelemetrySavedViewState.ts +2 -0
  127. package/Types/Text.ts +34 -0
  128. package/Types/Trace/TraceAggregationType.ts +1 -0
  129. package/Types/Trace/TraceRecordingRuleDefinition.ts +74 -0
  130. package/UI/Components/BulkUpdate/BulkLabelActions.tsx +14 -14
  131. package/UI/Components/Forms/Fields/FormField.tsx +18 -12
  132. package/UI/Components/Input/Input.tsx +3 -1
  133. package/UI/Components/LogsViewer/LogsViewer.tsx +12 -9
  134. package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +10 -9
  135. package/UI/Components/LogsViewer/components/LogSearchBar.tsx +1 -1
  136. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +2 -2
  137. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +4 -4
  138. package/UI/Components/LogsViewer/components/LogsTable.tsx +5 -3
  139. package/UI/Components/Navbar/NavBarMenuModal.tsx +81 -44
  140. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +33 -10
  141. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +18 -3
  142. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +91 -68
  143. package/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.tsx +9 -2
  144. package/UI/Components/TextArea/TextArea.tsx +3 -1
  145. package/UI/Components/Toast/Toast.tsx +4 -2
  146. package/UI/Utils/LogExport.ts +2 -2
  147. package/UI/Utils/TelemetryService.ts +20 -20
  148. package/Utils/Dashboard/Components/DashboardTraceChartComponent.ts +134 -0
  149. package/Utils/Dashboard/Components/Index.ts +7 -0
  150. package/Utils/Telemetry/EntityKey.ts +151 -0
  151. package/Utils/Telemetry/EntityRelationship.ts +113 -0
  152. package/Utils/Traces/CriticalPath.ts +7 -7
  153. package/Utils/UUID.ts +57 -0
  154. package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.js +14 -13
  155. package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.js.map +1 -1
  156. package/build/dist/Models/AnalyticsModels/AuditLog.js +2 -1
  157. package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
  158. package/build/dist/Models/AnalyticsModels/ExceptionInstance.js +125 -22
  159. package/build/dist/Models/AnalyticsModels/ExceptionInstance.js.map +1 -1
  160. package/build/dist/Models/AnalyticsModels/Index.js +7 -2
  161. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  162. package/build/dist/Models/AnalyticsModels/Log.js +123 -22
  163. package/build/dist/Models/AnalyticsModels/Log.js.map +1 -1
  164. package/build/dist/Models/AnalyticsModels/Metric.js +125 -27
  165. package/build/dist/Models/AnalyticsModels/Metric.js.map +1 -1
  166. package/build/dist/Models/AnalyticsModels/MetricBaselineHourly.js +38 -21
  167. package/build/dist/Models/AnalyticsModels/MetricBaselineHourly.js.map +1 -1
  168. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1m.js +17 -16
  169. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1m.js.map +1 -1
  170. package/build/dist/Models/AnalyticsModels/{MetricItemAggMV1mByHost.js → MetricItemAggMV1mByHostV2.js} +54 -42
  171. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByHostV2.js.map +1 -0
  172. package/build/dist/Models/AnalyticsModels/MonitorLog.js +4 -1
  173. package/build/dist/Models/AnalyticsModels/MonitorLog.js.map +1 -1
  174. package/build/dist/Models/AnalyticsModels/Profile.js +132 -26
  175. package/build/dist/Models/AnalyticsModels/Profile.js.map +1 -1
  176. package/build/dist/Models/AnalyticsModels/ProfileSample.js +121 -23
  177. package/build/dist/Models/AnalyticsModels/ProfileSample.js.map +1 -1
  178. package/build/dist/Models/AnalyticsModels/Span.js +144 -26
  179. package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
  180. package/build/dist/Models/DatabaseModels/CloudResourceInstance.js.map +1 -1
  181. package/build/dist/Models/DatabaseModels/CloudResourceOwnerTeam.js.map +1 -1
  182. package/build/dist/Models/DatabaseModels/CloudResourceOwnerUser.js.map +1 -1
  183. package/build/dist/Models/DatabaseModels/Index.js +4 -0
  184. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  185. package/build/dist/Models/DatabaseModels/Service.js +30 -0
  186. package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
  187. package/build/dist/Models/DatabaseModels/TelemetryEntity.js +419 -0
  188. package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +1 -0
  189. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js +317 -0
  190. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +1 -0
  191. package/build/dist/Models/DatabaseModels/TelemetryException.js +12 -12
  192. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  193. package/build/dist/Models/DatabaseModels/TelemetryUsageBilling.js +7 -7
  194. package/build/dist/Models/DatabaseModels/TelemetryUsageBilling.js.map +1 -1
  195. package/build/dist/Server/API/AIAgentDataAPI.js +14 -13
  196. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  197. package/build/dist/Server/API/DashboardAPI.js +2 -2
  198. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  199. package/build/dist/Server/API/TelemetryAPI.js +425 -129
  200. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  201. package/build/dist/Server/API/TelemetryExceptionAPI.js +2 -2
  202. package/build/dist/Server/API/TelemetryExceptionAPI.js.map +1 -1
  203. package/build/dist/Server/Infrastructure/ClickhouseConfig.js +12 -0
  204. package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
  205. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780931863719-AddTelemetryResourceMetadataColumns.js.map +1 -1
  206. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780933132562-AddServerlessFunctionTables.js.map +1 -1
  207. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1780935387827-AddCloudResourceTables.js.map +1 -1
  208. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781011482945-MigrationName.js +798 -0
  209. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781011482945-MigrationName.js.map +1 -0
  210. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781100000001-RenameTelemetryServiceIdToPrimaryEntityId.js +29 -0
  211. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781100000001-RenameTelemetryServiceIdToPrimaryEntityId.js.map +1 -0
  212. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781200000000-AddTelemetryEntityTable.js +38 -0
  213. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781200000000-AddTelemetryEntityTable.js.map +1 -0
  214. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781200000001-AddTelemetryEntityRelationshipTable.js +33 -0
  215. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781200000001-AddTelemetryEntityRelationshipTable.js.map +1 -0
  216. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781250074195-MigrationName.js +78 -0
  217. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781250074195-MigrationName.js.map +1 -0
  218. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781300000000-AddTelemetryEntityLabels.js +19 -0
  219. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781300000000-AddTelemetryEntityLabels.js.map +1 -0
  220. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781400000000-AddServiceTelemetrySdkLanguage.js +18 -0
  221. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781400000000-AddServiceTelemetrySdkLanguage.js.map +1 -0
  222. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -0
  223. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  224. package/build/dist/Server/Infrastructure/Queue.js +14 -3
  225. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  226. package/build/dist/Server/Middleware/TelemetryIngest.js +16 -18
  227. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  228. package/build/dist/Server/Services/AlertService.js +9 -9
  229. package/build/dist/Server/Services/AlertService.js.map +1 -1
  230. package/build/dist/Server/Services/AnalyticsDatabaseService.js +115 -40
  231. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  232. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js.map +1 -1
  233. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js.map +1 -1
  234. package/build/dist/Server/Services/ExceptionAggregationService.js +38 -18
  235. package/build/dist/Server/Services/ExceptionAggregationService.js.map +1 -1
  236. package/build/dist/Server/Services/HostService.js +2 -1
  237. package/build/dist/Server/Services/HostService.js.map +1 -1
  238. package/build/dist/Server/Services/IncidentService.js +19 -19
  239. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  240. package/build/dist/Server/Services/Index.js +6 -2
  241. package/build/dist/Server/Services/Index.js.map +1 -1
  242. package/build/dist/Server/Services/LogAggregationService.js +100 -42
  243. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  244. package/build/dist/Server/Services/MetricAggregationService.js +27 -14
  245. package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
  246. package/build/dist/Server/Services/MetricBaselineService.js +28 -28
  247. package/build/dist/Server/Services/MetricBaselineService.js.map +1 -1
  248. package/build/dist/Server/Services/MetricItemAggMV1mByHostV2Service.js +28 -0
  249. package/build/dist/Server/Services/MetricItemAggMV1mByHostV2Service.js.map +1 -0
  250. package/build/dist/Server/Services/MetricService.js +116 -31
  251. package/build/dist/Server/Services/MetricService.js.map +1 -1
  252. package/build/dist/Server/Services/OpenTelemetryIngestService.js +103 -36
  253. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  254. package/build/dist/Server/Services/ProfileAggregationService.js +613 -105
  255. package/build/dist/Server/Services/ProfileAggregationService.js.map +1 -1
  256. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js.map +1 -1
  257. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js.map +1 -1
  258. package/build/dist/Server/Services/ServerlessFunctionInstanceService.js +4 -2
  259. package/build/dist/Server/Services/ServerlessFunctionInstanceService.js.map +1 -1
  260. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js +2 -1
  261. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js.map +1 -1
  262. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js +2 -1
  263. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js.map +1 -1
  264. package/build/dist/Server/Services/ServiceService.js +9 -5
  265. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  266. package/build/dist/Server/Services/SpanService.js +217 -15
  267. package/build/dist/Server/Services/SpanService.js.map +1 -1
  268. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +72 -0
  269. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -0
  270. package/build/dist/Server/Services/TelemetryEntityService.js +201 -0
  271. package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -0
  272. package/build/dist/Server/Services/TelemetryExceptionService.js +18 -18
  273. package/build/dist/Server/Services/TelemetryExceptionService.js.map +1 -1
  274. package/build/dist/Server/Services/TelemetryUsageBillingService.js +27 -21
  275. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  276. package/build/dist/Server/Services/TraceAggregationService.js +568 -43
  277. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  278. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +38 -2
  279. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
  280. package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js +36 -2
  281. package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js.map +1 -1
  282. package/build/dist/Server/Types/Database/Permissions/BasePermission.js +25 -1
  283. package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
  284. package/build/dist/Server/Types/Database/Permissions/OwnedScopePermission.js +17 -3
  285. package/build/dist/Server/Types/Database/Permissions/OwnedScopePermission.js.map +1 -1
  286. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +1 -0
  287. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  288. package/build/dist/Server/Types/Database/QueryHelper.js +31 -0
  289. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  290. package/build/dist/Server/Utils/Alert/AlertPrivacyFilter.js +3 -2
  291. package/build/dist/Server/Utils/Alert/AlertPrivacyFilter.js.map +1 -1
  292. package/build/dist/Server/Utils/AlertEpisode/AlertEpisodePrivacyFilter.js +3 -2
  293. package/build/dist/Server/Utils/AlertEpisode/AlertEpisodePrivacyFilter.js.map +1 -1
  294. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
  295. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -0
  296. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +97 -3
  297. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  298. package/build/dist/Server/Utils/Incident/IncidentPrivacyFilter.js +3 -2
  299. package/build/dist/Server/Utils/Incident/IncidentPrivacyFilter.js.map +1 -1
  300. package/build/dist/Server/Utils/IncidentEpisode/IncidentEpisodePrivacyFilter.js +3 -2
  301. package/build/dist/Server/Utils/IncidentEpisode/IncidentEpisodePrivacyFilter.js.map +1 -1
  302. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +1 -1
  303. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  304. package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js +1 -2
  305. package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js.map +1 -1
  306. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +3 -4
  307. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  308. package/build/dist/Server/Utils/PrivacyFilterUtil.js +47 -0
  309. package/build/dist/Server/Utils/PrivacyFilterUtil.js.map +1 -0
  310. package/build/dist/Server/Utils/Profile/PprofEncoder.js +132 -4
  311. package/build/dist/Server/Utils/Profile/PprofEncoder.js.map +1 -1
  312. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +228 -0
  313. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -0
  314. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +5 -0
  315. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
  316. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +569 -0
  317. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -0
  318. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +14 -9
  319. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  320. package/build/dist/Types/AnalyticsDatabase/TableColumnType.js +1 -0
  321. package/build/dist/Types/AnalyticsDatabase/TableColumnType.js.map +1 -1
  322. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  323. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  324. package/build/dist/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.js +2 -0
  325. package/build/dist/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.js.map +1 -0
  326. package/build/dist/Types/Dashboard/DashboardTemplates.js +4 -5
  327. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  328. package/build/dist/Types/Log/LogQueryParser.js +2 -2
  329. package/build/dist/Types/Log/LogQueryParser.js.map +1 -1
  330. package/build/dist/Types/Log/LogQueryToFilter.js +1 -1
  331. package/build/dist/Types/Log/LogQueryToFilter.js.map +1 -1
  332. package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js +9 -1
  333. package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js.map +1 -1
  334. package/build/dist/Types/Monitor/MonitorStepLogMonitor.js +9 -1
  335. package/build/dist/Types/Monitor/MonitorStepLogMonitor.js.map +1 -1
  336. package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js +13 -0
  337. package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js.map +1 -1
  338. package/build/dist/Types/Monitor/MonitorStepProfileMonitor.js +9 -1
  339. package/build/dist/Types/Monitor/MonitorStepProfileMonitor.js.map +1 -1
  340. package/build/dist/Types/Monitor/MonitorStepTraceMonitor.js +9 -1
  341. package/build/dist/Types/Monitor/MonitorStepTraceMonitor.js.map +1 -1
  342. package/build/dist/Types/Monitor/MonitorType.js +8 -1
  343. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  344. package/build/dist/Types/ObjectID.js +9 -0
  345. package/build/dist/Types/ObjectID.js.map +1 -1
  346. package/build/dist/Types/Permission.js.map +1 -1
  347. package/build/dist/Types/Telemetry/EntityRelationshipType.js +32 -0
  348. package/build/dist/Types/Telemetry/EntityRelationshipType.js.map +1 -0
  349. package/build/dist/Types/Telemetry/EntityType.js +34 -0
  350. package/build/dist/Types/Telemetry/EntityType.js.map +1 -0
  351. package/build/dist/Types/Text.js +32 -1
  352. package/build/dist/Types/Text.js.map +1 -1
  353. package/build/dist/Types/Trace/TraceAggregationType.js +1 -0
  354. package/build/dist/Types/Trace/TraceAggregationType.js.map +1 -1
  355. package/build/dist/Types/Trace/TraceRecordingRuleDefinition.js +50 -1
  356. package/build/dist/Types/Trace/TraceRecordingRuleDefinition.js.map +1 -1
  357. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -1
  358. package/build/dist/UI/Components/Forms/Fields/FormField.js +15 -12
  359. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  360. package/build/dist/UI/Components/Input/Input.js +3 -1
  361. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  362. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +10 -9
  363. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  364. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +8 -8
  365. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
  366. package/build/dist/UI/Components/LogsViewer/components/LogSearchBar.js +1 -1
  367. package/build/dist/UI/Components/LogsViewer/components/LogSearchBar.js.map +1 -1
  368. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +2 -2
  369. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  370. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +4 -4
  371. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  372. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +3 -3
  373. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
  374. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +43 -30
  375. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  376. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +6 -2
  377. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  378. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +14 -3
  379. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  380. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +18 -10
  381. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  382. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.js +4 -2
  383. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.js.map +1 -1
  384. package/build/dist/UI/Components/TextArea/TextArea.js +3 -1
  385. package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
  386. package/build/dist/UI/Components/Toast/Toast.js +4 -2
  387. package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
  388. package/build/dist/UI/Utils/LogExport.js +2 -2
  389. package/build/dist/UI/Utils/LogExport.js.map +1 -1
  390. package/build/dist/UI/Utils/TelemetryService.js +16 -16
  391. package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
  392. package/build/dist/Utils/Dashboard/Components/DashboardTraceChartComponent.js +110 -0
  393. package/build/dist/Utils/Dashboard/Components/DashboardTraceChartComponent.js.map +1 -0
  394. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  395. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  396. package/build/dist/Utils/Telemetry/EntityKey.js +115 -0
  397. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -0
  398. package/build/dist/Utils/Telemetry/EntityRelationship.js +71 -0
  399. package/build/dist/Utils/Telemetry/EntityRelationship.js.map +1 -0
  400. package/build/dist/Utils/Traces/CriticalPath.js +5 -5
  401. package/build/dist/Utils/Traces/CriticalPath.js.map +1 -1
  402. package/build/dist/Utils/UUID.js +50 -0
  403. package/build/dist/Utils/UUID.js.map +1 -1
  404. package/package.json +2 -1
  405. package/tsconfig.json +10 -1
  406. package/Server/Services/MetricItemAggMV1mByHostService.ts +0 -30
  407. package/Types/Profile/ProfileMetricType.ts +0 -16
  408. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByHost.js.map +0 -1
  409. package/build/dist/Server/Services/MetricItemAggMV1mByHostService.js +0 -28
  410. package/build/dist/Server/Services/MetricItemAggMV1mByHostService.js.map +0 -1
  411. package/build/dist/Tests/MockType.js +0 -5
  412. package/build/dist/Tests/MockType.js.map +0 -1
  413. package/build/dist/Tests/Models/AnalyticsModels/Log.test.js +0 -12
  414. package/build/dist/Tests/Models/AnalyticsModels/Log.test.js.map +0 -1
  415. package/build/dist/Tests/Models/File.test.js +0 -10
  416. package/build/dist/Tests/Models/File.test.js.map +0 -1
  417. package/build/dist/Tests/Server/API/BaseAPI.test.js +0 -590
  418. package/build/dist/Tests/Server/API/BaseAPI.test.js.map +0 -1
  419. package/build/dist/Tests/Server/API/Helpers.js +0 -27
  420. package/build/dist/Tests/Server/API/Helpers.js.map +0 -1
  421. package/build/dist/Tests/Server/API/ProbeAPI.test.js +0 -84
  422. package/build/dist/Tests/Server/API/ProbeAPI.test.js.map +0 -1
  423. package/build/dist/Tests/Server/API/ProjectAPI.test.js +0 -170
  424. package/build/dist/Tests/Server/API/ProjectAPI.test.js.map +0 -1
  425. package/build/dist/Tests/Server/API/UserSmsApi.test.js +0 -177
  426. package/build/dist/Tests/Server/API/UserSmsApi.test.js.map +0 -1
  427. package/build/dist/Tests/Server/Middleware/BearerTokenAuthorization.test.js +0 -63
  428. package/build/dist/Tests/Server/Middleware/BearerTokenAuthorization.test.js.map +0 -1
  429. package/build/dist/Tests/Server/Middleware/ClusterKeyAuthorization.test.js +0 -58
  430. package/build/dist/Tests/Server/Middleware/ClusterKeyAuthorization.test.js.map +0 -1
  431. package/build/dist/Tests/Server/Middleware/NotificationMiddleware.test.js +0 -101
  432. package/build/dist/Tests/Server/Middleware/NotificationMiddleware.test.js.map +0 -1
  433. package/build/dist/Tests/Server/Middleware/ProjectAuthorization.test.js +0 -160
  434. package/build/dist/Tests/Server/Middleware/ProjectAuthorization.test.js.map +0 -1
  435. package/build/dist/Tests/Server/Middleware/UserAuthorization.test.js +0 -410
  436. package/build/dist/Tests/Server/Middleware/UserAuthorization.test.js.map +0 -1
  437. package/build/dist/Tests/Server/Services/AlertEpisodeMemberService.test.js +0 -165
  438. package/build/dist/Tests/Server/Services/AlertEpisodeMemberService.test.js.map +0 -1
  439. package/build/dist/Tests/Server/Services/AlertEpisodeService.test.js +0 -193
  440. package/build/dist/Tests/Server/Services/AlertEpisodeService.test.js.map +0 -1
  441. package/build/dist/Tests/Server/Services/AlertGroupingEngineService.test.js +0 -435
  442. package/build/dist/Tests/Server/Services/AlertGroupingEngineService.test.js.map +0 -1
  443. package/build/dist/Tests/Server/Services/AlertGroupingRuleService.test.js +0 -320
  444. package/build/dist/Tests/Server/Services/AlertGroupingRuleService.test.js.map +0 -1
  445. package/build/dist/Tests/Server/Services/AnalyticsDatabaseService.test.js +0 -266
  446. package/build/dist/Tests/Server/Services/AnalyticsDatabaseService.test.js.map +0 -1
  447. package/build/dist/Tests/Server/Services/BillingService.test.js +0 -910
  448. package/build/dist/Tests/Server/Services/BillingService.test.js.map +0 -1
  449. package/build/dist/Tests/Server/Services/LogAggregationService.test.js +0 -75
  450. package/build/dist/Tests/Server/Services/LogAggregationService.test.js.map +0 -1
  451. package/build/dist/Tests/Server/Services/ProbeService.test.js +0 -127
  452. package/build/dist/Tests/Server/Services/ProbeService.test.js.map +0 -1
  453. package/build/dist/Tests/Server/Services/ScheduledMaintenanceService.test.js +0 -114
  454. package/build/dist/Tests/Server/Services/ScheduledMaintenanceService.test.js.map +0 -1
  455. package/build/dist/Tests/Server/Services/TeamMemberService.test.js +0 -106
  456. package/build/dist/Tests/Server/Services/TeamMemberService.test.js.map +0 -1
  457. package/build/dist/Tests/Server/Services/TelemetryAttributeService.test.js +0 -50
  458. package/build/dist/Tests/Server/Services/TelemetryAttributeService.test.js.map +0 -1
  459. package/build/dist/Tests/Server/TestingUtils/Init.js +0 -4
  460. package/build/dist/Tests/Server/TestingUtils/Init.js.map +0 -1
  461. package/build/dist/Tests/Server/TestingUtils/Postgres/TestDataSourceOptions.js +0 -9
  462. package/build/dist/Tests/Server/TestingUtils/Postgres/TestDataSourceOptions.js.map +0 -1
  463. package/build/dist/Tests/Server/TestingUtils/Redis/TestRedisOptions.js +0 -16
  464. package/build/dist/Tests/Server/TestingUtils/Redis/TestRedisOptions.js.map +0 -1
  465. package/build/dist/Tests/Server/TestingUtils/Services/BillingServiceHelper.js +0 -125
  466. package/build/dist/Tests/Server/TestingUtils/Services/BillingServiceHelper.js.map +0 -1
  467. package/build/dist/Tests/Server/TestingUtils/Services/ProjectServiceHelper.js +0 -39
  468. package/build/dist/Tests/Server/TestingUtils/Services/ProjectServiceHelper.js.map +0 -1
  469. package/build/dist/Tests/Server/TestingUtils/Services/ScheduledMaintenanceServiceHelper.js +0 -20
  470. package/build/dist/Tests/Server/TestingUtils/Services/ScheduledMaintenanceServiceHelper.js.map +0 -1
  471. package/build/dist/Tests/Server/TestingUtils/Services/ScheduledMaintenanceStateServiceHelper.js +0 -31
  472. package/build/dist/Tests/Server/TestingUtils/Services/ScheduledMaintenanceStateServiceHelper.js.map +0 -1
  473. package/build/dist/Tests/Server/TestingUtils/Services/TeamMemberServiceHelper.js +0 -14
  474. package/build/dist/Tests/Server/TestingUtils/Services/TeamMemberServiceHelper.js.map +0 -1
  475. package/build/dist/Tests/Server/TestingUtils/Services/TeamServiceHelper.js +0 -21
  476. package/build/dist/Tests/Server/TestingUtils/Services/TeamServiceHelper.js.map +0 -1
  477. package/build/dist/Tests/Server/TestingUtils/Services/Types.js +0 -2
  478. package/build/dist/Tests/Server/TestingUtils/Services/Types.js.map +0 -1
  479. package/build/dist/Tests/Server/TestingUtils/Services/UserServiceHelper.js +0 -37
  480. package/build/dist/Tests/Server/TestingUtils/Services/UserServiceHelper.js.map +0 -1
  481. package/build/dist/Tests/Server/TestingUtils/__mocks__/Stripe.mock.js +0 -13
  482. package/build/dist/Tests/Server/TestingUtils/__mocks__/Stripe.mock.js.map +0 -1
  483. package/build/dist/Tests/Server/TestingUtils/__mocks__/TestDatabase.mock.js +0 -22
  484. package/build/dist/Tests/Server/TestingUtils/__mocks__/TestDatabase.mock.js.map +0 -1
  485. package/build/dist/Tests/Server/Types/Domain.test.js +0 -78
  486. package/build/dist/Tests/Server/Types/Domain.test.js.map +0 -1
  487. package/build/dist/Tests/Server/Utils/AnalyticsDatabase/Statement.test.js +0 -94
  488. package/build/dist/Tests/Server/Utils/AnalyticsDatabase/Statement.test.js.map +0 -1
  489. package/build/dist/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.js +0 -459
  490. package/build/dist/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.js.map +0 -1
  491. package/build/dist/Tests/Server/Utils/Cookie.test.js +0 -83
  492. package/build/dist/Tests/Server/Utils/Cookie.test.js.map +0 -1
  493. package/build/dist/Tests/Server/Utils/CronTab.test.js +0 -29
  494. package/build/dist/Tests/Server/Utils/CronTab.test.js.map +0 -1
  495. package/build/dist/Tests/Server/Utils/JsonToCsv.test.js +0 -114
  496. package/build/dist/Tests/Server/Utils/JsonToCsv.test.js.map +0 -1
  497. package/build/dist/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.js +0 -606
  498. package/build/dist/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.js.map +0 -1
  499. package/build/dist/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.js +0 -255
  500. package/build/dist/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.js.map +0 -1
  501. package/build/dist/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.js +0 -142
  502. package/build/dist/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.js.map +0 -1
  503. package/build/dist/Tests/Server/Utils/StatusPageResource.test.js +0 -122
  504. package/build/dist/Tests/Server/Utils/StatusPageResource.test.js.map +0 -1
  505. package/build/dist/Tests/Server/Utils/Telemetry/LogExceptionExtractor.test.js +0 -0
  506. package/build/dist/Tests/Server/Utils/Telemetry/LogExceptionExtractor.test.js.map +0 -1
  507. package/build/dist/Tests/Server/Utils/VM/VMAPI.test.js +0 -205
  508. package/build/dist/Tests/Server/Utils/VM/VMAPI.test.js.map +0 -1
  509. package/build/dist/Tests/Spy.js +0 -4
  510. package/build/dist/Tests/Spy.js.map +0 -1
  511. package/build/dist/Tests/Types/API/ErrorResponse.test.js +0 -13
  512. package/build/dist/Tests/Types/API/ErrorResponse.test.js.map +0 -1
  513. package/build/dist/Tests/Types/API/HTTPErrorResponse.test.js +0 -33
  514. package/build/dist/Tests/Types/API/HTTPErrorResponse.test.js.map +0 -1
  515. package/build/dist/Tests/Types/API/HTTPMethod.test.js +0 -16
  516. package/build/dist/Tests/Types/API/HTTPMethod.test.js.map +0 -1
  517. package/build/dist/Tests/Types/API/Headers.test.js +0 -14
  518. package/build/dist/Tests/Types/API/Headers.test.js.map +0 -1
  519. package/build/dist/Tests/Types/API/Hostname.test.js +0 -22
  520. package/build/dist/Tests/Types/API/Hostname.test.js.map +0 -1
  521. package/build/dist/Tests/Types/API/Protocal.test.js +0 -19
  522. package/build/dist/Tests/Types/API/Protocal.test.js.map +0 -1
  523. package/build/dist/Tests/Types/API/Response.test.js +0 -14
  524. package/build/dist/Tests/Types/API/Response.test.js.map +0 -1
  525. package/build/dist/Tests/Types/API/ResponseType.test.js +0 -13
  526. package/build/dist/Tests/Types/API/ResponseType.test.js.map +0 -1
  527. package/build/dist/Tests/Types/API/Route.test.js +0 -30
  528. package/build/dist/Tests/Types/API/Route.test.js.map +0 -1
  529. package/build/dist/Tests/Types/API/StatusCode.test.js +0 -26
  530. package/build/dist/Tests/Types/API/StatusCode.test.js.map +0 -1
  531. package/build/dist/Tests/Types/API/URL.test.js +0 -33
  532. package/build/dist/Tests/Types/API/URL.test.js.map +0 -1
  533. package/build/dist/Tests/Types/Alerts/AlertEventType.test.js +0 -34
  534. package/build/dist/Tests/Types/Alerts/AlertEventType.test.js.map +0 -1
  535. package/build/dist/Tests/Types/Alerts/AlertType.test.js +0 -19
  536. package/build/dist/Tests/Types/Alerts/AlertType.test.js.map +0 -1
  537. package/build/dist/Tests/Types/AppEnvironment.test.js +0 -13
  538. package/build/dist/Tests/Types/AppEnvironment.test.js.map +0 -1
  539. package/build/dist/Tests/Types/ApplicationLog/ApplicationLogType.test.js +0 -13
  540. package/build/dist/Tests/Types/ApplicationLog/ApplicationLogType.test.js.map +0 -1
  541. package/build/dist/Tests/Types/ArrayUtil.test.js +0 -71
  542. package/build/dist/Tests/Types/ArrayUtil.test.js.map +0 -1
  543. package/build/dist/Tests/Types/Billing/SubscriptionPlan.test.js +0 -181
  544. package/build/dist/Tests/Types/Billing/SubscriptionPlan.test.js.map +0 -1
  545. package/build/dist/Tests/Types/BrandColors.test.js +0 -124
  546. package/build/dist/Tests/Types/BrandColors.test.js.map +0 -1
  547. package/build/dist/Tests/Types/Char.test.js +0 -82
  548. package/build/dist/Tests/Types/Char.test.js.map +0 -1
  549. package/build/dist/Tests/Types/Code/CodeType.test.js +0 -13
  550. package/build/dist/Tests/Types/Code/CodeType.test.js.map +0 -1
  551. package/build/dist/Tests/Types/Color.test.js +0 -44
  552. package/build/dist/Tests/Types/Color.test.js.map +0 -1
  553. package/build/dist/Tests/Types/Company/CompanySize.test.js +0 -20
  554. package/build/dist/Tests/Types/Company/CompanySize.test.js.map +0 -1
  555. package/build/dist/Tests/Types/Company/JobRole.test.js +0 -22
  556. package/build/dist/Tests/Types/Company/JobRole.test.js.map +0 -1
  557. package/build/dist/Tests/Types/Countries.test.js +0 -249
  558. package/build/dist/Tests/Types/Countries.test.js.map +0 -1
  559. package/build/dist/Tests/Types/Database/ColumnLength.test.js +0 -43
  560. package/build/dist/Tests/Types/Database/ColumnLength.test.js.map +0 -1
  561. package/build/dist/Tests/Types/Database/ColumnType.test.js +0 -79
  562. package/build/dist/Tests/Types/Database/ColumnType.test.js.map +0 -1
  563. package/build/dist/Tests/Types/Database/Columns.test.js +0 -20
  564. package/build/dist/Tests/Types/Database/Columns.test.js.map +0 -1
  565. package/build/dist/Tests/Types/Database/CompareBase.test.js +0 -37
  566. package/build/dist/Tests/Types/Database/CompareBase.test.js.map +0 -1
  567. package/build/dist/Tests/Types/Database/Date.test.js +0 -62
  568. package/build/dist/Tests/Types/Database/Date.test.js.map +0 -1
  569. package/build/dist/Tests/Types/Database/EqualTo.test.js +0 -65
  570. package/build/dist/Tests/Types/Database/EqualTo.test.js.map +0 -1
  571. package/build/dist/Tests/Types/Database/EqualToOrNull.test.js +0 -62
  572. package/build/dist/Tests/Types/Database/EqualToOrNull.test.js.map +0 -1
  573. package/build/dist/Tests/Types/Database/InBetween.test.js +0 -72
  574. package/build/dist/Tests/Types/Database/InBetween.test.js.map +0 -1
  575. package/build/dist/Tests/Types/Database/LimitMax.test.js +0 -18
  576. package/build/dist/Tests/Types/Database/LimitMax.test.js.map +0 -1
  577. package/build/dist/Tests/Types/Database/NotEqual.test.js +0 -19
  578. package/build/dist/Tests/Types/Database/NotEqual.test.js.map +0 -1
  579. package/build/dist/Tests/Types/Database/Search.test.js +0 -10
  580. package/build/dist/Tests/Types/Database/Search.test.js.map +0 -1
  581. package/build/dist/Tests/Types/DatabaseType.test.js +0 -7
  582. package/build/dist/Tests/Types/DatabaseType.test.js.map +0 -1
  583. package/build/dist/Tests/Types/Date.test.js +0 -194
  584. package/build/dist/Tests/Types/Date.test.js.map +0 -1
  585. package/build/dist/Tests/Types/Dictionary.test.js +0 -25
  586. package/build/dist/Tests/Types/Dictionary.test.js.map +0 -1
  587. package/build/dist/Tests/Types/Domain.test.js +0 -54
  588. package/build/dist/Tests/Types/Domain.test.js.map +0 -1
  589. package/build/dist/Tests/Types/Email/Email.test.js +0 -51
  590. package/build/dist/Tests/Types/Email/Email.test.js.map +0 -1
  591. package/build/dist/Tests/Types/EmailWithName.test.js +0 -36
  592. package/build/dist/Tests/Types/EmailWithName.test.js.map +0 -1
  593. package/build/dist/Tests/Types/EncryptionAlgorithm.test.js +0 -7
  594. package/build/dist/Tests/Types/EncryptionAlgorithm.test.js.map +0 -1
  595. package/build/dist/Tests/Types/Exception/ApiException.test.js +0 -10
  596. package/build/dist/Tests/Types/Exception/ApiException.test.js.map +0 -1
  597. package/build/dist/Tests/Types/Exception/BadDataException.test.js +0 -12
  598. package/build/dist/Tests/Types/Exception/BadDataException.test.js.map +0 -1
  599. package/build/dist/Tests/Types/Exception/BadOperationException.test.js +0 -10
  600. package/build/dist/Tests/Types/Exception/BadOperationException.test.js.map +0 -1
  601. package/build/dist/Tests/Types/Exception/BadRequestException.test.js +0 -12
  602. package/build/dist/Tests/Types/Exception/BadRequestException.test.js.map +0 -1
  603. package/build/dist/Tests/Types/Exception/DatabaseNotConnectedException.test.js +0 -10
  604. package/build/dist/Tests/Types/Exception/DatabaseNotConnectedException.test.js.map +0 -1
  605. package/build/dist/Tests/Types/Exception/Exception.test.js +0 -15
  606. package/build/dist/Tests/Types/Exception/Exception.test.js.map +0 -1
  607. package/build/dist/Tests/Types/Exception/NotImplementedException.test.js +0 -12
  608. package/build/dist/Tests/Types/Exception/NotImplementedException.test.js.map +0 -1
  609. package/build/dist/Tests/Types/File.test.js +0 -22
  610. package/build/dist/Tests/Types/File.test.js.map +0 -1
  611. package/build/dist/Tests/Types/HashedString.test.js +0 -51
  612. package/build/dist/Tests/Types/HashedString.test.js.map +0 -1
  613. package/build/dist/Tests/Types/Html.test.js +0 -8
  614. package/build/dist/Tests/Types/Html.test.js.map +0 -1
  615. package/build/dist/Tests/Types/IP/IP.test.js +0 -65
  616. package/build/dist/Tests/Types/IP/IP.test.js.map +0 -1
  617. package/build/dist/Tests/Types/IP/IPType.test.js +0 -10
  618. package/build/dist/Tests/Types/IP/IPType.test.js.map +0 -1
  619. package/build/dist/Tests/Types/IP/IPv4.test.js +0 -17
  620. package/build/dist/Tests/Types/IP/IPv4.test.js.map +0 -1
  621. package/build/dist/Tests/Types/IP/IPv6.test.js +0 -17
  622. package/build/dist/Tests/Types/IP/IPv6.test.js.map +0 -1
  623. package/build/dist/Tests/Types/JSON.test.js +0 -37
  624. package/build/dist/Tests/Types/JSON.test.js.map +0 -1
  625. package/build/dist/Tests/Types/JSONFunctions.test.js +0 -38
  626. package/build/dist/Tests/Types/JSONFunctions.test.js.map +0 -1
  627. package/build/dist/Tests/Types/ListData.test.js +0 -34
  628. package/build/dist/Tests/Types/ListData.test.js.map +0 -1
  629. package/build/dist/Tests/Types/Monitor/KubernetesAlertTemplates.test.js +0 -121
  630. package/build/dist/Tests/Types/Monitor/KubernetesAlertTemplates.test.js.map +0 -1
  631. package/build/dist/Tests/Types/Name.test.js +0 -26
  632. package/build/dist/Tests/Types/Name.test.js.map +0 -1
  633. package/build/dist/Tests/Types/ObjectID.test.js +0 -12
  634. package/build/dist/Tests/Types/ObjectID.test.js.map +0 -1
  635. package/build/dist/Tests/Types/OnCallDutyPolicy/LayerUtil.test.js +0 -530
  636. package/build/dist/Tests/Types/OnCallDutyPolicy/LayerUtil.test.js.map +0 -1
  637. package/build/dist/Tests/Types/Permission.test.js +0 -99
  638. package/build/dist/Tests/Types/Permission.test.js.map +0 -1
  639. package/build/dist/Tests/Types/Phone.test.js +0 -37
  640. package/build/dist/Tests/Types/Phone.test.js.map +0 -1
  641. package/build/dist/Tests/Types/Port.test.js +0 -35
  642. package/build/dist/Tests/Types/Port.test.js.map +0 -1
  643. package/build/dist/Tests/Types/PositiveNumber.test.js +0 -101
  644. package/build/dist/Tests/Types/PositiveNumber.test.js.map +0 -1
  645. package/build/dist/Tests/Types/SecuritySeverity.test.js +0 -16
  646. package/build/dist/Tests/Types/SecuritySeverity.test.js.map +0 -1
  647. package/build/dist/Tests/Types/SerializableObject.test.js +0 -37
  648. package/build/dist/Tests/Types/SerializableObject.test.js.map +0 -1
  649. package/build/dist/Tests/Types/Sleep.test.js +0 -14
  650. package/build/dist/Tests/Types/Sleep.test.js.map +0 -1
  651. package/build/dist/Tests/Types/Text.test.js +0 -8
  652. package/build/dist/Tests/Types/Text.test.js.map +0 -1
  653. package/build/dist/Tests/Types/Timezone.test.js +0 -596
  654. package/build/dist/Tests/Types/Timezone.test.js.map +0 -1
  655. package/build/dist/Tests/Types/Typeof.test.js +0 -16
  656. package/build/dist/Tests/Types/Typeof.test.js.map +0 -1
  657. package/build/dist/Tests/Types/UserType.test.js +0 -16
  658. package/build/dist/Tests/Types/UserType.test.js.map +0 -1
  659. package/build/dist/Tests/Types/Version.test.js +0 -35
  660. package/build/dist/Tests/Types/Version.test.js.map +0 -1
  661. package/build/dist/Tests/Types/XML.test.js +0 -35
  662. package/build/dist/Tests/Types/XML.test.js.map +0 -1
  663. package/build/dist/Tests/UI/Components/404.test.js +0 -59
  664. package/build/dist/Tests/UI/Components/404.test.js.map +0 -1
  665. package/build/dist/Tests/UI/Components/Alert.test.js +0 -83
  666. package/build/dist/Tests/UI/Components/Alert.test.js.map +0 -1
  667. package/build/dist/Tests/UI/Components/Badge.test.js +0 -59
  668. package/build/dist/Tests/UI/Components/Badge.test.js.map +0 -1
  669. package/build/dist/Tests/UI/Components/BasicForm.test.js +0 -92
  670. package/build/dist/Tests/UI/Components/BasicForm.test.js.map +0 -1
  671. package/build/dist/Tests/UI/Components/Breadcrumbs.test.js +0 -69
  672. package/build/dist/Tests/UI/Components/Breadcrumbs.test.js.map +0 -1
  673. package/build/dist/Tests/UI/Components/Button.test.js +0 -104
  674. package/build/dist/Tests/UI/Components/Button.test.js.map +0 -1
  675. package/build/dist/Tests/UI/Components/Card.test.js +0 -81
  676. package/build/dist/Tests/UI/Components/Card.test.js.map +0 -1
  677. package/build/dist/Tests/UI/Components/ColorViewer.test.js +0 -42
  678. package/build/dist/Tests/UI/Components/ColorViewer.test.js.map +0 -1
  679. package/build/dist/Tests/UI/Components/ComponentsModal.test.js +0 -233
  680. package/build/dist/Tests/UI/Components/ComponentsModal.test.js.map +0 -1
  681. package/build/dist/Tests/UI/Components/ConfirmModal.test.js +0 -57
  682. package/build/dist/Tests/UI/Components/ConfirmModal.test.js.map +0 -1
  683. package/build/dist/Tests/UI/Components/DictionaryOfStrings.test.js +0 -84
  684. package/build/dist/Tests/UI/Components/DictionaryOfStrings.test.js.map +0 -1
  685. package/build/dist/Tests/UI/Components/Dropdown.test.js +0 -146
  686. package/build/dist/Tests/UI/Components/Dropdown.test.js.map +0 -1
  687. package/build/dist/Tests/UI/Components/DuplicateModel.test.js +0 -229
  688. package/build/dist/Tests/UI/Components/DuplicateModel.test.js.map +0 -1
  689. package/build/dist/Tests/UI/Components/EmptyState/EmptyState.test.js +0 -26
  690. package/build/dist/Tests/UI/Components/EmptyState/EmptyState.test.js.map +0 -1
  691. package/build/dist/Tests/UI/Components/ErrorBoundary.test.js +0 -32
  692. package/build/dist/Tests/UI/Components/ErrorBoundary.test.js.map +0 -1
  693. package/build/dist/Tests/UI/Components/FilePicker.test.js +0 -342
  694. package/build/dist/Tests/UI/Components/FilePicker.test.js.map +0 -1
  695. package/build/dist/Tests/UI/Components/HiddenText.test.js +0 -50
  696. package/build/dist/Tests/UI/Components/HiddenText.test.js.map +0 -1
  697. package/build/dist/Tests/UI/Components/Input.test.js +0 -223
  698. package/build/dist/Tests/UI/Components/Input.test.js.map +0 -1
  699. package/build/dist/Tests/UI/Components/Item.test.js +0 -58
  700. package/build/dist/Tests/UI/Components/Item.test.js.map +0 -1
  701. package/build/dist/Tests/UI/Components/List.test.js +0 -83
  702. package/build/dist/Tests/UI/Components/List.test.js.map +0 -1
  703. package/build/dist/Tests/UI/Components/Loader.test.js +0 -19
  704. package/build/dist/Tests/UI/Components/Loader.test.js.map +0 -1
  705. package/build/dist/Tests/UI/Components/MarkdownEditor.test.js +0 -85
  706. package/build/dist/Tests/UI/Components/MarkdownEditor.test.js.map +0 -1
  707. package/build/dist/Tests/UI/Components/MasterPage.test.js +0 -46
  708. package/build/dist/Tests/UI/Components/MasterPage.test.js.map +0 -1
  709. package/build/dist/Tests/UI/Components/Modal.test.js +0 -127
  710. package/build/dist/Tests/UI/Components/Modal.test.js.map +0 -1
  711. package/build/dist/Tests/UI/Components/NavBar.test.js +0 -52
  712. package/build/dist/Tests/UI/Components/NavBar.test.js.map +0 -1
  713. package/build/dist/Tests/UI/Components/OrderedStatesList.test.js +0 -86
  714. package/build/dist/Tests/UI/Components/OrderedStatesList.test.js.map +0 -1
  715. package/build/dist/Tests/UI/Components/Pagination.test.js +0 -137
  716. package/build/dist/Tests/UI/Components/Pagination.test.js.map +0 -1
  717. package/build/dist/Tests/UI/Components/Pill.test.js +0 -55
  718. package/build/dist/Tests/UI/Components/Pill.test.js.map +0 -1
  719. package/build/dist/Tests/UI/Components/Probe.test.js +0 -52
  720. package/build/dist/Tests/UI/Components/Probe.test.js.map +0 -1
  721. package/build/dist/Tests/UI/Components/ProgressBar.test.js +0 -41
  722. package/build/dist/Tests/UI/Components/ProgressBar.test.js.map +0 -1
  723. package/build/dist/Tests/UI/Components/RadioButtons.test.js +0 -66
  724. package/build/dist/Tests/UI/Components/RadioButtons.test.js.map +0 -1
  725. package/build/dist/Tests/UI/Components/SideMenuItem.test.js +0 -99
  726. package/build/dist/Tests/UI/Components/SideMenuItem.test.js.map +0 -1
  727. package/build/dist/Tests/UI/Components/SideOver.test.js +0 -77
  728. package/build/dist/Tests/UI/Components/SideOver.test.js.map +0 -1
  729. package/build/dist/Tests/UI/Components/Tabs.test.js +0 -56
  730. package/build/dist/Tests/UI/Components/Tabs.test.js.map +0 -1
  731. package/build/dist/Tests/UI/Components/Template/Template.test.js +0 -15
  732. package/build/dist/Tests/UI/Components/Template/Template.test.js.map +0 -1
  733. package/build/dist/Tests/UI/Components/TextArea.test.js +0 -112
  734. package/build/dist/Tests/UI/Components/TextArea.test.js.map +0 -1
  735. package/build/dist/Tests/UI/Components/TimePicker/TimePicker.test.js +0 -352
  736. package/build/dist/Tests/UI/Components/TimePicker/TimePicker.test.js.map +0 -1
  737. package/build/dist/Tests/UI/Components/Toast.test.js +0 -48
  738. package/build/dist/Tests/UI/Components/Toast.test.js.map +0 -1
  739. package/build/dist/Tests/UI/Components/Toggle.test.js +0 -95
  740. package/build/dist/Tests/UI/Components/Toggle.test.js.map +0 -1
  741. package/build/dist/Tests/UI/Components/TopSection.test.js +0 -33
  742. package/build/dist/Tests/UI/Components/TopSection.test.js.map +0 -1
  743. package/build/dist/Tests/UI/Components/XAxis.test.js +0 -21
  744. package/build/dist/Tests/UI/Components/XAxis.test.js.map +0 -1
  745. package/build/dist/Tests/UI/Index.js +0 -2
  746. package/build/dist/Tests/UI/Index.js.map +0 -1
  747. package/build/dist/Tests/UI/Mocks/FileMock.js +0 -3
  748. package/build/dist/Tests/UI/Mocks/FileMock.js.map +0 -1
  749. package/build/dist/Tests/Utils/API.test.js +0 -399
  750. package/build/dist/Tests/Utils/API.test.js.map +0 -1
  751. package/build/dist/Tests/Utils/Analytics.test.js +0 -67
  752. package/build/dist/Tests/Utils/Analytics.test.js.map +0 -1
  753. package/build/dist/Tests/Utils/CronTime.test.js +0 -22
  754. package/build/dist/Tests/Utils/CronTime.test.js.map +0 -1
  755. package/build/dist/Tests/Utils/Faker.test.js +0 -27
  756. package/build/dist/Tests/Utils/Faker.test.js.map +0 -1
  757. package/build/dist/Tests/Utils/MetricUnitUtil.test.js +0 -187
  758. package/build/dist/Tests/Utils/MetricUnitUtil.test.js.map +0 -1
  759. package/build/dist/Tests/Utils/Metrics/MetricFormulaEvaluator.test.js +0 -224
  760. package/build/dist/Tests/Utils/Metrics/MetricFormulaEvaluator.test.js.map +0 -1
  761. package/build/dist/Tests/Utils/Metrics/MetricResultUnitConverter.test.js +0 -180
  762. package/build/dist/Tests/Utils/Metrics/MetricResultUnitConverter.test.js.map +0 -1
  763. package/build/dist/Tests/Utils/RecordingRuleExpression.test.js +0 -142
  764. package/build/dist/Tests/Utils/RecordingRuleExpression.test.js.map +0 -1
  765. package/build/dist/Tests/Utils/Slug.test.js +0 -20
  766. package/build/dist/Tests/Utils/Slug.test.js.map +0 -1
  767. package/build/dist/Tests/Utils/UUID.test.js +0 -48
  768. package/build/dist/Tests/Utils/UUID.test.js.map +0 -1
  769. package/build/dist/Tests/jest.setup.js +0 -30
  770. package/build/dist/Tests/jest.setup.js.map +0 -1
  771. package/build/dist/Types/Profile/ProfileMetricType.js +0 -17
  772. package/build/dist/Types/Profile/ProfileMetricType.js.map +0 -1
@@ -1,5 +1,7 @@
1
1
  import { SQL, Statement } from "../Utils/AnalyticsDatabase/Statement";
2
+ import { getQuerySettings } from "../Utils/AnalyticsDatabase/QuerySettingsHelper";
2
3
  import ProfileSampleDatabaseService from "./ProfileSampleService";
4
+ import ProfileDatabaseService from "./ProfileService";
3
5
  import TableColumnType from "../../Types/AnalyticsDatabase/TableColumnType";
4
6
  import { JSONObject } from "../../Types/JSON";
5
7
  import ObjectID from "../../Types/ObjectID";
@@ -39,6 +41,15 @@ export interface FlamegraphRequest {
39
41
  profileTypes?: Array<string>;
40
42
  }
41
43
 
44
+ export interface FlamegraphResult {
45
+ flamegraph: ProfileFlamegraphNode;
46
+ /**
47
+ * True when the unique-stack LIMIT was hit, i.e. the smallest stacks in
48
+ * the window were dropped and the tree undercounts the true totals.
49
+ */
50
+ truncated: boolean;
51
+ }
52
+
42
53
  export interface FunctionListItem {
43
54
  functionName: string;
44
55
  fileName: string;
@@ -50,8 +61,19 @@ export interface FunctionListItem {
50
61
 
51
62
  export interface FunctionListRequest {
52
63
  projectId: ObjectID;
53
- startTime: Date;
54
- endTime: Date;
64
+ /**
65
+ * When present, restricts the list to the samples of a single ingested
66
+ * profile so the per-profile detail view and the windowed view share
67
+ * one code path.
68
+ */
69
+ profileId?: string;
70
+ /**
71
+ * Optional when profileId is given: a single profile's samples are
72
+ * already bounded, and forcing a window here would silently drop any
73
+ * profile captured before the window started.
74
+ */
75
+ startTime?: Date;
76
+ endTime?: Date;
55
77
  serviceIds?: Array<ObjectID>;
56
78
  profileType?: string;
57
79
  profileTypes?: Array<string>;
@@ -59,6 +81,21 @@ export interface FunctionListRequest {
59
81
  sortBy?: "selfValue" | "totalValue" | "sampleCount";
60
82
  }
61
83
 
84
+ export interface FunctionListResult {
85
+ functions: Array<FunctionListItem>;
86
+ /**
87
+ * Sum of `value` across ALL sample rows matching the filters (computed
88
+ * pre-limit, same unit as the per-function values). Lets the UI render
89
+ * accurate "% of total" figures even when the list is truncated.
90
+ */
91
+ windowTotal: number;
92
+ /**
93
+ * True when the unique-stack LIMIT was hit, i.e. the smallest stacks in
94
+ * the window were dropped and per-function values undercount.
95
+ */
96
+ truncated: boolean;
97
+ }
98
+
62
99
  export interface ServiceActivityRequest {
63
100
  projectId: ObjectID;
64
101
  startTime: Date;
@@ -77,7 +114,7 @@ export interface ServiceActivityRequest {
77
114
  }
78
115
 
79
116
  export interface ServiceActivityItem {
80
- serviceId: string;
117
+ primaryEntityId: string;
81
118
  sampleCount: number;
82
119
  profileCount: number;
83
120
  totalValue: number;
@@ -109,6 +146,100 @@ export interface DiffFlamegraphNode {
109
146
  frameType: string;
110
147
  }
111
148
 
149
+ export interface DiffFlamegraphResult {
150
+ diffFlamegraph: DiffFlamegraphNode;
151
+ /**
152
+ * True when EITHER window's unique-stack LIMIT was hit. A truncated
153
+ * side undercounts its totals, which would otherwise masquerade as a
154
+ * regression/improvement in the delta — the UI must caveat the diff.
155
+ */
156
+ truncated: boolean;
157
+ }
158
+
159
+ export interface FunctionFocusRequest {
160
+ projectId: ObjectID;
161
+ functionName: string;
162
+ /**
163
+ * May be the empty string: bare frames (folded/collapsed uploads and
164
+ * address-only frames) carry no file information, and the empty
165
+ * fileName is part of the function's identity for matching.
166
+ */
167
+ fileName: string;
168
+ profileId?: string;
169
+ startTime?: Date;
170
+ endTime?: Date;
171
+ serviceIds?: Array<ObjectID>;
172
+ profileType?: string;
173
+ profileTypes?: Array<string>;
174
+ }
175
+
176
+ export interface FunctionFocusResult {
177
+ functionName: string;
178
+ fileName: string;
179
+ /**
180
+ * Sum of `value` over every matching stack, counted once per stack
181
+ * even when the function recurses. Equals callers.totalValue and
182
+ * callees.totalValue (both trees are rooted at the focused function).
183
+ */
184
+ totalValue: number;
185
+ /** Sum of `value` over stacks where the focused function is the leaf. */
186
+ selfValue: number;
187
+ sampleCount: number;
188
+ /**
189
+ * Sum of `value` over ALL rows matching the non-function filters, so
190
+ * the UI can show "% of window" figures for the focused function.
191
+ */
192
+ windowTotal: number;
193
+ /**
194
+ * Root = the focused function; children = DIRECT callers, grandchildren
195
+ * = callers-of-callers. Node weights are the value flowing through that
196
+ * caller chain into the function.
197
+ */
198
+ callers: ProfileFlamegraphNode;
199
+ /**
200
+ * Root = the focused function; children = direct callees (frames toward
201
+ * the leaf), and so on.
202
+ */
203
+ callees: ProfileFlamegraphNode;
204
+ truncated: boolean;
205
+ }
206
+
207
+ export interface BreakdownRequest {
208
+ projectId: ObjectID;
209
+ startTime: Date;
210
+ endTime: Date;
211
+ /**
212
+ * "service" groups by primaryEntityId; any other value is treated as a
213
+ * Profile attribute key and groups by that attribute's value.
214
+ */
215
+ breakdownBy: string;
216
+ serviceIds?: Array<ObjectID>;
217
+ profileType?: string;
218
+ profileTypes?: Array<string>;
219
+ limit?: number;
220
+ }
221
+
222
+ export interface BreakdownItem {
223
+ /**
224
+ * The group value: a primaryEntityId string for breakdownBy="service"
225
+ * (the UI resolves display names), otherwise the raw attribute value.
226
+ */
227
+ value: string;
228
+ sampleCount: number;
229
+ profileCount: number;
230
+ /** 0-100 percentage of totalSampleCount. */
231
+ share: number;
232
+ }
233
+
234
+ export interface BreakdownResult {
235
+ items: Array<BreakdownItem>;
236
+ /**
237
+ * Sum of sampleCount across ALL groups (computed pre-limit), so shares
238
+ * stay accurate even when only the top-N items are returned.
239
+ */
240
+ totalSampleCount: number;
241
+ }
242
+
112
243
  interface ParsedFrame {
113
244
  functionName: string;
114
245
  fileName: string;
@@ -119,25 +250,45 @@ interface ParsedFrame {
119
250
 
120
251
  export class ProfileAggregationService {
121
252
  private static readonly TABLE_NAME: string = AnalyticsTableName.ProfileSample;
253
+ private static readonly PROFILE_TABLE_NAME: string =
254
+ AnalyticsTableName.Profile;
122
255
  private static readonly DEFAULT_FUNCTION_LIST_LIMIT: number = 50;
123
- private static readonly MAX_SAMPLE_FETCH: number = 50000;
256
+ private static readonly DEFAULT_BREAKDOWN_LIMIT: number = 10;
257
+ /**
258
+ * Cap on unique groups fetched by a breakdown query. Groups are ordered
259
+ * by summed sampleCount, so hitting the cap drops the quietest groups
260
+ * first — totals over the fetched groups stay representative even for
261
+ * pathological high-cardinality attribute keys.
262
+ */
263
+ private static readonly MAX_BREAKDOWN_GROUP_FETCH: number = 10000;
264
+ /**
265
+ * Cap on unique (stacktrace, frameTypes) groups fetched per query.
266
+ * Sample reads GROUP BY stack identity and ORDER BY summed value, so
267
+ * hitting this cap drops the *smallest* stacks first — truncation is
268
+ * deterministic and barely visible in a flamegraph, unlike a LIMIT over
269
+ * raw unordered sample rows.
270
+ */
271
+ private static readonly MAX_STACK_FETCH: number = 10000;
124
272
 
125
273
  /**
126
274
  * Build a flamegraph tree from ProfileSample records.
127
275
  *
128
276
  * Each sample has a `stacktrace` array where each element follows the
129
277
  * format "functionName@fileName:lineNumber". The array is ordered
130
- * bottom-up (index 0 = root, last index = leaf).
278
+ * LEAF-FIRST (index 0 = leaf, last index = root) — the pprof
279
+ * Sample.location_id and OTLP Stack.location_indices conventions both
280
+ * store the innermost frame first, and ingestion preserves wire order.
131
281
  *
132
- * We aggregate samples that share common stack prefixes into a tree of
282
+ * Samples are pre-aggregated in ClickHouse by stack identity, then
283
+ * stacks sharing common prefixes are merged into a tree of
133
284
  * ProfileFlamegraphNode objects.
134
285
  */
135
286
  @CaptureSpan()
136
287
  public static async getFlamegraph(
137
288
  request: FlamegraphRequest,
138
- ): Promise<ProfileFlamegraphNode> {
289
+ ): Promise<FlamegraphResult> {
139
290
  const statement: Statement =
140
- ProfileAggregationService.buildFlamegraphQuery(request);
291
+ ProfileAggregationService.buildGroupedStackQuery(request);
141
292
 
142
293
  const dbResult: Results =
143
294
  await ProfileSampleDatabaseService.executeQuery(statement);
@@ -146,8 +297,10 @@ export class ProfileAggregationService {
146
297
  }>();
147
298
 
148
299
  const rows: Array<JSONObject> = response.data || [];
300
+ const truncated: boolean =
301
+ rows.length >= ProfileAggregationService.MAX_STACK_FETCH;
149
302
 
150
- // Build the tree from samples
303
+ // Build the tree from the pre-aggregated stacks
151
304
  const root: ProfileFlamegraphNode = {
152
305
  functionName: "(root)",
153
306
  fileName: "",
@@ -158,36 +311,52 @@ export class ProfileAggregationService {
158
311
  frameType: "",
159
312
  };
160
313
 
314
+ /*
315
+ * Per-node child index so frame lookup is O(1) instead of a linear
316
+ * children.find() — wide fan-out (thousands of siblings under root)
317
+ * made the scan quadratic. Kept outside the nodes so the serialized
318
+ * tree shape is unchanged.
319
+ */
320
+ const childIndex: WeakMap<
321
+ ProfileFlamegraphNode,
322
+ Map<string, ProfileFlamegraphNode>
323
+ > = new WeakMap();
324
+
161
325
  for (const row of rows) {
162
326
  const stacktrace: Array<string> =
163
327
  (row["stacktrace"] as Array<string>) || [];
164
328
  const frameTypes: Array<string> =
165
329
  (row["frameTypes"] as Array<string>) || [];
166
- const value: number = Number(row["value"] || 0);
330
+ const value: number = Number(row["totalValue"] || 0);
167
331
 
168
332
  if (stacktrace.length === 0) {
169
333
  continue;
170
334
  }
171
335
 
172
- // Walk down the tree, creating nodes as needed
336
+ /*
337
+ * Walk down the tree, creating nodes as needed. Stored stacks are
338
+ * leaf-first, so iterate from the END of the array (root) toward
339
+ * index 0 (leaf) to build the tree root-to-leaf.
340
+ */
173
341
  let currentNode: ProfileFlamegraphNode = root;
174
342
  currentNode.totalValue += value;
175
343
 
176
- for (let i: number = 0; i < stacktrace.length; i++) {
344
+ for (let i: number = stacktrace.length - 1; i >= 0; i--) {
177
345
  const frame: ParsedFrame = ProfileAggregationService.parseFrame(
178
346
  stacktrace[i]!,
179
347
  );
180
348
  const frameType: string = frameTypes[i] || "";
349
+ const frameKey: string = `${frame.functionName}@${frame.fileName}:${frame.lineNumber}`;
350
+
351
+ let index: Map<string, ProfileFlamegraphNode> | undefined =
352
+ childIndex.get(currentNode);
181
353
 
182
- // Find or create child
183
- let childNode: ProfileFlamegraphNode | undefined =
184
- currentNode.children.find((child: ProfileFlamegraphNode): boolean => {
185
- return (
186
- child.functionName === frame.functionName &&
187
- child.fileName === frame.fileName &&
188
- child.lineNumber === frame.lineNumber
189
- );
190
- });
354
+ if (!index) {
355
+ index = new Map<string, ProfileFlamegraphNode>();
356
+ childIndex.set(currentNode, index);
357
+ }
358
+
359
+ let childNode: ProfileFlamegraphNode | undefined = index.get(frameKey);
191
360
 
192
361
  if (!childNode) {
193
362
  childNode = {
@@ -200,12 +369,13 @@ export class ProfileAggregationService {
200
369
  frameType: frameType,
201
370
  };
202
371
  currentNode.children.push(childNode);
372
+ index.set(frameKey, childNode);
203
373
  }
204
374
 
205
375
  childNode.totalValue += value;
206
376
 
207
- // If this is the leaf frame, add to selfValue
208
- if (i === stacktrace.length - 1) {
377
+ // Index 0 is the leaf frame in leaf-first storage — it gets selfValue
378
+ if (i === 0) {
209
379
  childNode.selfValue += value;
210
380
  }
211
381
 
@@ -213,29 +383,67 @@ export class ProfileAggregationService {
213
383
  }
214
384
  }
215
385
 
216
- return root;
386
+ return { flamegraph: root, truncated };
217
387
  }
218
388
 
219
389
  /**
220
390
  * Return the top functions aggregated across samples, sorted by the
221
- * requested metric (selfValue, totalValue, or sampleCount).
391
+ * requested metric (selfValue, totalValue, or sampleCount), along with
392
+ * the pre-limit window total so callers can show "% of total" figures.
222
393
  */
223
394
  @CaptureSpan()
224
395
  public static async getFunctionList(
225
396
  request: FunctionListRequest,
226
- ): Promise<Array<FunctionListItem>> {
397
+ ): Promise<FunctionListResult> {
398
+ const filters: FlamegraphRequest = {
399
+ projectId: request.projectId,
400
+ ...(request.startTime !== undefined && { startTime: request.startTime }),
401
+ ...(request.endTime !== undefined && { endTime: request.endTime }),
402
+ ...(request.profileId !== undefined && { profileId: request.profileId }),
403
+ ...(request.serviceIds !== undefined && {
404
+ serviceIds: request.serviceIds,
405
+ }),
406
+ ...(request.profileType !== undefined && {
407
+ profileType: request.profileType,
408
+ }),
409
+ ...(request.profileTypes !== undefined && {
410
+ profileTypes: request.profileTypes,
411
+ }),
412
+ };
413
+
227
414
  const statement: Statement =
228
- ProfileAggregationService.buildFunctionListQuery(request);
415
+ ProfileAggregationService.buildGroupedStackQuery(filters);
416
+ const windowTotalStatement: Statement =
417
+ ProfileAggregationService.buildWindowTotalQuery(filters);
418
+
419
+ /*
420
+ * The window total must be computed over ALL matching rows (pre-limit),
421
+ * so it cannot be derived from the capped grouped result. It is a
422
+ * single cheap aggregate, so run both queries concurrently.
423
+ */
424
+ const [dbResult, windowTotalDbResult]: [Results, Results] =
425
+ await Promise.all([
426
+ ProfileSampleDatabaseService.executeQuery(statement),
427
+ ProfileSampleDatabaseService.executeQuery(windowTotalStatement),
428
+ ]);
229
429
 
230
- const dbResult: Results =
231
- await ProfileSampleDatabaseService.executeQuery(statement);
232
430
  const response: DbJSONResponse = await dbResult.json<{
233
431
  data?: Array<JSONObject>;
234
432
  }>();
433
+ const windowTotalResponse: DbJSONResponse = await windowTotalDbResult.json<{
434
+ data?: Array<JSONObject>;
435
+ }>();
235
436
 
236
437
  const rows: Array<JSONObject> = response.data || [];
438
+ const truncated: boolean =
439
+ rows.length >= ProfileAggregationService.MAX_STACK_FETCH;
237
440
 
238
- // Aggregate per-function stats in-memory from the raw samples
441
+ const windowTotalRows: Array<JSONObject> = windowTotalResponse.data || [];
442
+ const windowTotal: number = Number(
443
+ windowTotalRows[0]?.["windowTotal"] || 0,
444
+ );
445
+
446
+ // Aggregate per-function stats from the pre-aggregated stacks
239
447
  const functionMap: Map<
240
448
  string,
241
449
  {
@@ -253,7 +461,12 @@ export class ProfileAggregationService {
253
461
  (row["stacktrace"] as Array<string>) || [];
254
462
  const frameTypes: Array<string> =
255
463
  (row["frameTypes"] as Array<string>) || [];
256
- const value: number = Number(row["value"] || 0);
464
+ const value: number = Number(row["totalValue"] || 0);
465
+ /*
466
+ * Each grouped row stands in for `sampleCount` raw samples sharing
467
+ * one stack, so per-function sample counts add the group size, not 1.
468
+ */
469
+ const groupSampleCount: number = Number(row["sampleCount"] || 0);
257
470
 
258
471
  if (stacktrace.length === 0) {
259
472
  continue;
@@ -267,7 +480,8 @@ export class ProfileAggregationService {
267
480
  );
268
481
  const frameType: string = frameTypes[i] || "";
269
482
  const key: string = `${frame.functionName}@${frame.fileName}:${frame.lineNumber}`;
270
- const isLeaf: boolean = i === stacktrace.length - 1;
483
+ // Stacks are stored leaf-first, so index 0 is the leaf frame.
484
+ const isLeaf: boolean = i === 0;
271
485
 
272
486
  let entry: FunctionListItem | undefined = functionMap.get(key);
273
487
 
@@ -283,10 +497,10 @@ export class ProfileAggregationService {
283
497
  functionMap.set(key, entry);
284
498
  }
285
499
 
286
- // totalValue: count the value once per unique function per sample
500
+ // totalValue: count the value once per unique function per stack
287
501
  if (!seenInThisSample.has(key)) {
288
502
  entry.totalValue += value;
289
- entry.sampleCount += 1;
503
+ entry.sampleCount += groupSampleCount;
290
504
  seenInThisSample.add(key);
291
505
  }
292
506
 
@@ -316,19 +530,320 @@ export class ProfileAggregationService {
316
530
  const limit: number =
317
531
  request.limit ?? ProfileAggregationService.DEFAULT_FUNCTION_LIST_LIMIT;
318
532
 
319
- return items.slice(0, limit);
533
+ return {
534
+ functions: items.slice(0, limit),
535
+ windowTotal,
536
+ truncated,
537
+ };
538
+ }
539
+
540
+ /**
541
+ * "Sandwich" aggregation for one function: every matching stack is
542
+ * split at the focused function, the frames toward the root become the
543
+ * callers tree and the frames toward the leaf become the callees tree.
544
+ * Both trees are rooted at the focused function itself so the UI can
545
+ * render them stacked around a single center row.
546
+ *
547
+ * Frames match on functionName + fileName only — line numbers shift on
548
+ * every deploy (and with inlining), so including them would split one
549
+ * logical function into many.
550
+ */
551
+ @CaptureSpan()
552
+ public static async getFunctionFocus(
553
+ request: FunctionFocusRequest,
554
+ ): Promise<FunctionFocusResult> {
555
+ const filters: FlamegraphRequest = {
556
+ projectId: request.projectId,
557
+ ...(request.profileId !== undefined && { profileId: request.profileId }),
558
+ ...(request.startTime !== undefined && { startTime: request.startTime }),
559
+ ...(request.endTime !== undefined && { endTime: request.endTime }),
560
+ ...(request.serviceIds !== undefined && {
561
+ serviceIds: request.serviceIds,
562
+ }),
563
+ ...(request.profileType !== undefined && {
564
+ profileType: request.profileType,
565
+ }),
566
+ ...(request.profileTypes !== undefined && {
567
+ profileTypes: request.profileTypes,
568
+ }),
569
+ };
570
+
571
+ const statement: Statement =
572
+ ProfileAggregationService.buildFunctionStackQuery(
573
+ filters,
574
+ request.functionName,
575
+ request.fileName,
576
+ );
577
+ const windowTotalStatement: Statement =
578
+ ProfileAggregationService.buildWindowTotalQuery(filters);
579
+
580
+ /*
581
+ * windowTotal deliberately ignores the function prefilter — it is the
582
+ * denominator for "% of window" figures, so it must cover every row
583
+ * matching the non-function filters. Both reads are independent, so
584
+ * run them concurrently.
585
+ */
586
+ const [dbResult, windowTotalDbResult]: [Results, Results] =
587
+ await Promise.all([
588
+ ProfileSampleDatabaseService.executeQuery(statement),
589
+ ProfileSampleDatabaseService.executeQuery(windowTotalStatement),
590
+ ]);
591
+
592
+ const response: DbJSONResponse = await dbResult.json<{
593
+ data?: Array<JSONObject>;
594
+ }>();
595
+ const windowTotalResponse: DbJSONResponse = await windowTotalDbResult.json<{
596
+ data?: Array<JSONObject>;
597
+ }>();
598
+
599
+ const rows: Array<JSONObject> = response.data || [];
600
+ const truncated: boolean =
601
+ rows.length >= ProfileAggregationService.MAX_STACK_FETCH;
602
+
603
+ const windowTotalRows: Array<JSONObject> = windowTotalResponse.data || [];
604
+ const windowTotal: number = Number(
605
+ windowTotalRows[0]?.["windowTotal"] || 0,
606
+ );
607
+
608
+ /*
609
+ * Both trees are rooted at the focused function. lineNumber is 0
610
+ * because the view aggregates across line numbers by design.
611
+ */
612
+ const callers: ProfileFlamegraphNode = {
613
+ functionName: request.functionName,
614
+ fileName: request.fileName,
615
+ lineNumber: 0,
616
+ selfValue: 0,
617
+ totalValue: 0,
618
+ children: [],
619
+ frameType: "",
620
+ };
621
+ const callees: ProfileFlamegraphNode = {
622
+ functionName: request.functionName,
623
+ fileName: request.fileName,
624
+ lineNumber: 0,
625
+ selfValue: 0,
626
+ totalValue: 0,
627
+ children: [],
628
+ frameType: "",
629
+ };
630
+
631
+ /*
632
+ * Per-node child index for O(1) frame lookup, mirroring getFlamegraph.
633
+ * One map serves both trees since it is keyed by parent node identity.
634
+ */
635
+ const childIndex: WeakMap<
636
+ ProfileFlamegraphNode,
637
+ Map<string, ProfileFlamegraphNode>
638
+ > = new WeakMap();
639
+
640
+ let totalValue: number = 0;
641
+ let selfValue: number = 0;
642
+ let sampleCount: number = 0;
643
+
644
+ for (const row of rows) {
645
+ const stacktrace: Array<string> =
646
+ (row["stacktrace"] as Array<string>) || [];
647
+ const frameTypes: Array<string> =
648
+ (row["frameTypes"] as Array<string>) || [];
649
+ const value: number = Number(row["totalValue"] || 0);
650
+ const groupSampleCount: number = Number(row["sampleCount"] || 0);
651
+
652
+ if (stacktrace.length === 0) {
653
+ continue;
654
+ }
655
+
656
+ /*
657
+ * Stacks are leaf-first, so scanning from the END finds the
658
+ * occurrence CLOSEST TO THE ROOT first. For recursive functions
659
+ * this attributes the whole recursive subtree (including nested
660
+ * occurrences) to one split point, so each stack's value is
661
+ * counted exactly once.
662
+ */
663
+ let occurrenceIndex: number = -1;
664
+
665
+ for (let i: number = stacktrace.length - 1; i >= 0; i--) {
666
+ const frame: ParsedFrame = ProfileAggregationService.parseFrame(
667
+ stacktrace[i]!,
668
+ );
669
+ if (
670
+ frame.functionName === request.functionName &&
671
+ frame.fileName === request.fileName
672
+ ) {
673
+ occurrenceIndex = i;
674
+ break;
675
+ }
676
+ }
677
+
678
+ /*
679
+ * The ClickHouse prefilter is a prefix match and can overmatch
680
+ * when a fileName containing colons shares a prefix with another
681
+ * (parseFrame splits on the LAST colon) — drop those rows here.
682
+ */
683
+ if (occurrenceIndex === -1) {
684
+ continue;
685
+ }
686
+
687
+ totalValue += value;
688
+ sampleCount += groupSampleCount;
689
+
690
+ /*
691
+ * Self time counts whenever the function is the EXECUTING (leaf)
692
+ * frame — checked against index 0 directly rather than the split
693
+ * point, because a recursive stack splits at the root-most
694
+ * occurrence while the leaf may still be the same function
695
+ * (standard sandwich-view semantics: self = "was on CPU").
696
+ */
697
+ const leafFrame: ParsedFrame = ProfileAggregationService.parseFrame(
698
+ stacktrace[0]!,
699
+ );
700
+ if (
701
+ leafFrame.functionName === request.functionName &&
702
+ leafFrame.fileName === request.fileName
703
+ ) {
704
+ selfValue += value;
705
+ }
706
+
707
+ const occurrenceFrameType: string = frameTypes[occurrenceIndex] || "";
708
+
709
+ if (!callers.frameType) {
710
+ callers.frameType = occurrenceFrameType;
711
+ }
712
+ if (!callees.frameType) {
713
+ callees.frameType = occurrenceFrameType;
714
+ }
715
+
716
+ callers.totalValue += value;
717
+ callees.totalValue += value;
718
+
719
+ /*
720
+ * Caller chain: frames ABOVE the occurrence (toward the root),
721
+ * direct caller first so depth in the tree equals caller distance.
722
+ */
723
+ const callerIndices: Array<number> = [];
724
+ for (let i: number = occurrenceIndex + 1; i < stacktrace.length; i++) {
725
+ callerIndices.push(i);
726
+ }
727
+
728
+ /*
729
+ * Callee chain: frames BELOW the occurrence (toward the leaf),
730
+ * direct callee first.
731
+ */
732
+ const calleeIndices: Array<number> = [];
733
+ for (let i: number = occurrenceIndex - 1; i >= 0; i--) {
734
+ calleeIndices.push(i);
735
+ }
736
+
737
+ ProfileAggregationService.appendFocusChain({
738
+ root: callers,
739
+ stacktrace,
740
+ frameTypes,
741
+ frameIndices: callerIndices,
742
+ value,
743
+ childIndex,
744
+ });
745
+
746
+ ProfileAggregationService.appendFocusChain({
747
+ root: callees,
748
+ stacktrace,
749
+ frameTypes,
750
+ frameIndices: calleeIndices,
751
+ value,
752
+ childIndex,
753
+ });
754
+ }
755
+
756
+ return {
757
+ functionName: request.functionName,
758
+ fileName: request.fileName,
759
+ totalValue,
760
+ selfValue,
761
+ sampleCount,
762
+ windowTotal,
763
+ callers,
764
+ callees,
765
+ truncated,
766
+ };
767
+ }
768
+
769
+ /**
770
+ * Walk one split half of a stack into a focus tree, merging frames on
771
+ * functionName + fileName (line numbers aggregated away — same
772
+ * deploy-stability rationale as the focused-function match itself).
773
+ * The terminal node of the chain absorbs selfValue: in the callers
774
+ * tree that is the stack root ("the chain starts here"), in the
775
+ * callees tree the leaf ("the time bottoms out here"). An empty chain
776
+ * terminates at the focused root itself.
777
+ */
778
+ private static appendFocusChain(data: {
779
+ root: ProfileFlamegraphNode;
780
+ stacktrace: Array<string>;
781
+ frameTypes: Array<string>;
782
+ frameIndices: Array<number>;
783
+ value: number;
784
+ childIndex: WeakMap<
785
+ ProfileFlamegraphNode,
786
+ Map<string, ProfileFlamegraphNode>
787
+ >;
788
+ }): void {
789
+ let currentNode: ProfileFlamegraphNode = data.root;
790
+
791
+ for (const frameIndex of data.frameIndices) {
792
+ const frame: ParsedFrame = ProfileAggregationService.parseFrame(
793
+ data.stacktrace[frameIndex]!,
794
+ );
795
+ const frameType: string = data.frameTypes[frameIndex] || "";
796
+ const frameKey: string = `${frame.functionName}@${frame.fileName}`;
797
+
798
+ let index: Map<string, ProfileFlamegraphNode> | undefined =
799
+ data.childIndex.get(currentNode);
800
+
801
+ if (!index) {
802
+ index = new Map<string, ProfileFlamegraphNode>();
803
+ data.childIndex.set(currentNode, index);
804
+ }
805
+
806
+ let childNode: ProfileFlamegraphNode | undefined = index.get(frameKey);
807
+
808
+ if (!childNode) {
809
+ childNode = {
810
+ functionName: frame.functionName,
811
+ fileName: frame.fileName,
812
+ lineNumber: 0,
813
+ selfValue: 0,
814
+ totalValue: 0,
815
+ children: [],
816
+ frameType: frameType,
817
+ };
818
+ currentNode.children.push(childNode);
819
+ index.set(frameKey, childNode);
820
+ }
821
+
822
+ childNode.totalValue += data.value;
823
+ currentNode = childNode;
824
+ }
825
+
826
+ currentNode.selfValue += data.value;
320
827
  }
321
828
 
322
829
  /**
323
830
  * Build a diff flamegraph comparing two time ranges.
324
- * Returns a tree where each node has baseline/comparison values and deltas.
831
+ * Returns a tree where each node has baseline/comparison values and
832
+ * deltas, plus a truncation flag covering both source windows.
325
833
  */
326
834
  @CaptureSpan()
327
835
  public static async getDiffFlamegraph(
328
836
  request: DiffFlamegraphRequest,
329
- ): Promise<DiffFlamegraphNode> {
330
- const baselineTree: ProfileFlamegraphNode =
331
- await ProfileAggregationService.getFlamegraph({
837
+ ): Promise<DiffFlamegraphResult> {
838
+ /*
839
+ * The two windows are independent reads, so fetch them concurrently —
840
+ * sequential awaits doubled the latency of every diff request.
841
+ */
842
+ const [baselineResult, comparisonResult]: [
843
+ FlamegraphResult,
844
+ FlamegraphResult,
845
+ ] = await Promise.all([
846
+ ProfileAggregationService.getFlamegraph({
332
847
  projectId: request.projectId,
333
848
  startTime: request.baselineStartTime,
334
849
  endTime: request.baselineEndTime,
@@ -341,10 +856,8 @@ export class ProfileAggregationService {
341
856
  ...(request.profileTypes !== undefined && {
342
857
  profileTypes: request.profileTypes,
343
858
  }),
344
- });
345
-
346
- const comparisonTree: ProfileFlamegraphNode =
347
- await ProfileAggregationService.getFlamegraph({
859
+ }),
860
+ ProfileAggregationService.getFlamegraph({
348
861
  projectId: request.projectId,
349
862
  startTime: request.comparisonStartTime,
350
863
  endTime: request.comparisonEndTime,
@@ -357,12 +870,16 @@ export class ProfileAggregationService {
357
870
  ...(request.profileTypes !== undefined && {
358
871
  profileTypes: request.profileTypes,
359
872
  }),
360
- });
873
+ }),
874
+ ]);
361
875
 
362
- return ProfileAggregationService.mergeDiffTrees(
363
- baselineTree,
364
- comparisonTree,
365
- );
876
+ return {
877
+ diffFlamegraph: ProfileAggregationService.mergeDiffTrees(
878
+ baselineResult.flamegraph,
879
+ comparisonResult.flamegraph,
880
+ ),
881
+ truncated: baselineResult.truncated || comparisonResult.truncated,
882
+ };
366
883
  }
367
884
 
368
885
  private static mergeDiffTrees(
@@ -442,10 +959,14 @@ export class ProfileAggregationService {
442
959
  }
443
960
 
444
961
  /**
445
- * Aggregate sample / profile counts per serviceId for a time window.
962
+ * Aggregate sample / profile counts per primaryEntityId for a time window.
446
963
  * Drives the "loudest services first" sort on the Profiles dashboard
447
964
  * so a developer opening the page lands on the workloads that are
448
965
  * actually doing work rather than scrolling past kernel-thread noise.
966
+ *
967
+ * Reads the small Profile table (one row per ingested profile, with a
968
+ * denormalized sampleCount) instead of scanning every row of the huge
969
+ * ProfileSample table for what is just a per-service ranking.
449
970
  */
450
971
  @CaptureSpan()
451
972
  public static async getServiceActivity(
@@ -455,7 +976,7 @@ export class ProfileAggregationService {
455
976
  ProfileAggregationService.buildServiceActivityQuery(request);
456
977
 
457
978
  const dbResult: Results =
458
- await ProfileSampleDatabaseService.executeQuery(statement);
979
+ await ProfileDatabaseService.executeQuery(statement);
459
980
  const response: DbJSONResponse = await dbResult.json<{
460
981
  data?: Array<JSONObject>;
461
982
  }>();
@@ -463,28 +984,105 @@ export class ProfileAggregationService {
463
984
  const rows: Array<JSONObject> = response.data || [];
464
985
  const out: Array<ServiceActivityItem> = [];
465
986
  for (const row of rows) {
466
- const serviceId: string = String(row["serviceId"] || "");
467
- if (!serviceId) {
987
+ const primaryEntityId: string = String(row["primaryEntityId"] || "");
988
+ if (!primaryEntityId) {
468
989
  continue;
469
990
  }
470
991
  out.push({
471
- serviceId,
472
- sampleCount: Number(row["sampleCount"] || 0),
992
+ primaryEntityId,
993
+ sampleCount: Number(row["totalSampleCount"] || 0),
473
994
  profileCount: Number(row["profileCount"] || 0),
474
- totalValue: Number(row["totalValue"] || 0),
995
+ /*
996
+ * Profile rows do not carry a summed sample value, and no client
997
+ * reads this field — it is kept at 0 purely so the response shape
998
+ * stays stable for existing consumers.
999
+ */
1000
+ totalValue: 0,
475
1001
  });
476
1002
  }
477
1003
  return out;
478
1004
  }
479
1005
 
1006
+ /**
1007
+ * Group profiling volume by a dimension ("service" = primaryEntityId,
1008
+ * anything else = a Profile attribute key) over a time window.
1009
+ *
1010
+ * Reads the small Profile table (one row per ingested profile with a
1011
+ * denormalized sampleCount) — same reasoning as getServiceActivity: a
1012
+ * share-of-volume ranking never needs the huge ProfileSample table.
1013
+ *
1014
+ * totalSampleCount sums over ALL fetched groups before the limit is
1015
+ * applied, so item shares stay percentages of the real total rather
1016
+ * than of the visible top-N.
1017
+ */
1018
+ @CaptureSpan()
1019
+ public static async getBreakdown(
1020
+ request: BreakdownRequest,
1021
+ ): Promise<BreakdownResult> {
1022
+ const statement: Statement =
1023
+ ProfileAggregationService.buildBreakdownQuery(request);
1024
+
1025
+ const dbResult: Results =
1026
+ await ProfileDatabaseService.executeQuery(statement);
1027
+ const response: DbJSONResponse = await dbResult.json<{
1028
+ data?: Array<JSONObject>;
1029
+ }>();
1030
+
1031
+ const rows: Array<JSONObject> = response.data || [];
1032
+
1033
+ // Rows arrive sorted by summed sampleCount descending (query ORDER BY).
1034
+ const allItems: Array<BreakdownItem> = [];
1035
+ let totalSampleCount: number = 0;
1036
+
1037
+ for (const row of rows) {
1038
+ const value: string = String(row["breakdownValue"] || "");
1039
+ if (!value) {
1040
+ continue;
1041
+ }
1042
+
1043
+ const groupSampleCount: number = Number(row["totalSampleCount"] || 0);
1044
+ totalSampleCount += groupSampleCount;
1045
+
1046
+ allItems.push({
1047
+ value,
1048
+ sampleCount: groupSampleCount,
1049
+ profileCount: Number(row["profileCount"] || 0),
1050
+ share: 0,
1051
+ });
1052
+ }
1053
+
1054
+ const limit: number =
1055
+ request.limit ?? ProfileAggregationService.DEFAULT_BREAKDOWN_LIMIT;
1056
+ const items: Array<BreakdownItem> = allItems.slice(0, limit);
1057
+
1058
+ for (const item of items) {
1059
+ item.share =
1060
+ totalSampleCount > 0 ? (item.sampleCount / totalSampleCount) * 100 : 0;
1061
+ }
1062
+
1063
+ return { items, totalSampleCount };
1064
+ }
1065
+
480
1066
  // --- Query builders ---
481
1067
 
482
- private static buildFlamegraphQuery(request: FlamegraphRequest): Statement {
1068
+ /**
1069
+ * Fetch samples pre-aggregated by stack identity. Collapsing identical
1070
+ * (stacktrace, frameTypes) pairs in ClickHouse shrinks tens of thousands
1071
+ * of raw sample rows to a few hundred unique stacks before they cross
1072
+ * the wire, and the ORDER BY makes the LIMIT drop the smallest stacks
1073
+ * first instead of an arbitrary subset.
1074
+ *
1075
+ * `value` is stored as Int128 in ClickHouse, so the sum is wrapped in
1076
+ * toFloat64 to keep the JSON output numeric (toFloat64OrZero would fail
1077
+ * with "Illegal type Int128").
1078
+ */
1079
+ private static buildGroupedStackQuery(request: FlamegraphRequest): Statement {
483
1080
  const statement: Statement = SQL`
484
1081
  SELECT
485
1082
  stacktrace,
486
1083
  frameTypes,
487
- value
1084
+ toFloat64(sum(value)) AS totalValue,
1085
+ count() AS sampleCount
488
1086
  FROM ${ProfileAggregationService.TABLE_NAME}
489
1087
  WHERE projectId = ${{
490
1088
  type: TableColumnType.ObjectID,
@@ -492,92 +1090,136 @@ export class ProfileAggregationService {
492
1090
  }}
493
1091
  `;
494
1092
 
495
- if (request.profileId) {
496
- statement.append(
497
- SQL` AND profileId = ${{
498
- type: TableColumnType.Text,
499
- value: request.profileId,
500
- }}`,
501
- );
502
- }
503
-
504
- if (request.startTime) {
505
- statement.append(
506
- SQL` AND time >= ${{
507
- type: TableColumnType.Date,
508
- value: request.startTime,
509
- }}`,
510
- );
511
- }
512
-
513
- if (request.endTime) {
514
- statement.append(
515
- SQL` AND time <= ${{
516
- type: TableColumnType.Date,
517
- value: request.endTime,
518
- }}`,
519
- );
520
- }
521
-
522
- ProfileAggregationService.appendCommonFilters(statement, request);
1093
+ ProfileAggregationService.appendSampleFilters(statement, request);
523
1094
 
524
1095
  statement.append(
525
- SQL` LIMIT ${{
526
- type: TableColumnType.Number,
527
- value: ProfileAggregationService.MAX_SAMPLE_FETCH,
528
- }}`,
1096
+ SQL` GROUP BY stacktrace, frameTypes
1097
+ ORDER BY totalValue DESC
1098
+ LIMIT ${{
1099
+ type: TableColumnType.Number,
1100
+ value: ProfileAggregationService.MAX_STACK_FETCH,
1101
+ }}`,
529
1102
  );
530
1103
 
531
1104
  /*
532
- * Cap runtime below the client's 58s request_timeout; a flamegraph
533
- * over a busy project can pull MAX_SAMPLE_FETCH raw samples. 'break'
534
- * yields a partial flamegraph rather than holding a pool connection.
1105
+ * Cap runtime below the client's 58s request_timeout; 'break' yields
1106
+ * a partial (top stacks) result rather than holding a pool connection.
535
1107
  */
536
1108
  statement.append(
537
- " SETTINGS max_execution_time = 45, timeout_overflow_mode = 'break'",
1109
+ getQuerySettings({
1110
+ maxExecutionTimeInSeconds: 45,
1111
+ timeoutOverflowMode: "break",
1112
+ }),
538
1113
  );
539
1114
 
540
1115
  return statement;
541
1116
  }
542
1117
 
543
- private static buildFunctionListQuery(
544
- request: FunctionListRequest,
1118
+ /**
1119
+ * Grouped-stack query restricted to stacks containing one function, so
1120
+ * a sandwich aggregation never pulls the full window's stacks over the
1121
+ * wire just to discard most of them.
1122
+ *
1123
+ * Stored frame strings are "functionName" + ("@fileName" when fileName
1124
+ * is non-empty) + (":lineNumber" when lineNumber > 0) — see
1125
+ * OtelProfilesIngestService.resolveStackFrames. Line numbers shift
1126
+ * across deploys, so the predicate matches the functionName+fileName
1127
+ * identity only:
1128
+ * - non-empty fileName: exact "fn@file" (no line recorded) OR prefix
1129
+ * "fn@file:" (line recorded);
1130
+ * - empty fileName: the exact bare frame (folded uploads and
1131
+ * address-only frames store just the name — parseFrame treats any
1132
+ * '@'-less frame as all functionName, so equality is the full
1133
+ * match).
1134
+ * The prefix form can overmatch when one colon-bearing fileName is a
1135
+ * prefix of another (parseFrame splits on the LAST colon), so callers
1136
+ * must re-check each frame in memory via parseFrame.
1137
+ */
1138
+ private static buildFunctionStackQuery(
1139
+ request: FlamegraphRequest,
1140
+ functionName: string,
1141
+ fileName: string,
545
1142
  ): Statement {
546
1143
  const statement: Statement = SQL`
547
1144
  SELECT
548
1145
  stacktrace,
549
1146
  frameTypes,
550
- value
1147
+ toFloat64(sum(value)) AS totalValue,
1148
+ count() AS sampleCount
551
1149
  FROM ${ProfileAggregationService.TABLE_NAME}
552
1150
  WHERE projectId = ${{
553
1151
  type: TableColumnType.ObjectID,
554
1152
  value: request.projectId,
555
1153
  }}
556
- AND time >= ${{
557
- type: TableColumnType.Date,
558
- value: request.startTime,
559
- }}
560
- AND time <= ${{
561
- type: TableColumnType.Date,
562
- value: request.endTime,
563
- }}
564
1154
  `;
565
1155
 
566
- ProfileAggregationService.appendCommonFilters(statement, request);
1156
+ ProfileAggregationService.appendSampleFilters(statement, request);
1157
+
1158
+ if (fileName) {
1159
+ statement.append(
1160
+ SQL` AND arrayExists(x -> (x = ${{
1161
+ type: TableColumnType.Text,
1162
+ value: `${functionName}@${fileName}`,
1163
+ }} OR startsWith(x, ${{
1164
+ type: TableColumnType.Text,
1165
+ value: `${functionName}@${fileName}:`,
1166
+ }})), stacktrace)`,
1167
+ );
1168
+ } else {
1169
+ statement.append(
1170
+ SQL` AND has(stacktrace, ${{
1171
+ type: TableColumnType.Text,
1172
+ value: functionName,
1173
+ }})`,
1174
+ );
1175
+ }
567
1176
 
568
1177
  statement.append(
569
- SQL` LIMIT ${{
570
- type: TableColumnType.Number,
571
- value: ProfileAggregationService.MAX_SAMPLE_FETCH,
572
- }}`,
1178
+ SQL` GROUP BY stacktrace, frameTypes
1179
+ ORDER BY totalValue DESC
1180
+ LIMIT ${{
1181
+ type: TableColumnType.Number,
1182
+ value: ProfileAggregationService.MAX_STACK_FETCH,
1183
+ }}`,
573
1184
  );
574
1185
 
575
1186
  /*
576
1187
  * Cap runtime below the client's 58s request_timeout; 'break' yields
577
- * a partial function list rather than holding a pool connection.
1188
+ * a partial (top stacks) result rather than holding a pool connection.
578
1189
  */
579
1190
  statement.append(
580
- " SETTINGS max_execution_time = 45, timeout_overflow_mode = 'break'",
1191
+ getQuerySettings({
1192
+ maxExecutionTimeInSeconds: 45,
1193
+ timeoutOverflowMode: "break",
1194
+ }),
1195
+ );
1196
+
1197
+ return statement;
1198
+ }
1199
+
1200
+ /**
1201
+ * Total of `value` across every sample row matching the filters — no
1202
+ * GROUP BY and no LIMIT, so it stays correct even when the grouped
1203
+ * stack query truncates.
1204
+ */
1205
+ private static buildWindowTotalQuery(request: FlamegraphRequest): Statement {
1206
+ const statement: Statement = SQL`
1207
+ SELECT
1208
+ toFloat64(sum(value)) AS windowTotal
1209
+ FROM ${ProfileAggregationService.TABLE_NAME}
1210
+ WHERE projectId = ${{
1211
+ type: TableColumnType.ObjectID,
1212
+ value: request.projectId,
1213
+ }}
1214
+ `;
1215
+
1216
+ ProfileAggregationService.appendSampleFilters(statement, request);
1217
+
1218
+ statement.append(
1219
+ getQuerySettings({
1220
+ maxExecutionTimeInSeconds: 45,
1221
+ timeoutOverflowMode: "break",
1222
+ }),
581
1223
  );
582
1224
 
583
1225
  return statement;
@@ -587,32 +1229,33 @@ export class ProfileAggregationService {
587
1229
  request: ServiceActivityRequest,
588
1230
  ): Statement {
589
1231
  /*
590
- * sum(value) directly value is stored as Int128 in ClickHouse, so
591
- * toFloat64OrZero would fail ("Illegal type Int128"); a plain sum is
592
- * the right idiom here, and we coerce to Number when serialising in
593
- * getServiceActivity.
1232
+ * One Profile row per ingested profile with a denormalized sampleCount,
1233
+ * so the per-service ranking never has to touch the (orders of
1234
+ * magnitude larger) ProfileSample table. uniqExact tolerates duplicate
1235
+ * rows for the same profileId from re-ingestion.
594
1236
  */
595
1237
  const statement: Statement = SQL`
596
1238
  SELECT
597
- toString(serviceId) AS serviceId,
598
- count() AS sampleCount,
599
- uniqExact(profileId) AS profileCount,
600
- toFloat64(sum(value)) AS totalValue
601
- FROM ${ProfileAggregationService.TABLE_NAME}
1239
+ toString(primaryEntityId) AS primaryEntityId,
1240
+ toFloat64(sum(sampleCount)) AS totalSampleCount,
1241
+ uniqExact(profileId) AS profileCount
1242
+ FROM ${ProfileAggregationService.PROFILE_TABLE_NAME}
602
1243
  WHERE projectId = ${{
603
1244
  type: TableColumnType.ObjectID,
604
1245
  value: request.projectId,
605
1246
  }}
606
- AND time >= ${{
1247
+ AND startTime >= ${{
607
1248
  type: TableColumnType.Date,
608
1249
  value: request.startTime,
609
1250
  }}
610
- AND time <= ${{
1251
+ AND startTime <= ${{
611
1252
  type: TableColumnType.Date,
612
1253
  value: request.endTime,
613
1254
  }}
614
1255
  `;
615
1256
 
1257
+ statement.append(" AND retentionDate >= now()");
1258
+
616
1259
  /*
617
1260
  * profileTypes (array) wins over profileType (single) so the UI
618
1261
  * can OR together every raw type string in a category.
@@ -634,8 +1277,8 @@ export class ProfileAggregationService {
634
1277
  }
635
1278
 
636
1279
  statement.append(
637
- SQL` GROUP BY serviceId
638
- ORDER BY sampleCount DESC
1280
+ SQL` GROUP BY primaryEntityId
1281
+ ORDER BY totalSampleCount DESC
639
1282
  LIMIT 10000`,
640
1283
  );
641
1284
 
@@ -644,12 +1287,147 @@ export class ProfileAggregationService {
644
1287
  * partial service activity rather than holding a pool connection.
645
1288
  */
646
1289
  statement.append(
647
- " SETTINGS max_execution_time = 45, timeout_overflow_mode = 'break'",
1290
+ getQuerySettings({
1291
+ maxExecutionTimeInSeconds: 45,
1292
+ timeoutOverflowMode: "break",
1293
+ }),
648
1294
  );
649
1295
 
650
1296
  return statement;
651
1297
  }
652
1298
 
1299
+ /**
1300
+ * Per-group volume aggregate over the Profile table for getBreakdown.
1301
+ *
1302
+ * The "service" dimension groups by primaryEntityId (mirroring
1303
+ * buildServiceActivityQuery); any other dimension is a Profile
1304
+ * attribute key, read via the parameter-bound Map subscript
1305
+ * `attributes[key]` — the same O(1) fast path the analytics query
1306
+ * generator uses for map equality. The subscript yields '' for missing
1307
+ * keys, so the != '' guard drops profiles without the attribute.
1308
+ */
1309
+ private static buildBreakdownQuery(request: BreakdownRequest): Statement {
1310
+ let statement: Statement;
1311
+
1312
+ if (request.breakdownBy === "service") {
1313
+ statement = SQL`
1314
+ SELECT
1315
+ toString(primaryEntityId) AS breakdownValue,
1316
+ toFloat64(sum(sampleCount)) AS totalSampleCount,
1317
+ uniqExact(profileId) AS profileCount
1318
+ FROM ${ProfileAggregationService.PROFILE_TABLE_NAME}
1319
+ WHERE projectId = ${{
1320
+ type: TableColumnType.ObjectID,
1321
+ value: request.projectId,
1322
+ }}
1323
+ `;
1324
+ } else {
1325
+ statement = SQL`
1326
+ SELECT
1327
+ attributes[${{
1328
+ type: TableColumnType.Text,
1329
+ value: request.breakdownBy,
1330
+ }}] AS breakdownValue,
1331
+ toFloat64(sum(sampleCount)) AS totalSampleCount,
1332
+ uniqExact(profileId) AS profileCount
1333
+ FROM ${ProfileAggregationService.PROFILE_TABLE_NAME}
1334
+ WHERE projectId = ${{
1335
+ type: TableColumnType.ObjectID,
1336
+ value: request.projectId,
1337
+ }}
1338
+ AND attributes[${{
1339
+ type: TableColumnType.Text,
1340
+ value: request.breakdownBy,
1341
+ }}] != ''
1342
+ `;
1343
+ }
1344
+
1345
+ statement.append(
1346
+ SQL` AND startTime >= ${{
1347
+ type: TableColumnType.Date,
1348
+ value: request.startTime,
1349
+ }} AND startTime <= ${{
1350
+ type: TableColumnType.Date,
1351
+ value: request.endTime,
1352
+ }}`,
1353
+ );
1354
+
1355
+ /*
1356
+ * Read-side retention filter: rows past their per-service retention
1357
+ * stay in their part until the whole part drops (ttl_only_drop_parts).
1358
+ */
1359
+ statement.append(" AND retentionDate >= now()");
1360
+
1361
+ ProfileAggregationService.appendCommonFilters(statement, request);
1362
+
1363
+ statement.append(
1364
+ SQL` GROUP BY breakdownValue
1365
+ ORDER BY totalSampleCount DESC
1366
+ LIMIT ${{
1367
+ type: TableColumnType.Number,
1368
+ value: ProfileAggregationService.MAX_BREAKDOWN_GROUP_FETCH,
1369
+ }}`,
1370
+ );
1371
+
1372
+ /*
1373
+ * Cap runtime below the client's 58s request_timeout; 'break' yields
1374
+ * a partial (top groups) result rather than holding a pool connection.
1375
+ */
1376
+ statement.append(
1377
+ getQuerySettings({
1378
+ maxExecutionTimeInSeconds: 45,
1379
+ timeoutOverflowMode: "break",
1380
+ }),
1381
+ );
1382
+
1383
+ return statement;
1384
+ }
1385
+
1386
+ /**
1387
+ * Shared WHERE-clause tail for ProfileSample reads: optional profileId /
1388
+ * time-window filters, the read-side retention filter, and the common
1389
+ * service / profile-type filters.
1390
+ */
1391
+ private static appendSampleFilters(
1392
+ statement: Statement,
1393
+ request: FlamegraphRequest,
1394
+ ): void {
1395
+ if (request.profileId) {
1396
+ statement.append(
1397
+ SQL` AND profileId = ${{
1398
+ type: TableColumnType.Text,
1399
+ value: request.profileId,
1400
+ }}`,
1401
+ );
1402
+ }
1403
+
1404
+ if (request.startTime) {
1405
+ statement.append(
1406
+ SQL` AND time >= ${{
1407
+ type: TableColumnType.Date,
1408
+ value: request.startTime,
1409
+ }}`,
1410
+ );
1411
+ }
1412
+
1413
+ if (request.endTime) {
1414
+ statement.append(
1415
+ SQL` AND time <= ${{
1416
+ type: TableColumnType.Date,
1417
+ value: request.endTime,
1418
+ }}`,
1419
+ );
1420
+ }
1421
+
1422
+ /*
1423
+ * Read-side retention filter: rows past their per-service retention
1424
+ * stay in their part until the whole part drops (ttl_only_drop_parts).
1425
+ */
1426
+ statement.append(" AND retentionDate >= now()");
1427
+
1428
+ ProfileAggregationService.appendCommonFilters(statement, request);
1429
+ }
1430
+
653
1431
  private static appendCommonFilters(
654
1432
  statement: Statement,
655
1433
  request: Pick<
@@ -659,7 +1437,7 @@ export class ProfileAggregationService {
659
1437
  ): void {
660
1438
  if (request.serviceIds && request.serviceIds.length > 0) {
661
1439
  statement.append(
662
- SQL` AND serviceId IN (${{
1440
+ SQL` AND primaryEntityId IN (${{
663
1441
  type: TableColumnType.ObjectID,
664
1442
  value: new Includes(
665
1443
  request.serviceIds.map((id: ObjectID) => {