Classify costs
This commit is contained in:
parent
7125ce9606
commit
b38a041f1e
|
@ -7,4 +7,5 @@ build
|
|||
node_modules
|
||||
out
|
||||
sentinel.h
|
||||
financials/????-??
|
||||
financials/????-??/*
|
||||
!financials/????-??/breakdown.txt
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
Riju :: $175.43
|
||||
CloudWatch :: $34.80
|
||||
EC2 :: $112.98
|
||||
Data Transfer :: $0.68
|
||||
EBS Snapshot :: $11.42
|
||||
EBS Volume :: $46.40
|
||||
EBS Volume :: $46.40
|
||||
gp2 :: $11.61
|
||||
gp3 :: $34.78
|
||||
Instance :: $54.48
|
||||
t2.small :: $0.04
|
||||
t3 :: $0.08
|
||||
t3.2xlarge :: $29.80
|
||||
t3.medium :: $14.77
|
||||
t3.small :: $9.78
|
||||
ECR :: $7.31
|
||||
Data Transfer :: $3.29
|
||||
Storage :: $4.02
|
||||
ELB :: $20.05
|
||||
Data Transfer :: $0.31
|
||||
LCUs :: $0.06
|
||||
Load Balancer :: $19.68
|
||||
S3 :: $0.29
|
|
@ -0,0 +1,18 @@
|
|||
Riju :: $52.21
|
||||
EC2 :: $27.85
|
||||
Data Transfer :: $0.03
|
||||
EBS Snapshot :: $1.51
|
||||
EBS Volume :: $15.87
|
||||
EBS Volume :: $15.87
|
||||
gp2 :: $0.60
|
||||
gp3 :: $15.27
|
||||
Instance :: $10.44
|
||||
t3.small :: $10.44
|
||||
ECR :: $6.00
|
||||
Data Transfer :: $1.38
|
||||
Storage :: $4.62
|
||||
ELB :: $18.25
|
||||
Data Transfer :: $0.17
|
||||
LCUs :: $0.06
|
||||
Load Balancer :: $18.02
|
||||
S3 :: $0.12
|
|
@ -184,6 +184,12 @@ def classify_line_item(item, billing_month=None, full=False):
|
|||
category = ["EC2"]
|
||||
if "ElasticIP:IdleAddress" in usage_type:
|
||||
category.append("EIP")
|
||||
# Apparently tags on EIPs are ignored for billing
|
||||
# purposes, so we just have to know what we were using
|
||||
# them for. (Leaving them uncategorized for 2021-07
|
||||
# though.)
|
||||
if billing_month != "2021-07":
|
||||
project = "Corona"
|
||||
elif "EBS:VolumeUsage" in usage_type:
|
||||
category.append("EBS Volume")
|
||||
category.extend(["EBS Volume", re.sub(r"^.+\.", "", usage_type)])
|
||||
|
@ -252,28 +258,29 @@ def uncategorized_last(key):
|
|||
return (key == "Uncategorized", key)
|
||||
|
||||
|
||||
def print_taxonomy(taxonomy, indent=""):
|
||||
def print_taxonomy(taxonomy, indent="", file=sys.stdout):
|
||||
cost = taxonomy["cost"]
|
||||
if not indent:
|
||||
print(f"(total) :: ${cost:.2f}")
|
||||
categories = taxonomy.get("categories", {})
|
||||
for category in sorted(categories, key=uncategorized_last):
|
||||
subtaxonomy = categories[category]
|
||||
cost = subtaxonomy["cost"]
|
||||
if cost < 0.01:
|
||||
continue
|
||||
print(f"{indent}{category} :: ${cost:.2f}")
|
||||
print_taxonomy(subtaxonomy, indent=indent + " ")
|
||||
print(f"{indent}{category} :: ${cost:.2f}", file=file)
|
||||
print_taxonomy(subtaxonomy, indent=indent + " ", file=file)
|
||||
|
||||
|
||||
def classify_costs(csv_path, **kwargs):
|
||||
items = [item for item in read_csv(csv_path) if item["lineItem/UnblendedCost"]]
|
||||
for item in items:
|
||||
item["lineItem/UnblendedCost"] = float(item["lineItem/UnblendedCost"])
|
||||
all_items = [item for item in read_csv(csv_path)]
|
||||
items = []
|
||||
for item in all_items:
|
||||
cost = item["lineItem/UnblendedCost"]
|
||||
if cost and float(cost):
|
||||
items.append({**item, "lineItem/UnblendedCost": float(cost)})
|
||||
taxonomy = {}
|
||||
for item in embed_taxes(items):
|
||||
add_to_taxonomy(taxonomy, classify_line_item(item, **kwargs), item)
|
||||
print_taxonomy(taxonomy)
|
||||
add_to_taxonomy(taxonomy, ["AWS", *classify_line_item(item, **kwargs)], item)
|
||||
return taxonomy
|
||||
|
||||
|
||||
def main():
|
||||
|
@ -284,7 +291,13 @@ def main():
|
|||
year, month = map(int, args.date.split("-"))
|
||||
billing_month = f"{year}-{month:02d}"
|
||||
csv_path = get_csv(year, month, force_download=args.force_download)
|
||||
classify_costs(csv_path, billing_month=billing_month)
|
||||
taxonomy = classify_costs(csv_path, billing_month=billing_month)
|
||||
print_taxonomy(taxonomy)
|
||||
riju_taxonomy = taxonomy["categories"]["AWS"]
|
||||
riju_taxonomy["categories"] = {"Riju": riju_taxonomy["categories"]["Riju"]}
|
||||
target_dir = ROOT / f"{year}-{month:02d}"
|
||||
with open(target_dir / "breakdown.txt", "w") as f:
|
||||
print_taxonomy(riju_taxonomy, file=f)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
Loading…
Reference in New Issue