[[rule]]
id = 7
name = "tikv-log-level"
description = "日志等级。可选值：\"trace\"，\"debug\"，\"info\"，\"warning\"，\"error\"，\"critical\"。默认值：\"info\""
variation =  "TikvConfig.log-level"
check_type = "config"
execute_rule = """
rule "tikv-log-level" "log level of tikv"  salience 6
begin
    if ToString(TikvConfig.GetValueByTagPath("log-level")) == "debug" || ToString(TikvConfig.GetValueByTagPath("log-level")) == "trace" {
        return false
    } else {
        return true
    }
end
"""
name_struct = "TikvConfig"
expect_res = ""   #
warn_level = "info"
version = ""

# todo check if TiFlash exist
[[rule]]
id = 8
name = "gc.enable-compaction-filter"
description = "是否开启 GC in Compaction Filter 特性"
variation =  "TikvConfig.gc.enable-compaction-filter"
check_type = "config"
execute_rule = """
rule "gc.enable-compaction-filter"
begin
    if ToBool(TikvConfig.GetValueByTagPath("gc.enable-compaction-filter")) == true && TikvConfig.Extra.TiFlashCnt > 0 {
        return false
    } else {
        return true
    }
end
"""
name_struct = "TikvConfig"
expect_res = ""   #
warn_level = "warning"
version = "v5.0.0||v5.0.1"

[[rule]]
id = 100
name = "tidb-max-days"
description = "日志保留的最长天数"
variation =  "TidbConfig.log.file.max-days"
check_type = "config"
execute_rule = """
rule "tidb-max-days"
begin
    if ToInt(TidbConfig.GetValueByTagPath("log.file.max-days")) < 1 {
        return false
    } else {
        return true
    }
end
"""
name_struct = "TidbConfig"
expect_res = ""   #
warn_level = "warning"
version = ""

[[rule]]
id = 101
name = "tidb-max-backups"
description = "日志文件保留的最大个数"
variation = "TidbConfig.log.file.max-backups"
check_type = "config"
execute_rule = """
rule "tidb-max-backups"
begin
    if ToInt(TidbConfig.GetValueByTagPath("log.file.max-backups")) < 1 {
        return false
    } else {
        return true
    }
end
"""
name_struct = "TidbConfig"
expect_res = ""   #
warn_level = "warning"
version = ""

[[rule]]
id = 102
name = "tidb-log-level"
description = "日志等级。可选值：\"trace\"，\"debug\"，\"info\"，\"warning\"，\"error\"，\"critical\"。默认值：\"info\""
variation = "TidbConfig.log.level"
check_type = "config"
execute_rule = """
rule "tidb-log-level"
begin
    if ToString(TidbConfig.GetValueByTagPath("log.level")) == "debug" {
        return false
    } else {
        return true
    }
end
"""
name_struct = "TidbConfig"
expect_res = ""   #
warn_level = "info"
version = ""

[[rule]]
id = 103
name = "tidb-enable-streaming"
description = "3.0.20, 4.0.9, 5.2.0 已废弃"
variation = "TidbConfig.enable-streaming"
check_type = "config"
execute_rule = """
rule "tidb-enable-streaming"
begin
    if ToBool(TidbConfig.GetValueByTagPath("enable-streaming")) == true {
        return false
    } else {
        return true
    }
end
"""
name_struct = "TidbConfig"
expect_res = ""   #
warn_level = "info"
version = ""

[[rule]]
id = 200
name = "pdconfig-max-snapshot-count"
description = "控制单个 store 最多同时接收或发送的 snapshot 数量，调度受制于这个配置来防止抢占正常业务的资源。"
variation = "PdConfig.schedule.max-snapshot-count"
check_type = "config"
execute_rule = """
rule "pdconfig-max-snapshot-count"
begin
    if ToInt(PdConfig.GetValueByTagPath("schedule.max-snapshot-count")) <= 0 {
        return false
    } else {
        return true
    }
end
"""
name_struct = "PdConfig"
expect_res = ""   #
warn_level = "info"
version = "> v4.0.0"

[[rule]]
id = 201
name = "pdconfig-max-pending-peer-count"
description = "控制单个 store 的 pending peer 上限，调度受制于这个配置来防止在部分节点产生大量日志落后的 Region。"
variation = "PdConfig.schedule.max-pending-peer-count"
check_type = "config"
execute_rule = """
rule "pdconfig-max-pending-peer-count"
begin
    if ToInt(PdConfig.GetValueByTagPath("schedule.max-pending-peer-count")) <= 0 {
        return false
    } else {
        return true
    }
end
"""
name_struct = "PdConfig"
expect_res = ""   #
warn_level = "info"
version = "> v4.0.0"

[[rule]]
id = 202
name = "pdconfig-leader-schedule-limit"
description = "同时进行 leader 调度的任务个数。"
variation = "PdConfig.schedule.leader-schedule-limit"
check_type = "config"
execute_rule = """
rule "pdconfig-leader-schedule-limit"
begin
    if ToInt(PdConfig.GetValueByTagPath("schedule.leader-schedule-limit")) <= 0 {
        return false
    } else {
        return true
    }
end
"""
name_struct = "PdConfig"
expect_res = ""   #
warn_level = "info"
version = "> v4.0.0"

[[rule]]
id = 203
name = "pdconfig-replica-schedule-limit-a"
description = "同时进行 replica 调度的任务个数。"
variation =  "PdConfig.schedule.replica-schedule-limit"
check_type = "config"
execute_rule = """
rule "pdconfig-replica-schedule-limit-a"
begin
    if ToInt(PdConfig.GetValueByTagPath("schedule.replica-schedule-limit")) <= 0
       || ToInt(PdConfig.GetValueByTagPath("schedule.replica-schedule-limit")) > 64 {
        return false
    } else {
        return true
    }
end
"""
name_struct = "PdConfig"
expect_res = ""   #
warn_level = "info"
version = "> v4.0.0"

[[rule]]
id = 204
name = "pdconfig-merge-schedule-limit"
description = "同时进行的 Region Merge 调度的任务，设置为 0 则关闭 Region Merge。"
variation = "PdConfig.schedule.merge-schedule-limit"
check_type = "config"
execute_rule = """
rule "pdconfig-merge-schedule-limit"
begin
    if ToInt(PdConfig.GetValueByTagPath("schedule.merge-schedule-limit")) <= 0
       || ToInt(PdConfig.GetValueByTagPath("schedule.merge-schedule-limit")) > 16 {
        return false
    } else {
        return true
    }
end
"""
name_struct = "PdConfig"
expect_res = ""   #
warn_level = "info"
version = "> v4.0.0"

[[rule]]
id = 205
name = "pdconfig-hot-region-schedule-limit"
description = "控制同时进行的 hot Region 任务。该配置项独立于 Region 调度。"
variation = "PdConfig.schedule.hot-region-schedule-limit"
check_type = "config"
execute_rule = """
rule "pdconfig-hot-region-schedule-limit"
begin
    if ToInt(PdConfig.GetValueByTagPath("schedule.hot-region-schedule-limit")) <= 0
       || ToInt(PdConfig.GetValueByTagPath("schedule.hot-region-schedule-limit")) > 8 {
        return false
    } else {
        return true
    }
end
"""
name_struct = "PdConfig"
expect_res = ""   #
warn_level = "info"
version = "> v4.0.0"

# todo add store limit rule

[[rule]]
id = 206
name = "pdconfig-store limit-n-add-peer"
description = "Store Limit 限制的主要是 operator 的消费速度，{n} 指 store id，这里对所有 store limit 都有同样的限制。"
variation = "PdConfig.schedule.store-limit"
check_type = "config"
execute_rule = """
rule "pdconfig-store limit-n-add-peer"
begin
    if ElemInRange(FlatMap(PdConfig.GetValueByTagPath("schedule.store-limit"),"add-peer"),0, 100) {
        return true
    }else {
        return false
    }
end
"""
name_struct = "PdConfig"
expect_res = ""   #
warn_level = "info"
version = "> v4.0.0"

[[rule]]
id = 206
name = "pdconfig-store limit-n-remove-peer"
description = "Store Limit 限制的主要是 operator 的消费速度，{n} 指 store id，这里对所有 store limit 都有同样的限制。"
variation = "PdConfig.schedule.store-limit"
check_type = "config"
execute_rule = """
rule "pdconfig-store limit-n-remove-peer"
begin
    if ElemInRange(FlatMap(PdConfig.GetValueByTagPath("schedule.store-limit"),"remove-peer"),0, 100) {
        return true
    }else {
        return false
    }
end
"""
name_struct = "PdConfig"
expect_res = ""   #
warn_level = "info"
version = "> v4.0.0"

[[rule]]
id = 208
name = "pdconfig-replica-schedule-limit-b"
description = "用来控制 replica 相关 operator 的产生速度（涉及到下线、补副本的操作都与该参数有关）。"
variation = "PdConfig.schedule.replica-schedule-limit,PdConfig.schedule.region-schedule-limit"
check_type = "config"
execute_rule = """
rule "pdconfig-replica-schedule-limit-b"
begin
    if ToInt(PdConfig.GetValueByTagPath("schedule.replica-schedule-limit"))
        > ToInt(PdConfig.GetValueByTagPath("schedule.region-schedule-limit")) {
        return false
    } else {
        return true
    }
end
"""
name_struct = "PdConfig"
expect_res = ""   #
warn_level = "warning"
version = "> v4.0.0"

[[rule]]
id = 209
name = "pdconfig-max-days"
description = "日志保留的最长天数。"
variation = "PdConfig.log.file.max-days"
check_type = "config"
execute_rule = """
rule "pdconfig-max-days"
begin
    if ToInt(PdConfig.GetValueByTagPath("log.file.max-days")) <= 0 {
        return false
    } else {
        return true
    }
end
"""
name_struct = "PdConfig"
expect_res = ""   #
warn_level = "warning"
version = "> v4.0.0"

[[rule]]
id = 210
name = "pdconfig-max-backups"
description = "日志文件保留的最大个数。"
variation = "PdConfig.log.file.max-backups"
check_type = "config"
execute_rule = """
rule "pdconfig-max-backups"
begin
    if ToInt(PdConfig.GetValueByTagPath("log.file.max-backups")) <= 0 {
        return false
    } else {
        return true
    }
end
"""
name_struct = "PdConfig"
expect_res = ""   #
warn_level = "warning"
version = "> v4.0.0"

[[rule]]
id = 211
name = "pdconfig-log-level"
description = "Log 级别。默认：\"info\" 我们能选择 debug, info, warn, error 或者 fatal。"
variation = "PdConfig.log.level"
check_type = "config"
execute_rule = """
rule "pdconfig-log-level"
begin
    if ToString(PdConfig.GetValueByTagPath("log.level")) == "debug" {
        return false
    } else {
        return true
    }
end
"""
name_struct = "PdConfig"
expect_res = ""   #
warn_level = "info"
version = "> v4.0.0"

[[rule]]
id = 300
name = "poor_effective_plan"
description = "执行计划选择了错误的索引"
variation = "plan_process_time"
check_type = "performance"
execute_rule = """
rule "poor_effective_plan"
begin
    count := 0
    forRange digest := dashboard.ExecutionPlanInfoList {
        ei = dashboard.ExecutionPlanInfoList[digest]
        maxExecutionInfo = dashboard.ExecutionPlanInfoList[0]
        minExecutionInfo = dashboard.ExecutionPlanInfoList[1]
        if !isNil(maxExecutionInfo)
            && !isNil(minExecutionInfo)
            && maxExecutionInfo.AvgProcessTime > 50 * minExecutionInfo.AvgProcessTime
            && maxExecutionInfo.MaxLastTime > minExecutionInfo.MaxLastTime {
            count = count + 1
        }
    }
    return count
end
"""
name_struct = "performance.dashboard"
expect_res = ""   #
warn_level = "warning"
version = "> v4.0.0"

[[rule]]
id = 301
name = "old_version_count"
description = ""
variation = "total_key,process_key"
check_type = "performance"
execute_rule = """
rule "old_version_count"
begin
    if dashboard.OldVersionProcesskey.Count > 0 && dashboard.OldVersionProcesskey.GcLifeTime > 10 * 60 {
        return false
    }
    return true
end
"""
name_struct = "performance.dashboard"
expect_res = ""   #
warn_level = "warning"
version = "> v4.0.0"

[[rule]]
id = 302
name = "scan_key_skip"  # todo check
description = ""
variation = "rocksdb_delete_skipped_count,process_keys"
check_type = "performance"
execute_rule = """
rule "scan_key_skip"
begin
    if dashboard.TombStoneStatistics.Count > 0 {
        return false
    }
    return true
end
"""
name_struct = "performance.dashboard"
expect_res = ""   #
warn_level = "info"
version = "> v4.0.0"

[[rule]]
id = 104
name = "new_collations_enabled_on_first_bootstrap"
description = "用于开启新的 collation 支持。"
variation =  "TidbConfig.new_collations_enabled_on_first_bootstrap"
execute_rule = """
rule "new_collations_enabled_on_first_bootstrap"
begin
    if ToBool(TidbConfig.GetValueByTagPath("new_collations_enabled_on_first_bootstrap")) == true {
        return false
    } else {
        return true
    }
end
"""
name_struct = "TidbConfig"
check_type = "config"
expect_res = ""   #
warn_level = "warning"
version = ""

[[rule]]
id = 105
name = "feedback-probability"
description = "TiDB 对查询收集统计信息反馈的概率,此功能默认关闭，暂不建议开启。如果开启此功能，对于每一个查询，TiDB 会以 feedback-probability 的概率收集查询的反馈，用于更新统计信息。"
variation =  "TidbConfig.performance.feedback-probability"
execute_rule = """
rule "feedback-probability"
begin
    if ToInt(TidbConfig.GetValueByTagPath("performance.feedback-probability")) != 0 {
        return false
    } else {
        return true
    }
end
"""
name_struct = "TidbConfig"
check_type = "config"
expect_res = "https://kb.pingcap.com/shared/v1/YtEKeySXI7-X14dKsMe1SZfq1F79w0lL3qlyZlVyZeGFh4pOYJkmS1hCzHtrfs9_MN39bCLf_GDiJQRHBPGWAKo_Kj_CPu3NPJG1yik2DIg"   #
warn_level = "warning"
version = ""

[[rule]]
id = 212
name = "flow-round-by-digit"
description = "PD 会对流量信息的末尾数字进行四舍五入处理，减少 Region 流量信息变化引起的统计信息更新。"
variation =  "PdConfig.pd-server.flow-round-by-digit"
execute_rule = """
rule "flow-round-by-digit"
begin
    if ToInt(PdConfig.GetValueByTagPath("pd-server.flow-round-by-digit")) == 127 {
        return false
    } else {
        return true
    }
end
"""
name_struct = "PdConfig"
check_type = "config"
expect_res = ""   #
warn_level = "info"
version = ">= v5.1.0"

[[rule]]
id = 213
name = "trace-region-flow"
description = "在5.1版本开始该配置被 flow-round-by-digit 替换。"
variation =  "PdConfig.pd-server.trace-region-flow"
execute_rule = """
rule "trace-region-flow"
begin
    if ToBool(PdConfig.GetValueByTagPath("pd-server.trace-region-flow")) == false {
        return false
    } else {
        return true
    }
end
"""
name_struct = "PdConfig"
check_type = "config"
expect_res = ""   #
warn_level = "info"
version = ">= v4.0.0,<= v4.0.15"

[[rule]]
id = 214
name = "strictly-match-label"
description = "打开强制 TiKV Label 和 PD 的 location-labels 是否匹配的检查。"
variation =  "PdConfig.replication.strictly-match-label"
execute_rule = """
rule "strictly-match-label"
begin
    if ToBool(PdConfig.GetValueByTagPath("replication.strictly-match-label")) == true {
        return false
    } else {
        return true
    }
end
"""
name_struct = "PdConfig"
check_type = "config"
expect_res = ""   #
warn_level = "warning"
version = ""

[[rule]]
id = 215
name = "max-replicas"
description = "打开强制 TiKV Label 和 PD 的 location-labels 是否匹配的检查。"
variation =  "PdConfig.replication.max-replicas"
execute_rule = """
rule "max-replicas"
begin
    if ToInt(PdConfig.GetValueByTagPath("replication.max-replicas")) < 3 {
        return false
    } else {
        return true
    }
end
"""
name_struct = "PdConfig"
check_type = "config"
expect_res = ""   #
warn_level = "warning"
version = ""

#[[rule]]
#id = 2333
#name = "tidb-max-backups"
#description = "日志文件保留的最大个数"
#variation = "TidbConfig.log.file.max-backups,TikvConfig.log-level"
#check_type = "config"
#execute_rule = """
#rule "tidb-max-backups"
#begin
#    if ToInt(TidbConfig.GetValueByTagPath("log.file.max-backups")) < 1 && ToString(TikvConfig.GetValueByTagPath("log-level")) == "debug" {
#        return false
#    } else {
#        return true
#    }
#end
#"""
#name_struct = "TidbConfig,TikvConfig"
#expect_res = ""   #
#warn_level = "warning"
#version = ""