@pagopa/dx-savemoney 0.1.1 → 0.1.3
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 +58 -9
- package/dist/azure/analyzer.d.ts +3 -1
- package/dist/azure/analyzer.d.ts.map +1 -1
- package/dist/azure/analyzer.js +16 -3
- package/dist/azure/analyzer.js.map +1 -1
- package/dist/azure/resources/container-app.d.ts +19 -0
- package/dist/azure/resources/container-app.d.ts.map +1 -0
- package/dist/azure/resources/container-app.js +113 -0
- package/dist/azure/resources/container-app.js.map +1 -0
- package/dist/azure/resources/index.d.ts +2 -0
- package/dist/azure/resources/index.d.ts.map +1 -1
- package/dist/azure/resources/index.js +2 -0
- package/dist/azure/resources/index.js.map +1 -1
- package/dist/azure/resources/public-ip.js +4 -4
- package/dist/azure/resources/public-ip.js.map +1 -1
- package/dist/azure/resources/static-web-app.d.ts +17 -0
- package/dist/azure/resources/static-web-app.d.ts.map +1 -0
- package/dist/azure/resources/static-web-app.js +60 -0
- package/dist/azure/resources/static-web-app.js.map +1 -0
- package/dist/azure/resources/storage.js +4 -4
- package/dist/azure/resources/storage.js.map +1 -1
- package/dist/azure/resources/vm.js +4 -4
- package/dist/azure/resources/vm.js.map +1 -1
- package/dist/azure/utils.d.ts +24 -0
- package/dist/azure/utils.d.ts.map +1 -1
- package/dist/azure/utils.js +72 -20
- package/dist/azure/utils.js.map +1 -1
- package/package.json +5 -4
- package/src/azure/analyzer.ts +31 -0
- package/src/azure/resources/container-app.ts +247 -0
- package/src/azure/resources/index.ts +2 -0
- package/src/azure/resources/public-ip.ts +4 -4
- package/src/azure/resources/static-web-app.ts +108 -0
- package/src/azure/resources/storage.ts +4 -4
- package/src/azure/resources/vm.ts +4 -4
- package/src/azure/utils.ts +109 -26
|
@@ -110,7 +110,7 @@ export async function analyzeVM(
|
|
|
110
110
|
monitorClient,
|
|
111
111
|
resource.id,
|
|
112
112
|
"Network In Total",
|
|
113
|
-
"
|
|
113
|
+
"Average",
|
|
114
114
|
timespanDays,
|
|
115
115
|
);
|
|
116
116
|
|
|
@@ -118,9 +118,9 @@ export async function analyzeVM(
|
|
|
118
118
|
// Less than 1% average CPU
|
|
119
119
|
reason += `Low CPU usage (avg ${cpuUsage.toFixed(2)}%). `;
|
|
120
120
|
}
|
|
121
|
-
if (networkIn !== null && networkIn < 1024 * 1024 *
|
|
122
|
-
// Less than
|
|
123
|
-
reason += `Low network traffic. `;
|
|
121
|
+
if (networkIn !== null && networkIn < 1024 * 1024 * 3) {
|
|
122
|
+
// Less than 3MB average per day
|
|
123
|
+
reason += `Low network traffic (${(networkIn / 1024 / 1024).toFixed(2)} MB/day avg). `;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
const result = { costRisk, reason, suspectedUnused: reason.length > 0 };
|
package/src/azure/utils.ts
CHANGED
|
@@ -8,6 +8,100 @@ import { getLogger } from "@logtape/logtape";
|
|
|
8
8
|
|
|
9
9
|
import type { AnalysisResult } from "../types.js";
|
|
10
10
|
|
|
11
|
+
type MetricDataPoint = {
|
|
12
|
+
average?: number;
|
|
13
|
+
count?: number;
|
|
14
|
+
maximum?: number;
|
|
15
|
+
minimum?: number;
|
|
16
|
+
total?: number;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Aggregates metric data points based on aggregation type.
|
|
21
|
+
*
|
|
22
|
+
* @param dataPoints - Array of metric data points
|
|
23
|
+
* @param aggregation - The aggregation type (e.g., "Average", "Total")
|
|
24
|
+
* @returns The aggregated value or null if unavailable
|
|
25
|
+
*/
|
|
26
|
+
export function aggregateDataPoints(
|
|
27
|
+
dataPoints: MetricDataPoint[],
|
|
28
|
+
aggregation: string,
|
|
29
|
+
): null | number {
|
|
30
|
+
const aggregationLower = aggregation.toLowerCase();
|
|
31
|
+
|
|
32
|
+
// Get all non-null values from the data points
|
|
33
|
+
const values = dataPoints
|
|
34
|
+
.map((dataPoint) => extractAggregatedValue(dataPoint, aggregation))
|
|
35
|
+
.filter((v): v is number => v !== null);
|
|
36
|
+
|
|
37
|
+
if (values.length === 0) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (aggregationLower === "total" || aggregationLower === "count") {
|
|
42
|
+
// Sum all values for Total/Count
|
|
43
|
+
return values.reduce((sum, v) => sum + v, 0);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (aggregationLower === "average") {
|
|
47
|
+
// Calculate the average of all values
|
|
48
|
+
return values.reduce((sum, v) => sum + v, 0) / values.length;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (aggregationLower === "maximum") {
|
|
52
|
+
// Find the maximum value
|
|
53
|
+
return Math.max(...values);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (aggregationLower === "minimum") {
|
|
57
|
+
// Find the minimum value
|
|
58
|
+
return Math.min(...values);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Extracts the aggregated value from metric data.
|
|
66
|
+
*
|
|
67
|
+
* @param metricData - The metric data point
|
|
68
|
+
* @param aggregation - The aggregation type (e.g., "Average", "Total")
|
|
69
|
+
* @returns The aggregated value or null if unavailable
|
|
70
|
+
*/
|
|
71
|
+
export function extractAggregatedValue(
|
|
72
|
+
metricData: MetricDataPoint,
|
|
73
|
+
aggregation: string,
|
|
74
|
+
): null | number {
|
|
75
|
+
const aggregationLower = aggregation.toLowerCase();
|
|
76
|
+
|
|
77
|
+
if (
|
|
78
|
+
aggregationLower === "average" &&
|
|
79
|
+
typeof metricData.average === "number"
|
|
80
|
+
) {
|
|
81
|
+
return metricData.average;
|
|
82
|
+
}
|
|
83
|
+
if (aggregationLower === "total" && typeof metricData.total === "number") {
|
|
84
|
+
return metricData.total;
|
|
85
|
+
}
|
|
86
|
+
if (
|
|
87
|
+
aggregationLower === "minimum" &&
|
|
88
|
+
typeof metricData.minimum === "number"
|
|
89
|
+
) {
|
|
90
|
+
return metricData.minimum;
|
|
91
|
+
}
|
|
92
|
+
if (
|
|
93
|
+
aggregationLower === "maximum" &&
|
|
94
|
+
typeof metricData.maximum === "number"
|
|
95
|
+
) {
|
|
96
|
+
return metricData.maximum;
|
|
97
|
+
}
|
|
98
|
+
if (aggregationLower === "count" && typeof metricData.count === "number") {
|
|
99
|
+
return metricData.count;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
11
105
|
/**
|
|
12
106
|
* Fetches a specific metric for a resource from Azure Monitor.
|
|
13
107
|
*
|
|
@@ -33,39 +127,28 @@ export async function getMetric(
|
|
|
33
127
|
timespan,
|
|
34
128
|
});
|
|
35
129
|
|
|
36
|
-
|
|
37
|
-
if (!metricData) {
|
|
130
|
+
if (result.value.length === 0) {
|
|
38
131
|
return null;
|
|
39
132
|
}
|
|
40
133
|
|
|
41
|
-
const
|
|
134
|
+
const metric = result.value[0];
|
|
42
135
|
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
-
typeof metricData.average === "number"
|
|
46
|
-
) {
|
|
47
|
-
return metricData.average;
|
|
48
|
-
}
|
|
49
|
-
if (aggregationLower === "total" && typeof metricData.total === "number") {
|
|
50
|
-
return metricData.total;
|
|
51
|
-
}
|
|
52
|
-
if (
|
|
53
|
-
aggregationLower === "minimum" &&
|
|
54
|
-
typeof metricData.minimum === "number"
|
|
55
|
-
) {
|
|
56
|
-
return metricData.minimum;
|
|
57
|
-
}
|
|
58
|
-
if (
|
|
59
|
-
aggregationLower === "maximum" &&
|
|
60
|
-
typeof metricData.maximum === "number"
|
|
61
|
-
) {
|
|
62
|
-
return metricData.maximum;
|
|
136
|
+
if (!metric.timeseries || metric.timeseries.length === 0) {
|
|
137
|
+
return null;
|
|
63
138
|
}
|
|
64
|
-
|
|
65
|
-
|
|
139
|
+
|
|
140
|
+
const timeserie = metric.timeseries[0];
|
|
141
|
+
|
|
142
|
+
if (!timeserie.data || timeserie.data.length === 0) {
|
|
143
|
+
return null;
|
|
66
144
|
}
|
|
67
145
|
|
|
68
|
-
|
|
146
|
+
const aggregatedValue = aggregateDataPoints(
|
|
147
|
+
timeserie.data as MetricDataPoint[],
|
|
148
|
+
aggregation,
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
return aggregatedValue;
|
|
69
152
|
} catch (error) {
|
|
70
153
|
const logger = getLogger(["savemoney", "azure", "metrics"]);
|
|
71
154
|
logger.error(
|