carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package console
2
3import (
4 "context"
5 "errors"
6 "log"
7 "strings"
8 "time"
9
10 "github.com/aws/aws-sdk-go-v2/aws"
11 "github.com/aws/aws-sdk-go-v2/service/cloudwatch"
12 "github.com/aws/aws-sdk-go-v2/service/cloudwatch/types"
13
14 "github.com/carlosframework/platform/internal/rootaws"
15)
16
17// The AWS adapter of the eligible-capacity metric (region HA spec 2 §4,
18// §25): CloudWatch, Carlos/Region EligibleBoxes, keyed by the placement
19// code, in each region's own CloudWatch, where the region-host module's
20// alarm reads it. Armed by CARLOS_REGION_METRICS=cloudwatch on the
21// console. The platform box's role needs cloudwatch:PutMetricData on the
22// Carlos/Region namespace: plan 2c grants it.
23
24const (
25 capacityNamespace = "Carlos/Region"
26 capacityMetric = "EligibleBoxes"
27)
28
29// capacityData is the exact PutMetricData input for one region's count.
30func capacityData(c regionCapacity, now time.Time) *cloudwatch.PutMetricDataInput {
31 return &cloudwatch.PutMetricDataInput{Namespace: aws.String(capacityNamespace), MetricData: []types.MetricDatum{{
32 MetricName: aws.String(capacityMetric),
33 Dimensions: []types.Dimension{{Name: aws.String("Region"), Value: aws.String(c.Placement)}},
34 Timestamp: aws.Time(now),
35 Unit: types.StandardUnitCount,
36 Value: aws.Float64(float64(c.Eligible)),
37 }}}
38}
39
40// cloudWatchCapacity publishes each count to its region's CloudWatch.
41type cloudWatchCapacity struct {
42 put func(ctx context.Context, awsRegion string, in *cloudwatch.PutMetricDataInput) error
43 now func() time.Time
44}
45
46func (c cloudWatchCapacity) PublishCapacity(ctx context.Context, counts []regionCapacity) error {
47 var errs []error
48 for _, n := range counts {
49 errs = append(errs, c.put(ctx, n.AWSRegion, capacityData(n, c.now())))
50 }
51 return errors.Join(errs...)
52}
53
54// capacityPublisherFromEnv is the console's publisher: CloudWatch when
55// CARLOS_REGION_METRICS is "cloudwatch", and nil otherwise, or when the
56// AWS configuration cannot be loaded (logged).
57func capacityPublisherFromEnv(ctx context.Context, getenv func(string) string) capacityPublisher {
58 if strings.TrimSpace(getenv("CARLOS_REGION_METRICS")) != "cloudwatch" {
59 return nil
60 }
61 cfg, err := rootaws.LoadDefaultConfig(ctx)
62 if err != nil {
63 log.Printf("console: eligible-capacity metric disabled: load aws config: %v", err)
64 return nil
65 }
66 return cloudWatchCapacity{now: time.Now, put: func(ctx context.Context, awsRegion string, in *cloudwatch.PutMetricDataInput) error {
67 _, err := cloudwatch.NewFromConfig(cfg, func(o *cloudwatch.Options) { o.Region = awsRegion }).PutMetricData(ctx, in)
68 return err
69 }}
70}
71