private int runMonitor(String[] monitorTargets) throws Exception {
    ChoreService choreService = null;

    // Launches chore for refreshing kerberos credentials if security is enabled.
    // Please see http://hbase.apache.org/book.html#_running_canary_in_a_kerberos_enabled_cluster
    // for more details.
    final ScheduledChore authChore = AuthUtil.getAuthChore(conf);
    if (authChore != null) {
      choreService = new ChoreService("CANARY_TOOL");
      choreService.scheduleChore(authChore);
    }

    // Start to prepare the stuffs
    Monitor monitor = null;
    Thread monitorThread;
    long startTime = 0;
    long currentTimeLength = 0;
    boolean failOnError = conf.getBoolean(HBASE_CANARY_FAIL_ON_ERROR, true);
    long timeout = conf.getLong(HBASE_CANARY_TIMEOUT, DEFAULT_TIMEOUT);
    // Get a connection to use in below.
    try (Connection connection = ConnectionFactory.createConnection(this.conf)) {
      do {
        // Do monitor !!
        try {
          monitor = this.newMonitor(connection, monitorTargets);
          startTime = EnvironmentEdgeManager.currentTime();
          monitorThread = new Thread(monitor, "CanaryMonitor-" + startTime);
          monitorThread.start();
          while (!monitor.isDone()) {
            // wait for 1 sec
            Thread.sleep(1000);
            // exit if any error occurs
            if (failOnError && monitor.hasError()) {
              monitorThread.interrupt();
              if (monitor.initialized) {
                return monitor.errorCode;
              } else {
                return INIT_ERROR_EXIT_CODE;
              }
            }
            currentTimeLength = EnvironmentEdgeManager.currentTime() - startTime;
            if (currentTimeLength > timeout) {
              LOG.error("The monitor is running too long (" + currentTimeLength
                + ") after timeout limit:" + timeout + " will be killed itself !!");
              monitorThread.interrupt();
              if (monitor.initialized) {
                return TIMEOUT_ERROR_EXIT_CODE;
              } else {
                return INIT_ERROR_EXIT_CODE;
              }
            }
          }

          if (failOnError && monitor.finalCheckForErrors()) {
            monitorThread.interrupt();
            return monitor.errorCode;
          }
        } finally {
          if (monitor != null) {
            monitor.close();
          }
        }

        Thread.sleep(interval);
      } while (interval > 0);
    } // try-with-resources close

    if (choreService != null) {
      choreService.shutdown();
    }
    return monitor.errorCode;
  }
This is a Map of table to timeout. The timeout is for reading all regions in the table; i.e. we
aggregate time to fetch each region and it needs to be less than this value else we log an
ERROR.
hbase-server/src/main/java/org/apache/hadoop/hbase/tool/CanaryTool.java