diff --git a/src/gausskernel/dbmind/tools/app/timed_app.py b/src/gausskernel/dbmind/tools/app/timed_app.py index 8945cd969..31e6790f9 100644 --- a/src/gausskernel/dbmind/tools/app/timed_app.py +++ b/src/gausskernel/dbmind/tools/app/timed_app.py @@ -20,78 +20,90 @@ from dbmind.common.dispatcher import timer from dbmind.service import dai from dbmind.common import utils +# Read the metric value range configuration from a simple config file metric_value_range_map = utils.read_simple_config_file(constants.METRIC_VALUE_RANGE_CONFIG) -detection_interval = global_vars.configs.getint( - 'SELF-MONITORING', 'detection_interval' -) +# Get the detection interval from the global configuration +detection_interval = global_vars.configs.getint('SELF-MONITORING', 'detection_interval') -last_detection_minutes = global_vars.configs.getint( - 'SELF-MONITORING', 'last_detection_time' -) / 60 +# Get the last detection time in minutes from the global configuration +last_detection_minutes = global_vars.configs.getint('SELF-MONITORING', 'last_detection_time') / 60 -how_long_to_forecast_minutes = global_vars.configs.getint( - 'SELF-MONITORING', 'forecasting_future_time' -) / 60 +# Get the time to forecast into the future in minutes from the global configuration +how_long_to_forecast_minutes = global_vars.configs.getint('SELF-MONITORING', 'forecasting_future_time') / 60 -"""The Four Golden Signals: +""" +The Four Golden Signals: https://sre.google/sre-book/monitoring-distributed-systems/#xref_monitoring_golden-signals """ -golden_kpi = list(map( - str.strip, - global_vars.configs.get( - 'SELF-MONITORING', 'golden_kpi' - ).split(',') -)) - +# Get the golden key performance indicators (KPIs) from the global configuration +golden_kpi = list(map(str.strip, global_vars.configs.get('SELF-MONITORING', 'golden_kpi').split(','))) def quickly_forecast_wrapper(sequence, forecasting_minutes): + # Call the quickly_forecast function with the given sequence and forecasting time forecast_result = quickly_forecast(sequence, forecasting_minutes) + + # Retrieve the metric value range for the sequence from the metric_value_range_map metric_value_range = metric_value_range_map.get(sequence.name) + + # Check if both metric value range and forecast result are available if metric_value_range and forecast_result: + # Split the metric value range into low and high values metric_value_range = metric_value_range.split(",") try: + # Convert the low and high values to floats metric_value_low = float(metric_value_range[0]) metric_value_high = float(metric_value_range[1]) except ValueError as ex: - logging.warning("quickly_forecast_wrapper value error:%s," - " so forecast_result will not be cliped." % ex) + # Log a warning if there is a value error and return the forecast result without clipping + logging.warning("quickly_forecast_wrapper value error:%s, so forecast_result will not be clipped." % ex) return forecast_result - + + # Get the forecast values as a list f_values = list(forecast_result.values) + + # Iterate over the forecast values and clip them to the metric value range if necessary for i in range(len(f_values)): if f_values[i] < metric_value_low: f_values[i] = metric_value_low if f_values[i] > metric_value_high: f_values[i] = metric_value_high + + # Update the forecast result values with the clipped values forecast_result.values = tuple(f_values) + + # Return the forecast result return forecast_result - - +//backend_timed_task @timer(detection_interval) def self_monitoring(): - # diagnose for slow queries + # Check if the slow query diagnosis task is in the backend timed task list if constants.SLOW_QUERY_DIAGNOSIS_NAME in global_vars.backend_timed_task: + # Retrieve all slow queries within the last detection minutes slow_query_collection = dai.get_all_slow_queries(last_detection_minutes) logging.debug('The length of slow_query_collection is %d.', len(slow_query_collection)) + + # Save the slow queries by executing the diagnose_query function in parallel dai.save_slow_queries( global_vars.worker.parallel_execute( diagnose_query, ((slow_query,) for slow_query in slow_query_collection) ) ) - @timer(how_long_to_forecast_minutes * 60) def forecast_kpi(): + # Check if the forecast task is in the backend timed task list if constants.FORECAST_NAME not in global_vars.backend_timed_task: return - - # The general training length is at least three times the forecasting length. + + # Calculate the required history length for training, considering the expansion factor expansion_factor = 5 enough_history_minutes = how_long_to_forecast_minutes * expansion_factor + + # Check if the enough_history_minutes value is valid if enough_history_minutes <= 0: logging.error( - 'The value of enough_history_minutes less than or equal to 0 ' + 'The value of enough_history_minutes is less than or equal to 0 ' 'and DBMind has ignored it.' ) return