mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-12-24 22:14:47 +02:00
Merge branch 'master' into feature/expand-http-payload-support
This commit is contained in:
commit
6ec6410808
10
db/patch-monitor-add-resend-interval.sql
Normal file
10
db/patch-monitor-add-resend-interval.sql
Normal file
@ -0,0 +1,10 @@
|
||||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD resend_interval INTEGER default 0 not null;
|
||||
|
||||
ALTER TABLE heartbeat
|
||||
ADD down_count INTEGER default 0 not null;
|
||||
|
||||
COMMIT;
|
@ -4,5 +4,5 @@ WORKDIR /app
|
||||
|
||||
# Install apprise, iputils for non-root ping, setpriv
|
||||
RUN apk add --no-cache iputils setpriv dumb-init python3 py3-cryptography py3-pip py3-six py3-yaml py3-click py3-markdown py3-requests py3-requests-oauthlib && \
|
||||
pip3 --no-cache-dir install apprise==0.9.9 && \
|
||||
pip3 --no-cache-dir install apprise==1.0.0 && \
|
||||
rm -rf /root/.cache
|
||||
|
@ -11,7 +11,7 @@ WORKDIR /app
|
||||
RUN apt update && \
|
||||
apt --yes --no-install-recommends install python3 python3-pip python3-cryptography python3-six python3-yaml python3-click python3-markdown python3-requests python3-requests-oauthlib \
|
||||
sqlite3 iputils-ping util-linux dumb-init && \
|
||||
pip3 --no-cache-dir install apprise==0.9.9 && \
|
||||
pip3 --no-cache-dir install apprise==1.0.0 && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
apt --yes autoremove
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "uptime-kuma",
|
||||
"version": "1.17.1",
|
||||
"version": "1.18.0-beta.0",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -63,6 +63,7 @@ class Database {
|
||||
"patch-add-sqlserver-monitor.sql": true,
|
||||
"patch-add-other-auth.sql": { parents: [ "patch-monitor-basic-auth.sql" ] },
|
||||
"patch-add-radius-monitor.sql": true,
|
||||
"patch-monitor-add-resend-interval.sql": true,
|
||||
"patch-http-body-encoding.sql": true
|
||||
};
|
||||
|
||||
|
@ -79,6 +79,7 @@ class Monitor extends BeanModel {
|
||||
type: this.type,
|
||||
interval: this.interval,
|
||||
retryInterval: this.retryInterval,
|
||||
resendInterval: this.resendInterval,
|
||||
keyword: this.keyword,
|
||||
expiryNotification: this.isEnabledExpiryNotification(),
|
||||
ignoreTls: this.getIgnoreTls(),
|
||||
@ -215,6 +216,7 @@ class Monitor extends BeanModel {
|
||||
bean.monitor_id = this.id;
|
||||
bean.time = R.isoDateTimeMillis(dayjs.utc());
|
||||
bean.status = DOWN;
|
||||
bean.downCount = previousBeat?.downCount || 0;
|
||||
|
||||
if (this.isUpsideDown()) {
|
||||
bean.status = flipStatus(bean.status);
|
||||
@ -612,12 +614,27 @@ class Monitor extends BeanModel {
|
||||
log.debug("monitor", `[${this.name}] sendNotification`);
|
||||
await Monitor.sendNotification(isFirstBeat, this, bean);
|
||||
|
||||
// Reset down count
|
||||
bean.downCount = 0;
|
||||
|
||||
// Clear Status Page Cache
|
||||
log.debug("monitor", `[${this.name}] apicache clear`);
|
||||
apicache.clear();
|
||||
|
||||
} else {
|
||||
bean.important = false;
|
||||
|
||||
if (bean.status === DOWN && this.resendInterval > 0) {
|
||||
++bean.downCount;
|
||||
if (bean.downCount >= this.resendInterval) {
|
||||
// Send notification again, because we are still DOWN
|
||||
log.debug("monitor", `[${this.name}] sendNotification again: Down Count: ${bean.downCount} | Resend Interval: ${this.resendInterval}`);
|
||||
await Monitor.sendNotification(isFirstBeat, this, bean);
|
||||
|
||||
// Reset down count
|
||||
bean.downCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bean.status === UP) {
|
||||
@ -628,7 +645,7 @@ class Monitor extends BeanModel {
|
||||
}
|
||||
log.warn("monitor", `Monitor #${this.id} '${this.name}': Pending: ${bean.msg} | Max retries: ${this.maxretries} | Retry: ${retries} | Retry Interval: ${beatInterval} seconds | Type: ${this.type}`);
|
||||
} else {
|
||||
log.warn("monitor", `Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Interval: ${beatInterval} seconds | Type: ${this.type}`);
|
||||
log.warn("monitor", `Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Interval: ${beatInterval} seconds | Type: ${this.type} | Down Count: ${bean.downCount} | Resend Interval: ${this.resendInterval}`);
|
||||
}
|
||||
|
||||
log.debug("monitor", `[${this.name}] Send to socket`);
|
||||
|
@ -669,6 +669,7 @@ let needSetup = false;
|
||||
bean.basic_auth_pass = monitor.basic_auth_pass;
|
||||
bean.interval = monitor.interval;
|
||||
bean.retryInterval = monitor.retryInterval;
|
||||
bean.resendInterval = monitor.resendInterval;
|
||||
bean.hostname = monitor.hostname;
|
||||
bean.maxretries = monitor.maxretries;
|
||||
bean.port = parseInt(monitor.port);
|
||||
@ -1279,6 +1280,7 @@ let needSetup = false;
|
||||
authDomain: monitorListData[i].authDomain,
|
||||
interval: monitorListData[i].interval,
|
||||
retryInterval: retryInterval,
|
||||
resendInterval: monitorListData[i].resendInterval || 0,
|
||||
hostname: monitorListData[i].hostname,
|
||||
maxretries: monitorListData[i].maxretries,
|
||||
port: monitorListData[i].port,
|
||||
|
@ -380,7 +380,7 @@ export default {
|
||||
deleteProxyMsg: "Сигурни ли сте, че желаете да изтриете това прокси за всички монитори?",
|
||||
proxyDescription: "За да функционират трябва да бъдат зададени към монитор.",
|
||||
enableProxyDescription: "Това прокси няма да има ефект върху заявките за мониторинг, докато не бъде активирано. Може да контролирате временното деактивиране на проксито от всички монитори чрез статуса на активиране.",
|
||||
setAsDefaultProxyDescription: "Това проки ще бъде включено по подразбиране за новите монитори. Може да го изключите по отделно за всеки един монитор.",
|
||||
setAsDefaultProxyDescription: "Това прокси ще бъде включено по подразбиране за новите монитори. Може да го изключите по отделно за всеки един монитор.",
|
||||
"Certificate Chain": "Верига на сертификата",
|
||||
Valid: "Валиден",
|
||||
Invalid: "Невалиден",
|
||||
@ -537,4 +537,29 @@ export default {
|
||||
Workstation: "Работна станция",
|
||||
disableCloudflaredNoAuthMsg: "Тъй като сте в режим \"No Auth mode\", парола не се изисква.",
|
||||
wayToGetLineNotifyToken: "Може да получите токен код за достъп от {0}",
|
||||
resendEveryXTimes: "Изпращай повторно на всеки {0} пъти",
|
||||
resendDisabled: "Повторното изпращане е изключено",
|
||||
"Resend Notification if Down X times consequently": "Повторно изпращане на известие, ако е недостъпен X пъти последователно",
|
||||
"Bark Group": "Bark група",
|
||||
"Bark Sound": "Bark звук",
|
||||
"HTTP Headers": "HTTP хедъри",
|
||||
"Trust Proxy": "Trust Proxy",
|
||||
HomeAssistant: "Home Assistant",
|
||||
RadiusSecret: "Radius таен код",
|
||||
RadiusSecretDescription: "Споделен таен код между клиент и сървър",
|
||||
RadiusCalledStationId: "Повиквана станция ID",
|
||||
RadiusCalledStationIdDescription: "Идентификатор на повикваното устройство",
|
||||
RadiusCallingStationId: "Повикваща станция ID",
|
||||
RadiusCallingStationIdDescription: "Идентификатор на повикващото устройство",
|
||||
"Setup Docker Host": "Настройка на Docker хост",
|
||||
"Connection Type": "Тип свързване",
|
||||
"Docker Daemon": "Docker демон",
|
||||
deleteDockerHostMsg: "Сигурни ли сте, че желаете да изтриете този Docker хост за всички монитори?",
|
||||
socket: "Сокет",
|
||||
tcp: "TCP / HTTP",
|
||||
"Docker Container": "Docker контейнер",
|
||||
"Container Name / ID": "Име на контейнер / ID",
|
||||
"Docker Host": "Docker хост",
|
||||
"Docker Hosts": "Docker хостове",
|
||||
trustProxyDescription: "Trust 'X-Forwarded-*' headers. Ако искате да получавате правилния IP адрес на клиента, а Uptime Kuma е зад системи като Nginx или Apache, трябва да разрешите тази опция.",
|
||||
};
|
||||
|
@ -165,7 +165,10 @@ export default {
|
||||
Pink: "Pink",
|
||||
"Search...": "Suchen...",
|
||||
"Heartbeat Retry Interval": "Überprüfungsintervall",
|
||||
"Resend Notification if Down X times consequently": "Benachrichtigung erneut senden, wenn Inaktiv X mal hintereinander",
|
||||
retryCheckEverySecond: "Alle {0} Sekunden neu versuchen",
|
||||
resendEveryXTimes: "Erneut versenden alle {0} mal",
|
||||
resendDisabled: "Erneut versenden deaktiviert",
|
||||
"Import Backup": "Backup importieren",
|
||||
"Export Backup": "Backup exportieren",
|
||||
"Avg. Ping": "Durchschn. Ping",
|
||||
|
@ -2,6 +2,8 @@ export default {
|
||||
languageName: "English",
|
||||
checkEverySecond: "Check every {0} seconds",
|
||||
retryCheckEverySecond: "Retry every {0} seconds",
|
||||
resendEveryXTimes: "Resend every {0} times",
|
||||
resendDisabled: "Resend disabled",
|
||||
retriesDescription: "Maximum retries before the service is marked as down and a notification is sent",
|
||||
ignoreTLSError: "Ignore TLS/SSL error for HTTPS websites",
|
||||
upsideDownModeDescription: "Flip the status upside down. If the service is reachable, it is DOWN.",
|
||||
@ -72,6 +74,7 @@ export default {
|
||||
"Heartbeat Interval": "Heartbeat Interval",
|
||||
Retries: "Retries",
|
||||
"Heartbeat Retry Interval": "Heartbeat Retry Interval",
|
||||
"Resend Notification if Down X times consequently": "Resend Notification if Down X times consequently",
|
||||
Advanced: "Advanced",
|
||||
"Upside Down Mode": "Upside Down Mode",
|
||||
"Max. Redirects": "Max. Redirects",
|
||||
@ -559,5 +562,19 @@ export default {
|
||||
disableCloudflaredNoAuthMsg: "You are in No Auth mode, password is not require.",
|
||||
trustProxyDescription: "Trust 'X-Forwarded-*' headers. If you want to get the correct client IP and your Uptime Kuma is behind such as Nginx or Apache, you should enable this.",
|
||||
wayToGetLineNotifyToken: "You can get an access token from {0}",
|
||||
Examples: "Examples",
|
||||
"Home Assistant URL": "Home Assistant URL",
|
||||
"Long-Lived Access Token": "Long-Lived Access Token",
|
||||
"Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ",
|
||||
"Notification Service": "Notification Service",
|
||||
"default: notify all devices": "default: notify all devices",
|
||||
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.",
|
||||
"Automations can optionally be triggered in Home Assistant:": "Automations can optionally be triggered in Home Assistant:",
|
||||
"Trigger type:": "Trigger type:",
|
||||
"Event type:": "Event type:",
|
||||
"Event data:": "Event data:",
|
||||
"Then choose an action, for example switch the scene to where an RGB light is red.": "Then choose an action, for example switch the scene to where an RGB light is red.",
|
||||
"Frontend Version": "Frontend Version",
|
||||
"Frontend Version do not match backend version!": "Frontend Version do not match backend version!",
|
||||
"Body Encoding": "Body Encoding",
|
||||
};
|
||||
|
@ -540,6 +540,45 @@ export default {
|
||||
settingsCertificateExpiry: "TLS 证书过期通知",
|
||||
certificationExpiryDescription: "HTTPS 监控项发现被监控目标的 TLS 证书剩余有效期少于以下天数时将发出通知:",
|
||||
"ntfy Topic": "ntfy 主题",
|
||||
"Domain": "域名",
|
||||
"Workstation": "工作站",
|
||||
Domain: "域名",
|
||||
Workstation: "工作站",
|
||||
resendEveryXTimes: "每 {0} 次失败则重复发送一次",
|
||||
resendDisabled: "为 0 时禁用重复发送",
|
||||
"Resend Notification if Down X times consequently": "连续失败时重复发送通知的间隔次数",
|
||||
"HTTP Headers": "HTTP 头",
|
||||
"Trust Proxy": "可信的代理类字段",
|
||||
HomeAssistant: "Home Assistant",
|
||||
RadiusSecret: "Radius 共享机密",
|
||||
RadiusSecretDescription: "客户端和服务器之间共享的密钥",
|
||||
RadiusCalledStationId: "NAS 网络访问服务器号码(Called Station Id)",
|
||||
RadiusCalledStationIdDescription: "所访问的服务器的标识",
|
||||
RadiusCallingStationId: "呼叫方号码(Calling Station Id)",
|
||||
RadiusCallingStationIdDescription: "发出请求的设备的标识",
|
||||
"Setup Docker Host": "配置 Docker 宿主信息",
|
||||
"Connection Type": "连接方式",
|
||||
"Docker Daemon": "Docker 守护进程",
|
||||
deleteDockerHostMsg: "您确定您要删除此 Docker 宿主设置吗?这会影响所有 Docker 监控项",
|
||||
socket: "Socket",
|
||||
tcp: "TCP / HTTP",
|
||||
"Docker Container": "Docker 容器",
|
||||
"Container Name / ID": "容器名称 / ID",
|
||||
"Docker Host": "Docker 宿主",
|
||||
"Docker Hosts": "Docker 宿主",
|
||||
disableCloudflaredNoAuthMsg: "您现在正处于 No Auth 模式,无需输入密码",
|
||||
trustProxyDescription: "信任 'X-Forwarded-*' 头。如果您的 Uptime Kuma 是通过 Nginx 或 Apache 等反代服务对外提供访问的话,则您应当启用本功能以获取正确的客户端 IP。",
|
||||
wayToGetLineNotifyToken: "您可以在 {0} 获取 Access token",
|
||||
Examples: "例如",
|
||||
"Home Assistant URL": "Home Assistant 地址",
|
||||
"Long-Lived Access Token": "长期访问令牌",
|
||||
"Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "长期访问令牌可通过点击左下角您的用户名,滚动到页面底部并点击 Create Token 按钮获取。",
|
||||
"Notification Service": "Notification Service",
|
||||
"default: notify all devices": "默认:通知所有设备",
|
||||
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "通知服务的列表可在 Home Assistant 中的 Developer Tools > Services 通过搜索您的设备或手机的名称来获得。",
|
||||
"Automations can optionally be triggered in Home Assistant:": "可以在 Home Assistant 使用下列模板设置自动化操作的触发条件:",
|
||||
"Trigger type:": "触发类型:",
|
||||
"Event type:": "事件类型:",
|
||||
"Event data:": "事件数据:",
|
||||
"Then choose an action, for example switch the scene to where an RGB light is red.": "然后您可以选择关联操作,例如切换到 RGB 灯发出红光的场景",
|
||||
"Frontend Version": "前端版本",
|
||||
"Frontend Version do not match backend version!": "前端版本与后端版本不符!",
|
||||
};
|
||||
|
@ -275,6 +275,15 @@
|
||||
<input id="retry-interval" v-model="monitor.retryInterval" type="number" class="form-control" required min="20" step="1">
|
||||
</div>
|
||||
|
||||
<div class="my-3">
|
||||
<label for="resend-interval" class="form-label">
|
||||
{{ $t("Resend Notification if Down X times consequently") }}
|
||||
<span v-if="monitor.resendInterval > 0">({{ $t("resendEveryXTimes", [ monitor.resendInterval ]) }})</span>
|
||||
<span v-else>({{ $t("resendDisabled") }})</span>
|
||||
</label>
|
||||
<input id="resend-interval" v-model="monitor.resendInterval" type="number" class="form-control" required min="0" step="1">
|
||||
</div>
|
||||
|
||||
<h2 v-if="monitor.type !== 'push'" class="mt-5 mb-2">{{ $t("Advanced") }}</h2>
|
||||
|
||||
<div v-if="monitor.type === 'http' || monitor.type === 'keyword' " class="my-3 form-check">
|
||||
@ -676,6 +685,7 @@ export default {
|
||||
method: "GET",
|
||||
interval: 60,
|
||||
retryInterval: this.interval,
|
||||
resendInterval: 0,
|
||||
maxretries: 0,
|
||||
notificationIDList: {},
|
||||
ignoreTls: false,
|
||||
|
Loading…
Reference in New Issue
Block a user