Last active
December 28, 2024 17:24
-
-
Save jedipunkz/ff3e0a3ba1aeee3f2d619f84c852f4c3 to your computer and use it in GitHub Desktop.
Revisions
-
jedipunkz renamed this gist
Jan 3, 2023 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
jedipunkz created this gist
Jan 3, 2023 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,163 @@ package main import ( "context" "encoding/json" "fmt" "io/ioutil" "log" "net/http" "net/url" "os" ) const ( ecsMetadataUriEnvV4 = "ECS_CONTAINER_METADATA_URI_V4" ) type Client struct { HTTPClient *http.Client endpoint string } type TaskMetadata struct { Cluster string `json:"Cluster"` TaskARN string `json:"TaskARN"` Family string `json:"Family"` Revision string `json:"Revision"` DesiredStatus string `json:"DesiredStatus"` KnownStatus string `json:"KnownStatus"` AvailabilityZone string `json:"AvailabilityZone"` LaunchType string `json:"LaunchType"` Containers []struct { DockerID string `json:"DockerId"` Name string `json:"Name"` DockerName string `json:"DockerName"` Image string `json:"Image"` ImageID string `json:"ImageID"` Labels map[string]string `json:"Labels"` DesiredStatus string `json:"DesiredStatus"` KnownStatus string `json:"KnownStatus"` Type string `json:"Type"` ContainerARN string `json:"ContainerARN"` } `json:"Containers"` } type StatsMetadata struct { CPUStats struct { CPUUsage struct { TotalUsage int `json:"total_usage"` PerCPUUsage []int `json:"percpu_usage"` UsageInKernelmode int `json:"usage_in_kernelmode"` UsageInUsermode int `json:"usage_in_usermode"` } `json:"cpu_usage"` SystemCPUUsage int `json:"system_cpu_usage"` OnlineCPUs int `json:"online_cpus"` ThrottlingData struct { Periods int `json:"periods"` ThrottledPeriods int `json:"throttled_periods"` ThrottledTime int `json:"throttled_time"` } `json:"throttling_data"` } `json:"cpu_stats"` PreCPUStats struct { CPUUsage struct { TotalUsage int `json:"total_usage"` PerCPUUsage []int `json:"percpu_usage"` UsageInKernelmode int `json:"usage_in_kernelmode"` UsageInUsermode int `json:"usage_in_usermode"` } `json:"cpu_usage"` SystemCPUUsage int `json:"system_cpu_usage"` OnlineCPUs int `json:"online_cpus"` ThrottlingData struct { Periods int `json:"periods"` ThrottledPeriods int `json:"throttled_periods"` ThrottledTime int `json:"throttled_time"` } `json:"throttling_data"` } `json:"precpu_stats"` } // NewClient retrurns a new ECS client and endpoint func NewClient(endpoint string) *Client { return &Client{ HTTPClient: &http.Client{}, endpoint: endpoint, } } // NewClientToMetadataEndpoint returns a new ECS client and endpoint func NewClientToMetadataEndpoint() (*Client, error) { const endpointURI = "ECS_CONTAINER_METADATA_URI_V4" endpoint := os.Getenv(endpointURI) if endpoint == "" { return nil, fmt.Errorf("environment variable %s not set", endpointURI) } _, err := url.Parse(endpoint) if err != nil { return nil, fmt.Errorf("invalid endpoint: %s", err) } return NewClient(endpoint), nil } func (c *Client) request(ctx context.Context, uri string, out interface{}) error { req, err := http.NewRequest("GET", uri, nil) if err != nil { return err } req = req.WithContext(ctx) resp, err := c.HTTPClient.Do(req) if err != nil { return err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return err } return json.Unmarshal(body, out) } func (c *Client) RetriveTaskMetadata(ctx context.Context) (TaskMetadata, error) { var output TaskMetadata err := c.request(ctx, c.endpoint+"/task", &output) return output, err } func (c *Client) RetriveStatsMetadata(ctx context.Context) (map[string]StatsMetadata, error) { output := make(map[string]StatsMetadata) err := c.request(ctx, c.endpoint+"/task/stats", &output) return output, err } func main() { ctx := context.Background() client, err := NewClientToMetadataEndpoint() if err != nil { log.Printf("error creating client: %s", err) } taskMetadata, err := client.RetriveTaskMetadata(ctx) if err != nil { log.Printf("error retrieving task metadata: %s", err) } statsMetadata, err := client.RetriveStatsMetadata(ctx) if err != nil { log.Printf("error retrieving task stats metadata: %s", err) } for _, container := range taskMetadata.Containers { s := statsMetadata[container.DockerID] if &s == nil { log.Printf("Could not find stats for container %s", container.DockerID) continue } log.Printf("Total CPU Usage: %d", s.CPUStats.CPUUsage.TotalUsage) log.Printf("CPU Usage: %f", (float64(s.CPUStats.CPUUsage.TotalUsage)-float64(s.PreCPUStats.CPUUsage.TotalUsage))/ (float64(s.CPUStats.SystemCPUUsage)-float64(s.PreCPUStats.SystemCPUUsage))* float64(s.CPUStats.OnlineCPUs)*100) } }