Skip to content

Commit 163a825

Browse files
authored
Fix unit conversions (#101)
1 parent 20e3e2c commit 163a825

File tree

18 files changed

+71
-43
lines changed

18 files changed

+71
-43
lines changed

cmd/plan.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Example usages:
4444
log.Fatal(err)
4545
}
4646

47-
input := workdir
47+
var input string
4848
if len(args) != 0 {
4949
input = args[0]
5050
if !filepath.IsAbs(input) {

internal/data/data/energy_coefficients.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"AWS": {
33
"cpu_min_wh": 0.74,
4-
"cpu_max_wh": 3.5,
4+
"cpu_max_wh": 5.23,
55
"storage_hdd_wh_tb": 0.65,
66
"storage_ssd_wh_tb": 1.2,
77
"networking_wh_gb": 1,

internal/estimate/coefficients/coefficients.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ func (cps *CoefficientsProviders) GetByProvider(provider providers.Provider) Coe
4949

5050
func (cps *CoefficientsProviders) getByProviderName(name string) Coefficients {
5151
r := reflect.ValueOf(cps)
52-
coefficients := reflect.Indirect(r).FieldByName(name)
53-
return coefficients.Interface().(Coefficients)
52+
coefficientsVal := reflect.Indirect(r).FieldByName(name)
53+
coefficients := coefficientsVal.Interface().(Coefficients)
54+
return coefficients
5455
}

internal/estimate/estimate.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func EstimateResources(resourceList map[string]resources.Resource) estimation.Es
4545
return estimation.EstimationReport{
4646
Info: estimation.EstimationInfo{
4747
UnitTime: viper.Get("unit.time").(string),
48-
UnitWattTime: fmt.Sprintf("%s%s", viper.Get("unit.power"), viper.Get("unit.time")),
48+
UnitWattTime: fmt.Sprintf("%s%s", "W", viper.Get("unit.time")),
4949
UnitCarbonEmissionsTime: fmt.Sprintf("%sCO2eq/%s", viper.Get("unit.carbon"), viper.Get("unit.time")),
5050
DateTime: time.Now(),
5151
InfoByProvider: map[providers.Provider]estimation.InfoByProvider{

internal/estimate/estimate/Energy.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ func estimateWattHour(resource *resources.ComputeResource) decimal.Decimal {
1818
log.Debugf("%v.%v Storage in Wh: %v", resource.Identification.ResourceType, resource.Identification.Name, storageInWh)
1919
gpuEstimationInWh := EstimateWattGPU(resource)
2020
log.Debugf("%v.%v GPUs in Wh: %v", resource.Identification.ResourceType, resource.Identification.Name, gpuEstimationInWh)
21-
pue := coefficients.GetEnergyCoefficients().GCP.PueAverage
21+
pue := coefficients.GetEnergyCoefficients().GetByProvider(resource.Identification.Provider).PueAverage
22+
2223
log.Debugf("%v.%v PUE %v", resource.Identification.ResourceType, resource.Identification.Name, pue)
2324
rawWattEstimate := decimal.Sum(
2425
cpuEstimationInWh,

internal/estimate/estimate/Resource.go

+34-33
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package estimate
22

33
import (
4+
"strings"
5+
46
"github.com/carboniferio/carbonifer/internal/estimate/coefficients"
57
"github.com/carboniferio/carbonifer/internal/estimate/estimation"
68

@@ -15,56 +17,55 @@ func EstimateSupportedResource(resource resources.Resource) *estimation.Estimati
1517

1618
var computeResource resources.ComputeResource = resource.(resources.ComputeResource)
1719
// Electric power used per unit of time
18-
avgWatt := estimateWattHour(&computeResource) // Watt hour
19-
if viper.Get("unit.power").(string) == "kW" {
20-
avgWatt = avgWatt.Div(decimal.NewFromInt(1000))
21-
}
22-
if viper.Get("unit.time").(string) == "m" {
23-
avgWatt = avgWatt.Mul(decimal.NewFromInt(24 * 30))
24-
}
25-
if viper.Get("unit.time").(string) == "y" {
26-
avgWatt = avgWatt.Mul(decimal.NewFromInt(24 * 365))
27-
}
28-
avgWattStr := avgWatt.String()
20+
// It's computed first in watt per hour
21+
avgWattHour := estimateWattHour(&computeResource) // Watt hour
22+
avgKWattHour := avgWattHour.Div(decimal.NewFromInt(1000))
2923

3024
// Regional grid emission per unit of time
25+
// regionEmissions are in gCO2/kWh
3126
regionEmissions, err := coefficients.RegionEmission(resource.GetIdentification().Provider, resource.GetIdentification().Region) // gCO2eq /kWh
3227
if err != nil {
3328
log.Fatalf("Error while getting region emissions for %v: %v", resource.GetAddress(), err)
3429
}
35-
if viper.Get("unit.power").(string) == "W" {
36-
regionEmissions.GridCarbonIntensity = regionEmissions.GridCarbonIntensity.Div(decimal.NewFromInt(1000))
30+
31+
// Carbon Emissions
32+
carbonEmissionInGCO2PerH := avgKWattHour.Mul(regionEmissions.GridCarbonIntensity)
33+
carbonEmissionPerTime := carbonEmissionInGCO2PerH
34+
if strings.ToLower(viper.GetString("unit.time")) == "d" {
35+
carbonEmissionPerTime = carbonEmissionPerTime.Mul(decimal.NewFromInt(24))
3736
}
38-
if viper.Get("unit.time").(string) == "m" {
39-
regionEmissions.GridCarbonIntensity = regionEmissions.GridCarbonIntensity.Mul(decimal.NewFromInt(24 * 30))
37+
if strings.ToLower(viper.GetString("unit.time")) == "m" {
38+
carbonEmissionPerTime = carbonEmissionPerTime.Mul(decimal.NewFromInt(24 * 30))
4039
}
41-
if viper.Get("unit.time").(string) == "y" {
42-
regionEmissions.GridCarbonIntensity = regionEmissions.GridCarbonIntensity.Mul(decimal.NewFromInt(24 * 365))
40+
if strings.ToLower(viper.GetString("unit.time")) == "y" {
41+
carbonEmissionPerTime = carbonEmissionPerTime.Mul(decimal.NewFromInt(24 * 365))
4342
}
44-
if viper.Get("unit.carbon").(string) == "kg" {
45-
regionEmissions.GridCarbonIntensity = regionEmissions.GridCarbonIntensity.Div(decimal.NewFromInt(1000))
43+
if strings.ToLower(viper.GetString("unit.carbon")) == "kg" {
44+
carbonEmissionPerTime = carbonEmissionPerTime.Div(decimal.NewFromInt(1000))
4645
}
47-
48-
// Carbon Emissions
49-
carbonEmissionPerTime := avgWatt.Mul(regionEmissions.GridCarbonIntensity)
5046
carbonEmissionPerTimeStr := carbonEmissionPerTime.String()
5147

5248
log.Debugf(
53-
"estimating resource %v.%v (%v): %v %v%v * %v %vCO2/%v%v = %v %vCO2/%v%v * %v",
49+
"estimating resource %v.%v (%v): %v %v%v * %v %vCO2/%v%v = %v %vCO2/%v%v * %v = %v %vCO2/%v%v * %v",
5450
computeResource.Identification.ResourceType,
5551
computeResource.Identification.Name,
5652
regionEmissions.Region,
57-
avgWattStr,
58-
viper.Get("unit.power").(string),
59-
viper.Get("unit.time").(string),
53+
avgKWattHour.String(),
54+
"kW",
55+
"h",
6056
regionEmissions.GridCarbonIntensity,
61-
viper.Get("unit.carbon").(string),
62-
viper.Get("unit.power").(string),
63-
viper.Get("unit.time").(string),
57+
"g",
58+
"kW",
59+
"h",
60+
carbonEmissionInGCO2PerH,
61+
"g",
62+
"kW",
63+
"h",
64+
resource.GetIdentification().Count,
6465
carbonEmissionPerTimeStr,
65-
viper.Get("unit.carbon").(string),
66-
viper.Get("unit.power").(string),
67-
viper.Get("unit.time").(string),
66+
viper.GetString("unit.carbon"),
67+
viper.GetString("unit.power"),
68+
viper.GetString("unit.time"),
6869
resource.GetIdentification().Count,
6970
)
7071

@@ -77,7 +78,7 @@ func EstimateSupportedResource(resource resources.Resource) *estimation.Estimati
7778

7879
est := &estimation.EstimationResource{
7980
Resource: &computeResource,
80-
Power: avgWatt.RoundFloor(10),
81+
Power: avgWattHour.RoundFloor(10),
8182
CarbonEmissions: carbonEmissionPerTime.RoundFloor(10),
8283
AverageCPUUsage: decimal.NewFromFloat(viper.GetFloat64("provider.gcp.avg_cpu_use")).RoundFloor(10),
8384
TotalCount: decimal.NewFromInt(count * replicationFactor),

internal/estimate/estimate_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ func TestEstimateResourceKilo(t *testing.T) {
149149
args: args{resourceGCPComputeBasic},
150150
want: &estimation.EstimationResource{
151151
Resource: &resourceGCPComputeBasic,
152-
Power: decimal.NewFromFloat(5472.56448).RoundFloor(10),
153-
CarbonEmissions: decimal.NewFromFloat(232.4745391104).RoundFloor(10),
152+
Power: decimal.NewFromFloat(7.600784).RoundFloor(10),
153+
CarbonEmissions: decimal.NewFromFloat(0.3228813043).RoundFloor(10),
154154
AverageCPUUsage: decimal.NewFromFloat(avgCPUUse),
155155
TotalCount: decimal.NewFromInt(1),
156156
},
@@ -160,8 +160,8 @@ func TestEstimateResourceKilo(t *testing.T) {
160160
args: args{resourceGCPComputeCPUType},
161161
want: &estimation.EstimationResource{
162162
Resource: &resourceGCPComputeCPUType,
163-
Power: decimal.NewFromFloat(6880.7275733647).RoundFloor(10),
164-
CarbonEmissions: decimal.NewFromFloat(292.2933073165).RoundFloor(10),
163+
Power: decimal.NewFromFloat(9.5565660741).RoundFloor(10),
164+
CarbonEmissions: decimal.NewFromFloat(0.4059629268).RoundFloor(10),
165165
AverageCPUUsage: decimal.NewFromFloat(avgCPUUse),
166166
TotalCount: decimal.NewFromInt(1),
167167
},

internal/terraform/terraform.go

+12
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,23 @@ func CarboniferPlan(input string) (*map[string]interface{}, error) {
120120
// If the path points to a file, run show
121121
if !fileInfo.IsDir() {
122122
parentDir := filepath.Dir(input)
123+
// Add the .carbonifer folder in workdir
124+
viper.AddConfigPath(filepath.Join(parentDir, ".carbonifer"))
123125
fileName := filepath.Base(input)
124126
viper.Set("workdir", parentDir)
125127
tfPlan, err := terraformShow(fileName)
126128
return tfPlan, err
129+
} else {
130+
viper.AddConfigPath(filepath.Join(input, ".carbonifer"))
127131
}
132+
133+
// Refresh viper config
134+
if err := viper.ReadInConfig(); err != nil {
135+
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
136+
log.Panic(err)
137+
}
138+
}
139+
128140
// If the path points to a directory, run plan
129141
viper.Set("workdir", input)
130142
tfPlan, err := TerraformPlan()

internal/utils/config.go

+2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ func basePath() string {
5656
return filepath.Join(d, "../..")
5757
}
5858

59+
var WorkDir string
60+
5961
func initViper(configFilePath string) {
6062
loadViperDefaults()
6163

test/terraform/gcp_1/provider.tf

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
provider "google" {
22
region = "europe-west9"
3+
project = "dummy-project"
34
}
45

test/terraform/gcp_cit/provider.tf

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
provider "google" {
22
region = "europe-west9"
3+
project = "dummy-project"
34
}
45

test/terraform/gcp_gke/variables.tf

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ variable "region" {
22
default = "europe-west9"
33
}
44

5+
variable "project" {
6+
default = "dummy-project"
7+
}
8+
59
variable "project_id" {
610
default = "cbf-terraform"
711
}

test/terraform/gcp_global_module/global.tf

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
provider "google" {
22
region = local.common_region
3+
project = "dummy-project"
34
}
45

56
locals {

test/terraform/gcp_group/main.tf

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ resource "google_compute_instance_group_manager" "my-group-manager" {
3838
resource "google_compute_autoscaler" "autoscaler" {
3939
name = "my-autoscaler"
4040
target = google_compute_instance_group_manager.my-group-manager.id
41+
zone = "europe-west9-a"
4142

4243
autoscaling_policy {
4344
max_replicas = 10

test/terraform/gcp_group/provider.tf

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
provider "google" {
22
region = "europe-west9"
3+
project = "dummy-project"
34
}
45

test/terraform/gcp_images/provider.tf

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
provider "google" {
22
region = "europe-west9"
3+
project = "dummy-project"
34
}
45

test/terraform/planRaw/plan.tfplan

52 Bytes
Binary file not shown.

test/terraform/planRaw/provider.tf

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
provider "google" {
22
region = "europe-west9"
3+
project = "dummy-project"
34
}
45

0 commit comments

Comments
 (0)