Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions examples/cost-analysis-export/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ func ConfigureAndProcess(ctx context.Context, operation string) error {
return fmt.Errorf("invalid config: %w", err)
}

ctx, cancel := context.WithTimeout(ctx, cfg.Timeout)
defer cancel()

app, err := NewApp(cfg)
if err != nil {
return err
Expand Down Expand Up @@ -182,7 +185,7 @@ func (a *App) Export(ctx context.Context) error {
return fmt.Errorf("creating request: %w", err)
}

// Execute request
// Execute request (timeout inherited from ctx)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("failed to reach cost analysis service: %w", err)
Expand Down Expand Up @@ -461,6 +464,10 @@ func (a *App) joinAndExportData(ctx context.Context) error {
if err != nil {
return fmt.Errorf("joining data: %w", err)
}
defer func() {
_ = file.Close()
_ = os.Remove(file.Name())
}()
slog.Info("data joined successfully", "file", file.Name())

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not an issue here. JoinData() already seeks back to position 0 before returning (line 812: tmpFile.Seek(0, 0)), so the file handle is at the start when UploadFile receives it. The Azure SDK's UploadFile also takes an *os.File and handles positioning internally.

contentType := "text/csv"
Expand Down Expand Up @@ -648,21 +655,21 @@ func stripBOMReader(r io.Reader) io.Reader {
// - MCA: https://learn.microsoft.com/en-us/azure/cost-management-billing/dataset-schema/cost-usage-details-mca
// - FOCUS: https://learn.microsoft.com/en-us/azure/cost-management-billing/dataset-schema/cost-usage-details-focus
var columnsToMultiply = map[string]bool{
"PreTaxCost": true,
"CostInBillingCurrency": true,
"costInBillingCurrency": true,
"BilledCost": true,
"EffectiveCost": true,
"ListCost": true,
"ContractedCost": true,
"costInUsd": true,
"PreTaxCost": true,
"CostInBillingCurrency": true,
"costInBillingCurrency": true,
"BilledCost": true,
"EffectiveCost": true,
"ListCost": true,
"ContractedCost": true,
"costInUsd": true,
"paygCostInBillingCurrency": true,
"paygCostInUsd": true,
"UsageQuantity": true,
"Quantity": true,
"quantity": true,
"ConsumedQuantity": true,
"PricingQuantity": true,
"paygCostInUsd": true,
"UsageQuantity": true,
"Quantity": true,
"quantity": true,
"ConsumedQuantity": true,
"PricingQuantity": true,
}

// resourceIDColumns lists possible column names for resource ID.
Expand Down