func parseDataMapTags()

in cloudwatch/helpers.go [84:142]


func parseDataMapTags(e *Event, logTags []string, t *fastTemplate, metadata TaskMetadata, uuid string, w io.Writer) (int64, error) {
	return t.ExecuteFunc(w, func(w io.Writer, tag string) (int, error) {
		switch tag {
		case "ecs_task_id":
			if metadata.TaskID != "" {
				return w.Write([]byte(metadata.TaskID))
			}

			return 0, fmt.Errorf("Failed to fetch ecs_task_id; The container is not running in ECS")
		case "ecs_cluster":
			if metadata.Cluster != "" {
				return w.Write([]byte(metadata.Cluster))
			}

			return 0, fmt.Errorf("Failed to fetch ecs_cluster; The container is not running in ECS")
		case "ecs_task_arn":
			if metadata.TaskARN != "" {
				return w.Write([]byte(metadata.TaskARN))
			}

			return 0, fmt.Errorf("Failed to fetch ecs_task_arn; The container is not running in ECS")
		case "uuid":
			return w.Write([]byte(uuid))
		}

		v := strings.Index(tag, "[")
		if v == -1 {
			v = len(tag)
		}

		if tag[:v] == "tag" {
			switch {
			default: // input string is either `tag` or `tag[`, so return the $tag.
				return w.Write([]byte(e.Tag))
			case len(tag) >= 5: // input string is at least "tag[x" where x is hopefully an integer 0-9.
				// The index value is always in the same position: 4:5 (this is why supporting more than 0-9 is rough)
				if v, _ = strconv.Atoi(tag[4:5]); len(logTags) <= v {
					return 0, fmt.Errorf("%s: %w", tag, ErrNoTagValue)
				}

				return w.Write([]byte(logTags[v]))
			}
		}

		switch val := e.Record[tag[:v]].(type) {
		case string:
			return w.Write([]byte(val))
		case map[interface{}]interface{}:
			i, err := parseKeysTemplate(val, tag[v:], w)

			return int(i), err
		case []byte:
			// we should never land here because the interface{} map should have already been converted to strings.
			return w.Write(val)
		default: // missing
			return 0, fmt.Errorf("%s: %w", tag, ErrMissingTagName)
		}
	})
}