During the development and review process of the disk health indicator we noticed that it was hard to understand. Since we learnt a lot from the first round of development we want to go through the code one more time and restructure it.
server/src/main/java/org/elasticsearch/health/node/DiskHealthIndicatorService.java
("the cluster was running out of disk space. The cluster is recovering and ingest capabilities should be restored "
                        + "within a few minutes.");
            } else {
                symptom += String.format(
                    Locale.ROOT,
                    "%d %s out of disk or running low on disk space.",
                    unhealthyDataNodes.size(),
                    unhealthyDataNodes.size() == 1 ? "node is" : "nodes are"
                );
            }
            if (unhealthyDataNodes.size() < allUnhealthyNodes.size()) {
                Set<String> unhealthyNonDataNodes = Sets.difference(allUnhealthyNodes, unhealthyDataNodes);
                String roles = getRolesOnNodes(unhealthyNonDataNodes, clusterState).stream()
                    .map(DiscoveryNodeRole::roleName)
                    .distinct()
                    .sorted()
                    .collect(Collectors.joining(", "));
                symptom += String.format(
                    Locale.ROOT,
                    " Furthermore %d node%s with roles: [%s] %s out of disk or running low on disk space.",
                    unhealthyNonDataNodes.size(),
                    unhealthyNonDataNodes.size() == 1 ? "" : "s",
                    roles,
                    unhealthyNonDataNodes.size() == 1 ? "is" : "are"
                );
            }
        } else {
            String roles = getRolesOnNodes(allUnhealthyNodes, clusterState).stream()
                .map(DiscoveryNodeRole::roleName)
                .distinct()