private static void doActionWhenDetectKeywords(
      AbstractNodeWrapper nodeWrapper,
      KeySetView<String, Boolean> keywords,
      Consumer<KillPointContext> action) {
    if (keywords.isEmpty()) {
      return;
    }
    final String logFileName;
    if (nodeWrapper instanceof ConfigNodeWrapper) {
      logFileName = "log_confignode_all.log";
    } else {
      logFileName = "log_datanode_all.log";
    }
    SystemType type = SystemType.getSystemType();
    ProcessBuilder builder;
    if (type == SystemType.LINUX || type == SystemType.MAC) {
      builder =
          new ProcessBuilder(
              "tail",
              "-f",
              nodeWrapper.getNodePath() + File.separator + "logs" + File.separator + logFileName);
    } else if (type == SystemType.WINDOWS) {
      builder =
          new ProcessBuilder(
              "powershell",
              "-Command",
              "Get-Content "
                  + nodeWrapper.getNodePath()
                  + File.separator
                  + "logs"
                  + File.separator
                  + logFileName
                  + " -Wait");
    } else {
      throw new UnsupportedOperationException("Unsupported system type " + type);
    }
    builder.redirectErrorStream(true);

    try {
      Process process = builder.start();
      try (BufferedReader reader =
          new BufferedReader(new InputStreamReader(process.getInputStream()))) {
        String line;
        while ((line = reader.readLine()) != null) {
          // if trigger more than one keyword at a same time, test code may have mistakes
          Assert.assertTrue(
              line,
              keywords.stream().map(KillPoint::addKillPointPrefix).filter(line::contains).count()
                  <= 1);
          String finalLine = line;
          Optional<String> detectedKeyword =
              keywords.stream()
                  .filter(keyword -> finalLine.contains(KillPoint.addKillPointPrefix(keyword)))
                  .findAny();
          if (detectedKeyword.isPresent()) {
            // each keyword only trigger once
            keywords.remove(detectedKeyword.get());
            action.accept(new KillPointContext(nodeWrapper, (AbstractEnv) EnvFactory.getEnv()));
            LOGGER.info("Kill point triggered: {}", detectedKeyword.get());
          }
          if (keywords.isEmpty()) {
            break;
          }
        }
      } catch (AssertionError e) {
        LOGGER.error("gg", e);
        throw e;
      }
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
Monitor the node's log and kill it when detect specific log.

@param nodeWrapper Easy to understand
@param keywords When detect these keywords in node's log, stop the node forcibly
integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java