@pagopa/dx-savemoney 0.2.5 → 0.3.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.
- package/README.md +33 -27
- package/dist/azure/analyzer.d.ts +49 -21
- package/dist/azure/analyzer.d.ts.map +1 -1
- package/dist/azure/analyzer.js +369 -93
- package/dist/azure/analyzer.js.map +1 -1
- package/dist/azure/analyzers/advisor.d.ts +68 -0
- package/dist/azure/analyzers/advisor.d.ts.map +1 -0
- package/dist/azure/analyzers/advisor.js +234 -0
- package/dist/azure/analyzers/advisor.js.map +1 -0
- package/dist/azure/analyzers/index.d.ts +8 -0
- package/dist/azure/analyzers/index.d.ts.map +1 -0
- package/dist/azure/analyzers/index.js +6 -0
- package/dist/azure/analyzers/index.js.map +1 -0
- package/dist/azure/analyzers/registry.d.ts +29 -0
- package/dist/azure/analyzers/registry.d.ts.map +1 -0
- package/dist/azure/analyzers/registry.js +79 -0
- package/dist/azure/analyzers/registry.js.map +1 -0
- package/dist/azure/analyzers/subscription.d.ts +53 -0
- package/dist/azure/analyzers/subscription.d.ts.map +1 -0
- package/dist/azure/analyzers/subscription.js +18 -0
- package/dist/azure/analyzers/subscription.js.map +1 -0
- package/dist/azure/analyzers/types.d.ts +62 -0
- package/dist/azure/analyzers/types.d.ts.map +1 -0
- package/dist/azure/analyzers/types.js +15 -0
- package/dist/azure/analyzers/types.js.map +1 -0
- package/dist/azure/config.d.ts.map +1 -1
- package/dist/azure/config.js +2 -0
- package/dist/azure/config.js.map +1 -1
- package/dist/azure/index.d.ts +1 -0
- package/dist/azure/index.d.ts.map +1 -1
- package/dist/azure/index.js +1 -0
- package/dist/azure/index.js.map +1 -1
- package/dist/azure/report.d.ts.map +1 -1
- package/dist/azure/report.js +178 -29
- package/dist/azure/report.js.map +1 -1
- package/dist/azure/resources/app-service.d.ts +2 -1
- package/dist/azure/resources/app-service.d.ts.map +1 -1
- package/dist/azure/resources/app-service.js +3 -3
- package/dist/azure/resources/app-service.js.map +1 -1
- package/dist/azure/resources/container-app.d.ts +2 -1
- package/dist/azure/resources/container-app.d.ts.map +1 -1
- package/dist/azure/resources/container-app.js +9 -9
- package/dist/azure/resources/container-app.js.map +1 -1
- package/dist/azure/resources/public-ip.d.ts +2 -1
- package/dist/azure/resources/public-ip.d.ts.map +1 -1
- package/dist/azure/resources/public-ip.js +2 -2
- package/dist/azure/resources/public-ip.js.map +1 -1
- package/dist/azure/resources/static-web-app.d.ts +2 -1
- package/dist/azure/resources/static-web-app.d.ts.map +1 -1
- package/dist/azure/resources/static-web-app.js +3 -3
- package/dist/azure/resources/static-web-app.js.map +1 -1
- package/dist/azure/resources/storage.d.ts +2 -1
- package/dist/azure/resources/storage.d.ts.map +1 -1
- package/dist/azure/resources/storage.js +2 -2
- package/dist/azure/resources/storage.js.map +1 -1
- package/dist/azure/resources/vm.d.ts +2 -1
- package/dist/azure/resources/vm.d.ts.map +1 -1
- package/dist/azure/resources/vm.js +3 -3
- package/dist/azure/resources/vm.js.map +1 -1
- package/dist/azure/types.d.ts +34 -1
- package/dist/azure/types.d.ts.map +1 -1
- package/dist/azure/utils.d.ts +35 -3
- package/dist/azure/utils.d.ts.map +1 -1
- package/dist/azure/utils.js +70 -29
- package/dist/azure/utils.js.map +1 -1
- package/dist/finding.d.ts +114 -0
- package/dist/finding.d.ts.map +1 -0
- package/dist/finding.js +51 -0
- package/dist/finding.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +5 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +14 -0
- package/dist/schema.js.map +1 -1
- package/package.json +4 -1
- package/src/__tests__/finding.test.ts +149 -0
- package/src/azure/__tests__/analyzer-tags.test.ts +74 -0
- package/src/azure/__tests__/report.test.ts +27 -0
- package/src/azure/__tests__/utils.test.ts +164 -2
- package/src/azure/analyzer.ts +513 -182
- package/src/azure/analyzers/__tests__/advisor.test.ts +367 -0
- package/src/azure/analyzers/advisor.ts +324 -0
- package/src/azure/analyzers/index.ts +14 -0
- package/src/azure/analyzers/registry.ts +196 -0
- package/src/azure/analyzers/subscription.ts +56 -0
- package/src/azure/analyzers/types.ts +66 -0
- package/src/azure/config.ts +2 -0
- package/src/azure/index.ts +1 -0
- package/src/azure/report.ts +206 -35
- package/src/azure/resources/app-service.ts +4 -0
- package/src/azure/resources/container-app.ts +10 -0
- package/src/azure/resources/public-ip.ts +3 -0
- package/src/azure/resources/static-web-app.ts +4 -0
- package/src/azure/resources/storage.ts +3 -0
- package/src/azure/resources/vm.ts +4 -0
- package/src/azure/types.ts +35 -1
- package/src/azure/utils.ts +110 -39
- package/src/finding.ts +152 -0
- package/src/index.ts +19 -1
- package/src/schema.ts +14 -0
package/dist/azure/report.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Azure report generation
|
|
3
3
|
*/
|
|
4
|
+
import Table from "cli-table3";
|
|
5
|
+
// Fixed column widths — keeps the Reason column within a readable width
|
|
6
|
+
// while allowing cli-table3 to word-wrap long content across multiple lines.
|
|
7
|
+
const COL_WIDTHS = [30, 35, 25, 8, 55];
|
|
4
8
|
// ANSI color codes — only applied when stdout is a TTY to avoid cluttering redirected output
|
|
5
9
|
const isTTY = process.stdout.isTTY ?? false;
|
|
6
10
|
const RED = isTTY ? "\x1b[31m" : "";
|
|
7
11
|
const YELLOW = isTTY ? "\x1b[33m" : "";
|
|
8
12
|
const BLUE = isTTY ? "\x1b[34m" : "";
|
|
13
|
+
const GREEN = isTTY ? "\x1b[32m" : "";
|
|
14
|
+
const CYAN = isTTY ? "\x1b[36m" : "";
|
|
9
15
|
const BOLD = isTTY ? "\x1b[1m" : "";
|
|
10
16
|
const RESET = isTTY ? "\x1b[0m" : "";
|
|
11
17
|
const DIM = isTTY ? "\x1b[2m" : "";
|
|
@@ -30,66 +36,209 @@ export async function generateReport(report, format) {
|
|
|
30
36
|
console.log(JSON.stringify(report, null, 2));
|
|
31
37
|
return;
|
|
32
38
|
}
|
|
33
|
-
// For other formats, we extract the summary data.
|
|
34
|
-
const summaryReport = report.map((r) => ({
|
|
35
|
-
costRisk: r.analysis.costRisk,
|
|
36
|
-
location: r.resource.location ?? "",
|
|
37
|
-
name: r.resource.name ?? "unknown",
|
|
38
|
-
reason: r.analysis.reason,
|
|
39
|
-
resourceGroup: r.resource.id?.split("/")[4],
|
|
40
|
-
subscriptionId: r.resource.id?.split("/")[2] ?? "unknown",
|
|
41
|
-
suspectedUnused: r.analysis.suspectedUnused,
|
|
42
|
-
type: r.resource.type ?? "unknown",
|
|
43
|
-
}));
|
|
44
39
|
if (format === "json") {
|
|
40
|
+
const summaryReport = report.map((r) => ({
|
|
41
|
+
costRisk: r.analysis.costRisk,
|
|
42
|
+
location: r.resource.location ?? "",
|
|
43
|
+
name: r.resource.name ?? "unknown",
|
|
44
|
+
reason: r.analysis.reason,
|
|
45
|
+
resourceGroup: r.resource.id?.split("/")[4],
|
|
46
|
+
subscriptionId: r.resource.id?.split("/")[2] ?? "unknown",
|
|
47
|
+
suspectedUnused: r.analysis.suspectedUnused,
|
|
48
|
+
type: r.resource.type ?? "unknown",
|
|
49
|
+
}));
|
|
45
50
|
console.log(JSON.stringify(summaryReport, null, 2));
|
|
46
51
|
}
|
|
47
52
|
else if (format === "lint") {
|
|
48
53
|
generateLintReport(report);
|
|
49
54
|
}
|
|
50
55
|
else {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
const summaryReport = report.map((r) => ({
|
|
57
|
+
costRisk: r.analysis.costRisk,
|
|
58
|
+
location: r.resource.location ?? "",
|
|
59
|
+
name: r.resource.name ?? "unknown",
|
|
60
|
+
reason: r.analysis.reason,
|
|
61
|
+
resourceGroup: r.resource.id?.split("/")[4],
|
|
62
|
+
subscriptionId: r.resource.id?.split("/")[2] ?? "unknown",
|
|
63
|
+
suspectedUnused: r.analysis.suspectedUnused,
|
|
64
|
+
type: r.resource.type ?? "unknown",
|
|
65
|
+
}));
|
|
66
|
+
const table = new Table({
|
|
67
|
+
colWidths: [...COL_WIDTHS],
|
|
68
|
+
head: ["Name", "Type", "Resource Group", "Risk", "Reason"],
|
|
69
|
+
wordWrap: true,
|
|
70
|
+
});
|
|
71
|
+
for (const r of summaryReport) {
|
|
72
|
+
table.push([
|
|
73
|
+
r.name,
|
|
74
|
+
r.type,
|
|
75
|
+
r.resourceGroup || "N/A",
|
|
76
|
+
r.costRisk,
|
|
77
|
+
r.reason,
|
|
78
|
+
]);
|
|
79
|
+
}
|
|
80
|
+
console.log(table.toString());
|
|
81
|
+
// Same summary block the lint format prints, so the table view also
|
|
82
|
+
// surfaces totals, source breakdown and estimated savings at a glance.
|
|
83
|
+
printSummary(computeSummary(report));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Walks the report once to compute totals, source breakdown and savings
|
|
88
|
+
* per currency without mutating it. Used by the table format, which has
|
|
89
|
+
* no per-line walk of its own.
|
|
90
|
+
*/
|
|
91
|
+
function computeSummary(report) {
|
|
92
|
+
const summary = {
|
|
93
|
+
counts: { high: 0, low: 0, medium: 0 },
|
|
94
|
+
savingsByCurrency: new Map(),
|
|
95
|
+
sourceCounts: {},
|
|
96
|
+
};
|
|
97
|
+
for (const entry of report) {
|
|
98
|
+
const lines = entry.findings?.length
|
|
99
|
+
? entry.findings.map((f) => ({
|
|
100
|
+
savings: f.estimatedMonthlySavings,
|
|
101
|
+
severity: f.severity,
|
|
102
|
+
source: f.source,
|
|
103
|
+
}))
|
|
104
|
+
: splitReasons(entry.analysis.reason).map(() => ({
|
|
105
|
+
savings: undefined,
|
|
106
|
+
severity: entry.analysis.costRisk,
|
|
107
|
+
source: "custom",
|
|
108
|
+
}));
|
|
109
|
+
for (const line of lines) {
|
|
110
|
+
summary.counts[line.severity]++;
|
|
111
|
+
summary.sourceCounts[line.source] =
|
|
112
|
+
(summary.sourceCounts[line.source] ?? 0) + 1;
|
|
113
|
+
if (line.savings) {
|
|
114
|
+
summary.savingsByCurrency.set(line.savings.currency, (summary.savingsByCurrency.get(line.savings.currency) ?? 0) +
|
|
115
|
+
line.savings.amount);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return summary;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Formats a monetary amount with an ISO 4217 currency code, falling back
|
|
123
|
+
* to the raw code prefix when the runtime locale data lacks the currency
|
|
124
|
+
* symbol.
|
|
125
|
+
*/
|
|
126
|
+
function formatAmount(amount, currency) {
|
|
127
|
+
try {
|
|
128
|
+
return new Intl.NumberFormat("en-US", {
|
|
129
|
+
currency,
|
|
130
|
+
maximumFractionDigits: 2,
|
|
131
|
+
minimumFractionDigits: 2,
|
|
132
|
+
style: "currency",
|
|
133
|
+
}).format(amount);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return `${currency} ${amount.toFixed(2)}`;
|
|
58
137
|
}
|
|
59
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Renders an estimated monthly savings value as the short "(€ 12.50/mo)"
|
|
141
|
+
* label that ships next to each lint line. Returns an empty string when
|
|
142
|
+
* the analyzer didn't provide an estimate.
|
|
143
|
+
*/
|
|
144
|
+
function formatSavings(savings) {
|
|
145
|
+
if (!savings)
|
|
146
|
+
return "";
|
|
147
|
+
return `(${formatAmount(savings.amount, savings.currency)}/mo)`;
|
|
148
|
+
}
|
|
60
149
|
/**
|
|
61
150
|
* Renders a linter-style report to stdout, grouping findings by resource.
|
|
62
151
|
*
|
|
152
|
+
* When `Finding[]` is attached to a report (Phase 1+), each finding is
|
|
153
|
+
* rendered with its `source` badge (e.g. `[advisor]`) and the estimated
|
|
154
|
+
* monthly savings, when known. For older payloads without `findings` we
|
|
155
|
+
* fall back to splitting `analysis.reason` like before so the format stays
|
|
156
|
+
* backward compatible.
|
|
157
|
+
*
|
|
63
158
|
* Example output:
|
|
64
159
|
*
|
|
65
160
|
* /subscriptions/.../virtualMachines/my-vm
|
|
66
|
-
* ✖ HIGH VM
|
|
67
|
-
* ✖ HIGH No tags found.
|
|
161
|
+
* ✖ HIGH [advisor] Right-size your VM. (€ 12.50/mo)
|
|
162
|
+
* ✖ HIGH [custom] No tags found.
|
|
68
163
|
*
|
|
69
164
|
* Summary: 3 issues found (2 high, 0 medium, 1 low)
|
|
165
|
+
* Estimated monthly savings: € 12.50
|
|
70
166
|
*/
|
|
71
167
|
function generateLintReport(report) {
|
|
72
|
-
const
|
|
168
|
+
const summary = {
|
|
169
|
+
counts: { high: 0, low: 0, medium: 0 },
|
|
170
|
+
savingsByCurrency: new Map(),
|
|
171
|
+
sourceCounts: {},
|
|
172
|
+
};
|
|
73
173
|
for (const entry of report) {
|
|
74
174
|
const resourceId = entry.resource.id ?? `unknown/${entry.resource.name ?? "unknown"}`;
|
|
75
|
-
const risk = entry.analysis.costRisk;
|
|
76
|
-
const findings = splitReasons(entry.analysis.reason);
|
|
77
175
|
console.log(`${BOLD}${resourceId}${RESET}`);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
176
|
+
const lines = entry.findings?.length
|
|
177
|
+
? entry.findings.map((f) => ({
|
|
178
|
+
extra: formatSavings(f.estimatedMonthlySavings),
|
|
179
|
+
severity: f.severity,
|
|
180
|
+
source: f.source,
|
|
181
|
+
text: f.reason,
|
|
182
|
+
}))
|
|
183
|
+
: splitReasons(entry.analysis.reason).map((text) => ({
|
|
184
|
+
extra: "",
|
|
185
|
+
severity: entry.analysis.costRisk,
|
|
186
|
+
source: "custom",
|
|
187
|
+
text,
|
|
188
|
+
}));
|
|
189
|
+
for (const line of lines) {
|
|
190
|
+
const icon = RISK_ICON[line.severity];
|
|
191
|
+
const color = RISK_COLOR[line.severity];
|
|
192
|
+
const label = `${color}${line.severity.toUpperCase().padEnd(6)}${RESET}`;
|
|
193
|
+
const sourceBadge = `${CYAN}[${line.source}]${RESET}`;
|
|
194
|
+
const extra = line.extra ? ` ${GREEN}${line.extra}${RESET}` : "";
|
|
195
|
+
console.log(` ${icon} ${label} ${sourceBadge} ${DIM}${line.text}${RESET}${extra}`);
|
|
196
|
+
summary.counts[line.severity]++;
|
|
197
|
+
summary.sourceCounts[line.source] =
|
|
198
|
+
(summary.sourceCounts[line.source] ?? 0) + 1;
|
|
199
|
+
}
|
|
200
|
+
if (entry.findings) {
|
|
201
|
+
for (const f of entry.findings) {
|
|
202
|
+
if (f.estimatedMonthlySavings) {
|
|
203
|
+
const { amount, currency } = f.estimatedMonthlySavings;
|
|
204
|
+
summary.savingsByCurrency.set(currency, (summary.savingsByCurrency.get(currency) ?? 0) + amount);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
84
207
|
}
|
|
85
208
|
console.log();
|
|
86
209
|
}
|
|
210
|
+
printSummary(summary);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Prints the shared trailer (issues, sources, estimated savings) used by
|
|
214
|
+
* both the lint and the table format.
|
|
215
|
+
*
|
|
216
|
+
* Savings are kept grouped by currency intentionally: Azure Advisor
|
|
217
|
+
* returns each recommendation in the subscription's native billing
|
|
218
|
+
* currency, so the same report can carry EUR and USD figures at the
|
|
219
|
+
* same time when subscriptions are billed in different regions. We do
|
|
220
|
+
* NOT convert across currencies — the rates would be both volatile and
|
|
221
|
+
* out of scope for this tool.
|
|
222
|
+
*/
|
|
223
|
+
function printSummary(summary) {
|
|
224
|
+
const { counts, savingsByCurrency, sourceCounts } = summary;
|
|
87
225
|
const total = counts.high + counts.medium + counts.low;
|
|
88
226
|
const summaryLine = `${BOLD}Summary:${RESET} ${total} issue${total !== 1 ? "s" : ""} found` +
|
|
89
227
|
` ${RED}(${counts.high} high${RESET}` +
|
|
90
228
|
`, ${YELLOW}${counts.medium} medium${RESET}` +
|
|
91
229
|
`, ${BLUE}${counts.low} low${RESET})`;
|
|
92
230
|
console.log(summaryLine);
|
|
231
|
+
const sourceBreakdown = Object.entries(sourceCounts)
|
|
232
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
233
|
+
.map(([source, n]) => `${n} ${source}`)
|
|
234
|
+
.join(", ");
|
|
235
|
+
if (sourceBreakdown) {
|
|
236
|
+
console.log(`${BOLD}Sources:${RESET} ${sourceBreakdown}`);
|
|
237
|
+
}
|
|
238
|
+
if (savingsByCurrency.size > 0) {
|
|
239
|
+
const parts = [...savingsByCurrency.entries()].map(([currency, amount]) => `${GREEN}${formatAmount(amount, currency)}${RESET}`);
|
|
240
|
+
console.log(`${BOLD}Estimated monthly savings:${RESET} ${parts.join(", ")}`);
|
|
241
|
+
}
|
|
93
242
|
}
|
|
94
243
|
/**
|
|
95
244
|
* Splits a concatenated reason string (sentences separated by ". ") into
|
package/dist/azure/report.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/azure/report.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/azure/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import type { WebSiteManagementClient } from "@azure/arm-appservice";
|
|
|
5
5
|
import type { MonitorClient } from "@azure/arm-monitor";
|
|
6
6
|
import * as armResources from "@azure/arm-resources";
|
|
7
7
|
import type { AnalysisResult, Thresholds } from "../../types.js";
|
|
8
|
+
import { type MetricsCache } from "../utils.js";
|
|
8
9
|
/**
|
|
9
10
|
* Analyzes an Azure App Service Plan for potential cost optimization.
|
|
10
11
|
*
|
|
@@ -14,5 +15,5 @@ import type { AnalysisResult, Thresholds } from "../../types.js";
|
|
|
14
15
|
* @param timespanDays - Number of days to analyze metrics
|
|
15
16
|
* @returns Analysis result with cost risk and reason
|
|
16
17
|
*/
|
|
17
|
-
export declare function analyzeAppServicePlan(resource: armResources.GenericResource, webSiteClient: WebSiteManagementClient, monitorClient: MonitorClient, timespanDays: number, thresholds?: Thresholds, verbose?: boolean): Promise<AnalysisResult>;
|
|
18
|
+
export declare function analyzeAppServicePlan(resource: armResources.GenericResource, webSiteClient: WebSiteManagementClient, monitorClient: MonitorClient, timespanDays: number, thresholds?: Thresholds, verbose?: boolean, cache?: MetricsCache): Promise<AnalysisResult>;
|
|
18
19
|
//# sourceMappingURL=app-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-service.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/app-service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAGrD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"app-service.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/app-service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAGrD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjE,OAAO,EAEL,KAAK,YAAY,EAIlB,MAAM,aAAa,CAAC;AAErB;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,YAAY,CAAC,eAAe,EACtC,aAAa,EAAE,uBAAuB,EACtC,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,MAAM,EACpB,UAAU,GAAE,UAA+B,EAC3C,OAAO,UAAQ,EACf,KAAK,CAAC,EAAE,YAAY,GACnB,OAAO,CAAC,cAAc,CAAC,CA2FzB"}
|
|
@@ -13,7 +13,7 @@ import { getMetric, verboseLog, verboseLogAnalysisResult, verboseLogResourceStar
|
|
|
13
13
|
* @param timespanDays - Number of days to analyze metrics
|
|
14
14
|
* @returns Analysis result with cost risk and reason
|
|
15
15
|
*/
|
|
16
|
-
export async function analyzeAppServicePlan(resource, webSiteClient, monitorClient, timespanDays, thresholds = DEFAULT_THRESHOLDS, verbose = false) {
|
|
16
|
+
export async function analyzeAppServicePlan(resource, webSiteClient, monitorClient, timespanDays, thresholds = DEFAULT_THRESHOLDS, verbose = false, cache) {
|
|
17
17
|
verboseLogResourceStart(verbose, resource.name || "unknown", "App Service Plan (microsoft.web/serverfarms)");
|
|
18
18
|
verboseLog(verbose, "Resource details:", resource);
|
|
19
19
|
const costRisk = "high";
|
|
@@ -38,8 +38,8 @@ export async function analyzeAppServicePlan(resource, webSiteClient, monitorClie
|
|
|
38
38
|
reason += "App Service Plan has no apps deployed. ";
|
|
39
39
|
}
|
|
40
40
|
// Check CPU and Memory metrics
|
|
41
|
-
const cpuPercentage = await getMetric(monitorClient, resource.id, "CpuPercentage", "Average", timespanDays);
|
|
42
|
-
const memoryPercentage = await getMetric(monitorClient, resource.id, "MemoryPercentage", "Average", timespanDays);
|
|
41
|
+
const cpuPercentage = await getMetric(monitorClient, resource.id, "CpuPercentage", "Average", timespanDays, cache);
|
|
42
|
+
const memoryPercentage = await getMetric(monitorClient, resource.id, "MemoryPercentage", "Average", timespanDays, cache);
|
|
43
43
|
if (cpuPercentage !== null &&
|
|
44
44
|
cpuPercentage < thresholds.appService.cpuPercent) {
|
|
45
45
|
reason += `Very low CPU usage (${cpuPercentage.toFixed(2)}%). `;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-service.js","sourceRoot":"","sources":["../../../src/azure/resources/app-service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAI7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,SAAS,
|
|
1
|
+
{"version":3,"file":"app-service.js","sourceRoot":"","sources":["../../../src/azure/resources/app-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import type { ContainerAppsAPIClient } from "@azure/arm-appcontainers";
|
|
|
5
5
|
import type { MonitorClient } from "@azure/arm-monitor";
|
|
6
6
|
import * as armResources from "@azure/arm-resources";
|
|
7
7
|
import type { AnalysisResult, Thresholds } from "../../types.js";
|
|
8
|
+
import { type MetricsCache } from "../utils.js";
|
|
8
9
|
/**
|
|
9
10
|
* Analyzes an Azure Container App for potential cost optimization.
|
|
10
11
|
*
|
|
@@ -15,5 +16,5 @@ import type { AnalysisResult, Thresholds } from "../../types.js";
|
|
|
15
16
|
* @param verbose - Enable verbose logging
|
|
16
17
|
* @returns Analysis result with cost risk and reason
|
|
17
18
|
*/
|
|
18
|
-
export declare function analyzeContainerApp(resource: armResources.GenericResource, containerAppsClient: ContainerAppsAPIClient, monitorClient: MonitorClient, timespanDays: number, thresholds?: Thresholds, verbose?: boolean): Promise<AnalysisResult>;
|
|
19
|
+
export declare function analyzeContainerApp(resource: armResources.GenericResource, containerAppsClient: ContainerAppsAPIClient, monitorClient: MonitorClient, timespanDays: number, thresholds?: Thresholds, verbose?: boolean, cache?: MetricsCache): Promise<AnalysisResult>;
|
|
19
20
|
//# sourceMappingURL=container-app.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container-app.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/container-app.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAGrD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"container-app.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/container-app.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAGrD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjE,OAAO,EAEL,KAAK,YAAY,EAIlB,MAAM,aAAa,CAAC;AAErB;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,YAAY,CAAC,eAAe,EACtC,mBAAmB,EAAE,sBAAsB,EAC3C,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,MAAM,EACpB,UAAU,GAAE,UAA+B,EAC3C,OAAO,UAAQ,EACf,KAAK,CAAC,EAAE,YAAY,GACnB,OAAO,CAAC,cAAc,CAAC,CAwEzB"}
|
|
@@ -14,7 +14,7 @@ import { getMetric, verboseLog, verboseLogAnalysisResult, verboseLogResourceStar
|
|
|
14
14
|
* @param verbose - Enable verbose logging
|
|
15
15
|
* @returns Analysis result with cost risk and reason
|
|
16
16
|
*/
|
|
17
|
-
export async function analyzeContainerApp(resource, containerAppsClient, monitorClient, timespanDays, thresholds = DEFAULT_THRESHOLDS, verbose = false) {
|
|
17
|
+
export async function analyzeContainerApp(resource, containerAppsClient, monitorClient, timespanDays, thresholds = DEFAULT_THRESHOLDS, verbose = false, cache) {
|
|
18
18
|
verboseLogResourceStart(verbose, resource.name || "unknown", "Container App (Microsoft.App/containerApps)");
|
|
19
19
|
verboseLog(verbose, "Resource details:", resource);
|
|
20
20
|
const costRisk = "medium";
|
|
@@ -39,8 +39,8 @@ export async function analyzeContainerApp(resource, containerAppsClient, monitor
|
|
|
39
39
|
template: appDetails.template,
|
|
40
40
|
},
|
|
41
41
|
}, reason, verbose);
|
|
42
|
-
reason = await checkResourceMetrics(resource, monitorClient, timespanDays, thresholds, reason, verbose);
|
|
43
|
-
reason = await checkNetworkMetrics(resource, monitorClient, timespanDays, thresholds, reason, verbose);
|
|
42
|
+
reason = await checkResourceMetrics(resource, monitorClient, timespanDays, thresholds, reason, verbose, cache);
|
|
43
|
+
reason = await checkNetworkMetrics(resource, monitorClient, timespanDays, thresholds, reason, verbose, cache);
|
|
44
44
|
}
|
|
45
45
|
catch (error) {
|
|
46
46
|
const logger = getLogger(["savemoney", "azure"]);
|
|
@@ -55,14 +55,14 @@ export async function analyzeContainerApp(resource, containerAppsClient, monitor
|
|
|
55
55
|
/**
|
|
56
56
|
* Checks network traffic metrics for a Container App.
|
|
57
57
|
*/
|
|
58
|
-
async function checkNetworkMetrics(resource, monitorClient, timespanDays, thresholds, reason, verbose) {
|
|
58
|
+
async function checkNetworkMetrics(resource, monitorClient, timespanDays, thresholds, reason, verbose, cache) {
|
|
59
59
|
let newReason = reason;
|
|
60
60
|
if (!resource.id) {
|
|
61
61
|
return newReason;
|
|
62
62
|
}
|
|
63
63
|
verboseLog(verbose, "Checking network metrics...");
|
|
64
|
-
const networkIn = await getMetric(monitorClient, resource.id, "RxBytes", "Average", timespanDays);
|
|
65
|
-
const networkOut = await getMetric(monitorClient, resource.id, "TxBytes", "Average", timespanDays);
|
|
64
|
+
const networkIn = await getMetric(monitorClient, resource.id, "RxBytes", "Average", timespanDays, cache);
|
|
65
|
+
const networkOut = await getMetric(monitorClient, resource.id, "TxBytes", "Average", timespanDays, cache);
|
|
66
66
|
verboseLog(verbose, `Network In: ${networkIn !== null ? `${(networkIn / 1048576).toFixed(2)} MB/day avg` : "N/A"}`);
|
|
67
67
|
verboseLog(verbose, `Network Out: ${networkOut !== null ? `${(networkOut / 1048576).toFixed(2)} MB/day avg` : "N/A"}`);
|
|
68
68
|
if (networkIn !== null &&
|
|
@@ -75,14 +75,14 @@ async function checkNetworkMetrics(resource, monitorClient, timespanDays, thresh
|
|
|
75
75
|
/**
|
|
76
76
|
* Checks resource usage metrics for a Container App.
|
|
77
77
|
*/
|
|
78
|
-
async function checkResourceMetrics(resource, monitorClient, timespanDays, thresholds, reason, verbose) {
|
|
78
|
+
async function checkResourceMetrics(resource, monitorClient, timespanDays, thresholds, reason, verbose, cache) {
|
|
79
79
|
let newReason = reason;
|
|
80
80
|
if (!resource.id) {
|
|
81
81
|
return newReason;
|
|
82
82
|
}
|
|
83
83
|
verboseLog(verbose, "Checking resource usage metrics...");
|
|
84
|
-
const cpuUsage = await getMetric(monitorClient, resource.id, "UsageNanoCores", "Average", timespanDays);
|
|
85
|
-
const memoryUsage = await getMetric(monitorClient, resource.id, "WorkingSetBytes", "Average", timespanDays);
|
|
84
|
+
const cpuUsage = await getMetric(monitorClient, resource.id, "UsageNanoCores", "Average", timespanDays, cache);
|
|
85
|
+
const memoryUsage = await getMetric(monitorClient, resource.id, "WorkingSetBytes", "Average", timespanDays, cache);
|
|
86
86
|
verboseLog(verbose, `CPU Usage: ${cpuUsage !== null ? `${(cpuUsage / 1000000000).toFixed(4)} cores` : "N/A"}`);
|
|
87
87
|
verboseLog(verbose, `Memory Usage: ${memoryUsage !== null ? `${(memoryUsage / 1048576).toFixed(2)} MB` : "N/A"}`);
|
|
88
88
|
if (cpuUsage !== null && cpuUsage < thresholds.containerApp.cpuNanoCores) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container-app.js","sourceRoot":"","sources":["../../../src/azure/resources/container-app.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAI7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,SAAS,
|
|
1
|
+
{"version":3,"file":"container-app.js","sourceRoot":"","sources":["../../../src/azure/resources/container-app.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAI7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,SAAS,EAET,UAAU,EACV,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAErB;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAsC,EACtC,mBAA2C,EAC3C,aAA4B,EAC5B,YAAoB,EACpB,aAAyB,kBAAkB,EAC3C,OAAO,GAAG,KAAK,EACf,KAAoB;IAEpB,uBAAuB,CACrB,OAAO,EACP,QAAQ,CAAC,IAAI,IAAI,SAAS,EAC1B,6CAA6C,CAC9C,CAAC;IACF,UAAU,CAAC,OAAO,EAAE,mBAAmB,EAAE,QAAQ,CAAC,CAAC;IAEnD,MAAM,QAAQ,GAA8B,QAAQ,CAAC;IACrD,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,OAAO;YACL,QAAQ;YACR,MAAM,EAAE,yBAAyB;YACjC,eAAe,EAAE,KAAK;SACvB,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,GAAG,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,iBAAiB,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,gBAAgB,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IAE1C,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,aAAa,CAAC,GAAG,CAC5D,iBAAiB,EACjB,gBAAgB,CACjB,CAAC;QAEF,UAAU,CAAC,OAAO,EAAE,4BAA4B,EAAE,UAAU,CAAC,CAAC;QAE9D,MAAM,GAAG,kBAAkB,CACzB;YACE,UAAU,EAAE;gBACV,iBAAiB,EAAE,UAAU,CAAC,iBAAiB;gBAC/C,aAAa,EAAE,UAAU,CAAC,aAAa;gBACvC,QAAQ,EAAE,UAAU,CAAC,QAAQ;aAC9B;SACF,EACD,MAAM,EACN,OAAO,CACR,CAAC;QACF,MAAM,GAAG,MAAM,oBAAoB,CACjC,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,UAAU,EACV,MAAM,EACN,OAAO,EACP,KAAK,CACN,CAAC;QACF,MAAM,GAAG,MAAM,mBAAmB,CAChC,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,UAAU,EACV,MAAM,EACN,OAAO,EACP,KAAK,CACN,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,CACT,2CAA2C,gBAAgB,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CACjH,CAAC;QACF,MAAM,IAAI,yDAAyD,CAAC;IACtE,CAAC;IAED,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,eAAe,EAAE,CAAC;IACpE,wBAAwB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,mBAAmB,CAChC,QAAsC,EACtC,aAA4B,EAC5B,YAAoB,EACpB,UAAsB,EACtB,MAAc,EACd,OAAgB,EAChB,KAAoB;IAEpB,IAAI,SAAS,GAAG,MAAM,CAAC;IAEvB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,UAAU,CAAC,OAAO,EAAE,6BAA6B,CAAC,CAAC;IAEnD,MAAM,SAAS,GAAG,MAAM,SAAS,CAC/B,aAAa,EACb,QAAQ,CAAC,EAAE,EACX,SAAS,EACT,SAAS,EACT,YAAY,EACZ,KAAK,CACN,CAAC;IAEF,MAAM,UAAU,GAAG,MAAM,SAAS,CAChC,aAAa,EACb,QAAQ,CAAC,EAAE,EACX,SAAS,EACT,SAAS,EACT,YAAY,EACZ,KAAK,CACN,CAAC;IAEF,UAAU,CACR,OAAO,EACP,eAAe,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,EAAE,CAC/F,CAAC;IACF,UAAU,CACR,OAAO,EACP,gBAAgB,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,EAAE,CAClG,CAAC;IAEF,IACE,SAAS,KAAK,IAAI;QAClB,UAAU,KAAK,IAAI;QACnB,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC,YAAY,CAAC,YAAY,EAC7D,CAAC;QACD,SAAS,IAAI,6BAA6B,CAAC,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAC5G,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,oBAAoB,CACjC,QAAsC,EACtC,aAA4B,EAC5B,YAAoB,EACpB,UAAsB,EACtB,MAAc,EACd,OAAgB,EAChB,KAAoB;IAEpB,IAAI,SAAS,GAAG,MAAM,CAAC;IAEvB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,UAAU,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;IAE1D,MAAM,QAAQ,GAAG,MAAM,SAAS,CAC9B,aAAa,EACb,QAAQ,CAAC,EAAE,EACX,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,KAAK,CACN,CAAC;IAEF,MAAM,WAAW,GAAG,MAAM,SAAS,CACjC,aAAa,EACb,QAAQ,CAAC,EAAE,EACX,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,KAAK,CACN,CAAC;IAEF,UAAU,CACR,OAAO,EACP,cAAc,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,CAC1F,CAAC;IACF,UAAU,CACR,OAAO,EACP,iBAAiB,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,GAAG,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAC7F,CAAC;IAEF,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,GAAG,UAAU,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;QACzE,SAAS,IAAI,uBAAuB,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC;IACpF,CAAC;IAED,IACE,WAAW,KAAK,IAAI;QACpB,WAAW,GAAG,UAAU,CAAC,YAAY,CAAC,WAAW,EACjD,CAAC;QACD,SAAS,IAAI,0BAA0B,CAAC,WAAW,GAAG,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;IACpF,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CACzB,UAMC,EACD,MAAc,EACd,OAAgB;IAEhB,IAAI,SAAS,GAAG,MAAM,CAAC;IAEvB,MAAM,EAAE,iBAAiB,EAAE,aAAa,EAAE,QAAQ,EAAE,GAClD,UAAU,CAAC,UAAU,IAAI,EAAE,CAAC;IAE9B,UAAU,CAAC,OAAO,EAAE,iBAAiB,QAAQ,EAAE,KAAK,EAAE,WAAW,IAAI,KAAK,EAAE,CAAC,CAAC;IAC9E,UAAU,CAAC,OAAO,EAAE,iBAAiB,QAAQ,EAAE,KAAK,EAAE,WAAW,IAAI,KAAK,EAAE,CAAC,CAAC;IAE9E,IAAI,iBAAiB,KAAK,WAAW,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QACrE,SAAS,IAAI,gCAAgC,CAAC;IAChD,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC;IACjD,MAAM,WAAW,GAAG,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC;IACjD,IAAI,WAAW,KAAK,CAAC,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;QAC3C,SAAS,IAAI,2CAA2C,CAAC;IAC3D,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -5,6 +5,7 @@ import type { MonitorClient } from "@azure/arm-monitor";
|
|
|
5
5
|
import type { NetworkManagementClient } from "@azure/arm-network";
|
|
6
6
|
import * as armResources from "@azure/arm-resources";
|
|
7
7
|
import type { AnalysisResult, Thresholds } from "../../types.js";
|
|
8
|
+
import { type MetricsCache } from "../utils.js";
|
|
8
9
|
/**
|
|
9
10
|
* Analyzes an Azure Public IP for potential cost optimization.
|
|
10
11
|
*
|
|
@@ -14,5 +15,5 @@ import type { AnalysisResult, Thresholds } from "../../types.js";
|
|
|
14
15
|
* @param timespanDays - Number of days to analyze metrics
|
|
15
16
|
* @returns Analysis result with cost risk and reason
|
|
16
17
|
*/
|
|
17
|
-
export declare function analyzePublicIp(resource: armResources.GenericResource, networkClient: NetworkManagementClient, monitorClient: MonitorClient, timespanDays: number, thresholds?: Thresholds, verbose?: boolean): Promise<AnalysisResult>;
|
|
18
|
+
export declare function analyzePublicIp(resource: armResources.GenericResource, networkClient: NetworkManagementClient, monitorClient: MonitorClient, timespanDays: number, thresholds?: Thresholds, verbose?: boolean, cache?: MetricsCache): Promise<AnalysisResult>;
|
|
18
19
|
//# sourceMappingURL=public-ip.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-ip.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/public-ip.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAElE,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAGrD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"public-ip.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/public-ip.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAElE,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAGrD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjE,OAAO,EAEL,KAAK,YAAY,EAIlB,MAAM,aAAa,CAAC;AAErB;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,YAAY,CAAC,eAAe,EACtC,aAAa,EAAE,uBAAuB,EACtC,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,MAAM,EACpB,UAAU,GAAE,UAA+B,EAC3C,OAAO,UAAQ,EACf,KAAK,CAAC,EAAE,YAAY,GACnB,OAAO,CAAC,cAAc,CAAC,CAuEzB"}
|
|
@@ -13,7 +13,7 @@ import { getMetric, verboseLog, verboseLogAnalysisResult, verboseLogResourceStar
|
|
|
13
13
|
* @param timespanDays - Number of days to analyze metrics
|
|
14
14
|
* @returns Analysis result with cost risk and reason
|
|
15
15
|
*/
|
|
16
|
-
export async function analyzePublicIp(resource, networkClient, monitorClient, timespanDays, thresholds = DEFAULT_THRESHOLDS, verbose = false) {
|
|
16
|
+
export async function analyzePublicIp(resource, networkClient, monitorClient, timespanDays, thresholds = DEFAULT_THRESHOLDS, verbose = false, cache) {
|
|
17
17
|
verboseLogResourceStart(verbose, resource.name || "unknown", "Public IP (microsoft.network/publicipaddresses)");
|
|
18
18
|
verboseLog(verbose, "Resource details:", resource);
|
|
19
19
|
const costRisk = "medium";
|
|
@@ -43,7 +43,7 @@ export async function analyzePublicIp(resource, networkClient, monitorClient, ti
|
|
|
43
43
|
reason += "Static IP not in use. ";
|
|
44
44
|
}
|
|
45
45
|
// Check network metrics for low usage
|
|
46
|
-
const bytesInDDoS = await getMetric(monitorClient, resource.id, "BytesInDDoS", "Average", timespanDays);
|
|
46
|
+
const bytesInDDoS = await getMetric(monitorClient, resource.id, "BytesInDDoS", "Average", timespanDays, cache);
|
|
47
47
|
if (bytesInDDoS !== null && bytesInDDoS < thresholds.publicIp.bytesInDDoS) {
|
|
48
48
|
reason += `Very low network traffic (${(bytesInDDoS / 1024 / 1024).toFixed(2)} MB/day avg). `;
|
|
49
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-ip.js","sourceRoot":"","sources":["../../../src/azure/resources/public-ip.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAI7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,SAAS,
|
|
1
|
+
{"version":3,"file":"public-ip.js","sourceRoot":"","sources":["../../../src/azure/resources/public-ip.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import type { MonitorClient } from "@azure/arm-monitor";
|
|
5
5
|
import * as armResources from "@azure/arm-resources";
|
|
6
6
|
import type { AnalysisResult, Thresholds } from "../../types.js";
|
|
7
|
+
import { type MetricsCache } from "../utils.js";
|
|
7
8
|
/**
|
|
8
9
|
* Analyzes an Azure Static Web App for potential cost optimization.
|
|
9
10
|
*
|
|
@@ -13,5 +14,5 @@ import type { AnalysisResult, Thresholds } from "../../types.js";
|
|
|
13
14
|
* @param verbose - Enable verbose logging
|
|
14
15
|
* @returns Analysis result with cost risk and reason
|
|
15
16
|
*/
|
|
16
|
-
export declare function analyzeStaticSite(resource: armResources.GenericResource, monitorClient: MonitorClient, timespanDays: number, thresholds?: Thresholds, verbose?: boolean): Promise<AnalysisResult>;
|
|
17
|
+
export declare function analyzeStaticSite(resource: armResources.GenericResource, monitorClient: MonitorClient, timespanDays: number, thresholds?: Thresholds, verbose?: boolean, cache?: MetricsCache): Promise<AnalysisResult>;
|
|
17
18
|
//# sourceMappingURL=static-web-app.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-web-app.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/static-web-app.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAGrD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"static-web-app.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/static-web-app.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAGrD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjE,OAAO,EAEL,KAAK,YAAY,EAIlB,MAAM,aAAa,CAAC;AAErB;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,YAAY,CAAC,eAAe,EACtC,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,MAAM,EACpB,UAAU,GAAE,UAA+B,EAC3C,OAAO,UAAQ,EACf,KAAK,CAAC,EAAE,YAAY,GACnB,OAAO,CAAC,cAAc,CAAC,CA2EzB"}
|
|
@@ -13,7 +13,7 @@ import { getMetric, verboseLog, verboseLogAnalysisResult, verboseLogResourceStar
|
|
|
13
13
|
* @param verbose - Enable verbose logging
|
|
14
14
|
* @returns Analysis result with cost risk and reason
|
|
15
15
|
*/
|
|
16
|
-
export async function analyzeStaticSite(resource, monitorClient, timespanDays, thresholds = DEFAULT_THRESHOLDS, verbose = false) {
|
|
16
|
+
export async function analyzeStaticSite(resource, monitorClient, timespanDays, thresholds = DEFAULT_THRESHOLDS, verbose = false, cache) {
|
|
17
17
|
verboseLogResourceStart(verbose, resource.name || "unknown", "Static Web App (Microsoft.Web/staticSites)");
|
|
18
18
|
verboseLog(verbose, "Resource details:", resource);
|
|
19
19
|
const costRisk = "low";
|
|
@@ -30,8 +30,8 @@ export async function analyzeStaticSite(resource, monitorClient, timespanDays, t
|
|
|
30
30
|
// Check for site hits (requests to the static site)
|
|
31
31
|
// Note: Static Web Apps metrics use Total aggregation, not Average
|
|
32
32
|
// Ref. https://learn.microsoft.com/en-us/azure/azure-monitor/reference/supported-metrics/microsoft-web-staticsites-metrics
|
|
33
|
-
const siteHits = await getMetric(monitorClient, resource.id, "SiteHits", "Total", timespanDays);
|
|
34
|
-
const bytesSent = await getMetric(monitorClient, resource.id, "BytesSent", "Total", timespanDays);
|
|
33
|
+
const siteHits = await getMetric(monitorClient, resource.id, "SiteHits", "Total", timespanDays, cache);
|
|
34
|
+
const bytesSent = await getMetric(monitorClient, resource.id, "BytesSent", "Total", timespanDays, cache);
|
|
35
35
|
verboseLog(verbose, `Site Hits: ${siteHits !== null ? `${siteHits.toFixed(0)} total requests` : "N/A"}`);
|
|
36
36
|
verboseLog(verbose, `Bytes Sent: ${bytesSent !== null ? `${(bytesSent / 1024 / 1024).toFixed(2)} MB total` : "N/A"}`);
|
|
37
37
|
// If both metrics are null, it means no data points exist (no traffic at all)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-web-app.js","sourceRoot":"","sources":["../../../src/azure/resources/static-web-app.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAI7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,SAAS,
|
|
1
|
+
{"version":3,"file":"static-web-app.js","sourceRoot":"","sources":["../../../src/azure/resources/static-web-app.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import type { MonitorClient } from "@azure/arm-monitor";
|
|
5
5
|
import * as armResources from "@azure/arm-resources";
|
|
6
6
|
import type { AnalysisResult, Thresholds } from "../../types.js";
|
|
7
|
+
import { type MetricsCache } from "../utils.js";
|
|
7
8
|
/**
|
|
8
9
|
* Analyzes an Azure Storage Account for potential cost optimization.
|
|
9
10
|
*
|
|
@@ -12,5 +13,5 @@ import type { AnalysisResult, Thresholds } from "../../types.js";
|
|
|
12
13
|
* @param timespanDays - Number of days to analyze metrics
|
|
13
14
|
* @returns Analysis result with cost risk and reason
|
|
14
15
|
*/
|
|
15
|
-
export declare function analyzeStorageAccount(resource: armResources.GenericResource, monitorClient: MonitorClient, timespanDays: number, thresholds?: Thresholds, verbose?: boolean): Promise<AnalysisResult>;
|
|
16
|
+
export declare function analyzeStorageAccount(resource: armResources.GenericResource, monitorClient: MonitorClient, timespanDays: number, thresholds?: Thresholds, verbose?: boolean, cache?: MetricsCache): Promise<AnalysisResult>;
|
|
16
17
|
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/storage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAErD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/storage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAErD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjE,OAAO,EAEL,KAAK,YAAY,EAIlB,MAAM,aAAa,CAAC;AAErB;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,YAAY,CAAC,eAAe,EACtC,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,MAAM,EACpB,UAAU,GAAE,UAA+B,EAC3C,OAAO,UAAQ,EACf,KAAK,CAAC,EAAE,YAAY,GACnB,OAAO,CAAC,cAAc,CAAC,CAuCzB"}
|
|
@@ -11,7 +11,7 @@ import { getMetric, verboseLog, verboseLogAnalysisResult, verboseLogResourceStar
|
|
|
11
11
|
* @param timespanDays - Number of days to analyze metrics
|
|
12
12
|
* @returns Analysis result with cost risk and reason
|
|
13
13
|
*/
|
|
14
|
-
export async function analyzeStorageAccount(resource, monitorClient, timespanDays, thresholds = DEFAULT_THRESHOLDS, verbose = false) {
|
|
14
|
+
export async function analyzeStorageAccount(resource, monitorClient, timespanDays, thresholds = DEFAULT_THRESHOLDS, verbose = false, cache) {
|
|
15
15
|
verboseLogResourceStart(verbose, resource.name || "unknown", "Storage Account (microsoft.storage/storageaccounts)");
|
|
16
16
|
verboseLog(verbose, "Resource details:", resource);
|
|
17
17
|
const costRisk = "medium";
|
|
@@ -22,7 +22,7 @@ export async function analyzeStorageAccount(resource, monitorClient, timespanDay
|
|
|
22
22
|
suspectedUnused: false,
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
|
-
const transactions = await getMetric(monitorClient, resource.id, "Transactions", "Average", timespanDays);
|
|
25
|
+
const transactions = await getMetric(monitorClient, resource.id, "Transactions", "Average", timespanDays, cache);
|
|
26
26
|
if (transactions !== null &&
|
|
27
27
|
transactions < thresholds.storage.transactionsPerDay) {
|
|
28
28
|
const result = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/azure/resources/storage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,SAAS,
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/azure/resources/storage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,SAAS,EAET,UAAU,EACV,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAErB;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,QAAsC,EACtC,aAA4B,EAC5B,YAAoB,EACpB,aAAyB,kBAAkB,EAC3C,OAAO,GAAG,KAAK,EACf,KAAoB;IAEpB,uBAAuB,CACrB,OAAO,EACP,QAAQ,CAAC,IAAI,IAAI,SAAS,EAC1B,qDAAqD,CACtD,CAAC;IACF,UAAU,CAAC,OAAO,EAAE,mBAAmB,EAAE,QAAQ,CAAC,CAAC;IAEnD,MAAM,QAAQ,GAA8B,QAAQ,CAAC;IACrD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,OAAO;YACL,QAAQ;YACR,MAAM,EAAE,yBAAyB;YACjC,eAAe,EAAE,KAAK;SACvB,CAAC;IACJ,CAAC;IACD,MAAM,YAAY,GAAG,MAAM,SAAS,CAClC,aAAa,EACb,QAAQ,CAAC,EAAE,EACX,cAAc,EACd,SAAS,EACT,YAAY,EACZ,KAAK,CACN,CAAC;IACF,IACE,YAAY,KAAK,IAAI;QACrB,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,kBAAkB,EACpD,CAAC;QACD,MAAM,MAAM,GAAG;YACb,QAAQ;YACR,MAAM,EAAE,+BAA+B,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa;YAC3E,eAAe,EAAE,IAAI;SACtB,CAAC;QACF,wBAAwB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1C,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,MAAM,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IAChE,wBAAwB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC;AAChB,CAAC"}
|