diff options
-rw-r--r-- | docs/customservices.md | 14 | ||||
-rw-r--r-- | src/components/services/Healhchecks.vue | 115 |
2 files changed, 129 insertions, 0 deletions
diff --git a/docs/customservices.md b/docs/customservices.md index efe8ca4..3f14f8c 100644 --- a/docs/customservices.md +++ b/docs/customservices.md | |||
@@ -19,6 +19,7 @@ within Homer: | |||
19 | + [Emby / Jellyfin](#emby--jellyfin) | 19 | + [Emby / Jellyfin](#emby--jellyfin) |
20 | + [Uptime Kuma](#uptime-kuma) | 20 | + [Uptime Kuma](#uptime-kuma) |
21 | + [Tautulli](#tautulli) | 21 | + [Tautulli](#tautulli) |
22 | + [Healthchecks](#healthchecks) | ||
22 | 23 | ||
23 | If you experiencing any issue, please have a look to the [troubleshooting](troubleshooting.md) page. | 24 | If you experiencing any issue, please have a look to the [troubleshooting](troubleshooting.md) page. |
24 | 25 | ||
@@ -223,3 +224,16 @@ endpoint pointing to Tautulli! | |||
223 | type: "Tautulli" | 224 | type: "Tautulli" |
224 | apikey: "MY-SUPER-SECRET-API-KEY" | 225 | apikey: "MY-SUPER-SECRET-API-KEY" |
225 | ``` | 226 | ``` |
227 | |||
228 | ## Healthchecks | ||
229 | |||
230 | This service displays information about the configured status checks from the Healthchecks application. | ||
231 | Two lines are needed in the config.yml : | ||
232 | |||
233 | ```yaml | ||
234 | type: "Healthchecks" | ||
235 | apikey: "01234deb70424befb1f4ef6a23456789" | ||
236 | ``` | ||
237 | |||
238 | The url must be the root url of the Healthchecks application. | ||
239 | The Healthchecks API key can be found in Settings > API Access > API key (read-only). The key is needed to access Healthchecks API. | ||
diff --git a/src/components/services/Healhchecks.vue b/src/components/services/Healhchecks.vue new file mode 100644 index 0000000..c60f241 --- /dev/null +++ b/src/components/services/Healhchecks.vue | |||
@@ -0,0 +1,115 @@ | |||
1 | <template> | ||
2 | <Generic :item="item"> | ||
3 | <template #indicator> | ||
4 | <div class="notifs"> | ||
5 | <strong v-if="up > 0" class="notif up" title="Up"> | ||
6 | {{ up }} | ||
7 | </strong> | ||
8 | <strong v-if="down > 0" class="notif down" title="Down"> | ||
9 | {{ down }} | ||
10 | </strong> | ||
11 | <strong v-if="grace > 0" class="notif grace" title="Grace"> | ||
12 | {{ grace }} | ||
13 | </strong> | ||
14 | </div> | ||
15 | </template> | ||
16 | </Generic> | ||
17 | </template> | ||
18 | |||
19 | <script> | ||
20 | import service from "@/mixins/service.js"; | ||
21 | import Generic from "./Generic.vue"; | ||
22 | |||
23 | export default { | ||
24 | name: "Healthchecks", | ||
25 | mixins: [service], | ||
26 | props: { | ||
27 | item: Object, | ||
28 | }, | ||
29 | components: { | ||
30 | Generic, | ||
31 | }, | ||
32 | data: () => ({ | ||
33 | api: null, | ||
34 | }), | ||
35 | computed: { | ||
36 | up: function () { | ||
37 | if (!this.api) { | ||
38 | return ""; | ||
39 | } | ||
40 | return this.api.checks?.filter((check) => { | ||
41 | return check.status.toLowerCase() === "up"; | ||
42 | }).length; | ||
43 | }, | ||
44 | down: function () { | ||
45 | if (!this.api) { | ||
46 | return ""; | ||
47 | } | ||
48 | return this.api.checks?.filter((check) => { | ||
49 | return check.status.toLowerCase() === "down"; | ||
50 | }).length; | ||
51 | }, | ||
52 | grace: function () { | ||
53 | if (!this.api) { | ||
54 | return ""; | ||
55 | } | ||
56 | return this.api.checks?.filter((check) => { | ||
57 | return check.status.toLowerCase() === "grace"; | ||
58 | }).length; | ||
59 | }, | ||
60 | }, | ||
61 | created() { | ||
62 | this.fetchStatus(); | ||
63 | }, | ||
64 | methods: { | ||
65 | fetchStatus: async function () { | ||
66 | const apikey = this.item.apikey; | ||
67 | if (!apikey) { | ||
68 | console.error( | ||
69 | "apikey is not present in config.yml for the Healthchecks entry!" | ||
70 | ); | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | const headers = { | ||
75 | "X-Api-Key": this.item.apikey, | ||
76 | }; | ||
77 | |||
78 | this.api = await this.fetch("/api/v1/checks/", { headers }).catch((e) => { | ||
79 | console.error(e); | ||
80 | }); | ||
81 | }, | ||
82 | }, | ||
83 | }; | ||
84 | </script> | ||
85 | |||
86 | <style scoped lang="scss"> | ||
87 | .notifs { | ||
88 | position: absolute; | ||
89 | color: white; | ||
90 | font-family: sans-serif; | ||
91 | top: 0.3em; | ||
92 | right: 0.5em; | ||
93 | |||
94 | .notif { | ||
95 | display: inline-block; | ||
96 | padding: 0.2em 0.35em; | ||
97 | border-radius: 0.25em; | ||
98 | position: relative; | ||
99 | margin-left: 0.3em; | ||
100 | font-size: 0.8em; | ||
101 | |||
102 | &.up { | ||
103 | background-color: #4fd671; | ||
104 | } | ||
105 | |||
106 | &.down { | ||
107 | background-color: #e51111; | ||
108 | } | ||
109 | |||
110 | &.grace { | ||
111 | background-color: #cdd02e; | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | </style> | ||