Last active
December 28, 2024 17:24
-
-
Save jedipunkz/ff3e0a3ba1aeee3f2d619f84c852f4c3 to your computer and use it in GitHub Desktop.
get ecs metadata
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 characters
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) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment