cds-caching 3.0.1 → 3.1.1
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.
- package/README.md +2 -2
- package/app/dashboard/Component-preload.js +2 -2
- package/app/dashboard/Component-preload.js.map +1 -1
- package/app/dashboard/index.html +1 -1
- package/app/dashboard/manifest.json +3 -3
- package/app/dashboard/service/CacheStatisticsService-dbg.js +1 -1
- package/app/dashboard/service/CacheStatisticsService-dbg.js.map +1 -1
- package/app/dashboard/service/CacheStatisticsService.js +1 -1
- package/app/dashboard/service/CacheStatisticsService.js.map +1 -1
- package/app/dashboard-src/index.html +1 -1
- package/app/dashboard-src/manifest.json +3 -3
- package/app/dashboard-src/service/CacheStatisticsService.ts +1 -1
- package/db/statistics.cds +56 -0
- package/index.cds +5 -0
- package/lib/CachingService.d.ts +29 -0
- package/lib/CachingService.js +49 -0
- package/lib/add.js +1 -1
- package/lib/config-normalizer.js +2 -0
- package/lib/dashboard-bootstrap.js +1 -1
- package/lib/operations/AsyncOperations.js +52 -24
- package/lib/operations/BasicOperations.js +6 -3
- package/lib/operations/CapOperations.js +59 -27
- package/lib/support/CacheStatisticsHandler.js +258 -13
- package/lib/support/RuntimeConfigurationManager.js +21 -1
- package/lib/support/StatisticsPersistenceManager.js +133 -0
- package/package.json +2 -2
- package/srv/caching-api-service.js +25 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CacheStatisticsService-dbg.js","names":["cacheAndIdFilter","___model_filters","cacheNameFilter","periodFilter","CacheStatisticsService","constructor","model","ODataModel","serviceUrl","autoExpandSelect","groupId","getModel","getCurrentMetrics","cacheName","binding","bindList","undefined","Sorter","path","descending","data","requestContexts","results","map","item","getObject","length","transformStatistics","error","console","MessageBox","getHistoricalMetrics","period","from","to","filters","push","Filter","operator","FilterOperator","GE","value1","LE","getTopKeys","getColdKeys","persistStatistics","context","bindContext","invoke","hits","misses","sets","deletes","errors","avgLatency","p95Latency","p99Latency","minLatency","maxLatency","avgHitLatency","p95HitLatency","p99HitLatency","minHitLatency","maxHitLatency","avgMissLatency","p95MissLatency","p99MissLatency","minMissLatency","maxMissLatency","avgSetLatency","avgDeleteLatency","memoryUsage","itemCount","hitRatio","throughput","errorRate","cacheEfficiency","uptimeMs","uniqueKeys","topKeys","coldKeys","lastPersisted","Date","toISOString","getAvailableMetrics","getMetricById","metricId","setMetricsEnabled","enabled","setParameter","setKeyMetricsEnabled"],"sources":["CacheStatisticsService.ts"],"sourcesContent":["import MessageBox from \"sap/m/MessageBox\";\nimport ODataModel from \"sap/ui/model/odata/v4/ODataModel\";\nimport Filter from \"sap/ui/model/Filter\";\nimport FilterOperator from \"sap/ui/model/FilterOperator\";\nimport Sorter from \"sap/ui/model/Sorter\";\nimport Context from \"sap/ui/model/odata/v4/Context\";\nimport { cacheAndIdFilter, cacheNameFilter, periodFilter } from \"../model/filters\";\n\nexport interface CacheStatistics {\n hits: number;\n misses: number;\n sets: number;\n deletes: number;\n errors: number;\n\n // Overall latency metrics\n avgLatency: number;\n p95Latency: number;\n p99Latency: number;\n minLatency: number;\n maxLatency: number;\n\n // Hit-specific latency metrics\n avgHitLatency: number;\n p95HitLatency: number;\n p99HitLatency: number;\n minHitLatency: number;\n maxHitLatency: number;\n\n // Miss-specific latency metrics\n avgMissLatency: number;\n p95MissLatency: number;\n p99MissLatency: number;\n minMissLatency: number;\n maxMissLatency: number;\n\n // Set/Delete latency metrics\n avgSetLatency: number;\n avgDeleteLatency: number;\n\n // Performance metrics\n memoryUsage: number;\n itemCount: number;\n hitRatio: number;\n throughput: number;\n errorRate: number;\n cacheEfficiency: number;\n uptimeMs: number;\n uniqueKeys: number;\n topKeys: KeyAccess[];\n coldKeys: KeyAccess[];\n lastPersisted: string;\n}\n\nexport interface KeyAccess {\n keyName: string;\n hits: number;\n misses: number;\n sets: number;\n deletes: number;\n total: number;\n lastAccess: string;\n dataType: string;\n serviceName: string;\n entityName: string;\n operation: string;\n metadata: string;\n}\n\nexport interface HistoricalStatistics {\n ID: string;\n cache: string;\n timestamp: string;\n period: string;\n\n hits: number;\n misses: number;\n sets: number;\n deletes: number;\n errors: number;\n totalRequests: number;\n\n avgHitLatency: number;\n p95HitLatency: number;\n p99HitLatency: number;\n minHitLatency: number;\n maxHitLatency: number;\n avgMissLatency: number;\n p95MissLatency: number;\n p99MissLatency: number;\n minMissLatency: number;\n maxMissLatency: number;\n avgSetLatency: number;\n avgDeleteLatency: number;\n\n hitRatio: number;\n throughput: number;\n errorRate: number;\n cacheEfficiency: number;\n\n nativeSets: number;\n nativeGets: number;\n nativeDeletes: number;\n nativeClears: number;\n nativeDeleteByTags: number;\n nativeErrors: number;\n totalNativeOperations: number;\n\n nativeThroughput: number;\n nativeErrorRate: number;\n\n memoryUsage: number;\n itemCount: number;\n uptimeMs: number;\n}\n\n/**\n * Service class for interacting with the Cache Statistics API using OData V4\n */\nexport default class CacheStatisticsService {\n private model: ODataModel;\n\n constructor(model?: ODataModel) {\n this.model = model || new ODataModel({\n serviceUrl: \"/odata/v4/caching/\",\n autoExpandSelect: true,\n groupId: \"$auto\"\n });\n }\n\n getModel(): ODataModel {\n return this.model;\n }\n\n async getCurrentMetrics(cacheName: string): Promise<CacheStatistics | null> {\n try {\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n [new Sorter({ path: \"timestamp\", descending: true })],\n [periodFilter(\"hourly\"), cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n const results = data.map((item: Context) => item.getObject());\n\n if (results.length > 0) {\n return this.transformStatistics(results[0]);\n }\n return null;\n } catch (error) {\n console.error(\"Error fetching current metrics:\", error);\n MessageBox.error(\"Failed to load current metrics\");\n return null;\n }\n }\n\n async getHistoricalMetrics(cacheName: string, period: string = \"hourly\", from?: string, to?: string): Promise<HistoricalStatistics[]> {\n try {\n const filters: Filter[] = [periodFilter(period), cacheNameFilter(cacheName)];\n if (from) {\n filters.push(new Filter({ path: \"timestamp\", operator: FilterOperator.GE, value1: from }));\n }\n if (to) {\n filters.push(new Filter({ path: \"timestamp\", operator: FilterOperator.LE, value1: to }));\n }\n\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n [new Sorter({ path: \"timestamp\", descending: true })],\n filters\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching historical metrics:\", error);\n MessageBox.error(\"Failed to load historical metrics\");\n return [];\n }\n }\n\n async getTopKeys(cacheName: string): Promise<KeyAccess[]> {\n try {\n const binding = this.model.bindList(\n \"/KeyMetrics\",\n undefined,\n [new Sorter({ path: \"totalRequests\", descending: true })],\n [periodFilter(\"current\"), cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching top keys:\", error);\n MessageBox.error(\"Failed to load top keys\");\n return [];\n }\n }\n\n async getColdKeys(cacheName: string): Promise<KeyAccess[]> {\n try {\n const binding = this.model.bindList(\n \"/KeyMetrics\",\n undefined,\n [new Sorter({ path: \"lastAccess\", descending: false })],\n [periodFilter(\"current\"), cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching cold keys:\", error);\n MessageBox.error(\"Failed to load cold keys\");\n return [];\n }\n }\n\n async persistStatistics(): Promise<boolean> {\n try {\n const context = this.model.bindContext(\"/persistStatistics(...)\");\n await context.invoke();\n return true;\n } catch (error) {\n console.error(\"Error persisting statistics:\", error);\n MessageBox.error(\"Failed to persist statistics\");\n return false;\n }\n }\n\n private transformStatistics(data: Record<string, unknown>): CacheStatistics {\n return {\n hits: (data.hits as number) || 0,\n misses: (data.misses as number) || 0,\n sets: (data.sets as number) || 0,\n deletes: (data.deletes as number) || 0,\n errors: (data.errors as number) || 0,\n\n avgLatency: (data.avgLatency as number) || 0,\n p95Latency: (data.p95Latency as number) || 0,\n p99Latency: (data.p99Latency as number) || 0,\n minLatency: (data.minLatency as number) || 0,\n maxLatency: (data.maxLatency as number) || 0,\n\n avgHitLatency: (data.avgHitLatency as number) || 0,\n p95HitLatency: (data.p95HitLatency as number) || 0,\n p99HitLatency: (data.p99HitLatency as number) || 0,\n minHitLatency: (data.minHitLatency as number) || 0,\n maxHitLatency: (data.maxHitLatency as number) || 0,\n\n avgMissLatency: (data.avgMissLatency as number) || 0,\n p95MissLatency: (data.p95MissLatency as number) || 0,\n p99MissLatency: (data.p99MissLatency as number) || 0,\n minMissLatency: (data.minMissLatency as number) || 0,\n maxMissLatency: (data.maxMissLatency as number) || 0,\n\n avgSetLatency: (data.avgSetLatency as number) || 0,\n avgDeleteLatency: (data.avgDeleteLatency as number) || 0,\n\n memoryUsage: (data.memoryUsage as number) || 0,\n itemCount: (data.itemCount as number) || 0,\n hitRatio: (data.hitRatio as number) || 0,\n throughput: (data.throughput as number) || 0,\n errorRate: (data.errorRate as number) || 0,\n cacheEfficiency: (data.cacheEfficiency as number) || 0,\n uptimeMs: (data.uptimeMs as number) || 0,\n uniqueKeys: 0,\n topKeys: [],\n coldKeys: [],\n lastPersisted: (data.lastPersisted as string) || new Date().toISOString()\n };\n }\n\n async getAvailableMetrics(cacheName: string): Promise<Record<string, unknown>[]> {\n try {\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n [new Sorter({ path: \"timestamp\", descending: true })],\n [cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching available metrics:\", error);\n MessageBox.error(\"Failed to load available metrics\");\n return [];\n }\n }\n\n async getMetricById(cacheName: string, metricId: string): Promise<CacheStatistics | null> {\n try {\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n undefined,\n cacheAndIdFilter(cacheName, metricId)\n );\n\n const data = await binding.requestContexts();\n const results = data.map((item: Context) => item.getObject());\n\n if (results.length > 0) {\n return this.transformStatistics(results[0]);\n }\n return null;\n } catch (error) {\n console.error(\"Error fetching metric by ID:\", error);\n MessageBox.error(\"Failed to load metric\");\n return null;\n }\n }\n\n async setMetricsEnabled(cacheName: string, enabled: boolean): Promise<boolean> {\n try {\n const context = this.model.bindContext(\"/setMetricsEnabled(...)\");\n context.setParameter(\"cache\", cacheName);\n context.setParameter(\"enabled\", enabled);\n await context.invoke();\n return true;\n } catch (error) {\n console.error(\"Error setting metrics enabled:\", error);\n MessageBox.error(\"Failed to update metrics configuration\");\n return false;\n }\n }\n\n async setKeyMetricsEnabled(cacheName: string, enabled: boolean): Promise<boolean> {\n try {\n const context = this.model.bindContext(\"/setKeyMetricsEnabled(...)\");\n context.setParameter(\"cache\", cacheName);\n context.setParameter(\"enabled\", enabled);\n await context.invoke();\n return true;\n } catch (error) {\n console.error(\"Error setting key metrics enabled:\", error);\n MessageBox.error(\"Failed to update key metrics configuration\");\n return false;\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"CacheStatisticsService-dbg.js","names":["cacheAndIdFilter","___model_filters","cacheNameFilter","periodFilter","CacheStatisticsService","constructor","model","ODataModel","serviceUrl","autoExpandSelect","groupId","getModel","getCurrentMetrics","cacheName","binding","bindList","undefined","Sorter","path","descending","data","requestContexts","results","map","item","getObject","length","transformStatistics","error","console","MessageBox","getHistoricalMetrics","period","from","to","filters","push","Filter","operator","FilterOperator","GE","value1","LE","getTopKeys","getColdKeys","persistStatistics","context","bindContext","invoke","hits","misses","sets","deletes","errors","avgLatency","p95Latency","p99Latency","minLatency","maxLatency","avgHitLatency","p95HitLatency","p99HitLatency","minHitLatency","maxHitLatency","avgMissLatency","p95MissLatency","p99MissLatency","minMissLatency","maxMissLatency","avgSetLatency","avgDeleteLatency","memoryUsage","itemCount","hitRatio","throughput","errorRate","cacheEfficiency","uptimeMs","uniqueKeys","topKeys","coldKeys","lastPersisted","Date","toISOString","getAvailableMetrics","getMetricById","metricId","setMetricsEnabled","enabled","setParameter","setKeyMetricsEnabled"],"sources":["CacheStatisticsService.ts"],"sourcesContent":["import MessageBox from \"sap/m/MessageBox\";\nimport ODataModel from \"sap/ui/model/odata/v4/ODataModel\";\nimport Filter from \"sap/ui/model/Filter\";\nimport FilterOperator from \"sap/ui/model/FilterOperator\";\nimport Sorter from \"sap/ui/model/Sorter\";\nimport Context from \"sap/ui/model/odata/v4/Context\";\nimport { cacheAndIdFilter, cacheNameFilter, periodFilter } from \"../model/filters\";\n\nexport interface CacheStatistics {\n hits: number;\n misses: number;\n sets: number;\n deletes: number;\n errors: number;\n\n // Overall latency metrics\n avgLatency: number;\n p95Latency: number;\n p99Latency: number;\n minLatency: number;\n maxLatency: number;\n\n // Hit-specific latency metrics\n avgHitLatency: number;\n p95HitLatency: number;\n p99HitLatency: number;\n minHitLatency: number;\n maxHitLatency: number;\n\n // Miss-specific latency metrics\n avgMissLatency: number;\n p95MissLatency: number;\n p99MissLatency: number;\n minMissLatency: number;\n maxMissLatency: number;\n\n // Set/Delete latency metrics\n avgSetLatency: number;\n avgDeleteLatency: number;\n\n // Performance metrics\n memoryUsage: number;\n itemCount: number;\n hitRatio: number;\n throughput: number;\n errorRate: number;\n cacheEfficiency: number;\n uptimeMs: number;\n uniqueKeys: number;\n topKeys: KeyAccess[];\n coldKeys: KeyAccess[];\n lastPersisted: string;\n}\n\nexport interface KeyAccess {\n keyName: string;\n hits: number;\n misses: number;\n sets: number;\n deletes: number;\n total: number;\n lastAccess: string;\n dataType: string;\n serviceName: string;\n entityName: string;\n operation: string;\n metadata: string;\n}\n\nexport interface HistoricalStatistics {\n ID: string;\n cache: string;\n timestamp: string;\n period: string;\n\n hits: number;\n misses: number;\n sets: number;\n deletes: number;\n errors: number;\n totalRequests: number;\n\n avgHitLatency: number;\n p95HitLatency: number;\n p99HitLatency: number;\n minHitLatency: number;\n maxHitLatency: number;\n avgMissLatency: number;\n p95MissLatency: number;\n p99MissLatency: number;\n minMissLatency: number;\n maxMissLatency: number;\n avgSetLatency: number;\n avgDeleteLatency: number;\n\n hitRatio: number;\n throughput: number;\n errorRate: number;\n cacheEfficiency: number;\n\n nativeSets: number;\n nativeGets: number;\n nativeDeletes: number;\n nativeClears: number;\n nativeDeleteByTags: number;\n nativeErrors: number;\n totalNativeOperations: number;\n\n nativeThroughput: number;\n nativeErrorRate: number;\n\n memoryUsage: number;\n itemCount: number;\n uptimeMs: number;\n}\n\n/**\n * Service class for interacting with the Cache Statistics API using OData V4\n */\nexport default class CacheStatisticsService {\n private model: ODataModel;\n\n constructor(model?: ODataModel) {\n this.model = model || new ODataModel({\n serviceUrl: \"/odata/v4/caching-api/\",\n autoExpandSelect: true,\n groupId: \"$auto\"\n });\n }\n\n getModel(): ODataModel {\n return this.model;\n }\n\n async getCurrentMetrics(cacheName: string): Promise<CacheStatistics | null> {\n try {\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n [new Sorter({ path: \"timestamp\", descending: true })],\n [periodFilter(\"hourly\"), cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n const results = data.map((item: Context) => item.getObject());\n\n if (results.length > 0) {\n return this.transformStatistics(results[0]);\n }\n return null;\n } catch (error) {\n console.error(\"Error fetching current metrics:\", error);\n MessageBox.error(\"Failed to load current metrics\");\n return null;\n }\n }\n\n async getHistoricalMetrics(cacheName: string, period: string = \"hourly\", from?: string, to?: string): Promise<HistoricalStatistics[]> {\n try {\n const filters: Filter[] = [periodFilter(period), cacheNameFilter(cacheName)];\n if (from) {\n filters.push(new Filter({ path: \"timestamp\", operator: FilterOperator.GE, value1: from }));\n }\n if (to) {\n filters.push(new Filter({ path: \"timestamp\", operator: FilterOperator.LE, value1: to }));\n }\n\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n [new Sorter({ path: \"timestamp\", descending: true })],\n filters\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching historical metrics:\", error);\n MessageBox.error(\"Failed to load historical metrics\");\n return [];\n }\n }\n\n async getTopKeys(cacheName: string): Promise<KeyAccess[]> {\n try {\n const binding = this.model.bindList(\n \"/KeyMetrics\",\n undefined,\n [new Sorter({ path: \"totalRequests\", descending: true })],\n [periodFilter(\"current\"), cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching top keys:\", error);\n MessageBox.error(\"Failed to load top keys\");\n return [];\n }\n }\n\n async getColdKeys(cacheName: string): Promise<KeyAccess[]> {\n try {\n const binding = this.model.bindList(\n \"/KeyMetrics\",\n undefined,\n [new Sorter({ path: \"lastAccess\", descending: false })],\n [periodFilter(\"current\"), cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching cold keys:\", error);\n MessageBox.error(\"Failed to load cold keys\");\n return [];\n }\n }\n\n async persistStatistics(): Promise<boolean> {\n try {\n const context = this.model.bindContext(\"/persistStatistics(...)\");\n await context.invoke();\n return true;\n } catch (error) {\n console.error(\"Error persisting statistics:\", error);\n MessageBox.error(\"Failed to persist statistics\");\n return false;\n }\n }\n\n private transformStatistics(data: Record<string, unknown>): CacheStatistics {\n return {\n hits: (data.hits as number) || 0,\n misses: (data.misses as number) || 0,\n sets: (data.sets as number) || 0,\n deletes: (data.deletes as number) || 0,\n errors: (data.errors as number) || 0,\n\n avgLatency: (data.avgLatency as number) || 0,\n p95Latency: (data.p95Latency as number) || 0,\n p99Latency: (data.p99Latency as number) || 0,\n minLatency: (data.minLatency as number) || 0,\n maxLatency: (data.maxLatency as number) || 0,\n\n avgHitLatency: (data.avgHitLatency as number) || 0,\n p95HitLatency: (data.p95HitLatency as number) || 0,\n p99HitLatency: (data.p99HitLatency as number) || 0,\n minHitLatency: (data.minHitLatency as number) || 0,\n maxHitLatency: (data.maxHitLatency as number) || 0,\n\n avgMissLatency: (data.avgMissLatency as number) || 0,\n p95MissLatency: (data.p95MissLatency as number) || 0,\n p99MissLatency: (data.p99MissLatency as number) || 0,\n minMissLatency: (data.minMissLatency as number) || 0,\n maxMissLatency: (data.maxMissLatency as number) || 0,\n\n avgSetLatency: (data.avgSetLatency as number) || 0,\n avgDeleteLatency: (data.avgDeleteLatency as number) || 0,\n\n memoryUsage: (data.memoryUsage as number) || 0,\n itemCount: (data.itemCount as number) || 0,\n hitRatio: (data.hitRatio as number) || 0,\n throughput: (data.throughput as number) || 0,\n errorRate: (data.errorRate as number) || 0,\n cacheEfficiency: (data.cacheEfficiency as number) || 0,\n uptimeMs: (data.uptimeMs as number) || 0,\n uniqueKeys: 0,\n topKeys: [],\n coldKeys: [],\n lastPersisted: (data.lastPersisted as string) || new Date().toISOString()\n };\n }\n\n async getAvailableMetrics(cacheName: string): Promise<Record<string, unknown>[]> {\n try {\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n [new Sorter({ path: \"timestamp\", descending: true })],\n [cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching available metrics:\", error);\n MessageBox.error(\"Failed to load available metrics\");\n return [];\n }\n }\n\n async getMetricById(cacheName: string, metricId: string): Promise<CacheStatistics | null> {\n try {\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n undefined,\n cacheAndIdFilter(cacheName, metricId)\n );\n\n const data = await binding.requestContexts();\n const results = data.map((item: Context) => item.getObject());\n\n if (results.length > 0) {\n return this.transformStatistics(results[0]);\n }\n return null;\n } catch (error) {\n console.error(\"Error fetching metric by ID:\", error);\n MessageBox.error(\"Failed to load metric\");\n return null;\n }\n }\n\n async setMetricsEnabled(cacheName: string, enabled: boolean): Promise<boolean> {\n try {\n const context = this.model.bindContext(\"/setMetricsEnabled(...)\");\n context.setParameter(\"cache\", cacheName);\n context.setParameter(\"enabled\", enabled);\n await context.invoke();\n return true;\n } catch (error) {\n console.error(\"Error setting metrics enabled:\", error);\n MessageBox.error(\"Failed to update metrics configuration\");\n return false;\n }\n }\n\n async setKeyMetricsEnabled(cacheName: string, enabled: boolean): Promise<boolean> {\n try {\n const context = this.model.bindContext(\"/setKeyMetricsEnabled(...)\");\n context.setParameter(\"cache\", cacheName);\n context.setParameter(\"enabled\", enabled);\n await context.invoke();\n return true;\n } catch (error) {\n console.error(\"Error setting key metrics enabled:\", error);\n MessageBox.error(\"Failed to update key metrics configuration\");\n return false;\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
sap.ui.define(["sap/m/MessageBox","sap/ui/model/odata/v4/ODataModel","sap/ui/model/Filter","sap/ui/model/FilterOperator","sap/ui/model/Sorter","../model/filters"],function(e,t,r,s,a,n){"use strict";const i=n["cacheAndIdFilter"];const c=n["cacheNameFilter"];const o=n["periodFilter"];class l{constructor(e){this.model=e||new t({serviceUrl:"/odata/v4/caching/",autoExpandSelect:true,groupId:"$auto"})}getModel(){return this.model}async getCurrentMetrics(t){try{const e=this.model.bindList("/Metrics",undefined,[new a({path:"timestamp",descending:true})],[o("hourly"),c(t)]);const r=await e.requestContexts();const s=r.map(e=>e.getObject());if(s.length>0){return this.transformStatistics(s[0])}return null}catch(t){console.error("Error fetching current metrics:",t);e.error("Failed to load current metrics");return null}}async getHistoricalMetrics(t,n="hourly",i,l){try{const e=[o(n),c(t)];if(i){e.push(new r({path:"timestamp",operator:s.GE,value1:i}))}if(l){e.push(new r({path:"timestamp",operator:s.LE,value1:l}))}const d=this.model.bindList("/Metrics",undefined,[new a({path:"timestamp",descending:true})],e);const u=await d.requestContexts();return u.map(e=>e.getObject())}catch(t){console.error("Error fetching historical metrics:",t);e.error("Failed to load historical metrics");return[]}}async getTopKeys(t){try{const e=this.model.bindList("/KeyMetrics",undefined,[new a({path:"totalRequests",descending:true})],[o("current"),c(t)]);const r=await e.requestContexts();return r.map(e=>e.getObject())}catch(t){console.error("Error fetching top keys:",t);e.error("Failed to load top keys");return[]}}async getColdKeys(t){try{const e=this.model.bindList("/KeyMetrics",undefined,[new a({path:"lastAccess",descending:false})],[o("current"),c(t)]);const r=await e.requestContexts();return r.map(e=>e.getObject())}catch(t){console.error("Error fetching cold keys:",t);e.error("Failed to load cold keys");return[]}}async persistStatistics(){try{const e=this.model.bindContext("/persistStatistics(...)");await e.invoke();return true}catch(t){console.error("Error persisting statistics:",t);e.error("Failed to persist statistics");return false}}transformStatistics(e){return{hits:e.hits||0,misses:e.misses||0,sets:e.sets||0,deletes:e.deletes||0,errors:e.errors||0,avgLatency:e.avgLatency||0,p95Latency:e.p95Latency||0,p99Latency:e.p99Latency||0,minLatency:e.minLatency||0,maxLatency:e.maxLatency||0,avgHitLatency:e.avgHitLatency||0,p95HitLatency:e.p95HitLatency||0,p99HitLatency:e.p99HitLatency||0,minHitLatency:e.minHitLatency||0,maxHitLatency:e.maxHitLatency||0,avgMissLatency:e.avgMissLatency||0,p95MissLatency:e.p95MissLatency||0,p99MissLatency:e.p99MissLatency||0,minMissLatency:e.minMissLatency||0,maxMissLatency:e.maxMissLatency||0,avgSetLatency:e.avgSetLatency||0,avgDeleteLatency:e.avgDeleteLatency||0,memoryUsage:e.memoryUsage||0,itemCount:e.itemCount||0,hitRatio:e.hitRatio||0,throughput:e.throughput||0,errorRate:e.errorRate||0,cacheEfficiency:e.cacheEfficiency||0,uptimeMs:e.uptimeMs||0,uniqueKeys:0,topKeys:[],coldKeys:[],lastPersisted:e.lastPersisted||(new Date).toISOString()}}async getAvailableMetrics(t){try{const e=this.model.bindList("/Metrics",undefined,[new a({path:"timestamp",descending:true})],[c(t)]);const r=await e.requestContexts();return r.map(e=>e.getObject())}catch(t){console.error("Error fetching available metrics:",t);e.error("Failed to load available metrics");return[]}}async getMetricById(t,r){try{const e=this.model.bindList("/Metrics",undefined,undefined,i(t,r));const s=await e.requestContexts();const a=s.map(e=>e.getObject());if(a.length>0){return this.transformStatistics(a[0])}return null}catch(t){console.error("Error fetching metric by ID:",t);e.error("Failed to load metric");return null}}async setMetricsEnabled(t,r){try{const e=this.model.bindContext("/setMetricsEnabled(...)");e.setParameter("cache",t);e.setParameter("enabled",r);await e.invoke();return true}catch(t){console.error("Error setting metrics enabled:",t);e.error("Failed to update metrics configuration");return false}}async setKeyMetricsEnabled(t,r){try{const e=this.model.bindContext("/setKeyMetricsEnabled(...)");e.setParameter("cache",t);e.setParameter("enabled",r);await e.invoke();return true}catch(t){console.error("Error setting key metrics enabled:",t);e.error("Failed to update key metrics configuration");return false}}}return l});
|
|
1
|
+
sap.ui.define(["sap/m/MessageBox","sap/ui/model/odata/v4/ODataModel","sap/ui/model/Filter","sap/ui/model/FilterOperator","sap/ui/model/Sorter","../model/filters"],function(e,t,r,s,a,n){"use strict";const i=n["cacheAndIdFilter"];const c=n["cacheNameFilter"];const o=n["periodFilter"];class l{constructor(e){this.model=e||new t({serviceUrl:"/odata/v4/caching-api/",autoExpandSelect:true,groupId:"$auto"})}getModel(){return this.model}async getCurrentMetrics(t){try{const e=this.model.bindList("/Metrics",undefined,[new a({path:"timestamp",descending:true})],[o("hourly"),c(t)]);const r=await e.requestContexts();const s=r.map(e=>e.getObject());if(s.length>0){return this.transformStatistics(s[0])}return null}catch(t){console.error("Error fetching current metrics:",t);e.error("Failed to load current metrics");return null}}async getHistoricalMetrics(t,n="hourly",i,l){try{const e=[o(n),c(t)];if(i){e.push(new r({path:"timestamp",operator:s.GE,value1:i}))}if(l){e.push(new r({path:"timestamp",operator:s.LE,value1:l}))}const d=this.model.bindList("/Metrics",undefined,[new a({path:"timestamp",descending:true})],e);const u=await d.requestContexts();return u.map(e=>e.getObject())}catch(t){console.error("Error fetching historical metrics:",t);e.error("Failed to load historical metrics");return[]}}async getTopKeys(t){try{const e=this.model.bindList("/KeyMetrics",undefined,[new a({path:"totalRequests",descending:true})],[o("current"),c(t)]);const r=await e.requestContexts();return r.map(e=>e.getObject())}catch(t){console.error("Error fetching top keys:",t);e.error("Failed to load top keys");return[]}}async getColdKeys(t){try{const e=this.model.bindList("/KeyMetrics",undefined,[new a({path:"lastAccess",descending:false})],[o("current"),c(t)]);const r=await e.requestContexts();return r.map(e=>e.getObject())}catch(t){console.error("Error fetching cold keys:",t);e.error("Failed to load cold keys");return[]}}async persistStatistics(){try{const e=this.model.bindContext("/persistStatistics(...)");await e.invoke();return true}catch(t){console.error("Error persisting statistics:",t);e.error("Failed to persist statistics");return false}}transformStatistics(e){return{hits:e.hits||0,misses:e.misses||0,sets:e.sets||0,deletes:e.deletes||0,errors:e.errors||0,avgLatency:e.avgLatency||0,p95Latency:e.p95Latency||0,p99Latency:e.p99Latency||0,minLatency:e.minLatency||0,maxLatency:e.maxLatency||0,avgHitLatency:e.avgHitLatency||0,p95HitLatency:e.p95HitLatency||0,p99HitLatency:e.p99HitLatency||0,minHitLatency:e.minHitLatency||0,maxHitLatency:e.maxHitLatency||0,avgMissLatency:e.avgMissLatency||0,p95MissLatency:e.p95MissLatency||0,p99MissLatency:e.p99MissLatency||0,minMissLatency:e.minMissLatency||0,maxMissLatency:e.maxMissLatency||0,avgSetLatency:e.avgSetLatency||0,avgDeleteLatency:e.avgDeleteLatency||0,memoryUsage:e.memoryUsage||0,itemCount:e.itemCount||0,hitRatio:e.hitRatio||0,throughput:e.throughput||0,errorRate:e.errorRate||0,cacheEfficiency:e.cacheEfficiency||0,uptimeMs:e.uptimeMs||0,uniqueKeys:0,topKeys:[],coldKeys:[],lastPersisted:e.lastPersisted||(new Date).toISOString()}}async getAvailableMetrics(t){try{const e=this.model.bindList("/Metrics",undefined,[new a({path:"timestamp",descending:true})],[c(t)]);const r=await e.requestContexts();return r.map(e=>e.getObject())}catch(t){console.error("Error fetching available metrics:",t);e.error("Failed to load available metrics");return[]}}async getMetricById(t,r){try{const e=this.model.bindList("/Metrics",undefined,undefined,i(t,r));const s=await e.requestContexts();const a=s.map(e=>e.getObject());if(a.length>0){return this.transformStatistics(a[0])}return null}catch(t){console.error("Error fetching metric by ID:",t);e.error("Failed to load metric");return null}}async setMetricsEnabled(t,r){try{const e=this.model.bindContext("/setMetricsEnabled(...)");e.setParameter("cache",t);e.setParameter("enabled",r);await e.invoke();return true}catch(t){console.error("Error setting metrics enabled:",t);e.error("Failed to update metrics configuration");return false}}async setKeyMetricsEnabled(t,r){try{const e=this.model.bindContext("/setKeyMetricsEnabled(...)");e.setParameter("cache",t);e.setParameter("enabled",r);await e.invoke();return true}catch(t){console.error("Error setting key metrics enabled:",t);e.error("Failed to update key metrics configuration");return false}}}return l});
|
|
2
2
|
//# sourceMappingURL=CacheStatisticsService.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CacheStatisticsService.js","names":["cacheAndIdFilter","___model_filters","cacheNameFilter","periodFilter","CacheStatisticsService","constructor","model","this","ODataModel","serviceUrl","autoExpandSelect","groupId","getModel","getCurrentMetrics","cacheName","binding","bindList","undefined","Sorter","path","descending","data","requestContexts","results","map","item","getObject","length","transformStatistics","error","console","MessageBox","getHistoricalMetrics","period","from","to","filters","push","Filter","operator","FilterOperator","GE","value1","LE","getTopKeys","getColdKeys","persistStatistics","context","bindContext","invoke","hits","misses","sets","deletes","errors","avgLatency","p95Latency","p99Latency","minLatency","maxLatency","avgHitLatency","p95HitLatency","p99HitLatency","minHitLatency","maxHitLatency","avgMissLatency","p95MissLatency","p99MissLatency","minMissLatency","maxMissLatency","avgSetLatency","avgDeleteLatency","memoryUsage","itemCount","hitRatio","throughput","errorRate","cacheEfficiency","uptimeMs","uniqueKeys","topKeys","coldKeys","lastPersisted","Date","toISOString","getAvailableMetrics","getMetricById","metricId","setMetricsEnabled","enabled","setParameter","setKeyMetricsEnabled"],"sources":["CacheStatisticsService.ts"],"sourcesContent":["import MessageBox from \"sap/m/MessageBox\";\nimport ODataModel from \"sap/ui/model/odata/v4/ODataModel\";\nimport Filter from \"sap/ui/model/Filter\";\nimport FilterOperator from \"sap/ui/model/FilterOperator\";\nimport Sorter from \"sap/ui/model/Sorter\";\nimport Context from \"sap/ui/model/odata/v4/Context\";\nimport { cacheAndIdFilter, cacheNameFilter, periodFilter } from \"../model/filters\";\n\nexport interface CacheStatistics {\n hits: number;\n misses: number;\n sets: number;\n deletes: number;\n errors: number;\n\n // Overall latency metrics\n avgLatency: number;\n p95Latency: number;\n p99Latency: number;\n minLatency: number;\n maxLatency: number;\n\n // Hit-specific latency metrics\n avgHitLatency: number;\n p95HitLatency: number;\n p99HitLatency: number;\n minHitLatency: number;\n maxHitLatency: number;\n\n // Miss-specific latency metrics\n avgMissLatency: number;\n p95MissLatency: number;\n p99MissLatency: number;\n minMissLatency: number;\n maxMissLatency: number;\n\n // Set/Delete latency metrics\n avgSetLatency: number;\n avgDeleteLatency: number;\n\n // Performance metrics\n memoryUsage: number;\n itemCount: number;\n hitRatio: number;\n throughput: number;\n errorRate: number;\n cacheEfficiency: number;\n uptimeMs: number;\n uniqueKeys: number;\n topKeys: KeyAccess[];\n coldKeys: KeyAccess[];\n lastPersisted: string;\n}\n\nexport interface KeyAccess {\n keyName: string;\n hits: number;\n misses: number;\n sets: number;\n deletes: number;\n total: number;\n lastAccess: string;\n dataType: string;\n serviceName: string;\n entityName: string;\n operation: string;\n metadata: string;\n}\n\nexport interface HistoricalStatistics {\n ID: string;\n cache: string;\n timestamp: string;\n period: string;\n\n hits: number;\n misses: number;\n sets: number;\n deletes: number;\n errors: number;\n totalRequests: number;\n\n avgHitLatency: number;\n p95HitLatency: number;\n p99HitLatency: number;\n minHitLatency: number;\n maxHitLatency: number;\n avgMissLatency: number;\n p95MissLatency: number;\n p99MissLatency: number;\n minMissLatency: number;\n maxMissLatency: number;\n avgSetLatency: number;\n avgDeleteLatency: number;\n\n hitRatio: number;\n throughput: number;\n errorRate: number;\n cacheEfficiency: number;\n\n nativeSets: number;\n nativeGets: number;\n nativeDeletes: number;\n nativeClears: number;\n nativeDeleteByTags: number;\n nativeErrors: number;\n totalNativeOperations: number;\n\n nativeThroughput: number;\n nativeErrorRate: number;\n\n memoryUsage: number;\n itemCount: number;\n uptimeMs: number;\n}\n\n/**\n * Service class for interacting with the Cache Statistics API using OData V4\n */\nexport default class CacheStatisticsService {\n private model: ODataModel;\n\n constructor(model?: ODataModel) {\n this.model = model || new ODataModel({\n serviceUrl: \"/odata/v4/caching/\",\n autoExpandSelect: true,\n groupId: \"$auto\"\n });\n }\n\n getModel(): ODataModel {\n return this.model;\n }\n\n async getCurrentMetrics(cacheName: string): Promise<CacheStatistics | null> {\n try {\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n [new Sorter({ path: \"timestamp\", descending: true })],\n [periodFilter(\"hourly\"), cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n const results = data.map((item: Context) => item.getObject());\n\n if (results.length > 0) {\n return this.transformStatistics(results[0]);\n }\n return null;\n } catch (error) {\n console.error(\"Error fetching current metrics:\", error);\n MessageBox.error(\"Failed to load current metrics\");\n return null;\n }\n }\n\n async getHistoricalMetrics(cacheName: string, period: string = \"hourly\", from?: string, to?: string): Promise<HistoricalStatistics[]> {\n try {\n const filters: Filter[] = [periodFilter(period), cacheNameFilter(cacheName)];\n if (from) {\n filters.push(new Filter({ path: \"timestamp\", operator: FilterOperator.GE, value1: from }));\n }\n if (to) {\n filters.push(new Filter({ path: \"timestamp\", operator: FilterOperator.LE, value1: to }));\n }\n\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n [new Sorter({ path: \"timestamp\", descending: true })],\n filters\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching historical metrics:\", error);\n MessageBox.error(\"Failed to load historical metrics\");\n return [];\n }\n }\n\n async getTopKeys(cacheName: string): Promise<KeyAccess[]> {\n try {\n const binding = this.model.bindList(\n \"/KeyMetrics\",\n undefined,\n [new Sorter({ path: \"totalRequests\", descending: true })],\n [periodFilter(\"current\"), cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching top keys:\", error);\n MessageBox.error(\"Failed to load top keys\");\n return [];\n }\n }\n\n async getColdKeys(cacheName: string): Promise<KeyAccess[]> {\n try {\n const binding = this.model.bindList(\n \"/KeyMetrics\",\n undefined,\n [new Sorter({ path: \"lastAccess\", descending: false })],\n [periodFilter(\"current\"), cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching cold keys:\", error);\n MessageBox.error(\"Failed to load cold keys\");\n return [];\n }\n }\n\n async persistStatistics(): Promise<boolean> {\n try {\n const context = this.model.bindContext(\"/persistStatistics(...)\");\n await context.invoke();\n return true;\n } catch (error) {\n console.error(\"Error persisting statistics:\", error);\n MessageBox.error(\"Failed to persist statistics\");\n return false;\n }\n }\n\n private transformStatistics(data: Record<string, unknown>): CacheStatistics {\n return {\n hits: (data.hits as number) || 0,\n misses: (data.misses as number) || 0,\n sets: (data.sets as number) || 0,\n deletes: (data.deletes as number) || 0,\n errors: (data.errors as number) || 0,\n\n avgLatency: (data.avgLatency as number) || 0,\n p95Latency: (data.p95Latency as number) || 0,\n p99Latency: (data.p99Latency as number) || 0,\n minLatency: (data.minLatency as number) || 0,\n maxLatency: (data.maxLatency as number) || 0,\n\n avgHitLatency: (data.avgHitLatency as number) || 0,\n p95HitLatency: (data.p95HitLatency as number) || 0,\n p99HitLatency: (data.p99HitLatency as number) || 0,\n minHitLatency: (data.minHitLatency as number) || 0,\n maxHitLatency: (data.maxHitLatency as number) || 0,\n\n avgMissLatency: (data.avgMissLatency as number) || 0,\n p95MissLatency: (data.p95MissLatency as number) || 0,\n p99MissLatency: (data.p99MissLatency as number) || 0,\n minMissLatency: (data.minMissLatency as number) || 0,\n maxMissLatency: (data.maxMissLatency as number) || 0,\n\n avgSetLatency: (data.avgSetLatency as number) || 0,\n avgDeleteLatency: (data.avgDeleteLatency as number) || 0,\n\n memoryUsage: (data.memoryUsage as number) || 0,\n itemCount: (data.itemCount as number) || 0,\n hitRatio: (data.hitRatio as number) || 0,\n throughput: (data.throughput as number) || 0,\n errorRate: (data.errorRate as number) || 0,\n cacheEfficiency: (data.cacheEfficiency as number) || 0,\n uptimeMs: (data.uptimeMs as number) || 0,\n uniqueKeys: 0,\n topKeys: [],\n coldKeys: [],\n lastPersisted: (data.lastPersisted as string) || new Date().toISOString()\n };\n }\n\n async getAvailableMetrics(cacheName: string): Promise<Record<string, unknown>[]> {\n try {\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n [new Sorter({ path: \"timestamp\", descending: true })],\n [cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching available metrics:\", error);\n MessageBox.error(\"Failed to load available metrics\");\n return [];\n }\n }\n\n async getMetricById(cacheName: string, metricId: string): Promise<CacheStatistics | null> {\n try {\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n undefined,\n cacheAndIdFilter(cacheName, metricId)\n );\n\n const data = await binding.requestContexts();\n const results = data.map((item: Context) => item.getObject());\n\n if (results.length > 0) {\n return this.transformStatistics(results[0]);\n }\n return null;\n } catch (error) {\n console.error(\"Error fetching metric by ID:\", error);\n MessageBox.error(\"Failed to load metric\");\n return null;\n }\n }\n\n async setMetricsEnabled(cacheName: string, enabled: boolean): Promise<boolean> {\n try {\n const context = this.model.bindContext(\"/setMetricsEnabled(...)\");\n context.setParameter(\"cache\", cacheName);\n context.setParameter(\"enabled\", enabled);\n await context.invoke();\n return true;\n } catch (error) {\n console.error(\"Error setting metrics enabled:\", error);\n MessageBox.error(\"Failed to update metrics configuration\");\n return false;\n }\n }\n\n async setKeyMetricsEnabled(cacheName: string, enabled: boolean): Promise<boolean> {\n try {\n const context = this.model.bindContext(\"/setKeyMetricsEnabled(...)\");\n context.setParameter(\"cache\", cacheName);\n context.setParameter(\"enabled\", enabled);\n await context.invoke();\n return true;\n } catch (error) {\n console.error(\"Error setting key metrics enabled:\", error);\n MessageBox.error(\"Failed to update key metrics configuration\");\n return false;\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"CacheStatisticsService.js","names":["cacheAndIdFilter","___model_filters","cacheNameFilter","periodFilter","CacheStatisticsService","constructor","model","this","ODataModel","serviceUrl","autoExpandSelect","groupId","getModel","getCurrentMetrics","cacheName","binding","bindList","undefined","Sorter","path","descending","data","requestContexts","results","map","item","getObject","length","transformStatistics","error","console","MessageBox","getHistoricalMetrics","period","from","to","filters","push","Filter","operator","FilterOperator","GE","value1","LE","getTopKeys","getColdKeys","persistStatistics","context","bindContext","invoke","hits","misses","sets","deletes","errors","avgLatency","p95Latency","p99Latency","minLatency","maxLatency","avgHitLatency","p95HitLatency","p99HitLatency","minHitLatency","maxHitLatency","avgMissLatency","p95MissLatency","p99MissLatency","minMissLatency","maxMissLatency","avgSetLatency","avgDeleteLatency","memoryUsage","itemCount","hitRatio","throughput","errorRate","cacheEfficiency","uptimeMs","uniqueKeys","topKeys","coldKeys","lastPersisted","Date","toISOString","getAvailableMetrics","getMetricById","metricId","setMetricsEnabled","enabled","setParameter","setKeyMetricsEnabled"],"sources":["CacheStatisticsService.ts"],"sourcesContent":["import MessageBox from \"sap/m/MessageBox\";\nimport ODataModel from \"sap/ui/model/odata/v4/ODataModel\";\nimport Filter from \"sap/ui/model/Filter\";\nimport FilterOperator from \"sap/ui/model/FilterOperator\";\nimport Sorter from \"sap/ui/model/Sorter\";\nimport Context from \"sap/ui/model/odata/v4/Context\";\nimport { cacheAndIdFilter, cacheNameFilter, periodFilter } from \"../model/filters\";\n\nexport interface CacheStatistics {\n hits: number;\n misses: number;\n sets: number;\n deletes: number;\n errors: number;\n\n // Overall latency metrics\n avgLatency: number;\n p95Latency: number;\n p99Latency: number;\n minLatency: number;\n maxLatency: number;\n\n // Hit-specific latency metrics\n avgHitLatency: number;\n p95HitLatency: number;\n p99HitLatency: number;\n minHitLatency: number;\n maxHitLatency: number;\n\n // Miss-specific latency metrics\n avgMissLatency: number;\n p95MissLatency: number;\n p99MissLatency: number;\n minMissLatency: number;\n maxMissLatency: number;\n\n // Set/Delete latency metrics\n avgSetLatency: number;\n avgDeleteLatency: number;\n\n // Performance metrics\n memoryUsage: number;\n itemCount: number;\n hitRatio: number;\n throughput: number;\n errorRate: number;\n cacheEfficiency: number;\n uptimeMs: number;\n uniqueKeys: number;\n topKeys: KeyAccess[];\n coldKeys: KeyAccess[];\n lastPersisted: string;\n}\n\nexport interface KeyAccess {\n keyName: string;\n hits: number;\n misses: number;\n sets: number;\n deletes: number;\n total: number;\n lastAccess: string;\n dataType: string;\n serviceName: string;\n entityName: string;\n operation: string;\n metadata: string;\n}\n\nexport interface HistoricalStatistics {\n ID: string;\n cache: string;\n timestamp: string;\n period: string;\n\n hits: number;\n misses: number;\n sets: number;\n deletes: number;\n errors: number;\n totalRequests: number;\n\n avgHitLatency: number;\n p95HitLatency: number;\n p99HitLatency: number;\n minHitLatency: number;\n maxHitLatency: number;\n avgMissLatency: number;\n p95MissLatency: number;\n p99MissLatency: number;\n minMissLatency: number;\n maxMissLatency: number;\n avgSetLatency: number;\n avgDeleteLatency: number;\n\n hitRatio: number;\n throughput: number;\n errorRate: number;\n cacheEfficiency: number;\n\n nativeSets: number;\n nativeGets: number;\n nativeDeletes: number;\n nativeClears: number;\n nativeDeleteByTags: number;\n nativeErrors: number;\n totalNativeOperations: number;\n\n nativeThroughput: number;\n nativeErrorRate: number;\n\n memoryUsage: number;\n itemCount: number;\n uptimeMs: number;\n}\n\n/**\n * Service class for interacting with the Cache Statistics API using OData V4\n */\nexport default class CacheStatisticsService {\n private model: ODataModel;\n\n constructor(model?: ODataModel) {\n this.model = model || new ODataModel({\n serviceUrl: \"/odata/v4/caching-api/\",\n autoExpandSelect: true,\n groupId: \"$auto\"\n });\n }\n\n getModel(): ODataModel {\n return this.model;\n }\n\n async getCurrentMetrics(cacheName: string): Promise<CacheStatistics | null> {\n try {\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n [new Sorter({ path: \"timestamp\", descending: true })],\n [periodFilter(\"hourly\"), cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n const results = data.map((item: Context) => item.getObject());\n\n if (results.length > 0) {\n return this.transformStatistics(results[0]);\n }\n return null;\n } catch (error) {\n console.error(\"Error fetching current metrics:\", error);\n MessageBox.error(\"Failed to load current metrics\");\n return null;\n }\n }\n\n async getHistoricalMetrics(cacheName: string, period: string = \"hourly\", from?: string, to?: string): Promise<HistoricalStatistics[]> {\n try {\n const filters: Filter[] = [periodFilter(period), cacheNameFilter(cacheName)];\n if (from) {\n filters.push(new Filter({ path: \"timestamp\", operator: FilterOperator.GE, value1: from }));\n }\n if (to) {\n filters.push(new Filter({ path: \"timestamp\", operator: FilterOperator.LE, value1: to }));\n }\n\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n [new Sorter({ path: \"timestamp\", descending: true })],\n filters\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching historical metrics:\", error);\n MessageBox.error(\"Failed to load historical metrics\");\n return [];\n }\n }\n\n async getTopKeys(cacheName: string): Promise<KeyAccess[]> {\n try {\n const binding = this.model.bindList(\n \"/KeyMetrics\",\n undefined,\n [new Sorter({ path: \"totalRequests\", descending: true })],\n [periodFilter(\"current\"), cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching top keys:\", error);\n MessageBox.error(\"Failed to load top keys\");\n return [];\n }\n }\n\n async getColdKeys(cacheName: string): Promise<KeyAccess[]> {\n try {\n const binding = this.model.bindList(\n \"/KeyMetrics\",\n undefined,\n [new Sorter({ path: \"lastAccess\", descending: false })],\n [periodFilter(\"current\"), cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching cold keys:\", error);\n MessageBox.error(\"Failed to load cold keys\");\n return [];\n }\n }\n\n async persistStatistics(): Promise<boolean> {\n try {\n const context = this.model.bindContext(\"/persistStatistics(...)\");\n await context.invoke();\n return true;\n } catch (error) {\n console.error(\"Error persisting statistics:\", error);\n MessageBox.error(\"Failed to persist statistics\");\n return false;\n }\n }\n\n private transformStatistics(data: Record<string, unknown>): CacheStatistics {\n return {\n hits: (data.hits as number) || 0,\n misses: (data.misses as number) || 0,\n sets: (data.sets as number) || 0,\n deletes: (data.deletes as number) || 0,\n errors: (data.errors as number) || 0,\n\n avgLatency: (data.avgLatency as number) || 0,\n p95Latency: (data.p95Latency as number) || 0,\n p99Latency: (data.p99Latency as number) || 0,\n minLatency: (data.minLatency as number) || 0,\n maxLatency: (data.maxLatency as number) || 0,\n\n avgHitLatency: (data.avgHitLatency as number) || 0,\n p95HitLatency: (data.p95HitLatency as number) || 0,\n p99HitLatency: (data.p99HitLatency as number) || 0,\n minHitLatency: (data.minHitLatency as number) || 0,\n maxHitLatency: (data.maxHitLatency as number) || 0,\n\n avgMissLatency: (data.avgMissLatency as number) || 0,\n p95MissLatency: (data.p95MissLatency as number) || 0,\n p99MissLatency: (data.p99MissLatency as number) || 0,\n minMissLatency: (data.minMissLatency as number) || 0,\n maxMissLatency: (data.maxMissLatency as number) || 0,\n\n avgSetLatency: (data.avgSetLatency as number) || 0,\n avgDeleteLatency: (data.avgDeleteLatency as number) || 0,\n\n memoryUsage: (data.memoryUsage as number) || 0,\n itemCount: (data.itemCount as number) || 0,\n hitRatio: (data.hitRatio as number) || 0,\n throughput: (data.throughput as number) || 0,\n errorRate: (data.errorRate as number) || 0,\n cacheEfficiency: (data.cacheEfficiency as number) || 0,\n uptimeMs: (data.uptimeMs as number) || 0,\n uniqueKeys: 0,\n topKeys: [],\n coldKeys: [],\n lastPersisted: (data.lastPersisted as string) || new Date().toISOString()\n };\n }\n\n async getAvailableMetrics(cacheName: string): Promise<Record<string, unknown>[]> {\n try {\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n [new Sorter({ path: \"timestamp\", descending: true })],\n [cacheNameFilter(cacheName)]\n );\n\n const data = await binding.requestContexts();\n return data.map((item: Context) => item.getObject());\n } catch (error) {\n console.error(\"Error fetching available metrics:\", error);\n MessageBox.error(\"Failed to load available metrics\");\n return [];\n }\n }\n\n async getMetricById(cacheName: string, metricId: string): Promise<CacheStatistics | null> {\n try {\n const binding = this.model.bindList(\n \"/Metrics\",\n undefined,\n undefined,\n cacheAndIdFilter(cacheName, metricId)\n );\n\n const data = await binding.requestContexts();\n const results = data.map((item: Context) => item.getObject());\n\n if (results.length > 0) {\n return this.transformStatistics(results[0]);\n }\n return null;\n } catch (error) {\n console.error(\"Error fetching metric by ID:\", error);\n MessageBox.error(\"Failed to load metric\");\n return null;\n }\n }\n\n async setMetricsEnabled(cacheName: string, enabled: boolean): Promise<boolean> {\n try {\n const context = this.model.bindContext(\"/setMetricsEnabled(...)\");\n context.setParameter(\"cache\", cacheName);\n context.setParameter(\"enabled\", enabled);\n await context.invoke();\n return true;\n } catch (error) {\n console.error(\"Error setting metrics enabled:\", error);\n MessageBox.error(\"Failed to update metrics configuration\");\n return false;\n }\n }\n\n async setKeyMetricsEnabled(cacheName: string, enabled: boolean): Promise<boolean> {\n try {\n const context = this.model.bindContext(\"/setKeyMetricsEnabled(...)\");\n context.setParameter(\"cache\", cacheName);\n context.setParameter(\"enabled\", enabled);\n await context.invoke();\n return true;\n } catch (error) {\n console.error(\"Error setting key metrics enabled:\", error);\n MessageBox.error(\"Failed to update key metrics configuration\");\n return false;\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dataSources": {
|
|
17
17
|
"caching": {
|
|
18
|
-
"uri": "/odata/v4/caching/",
|
|
18
|
+
"uri": "/odata/v4/caching-api/",
|
|
19
19
|
"type": "OData",
|
|
20
20
|
"settings": {
|
|
21
21
|
"odataVersion": "4.0"
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"id": "app"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"minUI5Version": "1.
|
|
42
|
+
"minUI5Version": "1.148.10",
|
|
43
43
|
"libs": {
|
|
44
44
|
"sap.ui.core": {},
|
|
45
45
|
"sap.m": {},
|
|
@@ -75,8 +75,8 @@
|
|
|
75
75
|
},
|
|
76
76
|
"": {
|
|
77
77
|
"type": "sap.ui.model.odata.v4.ODataModel",
|
|
78
|
+
"dataSource": "caching",
|
|
78
79
|
"settings": {
|
|
79
|
-
"serviceUrl": "/odata/v4/caching-api/",
|
|
80
80
|
"operationMode": "Server",
|
|
81
81
|
"autoExpandSelect": true,
|
|
82
82
|
"groupId": "$auto"
|
|
@@ -122,7 +122,7 @@ export default class CacheStatisticsService {
|
|
|
122
122
|
|
|
123
123
|
constructor(model?: ODataModel) {
|
|
124
124
|
this.model = model || new ODataModel({
|
|
125
|
-
serviceUrl: "/odata/v4/caching/",
|
|
125
|
+
serviceUrl: "/odata/v4/caching-api/",
|
|
126
126
|
autoExpandSelect: true,
|
|
127
127
|
groupId: "$auto"
|
|
128
128
|
});
|
package/db/statistics.cds
CHANGED
|
@@ -5,10 +5,13 @@ entity Caches {
|
|
|
5
5
|
config : String;
|
|
6
6
|
metricsEnabled : Boolean default false;
|
|
7
7
|
keyMetricsEnabled : Boolean default false;
|
|
8
|
+
tagMetricsEnabled : Boolean default false;
|
|
8
9
|
metrics : Composition of many Metrics
|
|
9
10
|
on metrics.cache = $self.name;
|
|
10
11
|
keyMetrics : Composition of many KeyMetrics
|
|
11
12
|
on keyMetrics.cache = $self.name;
|
|
13
|
+
tagMetrics : Composition of many TagMetrics
|
|
14
|
+
on tagMetrics.cache = $self.name;
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
entity Metrics {
|
|
@@ -126,3 +129,56 @@ entity KeyMetrics {
|
|
|
126
129
|
timestamp : DateTime; // When this key was first accessed
|
|
127
130
|
cacheOptions : String; // JSON string with cache options
|
|
128
131
|
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Per-tag metrics. Opt-in via `tagMetricsEnabled` / `metrics.tagMetricsEnabled`.
|
|
135
|
+
*
|
|
136
|
+
* An entry can carry several tags, so a single hit increments every matching tag
|
|
137
|
+
* row. Tag totals can therefore exceed cache-level `Metrics` totals — that is
|
|
138
|
+
* expected, not a bug. Query by the resolved tag string (exact match), e.g.
|
|
139
|
+
* `tag eq 'federation:Airports'`.
|
|
140
|
+
*/
|
|
141
|
+
entity TagMetrics {
|
|
142
|
+
key ID : String;
|
|
143
|
+
key cache : String;
|
|
144
|
+
key tag : String;
|
|
145
|
+
lastAccess : DateTime;
|
|
146
|
+
period : String enum {
|
|
147
|
+
current;
|
|
148
|
+
hourly;
|
|
149
|
+
daily;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// Read-through metrics (hits and misses only)
|
|
153
|
+
hits : Integer default 0;
|
|
154
|
+
misses : Integer default 0;
|
|
155
|
+
errors : Integer default 0;
|
|
156
|
+
totalRequests : Integer default 0;
|
|
157
|
+
hitRatio : Double;
|
|
158
|
+
cacheEfficiency : Double;
|
|
159
|
+
|
|
160
|
+
// Read-through latency metrics
|
|
161
|
+
avgHitLatency : Double;
|
|
162
|
+
minHitLatency : Double;
|
|
163
|
+
maxHitLatency : Double;
|
|
164
|
+
avgMissLatency : Double;
|
|
165
|
+
minMissLatency : Double;
|
|
166
|
+
maxMissLatency : Double;
|
|
167
|
+
avgReadThroughLatency : Double;
|
|
168
|
+
|
|
169
|
+
// Read-through performance metrics
|
|
170
|
+
throughput : Double;
|
|
171
|
+
errorRate : Double;
|
|
172
|
+
|
|
173
|
+
// Native function metrics (counts only)
|
|
174
|
+
nativeHits : Integer default 0;
|
|
175
|
+
nativeMisses : Integer default 0;
|
|
176
|
+
nativeSets : Integer default 0;
|
|
177
|
+
nativeDeletes : Integer default 0;
|
|
178
|
+
nativeErrors : Integer default 0;
|
|
179
|
+
totalNativeOperations : Integer default 0;
|
|
180
|
+
nativeThroughput : Double;
|
|
181
|
+
nativeErrorRate : Double;
|
|
182
|
+
|
|
183
|
+
timestamp : DateTime;
|
|
184
|
+
}
|
package/index.cds
CHANGED
|
@@ -39,8 +39,10 @@ context plugin.cds_caching {
|
|
|
39
39
|
action clear() returns Boolean;
|
|
40
40
|
action clearMetrics() returns Boolean;
|
|
41
41
|
action clearKeyMetrics() returns Boolean;
|
|
42
|
+
action clearTagMetrics() returns Boolean;
|
|
42
43
|
action setMetricsEnabled(enabled : Boolean) returns Boolean;
|
|
43
44
|
action setKeyMetricsEnabled(enabled : Boolean) returns Boolean;
|
|
45
|
+
action setTagMetricsEnabled(enabled : Boolean) returns Boolean;
|
|
44
46
|
};
|
|
45
47
|
|
|
46
48
|
@readonly
|
|
@@ -49,5 +51,8 @@ context plugin.cds_caching {
|
|
|
49
51
|
@readonly
|
|
50
52
|
entity KeyMetrics as projection on plugin.cds_caching.KeyMetrics;
|
|
51
53
|
|
|
54
|
+
@readonly
|
|
55
|
+
entity TagMetrics as projection on plugin.cds_caching.TagMetrics;
|
|
56
|
+
|
|
52
57
|
}
|
|
53
58
|
}
|
package/lib/CachingService.d.ts
CHANGED
|
@@ -58,6 +58,15 @@ export interface CacheKeyMetrics {
|
|
|
58
58
|
lastAccessed: Date;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
export interface CacheTagMetrics {
|
|
62
|
+
tag: string;
|
|
63
|
+
hits: number;
|
|
64
|
+
misses: number;
|
|
65
|
+
totalRequests: number;
|
|
66
|
+
hitRatio: number;
|
|
67
|
+
lastAccess: Date;
|
|
68
|
+
}
|
|
69
|
+
|
|
61
70
|
export interface CachableFunctionOptions {
|
|
62
71
|
'@cache.ttl'?: number;
|
|
63
72
|
'@cache.key'?: string | object;
|
|
@@ -280,6 +289,16 @@ export declare class CachingService extends Service {
|
|
|
280
289
|
*/
|
|
281
290
|
getCurrentKeyMetrics(): Promise<CacheKeyMetrics>;
|
|
282
291
|
|
|
292
|
+
/**
|
|
293
|
+
* Get tag-specific metrics for a specific period
|
|
294
|
+
*/
|
|
295
|
+
getTagMetrics(tag: string, from: Date, to: Date): Promise<CacheTagMetrics>;
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Get current tag metrics
|
|
299
|
+
*/
|
|
300
|
+
getCurrentTagMetrics(): Promise<Map<string, CacheTagMetrics> | null>;
|
|
301
|
+
|
|
283
302
|
/**
|
|
284
303
|
* Clear all metrics
|
|
285
304
|
*/
|
|
@@ -290,6 +309,11 @@ export declare class CachingService extends Service {
|
|
|
290
309
|
*/
|
|
291
310
|
clearKeyMetrics(): Promise<void>;
|
|
292
311
|
|
|
312
|
+
/**
|
|
313
|
+
* Clear tag metrics
|
|
314
|
+
*/
|
|
315
|
+
clearTagMetrics(): Promise<void>;
|
|
316
|
+
|
|
293
317
|
/**
|
|
294
318
|
* Enable or disable statistics at runtime
|
|
295
319
|
*/
|
|
@@ -300,6 +324,11 @@ export declare class CachingService extends Service {
|
|
|
300
324
|
*/
|
|
301
325
|
setKeyMetricsEnabled(enabled: boolean): Promise<void>;
|
|
302
326
|
|
|
327
|
+
/**
|
|
328
|
+
* Enable or disable tag tracking at runtime
|
|
329
|
+
*/
|
|
330
|
+
setTagMetricsEnabled(enabled: boolean): Promise<void>;
|
|
331
|
+
|
|
303
332
|
/**
|
|
304
333
|
* Persist metrics to database
|
|
305
334
|
*/
|
package/lib/CachingService.js
CHANGED
|
@@ -129,12 +129,16 @@ class CachingService extends cds.Service {
|
|
|
129
129
|
|
|
130
130
|
let metricsEnabled = config.metricsEnabled;
|
|
131
131
|
let keyMetricsEnabled = config.keyMetricsEnabled;
|
|
132
|
+
let tagMetricsEnabled = config.tagMetricsEnabled;
|
|
132
133
|
if (normalized.metrics?.enabled === true) {
|
|
133
134
|
metricsEnabled = true;
|
|
134
135
|
}
|
|
135
136
|
if (normalized.metrics?.keyMetricsEnabled === true) {
|
|
136
137
|
keyMetricsEnabled = true;
|
|
137
138
|
}
|
|
139
|
+
if (normalized.metrics?.tagMetricsEnabled === true) {
|
|
140
|
+
tagMetricsEnabled = true;
|
|
141
|
+
}
|
|
138
142
|
|
|
139
143
|
// Initialize statistics with runtime configuration support
|
|
140
144
|
this.statistics = new CacheStatisticsHandler({
|
|
@@ -142,6 +146,7 @@ class CachingService extends cds.Service {
|
|
|
142
146
|
...statsOpts,
|
|
143
147
|
});
|
|
144
148
|
this.statistics.enableKeyMetrics(keyMetricsEnabled);
|
|
149
|
+
this.statistics.enableTagMetrics(tagMetricsEnabled);
|
|
145
150
|
this.statistics.enableMetrics(metricsEnabled);
|
|
146
151
|
|
|
147
152
|
if (normalized.metrics?.enabled === true && isPluginModelAvailable()) {
|
|
@@ -158,6 +163,13 @@ class CachingService extends cds.Service {
|
|
|
158
163
|
this.log.warn(`Failed to persist keyMetricsEnabled from config for ${this.name}:`, error);
|
|
159
164
|
}
|
|
160
165
|
}
|
|
166
|
+
if (normalized.metrics?.tagMetricsEnabled === true && isPluginModelAvailable()) {
|
|
167
|
+
try {
|
|
168
|
+
await this.runtimeConfigManager.setTagMetricsEnabled(true);
|
|
169
|
+
} catch (error) {
|
|
170
|
+
this.log.warn(`Failed to persist tagMetricsEnabled from config for ${this.name}:`, error);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
161
173
|
|
|
162
174
|
// Initialize operation managers
|
|
163
175
|
this.basicOperations = new BasicOperations(
|
|
@@ -402,6 +414,25 @@ class CachingService extends cds.Service {
|
|
|
402
414
|
return this.statistics.getCurrentKeyMetrics();
|
|
403
415
|
}
|
|
404
416
|
|
|
417
|
+
/**
|
|
418
|
+
* Get tag-specific metrics for a specific period
|
|
419
|
+
* @param {string} tag - resolved tag string
|
|
420
|
+
* @param {Date} from
|
|
421
|
+
* @param {Date} to
|
|
422
|
+
* @returns {Promise<object>}
|
|
423
|
+
*/
|
|
424
|
+
async getTagMetrics(tag, from, to) {
|
|
425
|
+
return this.statistics.getTagMetrics(tag, from, to);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Get current tag metrics
|
|
430
|
+
* @returns {Promise<Map|null>}
|
|
431
|
+
*/
|
|
432
|
+
async getCurrentTagMetrics() {
|
|
433
|
+
return this.statistics.getCurrentTagMetrics();
|
|
434
|
+
}
|
|
435
|
+
|
|
405
436
|
|
|
406
437
|
|
|
407
438
|
/**
|
|
@@ -420,6 +451,14 @@ class CachingService extends cds.Service {
|
|
|
420
451
|
return this.statistics.clearKeyMetrics();
|
|
421
452
|
}
|
|
422
453
|
|
|
454
|
+
/**
|
|
455
|
+
* Clear tag metrics
|
|
456
|
+
* @returns {Promise<void>}
|
|
457
|
+
*/
|
|
458
|
+
async clearTagMetrics() {
|
|
459
|
+
return this.statistics.clearTagMetrics();
|
|
460
|
+
}
|
|
461
|
+
|
|
423
462
|
/**
|
|
424
463
|
* Enable or disable statistics at runtime
|
|
425
464
|
* @param {boolean} enabled - whether to enable statistics
|
|
@@ -440,6 +479,16 @@ class CachingService extends cds.Service {
|
|
|
440
479
|
this.statistics.enableKeyMetrics(enabled);
|
|
441
480
|
}
|
|
442
481
|
|
|
482
|
+
/**
|
|
483
|
+
* Enable or disable tag tracking at runtime
|
|
484
|
+
* @param {boolean} enabled - whether to enable tag tracking
|
|
485
|
+
* @returns {Promise<void>}
|
|
486
|
+
*/
|
|
487
|
+
async setTagMetricsEnabled(enabled) {
|
|
488
|
+
await this.runtimeConfigManager.setTagMetricsEnabled(enabled);
|
|
489
|
+
this.statistics.enableTagMetrics(enabled);
|
|
490
|
+
}
|
|
491
|
+
|
|
443
492
|
/**
|
|
444
493
|
* Persist metrics to database
|
|
445
494
|
* @returns {Promise<void>}
|
package/lib/add.js
CHANGED
package/lib/config-normalizer.js
CHANGED
|
@@ -97,9 +97,11 @@ function getStatisticsHandlerOptions(metrics) {
|
|
|
97
97
|
if (metrics.persistenceInterval != null) opts.persistenceInterval = metrics.persistenceInterval
|
|
98
98
|
if (metrics.maxLatencies != null) opts.maxLatencies = metrics.maxLatencies
|
|
99
99
|
if (metrics.maxKeyMetrics != null) opts.maxKeyMetrics = metrics.maxKeyMetrics
|
|
100
|
+
if (metrics.maxTagMetrics != null) opts.maxTagMetrics = metrics.maxTagMetrics
|
|
100
101
|
if (metrics.maxMetricFieldLength != null) opts.maxMetricFieldLength = metrics.maxMetricFieldLength
|
|
101
102
|
if (metrics.enabled === true) opts.metricsEnabled = true
|
|
102
103
|
if (metrics.keyMetricsEnabled === true) opts.keyMetricsEnabled = true
|
|
104
|
+
if (metrics.tagMetricsEnabled === true) opts.tagMetricsEnabled = true
|
|
103
105
|
return opts
|
|
104
106
|
}
|
|
105
107
|
|
|
@@ -12,7 +12,7 @@ const path = require('path')
|
|
|
12
12
|
* the runtime under a released dashboard, so a UI5 regression would surface as a
|
|
13
13
|
* broken dashboard in deployments that changed nothing.
|
|
14
14
|
*/
|
|
15
|
-
const DEFAULT_UI5_VERSION = '1.
|
|
15
|
+
const DEFAULT_UI5_VERSION = '1.148.10'
|
|
16
16
|
const DEFAULT_UI5_URL = `https://ui5.sap.com/${DEFAULT_UI5_VERSION}/resources/sap-ui-core.js`
|
|
17
17
|
|
|
18
18
|
/** Matches the bootstrap script tag, whatever order its attributes are in. */
|