SystemInfo parseCgroupsLine()

in apm-agent-core/src/main/java/co/elastic/apm/agent/impl/metadata/SystemInfo.java [360:414]


    SystemInfo parseCgroupsLine(String line) {
        final String[] fields = line.split(":", 3);
        if (fields.length == 3) {
            String cGroupPath = fields[2];

            // Looking whether the cgroup path part is delimited with `:`, e.g. in containerd cri
            int indexOfIdSeparator = cGroupPath.lastIndexOf(':');
            if (indexOfIdSeparator < 0) {
                indexOfIdSeparator = cGroupPath.lastIndexOf('/');
            }

            if (indexOfIdSeparator >= 0) {
                String idPart = cGroupPath.substring(indexOfIdSeparator + 1);

                // Legacy, e.g.: /system.slice/docker-<CID>.scope
                if (idPart.endsWith(".scope")) {
                    idPart = idPart.substring(0, idPart.length() - ".scope".length()).substring(idPart.lastIndexOf("-") + 1);
                }

                // Looking for kubernetes info
                String dir = cGroupPath.substring(0, indexOfIdSeparator);
                if (dir.length() > 0) {
                    final Pattern pattern = Pattern.compile(POD_REGEX);
                    final Matcher matcher = pattern.matcher(dir);
                    if (matcher.find()) {
                        for (int i = 1; i <= matcher.groupCount(); i++) {
                            String podUid = matcher.group(i);
                            if (podUid != null && !podUid.isEmpty()) {
                                // systemd cgroup driver is being used, so we need to unescape '_' back to '-'.
                                podUid = podUid.replace('_', '-');
                                logger.debug("Found Kubernetes pod UID: {}", podUid);
                                // By default, Kubernetes will set the hostname of the pod containers to the pod name. Users that override
                                // the name should use the Downward API to override the pod name or override the hostname through the hostname config.
                                kubernetes = new Kubernetes(getHostname(), null, null, podUid);
                                break;
                            }
                        }
                    }
                }

                // If the line matched the one of the kubernetes patterns, we assume that the last part is always the container ID.
                // Otherwise we validate that it is a 64-length hex string
                if (kubernetes != null ||
                    idPart.matches(CONTAINER_UID_REGEX) ||
                    idPart.matches(SHORTENED_UUID_PATTERN) ||
                    idPart.matches(AWS_FARGATE_UID_REGEX)) {
                    container = new Container(idPart);
                }
            }
        }
        if (container == null) {
            logger.debug("Could not parse container ID from line: {}", line);
        }
        return this;
    }