View Javadoc
1   /*
2    * Copyright 2012-2025 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.codelibs.fess.timer;
17  
18  import org.apache.logging.log4j.LogManager;
19  import org.apache.logging.log4j.Logger;
20  import org.codelibs.core.timer.TimeoutTarget;
21  import org.codelibs.fess.helper.SystemHelper;
22  import org.codelibs.fess.opensearch.client.SearchEngineClient;
23  import org.codelibs.fess.util.ComponentUtil;
24  import org.opensearch.action.admin.cluster.node.stats.NodeStats;
25  import org.opensearch.action.admin.cluster.node.stats.NodesStatsResponse;
26  import org.opensearch.monitor.os.OsStats;
27  
28  /**
29   * Timeout target that periodically monitors search engine CPU usage.
30   */
31  public class LoadControlMonitorTarget implements TimeoutTarget {
32  
33      private static final Logger logger = LogManager.getLogger(LoadControlMonitorTarget.class);
34  
35      private final SystemHelper systemHelper;
36  
37      private int consecutiveFailures = 0;
38  
39      /**
40       * Constructs a new load control monitor target.
41       *
42       * @param systemHelper the system helper to update with CPU usage
43       */
44      public LoadControlMonitorTarget(final SystemHelper systemHelper) {
45          this.systemHelper = systemHelper;
46      }
47  
48      @Override
49      public void expired() {
50          try {
51              final SearchEngineClient client = ComponentUtil.getSearchEngineClient();
52              final NodesStatsResponse response = client.admin().cluster().prepareNodesStats().addMetric("os").execute().actionGet(10000L);
53  
54              short maxCpu = 0;
55              for (final NodeStats nodeStats : response.getNodes()) {
56                  final OsStats os = nodeStats.getOs();
57                  if (os != null && os.getCpu() != null) {
58                      final short percent = os.getCpu().getPercent();
59                      if (percent > maxCpu) {
60                          maxCpu = percent;
61                      }
62                  }
63              }
64              systemHelper.setSearchEngineCpuPercent(maxCpu);
65              consecutiveFailures = 0;
66              if (logger.isDebugEnabled()) {
67                  logger.debug("Search Engine CPU: {}%", maxCpu);
68              }
69          } catch (final Exception e) {
70              systemHelper.setSearchEngineCpuPercent((short) 0);
71              consecutiveFailures++;
72              if (consecutiveFailures <= 3) {
73                  logger.warn("Failed to get search engine CPU stats: {}", e.getMessage(), e);
74              } else if (logger.isDebugEnabled()) {
75                  logger.debug("Failed to get search engine CPU stats: {}", e.getMessage(), e);
76              }
77          }
78      }
79  }