|
42 | 42 | import java.util.List; |
43 | 43 | import java.util.Locale; |
44 | 44 | import java.util.Map; |
| 45 | +import java.util.Optional; |
45 | 46 | import java.util.Set; |
46 | 47 | import java.util.concurrent.Semaphore; |
47 | 48 | import java.util.concurrent.TimeUnit; |
|
52 | 53 | import static org.elasticsearch.health.HealthStatus.RED; |
53 | 54 |
|
54 | 55 | /** |
55 | | - * This class periodically logs the results of the Health API to the standard Elasticsearch server log file. It a lifecycle |
56 | | - * aware component because it health depends on other lifecycle aware components. This means: |
| 56 | + * This class periodically logs the results of the Health API to the standard Elasticsearch server log file. It is a lifecycle |
| 57 | + * aware component because it depends on other lifecycle aware components. This means: |
57 | 58 | * - We do not schedule any jobs until the lifecycle state is STARTED |
58 | | - * - When the lifecycle state becomes STOPPED, do not schedule any more runs, but we do let the current one finish |
| 59 | + * - When the lifecycle state becomes STOPPED, we do not schedule any more runs, but we do let the current one finish |
59 | 60 | * - When the lifecycle state becomes CLOSED, we will interrupt the current run as well. |
60 | 61 | */ |
61 | 62 | public class HealthPeriodicLogger extends AbstractLifecycleComponent implements ClusterStateListener, SchedulerEngine.Listener { |
62 | 63 | public static final String HEALTH_FIELD_PREFIX = "elasticsearch.health"; |
63 | 64 | public static final String MESSAGE_FIELD = "message"; |
64 | 65 |
|
| 66 | + // duplicated from SlmHealthIndicatorService since x-pack not accessible |
| 67 | + private static final String SLM_HEALTH_INDICATOR_SERVICE_NAME = "slm"; |
| 68 | + private static final String SLM_HEALTH_INDICATOR_SERVICE_IMPACT_ID_MISSING_SNAPSHOT = "missing_snapshot"; |
| 69 | + |
65 | 70 | /** |
66 | 71 | * Valid modes of output for this logger |
67 | 72 | */ |
@@ -361,11 +366,25 @@ static Map<String, Object> convertToLoggedFields(List<HealthIndicatorResult> ind |
361 | 366 | String.format(Locale.ROOT, "%s.%s.status", HEALTH_FIELD_PREFIX, indicatorResult.name()), |
362 | 367 | indicatorResult.status().xContentValue() |
363 | 368 | ); |
364 | | - if (GREEN.equals(indicatorResult.status()) == false && indicatorResult.details() != null) { |
365 | | - result.put( |
366 | | - String.format(Locale.ROOT, "%s.%s.details", HEALTH_FIELD_PREFIX, indicatorResult.name()), |
367 | | - Strings.toString(indicatorResult.details()) |
368 | | - ); |
| 369 | + if (GREEN.equals(indicatorResult.status()) == false) { |
| 370 | + if (indicatorResult.details() != null) { |
| 371 | + result.put( |
| 372 | + String.format(Locale.ROOT, "%s.%s.details", HEALTH_FIELD_PREFIX, indicatorResult.name()), |
| 373 | + Strings.toString(indicatorResult.details()) |
| 374 | + ); |
| 375 | + } |
| 376 | + |
| 377 | + // output the SLM health indicator missing snapshot impact, so it can be specifically identified when occur |
| 378 | + if (SLM_HEALTH_INDICATOR_SERVICE_NAME.equals(indicatorResult.name())) { |
| 379 | + Optional<HealthIndicatorImpact> impactMissingSnapshot = indicatorResult.impacts() |
| 380 | + .stream() |
| 381 | + .filter(impact -> SLM_HEALTH_INDICATOR_SERVICE_IMPACT_ID_MISSING_SNAPSHOT.equals(impact.id())) |
| 382 | + .findFirst(); |
| 383 | + impactMissingSnapshot.ifPresent(impact -> result.put( |
| 384 | + String.format(Locale.ROOT, "%s.%s.%s", HEALTH_FIELD_PREFIX, indicatorResult.name(), impact.id()), |
| 385 | + true |
| 386 | + )); |
| 387 | + } |
369 | 388 | } |
370 | 389 | }); |
371 | 390 |
|
|
0 commit comments