Compare commits

...

3 commits

Author SHA1 Message Date
Bryan Gonzalez
51fc1b997c
Merge bd719d9987 into 6899603eb7 2024-11-09 15:30:21 +00:00
Abhigyan Mohanta
6899603eb7
fix #5314 Email Address Friendly Name Error (#5318)
Some checks failed
CodeQL / Analyze (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
validate / json-yaml-validate (push) Has been cancelled
validate / validate (push) Has been cancelled
Auto Test / armv7-simple-test (18, ARMv7) (push) Has been cancelled
Auto Test / armv7-simple-test (20, ARMv7) (push) Has been cancelled
Auto Test / check-linters (push) Has been cancelled
Auto Test / e2e-test (push) Has been cancelled
Auto Test / auto-test (18, ARM64) (push) Has been cancelled
Auto Test / auto-test (18, macos-latest) (push) Has been cancelled
Auto Test / auto-test (18, ubuntu-latest) (push) Has been cancelled
Auto Test / auto-test (18, windows-latest) (push) Has been cancelled
Auto Test / auto-test (20, ARM64) (push) Has been cancelled
Auto Test / auto-test (20, macos-latest) (push) Has been cancelled
Auto Test / auto-test (20, ubuntu-latest) (push) Has been cancelled
Auto Test / auto-test (20, windows-latest) (push) Has been cancelled
2024-11-09 23:30:08 +08:00
Bryan Gonzalez
bd719d9987 GH-5214: feat: Add Docker service availability monitoring
Introduces Docker service availability to monitor uptime
and status of Docker services alongside existing types.
Updates the database schema to support "docker_service".
Enhances the user interface to allow configuration of Docker
service parameters within the monitor setup.

This change allows for more granular monitoring capabilities
by checking the running state of services in a Docker environment.

Relates to implementing extended Docker monitoring functionalities.

implements #5214

Signed-off-by: Bryan Gonzalez <bryan@battleface.com>
2024-10-18 01:21:30 -04:00
6 changed files with 79 additions and 7 deletions

View file

@ -23,7 +23,7 @@ It is a temporary live demo, all data will be deleted after 10 minutes. Sponsore
## ⭐ Features
- Monitoring uptime for HTTP(s) / TCP / HTTP(s) Keyword / HTTP(s) Json Query / Ping / DNS Record / Push / Steam Game Server / Docker Containers
- Monitoring uptime for HTTP(s) / TCP / HTTP(s) Keyword / HTTP(s) Json Query / Ping / DNS Record / Push / Steam Game Server / Docker Containers / Docker Services
- Fancy, Reactive, Fast UI/UX
- Notifications via Telegram, Discord, Gotify, Slack, Pushover, Email (SMTP), and [90+ notification services, click here for the full list](https://github.com/louislam/uptime-kuma/tree/master/src/components/notifications)
- 20-second intervals

View file

@ -0,0 +1,11 @@
exports.up = function (knex) {
return knex.schema.alterTable("monitor", function (table) {
table.string("docker_service", 255);
});
};
exports.down = function (knex) {
return knex.schema.alterTable("monitor", function (table) {
table.dropColumn("docker_service");
});
};

View file

@ -120,6 +120,7 @@ class Monitor extends BeanModel {
dns_resolve_server: this.dns_resolve_server,
dns_last_result: this.dns_last_result,
docker_container: this.docker_container,
docker_service: this.docker_service,
docker_host: this.docker_host,
proxyId: this.proxy_id,
notificationIDList: preloadData.notifications.get(this.id) || {},
@ -757,6 +758,54 @@ class Monitor extends BeanModel {
} else {
throw Error("Container State is " + res.data.State.Status);
}
} else if (this.type === "docker-service-availability") { // TODO: add a service-health to count running vs desired (needs services api)
log.debug("monitor", `[${this.name}] Prepare Options for Axios`);
const options = {
url: `/tasks?filters={"service":{"${this.docker_service}":true}}`,
timeout: this.interval * 1000 * 0.8,
headers: {
"Accept": "*/*",
},
httpsAgent: new https.Agent({
maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)
rejectUnauthorized: !this.getIgnoreTls(),
secureOptions: crypto.constants.SSL_OP_LEGACY_SERVER_CONNECT,
}),
httpAgent: new http.Agent({
maxCachedSessions: 0,
}),
};
const dockerHost = await R.load("docker_host", this.docker_host);
if (!dockerHost) {
throw new Error("Failed to load docker host config");
}
if (dockerHost._dockerType === "socket") {
options.socketPath = dockerHost._dockerDaemon;
} else if (dockerHost._dockerType === "tcp") {
options.baseURL = DockerHost.patchDockerURL(dockerHost._dockerDaemon);
options.httpsAgent = new https.Agent(
DockerHost.getHttpsAgentOptions(dockerHost._dockerType, options.baseURL)
);
}
log.debug("monitor", `[${this.name}] Axios Request (get service tasks)`);
let res = await axios.request(options);
if (res.data.message) {
throw Error(res.data.message);
}
if (res.data.filter((task) => task.Status.State === "running").length) {
bean.status = UP;
bean.msg = `Service: ${this.docker_service} is available`;
} else {
bean.status = DOWN;
bean.msg = `Service: ${this.docker_service} is Down. No replicas available`;
}
} else if (this.type === "sqlserver") {
let startTime = dayjs().valueOf();

View file

@ -828,6 +828,7 @@ let needSetup = false;
bean.dns_resolve_server = monitor.dns_resolve_server;
bean.pushToken = monitor.pushToken;
bean.docker_container = monitor.docker_container;
bean.docker_service = monitor.docker_service;
bean.docker_host = monitor.docker_host;
bean.proxyId = Number.isInteger(monitor.proxyId) ? monitor.proxyId : null;
bean.mqttUsername = monitor.mqttUsername;

View file

@ -5,20 +5,20 @@
</div>
<div class="mb-3">
<label for="sendgrid-from-email" class="form-label">{{ $t("From Email") }}</label>
<input id="sendgrid-from-email" v-model="$parent.notification.sendgridFromEmail" type="email" class="form-control" required>
<input id="sendgrid-from-email" v-model="$parent.notification.sendgridFromEmail" type="text" class="form-control" required>
</div>
<div class="mb-3">
<label for="sendgrid-to-email" class="form-label">{{ $t("To Email") }}</label>
<input id="sendgrid-to-email" v-model="$parent.notification.sendgridToEmail" type="email" class="form-control" required>
<input id="sendgrid-to-email" v-model="$parent.notification.sendgridToEmail" type="text" class="form-control" required>
</div>
<div class="mb-3">
<label for="sendgrid-cc-email" class="form-label">{{ $t("smtpCC") }}</label>
<input id="sendgrid-cc-email" v-model="$parent.notification.sendgridCcEmail" type="email" class="form-control">
<input id="sendgrid-cc-email" v-model="$parent.notification.sendgridCcEmail" type="text" class="form-control">
<div class="form-text">{{ $t("Separate multiple email addresses with commas") }}</div>
</div>
<div class="mb-3">
<label for="sendgrid-bcc-email" class="form-label">{{ $t("smtpBCC") }}</label>
<input id="sendgrid-bcc-email" v-model="$parent.notification.sendgridBccEmail" type="email" class="form-control">
<input id="sendgrid-bcc-email" v-model="$parent.notification.sendgridBccEmail" type="text" class="form-control">
<small class="form-text text-muted">{{ $t("Separate multiple email addresses with commas") }}</small>
</div>
<div class="mb-3">

View file

@ -42,6 +42,9 @@
<option value="docker">
{{ $t("Docker Container") }}
</option>
<option value="docker-service-availability">
{{ $t("Docker Service (Simple Availability)") }}
</option>
<option value="real-browser">
HTTP(s) - Browser Engine (Chrome/Chromium) (Beta)
@ -414,9 +417,16 @@
<input id="docker_container" v-model="monitor.docker_container" type="text" class="form-control" required>
</div>
<!-- Docker Service Name / ID -->
<!-- For Docker Service Type -->
<div v-if="monitor.type === 'docker-service-availability'" class="my-3">
<label for="docker_service" class="form-label">{{ $t("Service Name / ID") }}</label>
<input id="docker_service" v-model="monitor.docker_service" type="text" class="form-control" required>
</div>
<!-- Docker Host -->
<!-- For Docker Type -->
<div v-if="monitor.type === 'docker'" class="my-3">
<div v-if="['docker', 'docker-service-availability'].includes(monitor.type)" class="my-3">
<div class="mb-3">
<label for="docker-host" class="form-label">{{ $t("Docker Host") }}</label>
<ActionSelect
@ -1089,6 +1099,7 @@ const monitorDefaults = {
dns_resolve_type: "A",
dns_resolve_server: "1.1.1.1",
docker_container: "",
docker_service: "",
docker_host: null,
proxyId: null,
mqttUsername: "",
@ -1665,7 +1676,7 @@ message HealthCheckResponse {
return false;
}
}
if (this.monitor.type === "docker") {
if ([ "docker", "docker-service-availability" ].includes(this.monitor.type)) {
if (this.monitor.docker_host == null) {
toast.error(this.$t("DockerHostRequired"));
return false;