mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-27 00:04:59 +03:00
feat(notifications): add a failed-check threshold for node.down alerts (#6768)
One lost heartbeat on a lossy link flipped a node offline and sent node.down, and the next probe sent node.up, so a flaky node flooded Telegram, email and Discord with alert pairs. A new nodeDownThreshold setting (default 1, today's behaviour) works like outboundDownThreshold: node.down fires once the failed-check streak reaches it, once per outage, and node.up only after a node.down was sent. The announcement is persisted in nodes.down_notified, so a restart inside the threshold window neither drops the outage's node.down nor re-announces nodes already reported offline; nodes offline at upgrade are seeded as announced.
This commit is contained in:
@@ -39,6 +39,7 @@ export const EXAMPLES: Record<string, unknown> = {
|
||||
"ldapUserAttr": "",
|
||||
"ldapUserFilter": "",
|
||||
"ldapVlessField": "",
|
||||
"nodeDownThreshold": 1,
|
||||
"outboundDownThreshold": 1,
|
||||
"pageSize": 0,
|
||||
"panelOutbound": "",
|
||||
@@ -227,6 +228,7 @@ export const EXAMPLES: Record<string, unknown> = {
|
||||
"ldapUserAttr": "",
|
||||
"ldapUserFilter": "",
|
||||
"ldapVlessField": "",
|
||||
"nodeDownThreshold": 1,
|
||||
"outboundDownThreshold": 1,
|
||||
"pageSize": 0,
|
||||
"panelOutbound": "",
|
||||
|
||||
@@ -126,6 +126,11 @@ export const SCHEMAS: Record<string, unknown> = {
|
||||
"ldapVlessField": {
|
||||
"type": "string"
|
||||
},
|
||||
"nodeDownThreshold": {
|
||||
"maximum": 100,
|
||||
"minimum": 1,
|
||||
"type": "integer"
|
||||
},
|
||||
"outboundDownThreshold": {
|
||||
"maximum": 100,
|
||||
"minimum": 1,
|
||||
@@ -613,6 +618,7 @@ export const SCHEMAS: Record<string, unknown> = {
|
||||
"ldapUserAttr",
|
||||
"ldapUserFilter",
|
||||
"ldapVlessField",
|
||||
"nodeDownThreshold",
|
||||
"outboundDownThreshold",
|
||||
"pageSize",
|
||||
"panelOutbound",
|
||||
@@ -906,6 +912,11 @@ export const SCHEMAS: Record<string, unknown> = {
|
||||
"ldapVlessField": {
|
||||
"type": "string"
|
||||
},
|
||||
"nodeDownThreshold": {
|
||||
"maximum": 100,
|
||||
"minimum": 1,
|
||||
"type": "integer"
|
||||
},
|
||||
"outboundDownThreshold": {
|
||||
"maximum": 100,
|
||||
"minimum": 1,
|
||||
@@ -1401,6 +1412,7 @@ export const SCHEMAS: Record<string, unknown> = {
|
||||
"ldapUserAttr",
|
||||
"ldapUserFilter",
|
||||
"ldapVlessField",
|
||||
"nodeDownThreshold",
|
||||
"outboundDownThreshold",
|
||||
"pageSize",
|
||||
"panelOutbound",
|
||||
|
||||
@@ -47,6 +47,7 @@ export interface AllSetting {
|
||||
ldapUserAttr: string;
|
||||
ldapUserFilter: string;
|
||||
ldapVlessField: string;
|
||||
nodeDownThreshold: number;
|
||||
outboundDownThreshold: number;
|
||||
pageSize: number;
|
||||
panelOutbound: string;
|
||||
@@ -236,6 +237,7 @@ export interface AllSettingView {
|
||||
ldapUserAttr: string;
|
||||
ldapUserFilter: string;
|
||||
ldapVlessField: string;
|
||||
nodeDownThreshold: number;
|
||||
outboundDownThreshold: number;
|
||||
pageSize: number;
|
||||
panelOutbound: string;
|
||||
|
||||
@@ -63,6 +63,7 @@ export const AllSettingSchema = z.object({
|
||||
ldapUserAttr: z.string(),
|
||||
ldapUserFilter: z.string(),
|
||||
ldapVlessField: z.string(),
|
||||
nodeDownThreshold: z.number().int().min(1).max(100),
|
||||
outboundDownThreshold: z.number().int().min(1).max(100),
|
||||
pageSize: z.number().int().min(0).max(1000),
|
||||
panelOutbound: z.string(),
|
||||
@@ -253,6 +254,7 @@ export const AllSettingViewSchema = z.object({
|
||||
ldapUserAttr: z.string(),
|
||||
ldapUserFilter: z.string(),
|
||||
ldapVlessField: z.string(),
|
||||
nodeDownThreshold: z.number().int().min(1).max(100),
|
||||
outboundDownThreshold: z.number().int().min(1).max(100),
|
||||
pageSize: z.number().int().min(0).max(1000),
|
||||
panelOutbound: z.string(),
|
||||
|
||||
Reference in New Issue
Block a user