in agent/stats/engine.go [640:719]
func (engine *DockerStatsEngine) taskContainerMetricsUnsafe(taskArn string) ([]*ecstcs.ContainerMetric, error) {
containerMap, taskExists := engine.tasksToContainers[taskArn]
if !taskExists {
return nil, fmt.Errorf("task not found")
}
var containerMetrics []*ecstcs.ContainerMetric
for _, container := range containerMap {
dockerID := container.containerMetadata.DockerID
// Check if the container is terminal. If it is, make sure that it is
// cleaned up properly. We might sometimes miss events from docker task
// engine and this helps in reconciling the state. The tcs client's
// GetInstanceMetrics probe is used as the trigger for this.
if engine.stopTrackingContainerUnsafe(container, taskArn) {
continue
}
// CPU and Memory are both critical, so skip the container if either of these fail.
cpuStatsSet, err := container.statsQueue.GetCPUStatsSet()
if err != nil {
seelog.Infof("cloudwatch metrics for container %v not collected, reason (cpu): %v", dockerID, err)
continue
}
memoryStatsSet, err := container.statsQueue.GetMemoryStatsSet()
if err != nil {
seelog.Infof("cloudwatch metrics for container %v not collected, reason (memory): %v", dockerID, err)
continue
}
containerMetric := &ecstcs.ContainerMetric{
ContainerName: &container.containerMetadata.Name,
CpuStatsSet: cpuStatsSet,
MemoryStatsSet: memoryStatsSet,
}
storageStatsSet, err := container.statsQueue.GetStorageStatsSet()
if err != nil {
seelog.Warnf("Error getting storage stats, err: %v, container: %v", err, dockerID)
} else {
containerMetric.StorageStatsSet = storageStatsSet
}
task, err := engine.resolver.ResolveTask(dockerID)
if err != nil {
seelog.Warnf("Task not found for container ID: %s", dockerID)
} else {
// send network stats for default/bridge/nat/awsvpc network modes
if !task.IsNetworkModeAWSVPC() && container.containerMetadata.NetworkMode != hostNetworkMode &&
container.containerMetadata.NetworkMode != noneNetworkMode {
networkStatsSet, err := container.statsQueue.GetNetworkStatsSet()
if err != nil {
// we log the error and still continue to publish cpu, memory stats
seelog.Warnf("Error getting network stats: %v, container: %v", err, dockerID)
} else {
containerMetric.NetworkStatsSet = networkStatsSet
}
} else if task.IsNetworkModeAWSVPC() {
taskStatsMap, taskExistsInTaskStats := engine.taskToTaskStats[taskArn]
if !taskExistsInTaskStats {
return nil, fmt.Errorf("task not found")
}
if dockerContainer, err := engine.resolver.ResolveContainer(dockerID); err != nil {
seelog.Debugf("Could not map container ID to container, container: %s, err: %s", dockerID, err)
} else {
// do not add network stats for pause container
if dockerContainer.Container.Type != apicontainer.ContainerCNIPause {
networkStats, err := taskStatsMap.StatsQueue.GetNetworkStatsSet()
if err != nil {
seelog.Warnf("error getting network stats: %v, task: %v", err, taskArn)
} else {
containerMetric.NetworkStatsSet = networkStats
}
}
}
}
}
containerMetrics = append(containerMetrics, containerMetric)
}
return containerMetrics, nil
}