cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
healthz.c
Go to the documentation of this file.
1
10#include <string.h>
11#include <stdio.h>
12
13/* -------------------------------------------------------------------------
14 * Internal probe registry
15 * ---------------------------------------------------------------------- */
16
17#define CWIST_HEALTHZ_MAX_PROBES 16
18
19typedef struct cwist_healthz_entry {
20 const char *name;
22 void *ctx;
23 bool active;
25
27static int g_entry_count = 0;
28
29/* -------------------------------------------------------------------------
30 * Registration
31 * ---------------------------------------------------------------------- */
32
45bool cwist_healthz_register(const char *name, cwist_health_probe_fn fn, void *ctx) {
46 if (!name || !fn) return false;
47
48 int first_free_slot = -1;
49 for (int i = 0; i < g_entry_count; ++i) {
50 if (g_entries[i].active) {
51 if (strcmp(g_entries[i].name, name) == 0) {
52 g_entries[i].fn = fn;
53 g_entries[i].ctx = ctx;
54 return true;
55 }
56 } else if (first_free_slot == -1) {
58 }
59 }
60
61 if (first_free_slot != -1) {
62 g_entries[first_free_slot].name = name;
63 g_entries[first_free_slot].fn = fn;
64 g_entries[first_free_slot].ctx = ctx;
65 g_entries[first_free_slot].active = true;
66 return true;
67 }
68
69 if (g_entry_count >= CWIST_HEALTHZ_MAX_PROBES) return false;
70
71 g_entries[g_entry_count].name = name;
72 g_entries[g_entry_count].fn = fn;
73 g_entries[g_entry_count].ctx = ctx;
74 g_entries[g_entry_count].active = true;
75 g_entry_count++;
76 return true;
77}
78
88void cwist_healthz_unregister(const char *name) {
89 if (!name) return;
90 for (int i = 0; i < g_entry_count; ++i) {
91 if (g_entries[i].active && strcmp(g_entries[i].name, name) == 0) {
92 g_entries[i].active = false;
93 }
94 }
95}
96
97/* -------------------------------------------------------------------------
98 * Evaluation
99 * ---------------------------------------------------------------------- */
100
107static const char *status_str(cwist_health_status_t s) {
108 switch (s) {
109 case CWIST_HEALTH_OK: return "ok";
110 case CWIST_HEALTH_DEGRADED: return "degraded";
111 case CWIST_HEALTH_FAIL: return "fail";
112 default: return "unknown";
113 }
114}
115
132 size_t count = 0;
134
135 for (int i = 0; i < g_entry_count; ++i) {
136 if (!g_entries[i].active) continue;
137 cwist_health_probe_t r = g_entries[i].fn(g_entries[i].ctx);
138 if (out_probes && count < max_probes) {
139 out_probes[count] = r;
140 }
141 if (!out_probes || count < max_probes) {
142 count++;
143 }
144 if (r.status == CWIST_HEALTH_FAIL)
148 }
149
150 if (out_count) *out_count = count;
152}
153
154/* -------------------------------------------------------------------------
155 * HTTP response helper
156 * ---------------------------------------------------------------------- */
157
169 if (!res) return;
170
172 size_t count = 0;
175
178 cwist_json_add_string(jb, "status", status_str(overall));
179 cwist_json_begin_array(jb, "probes");
180 for (size_t i = 0; i < count; ++i) {
182 cwist_json_add_string(jb, "name", probes[i].name);
183 cwist_json_add_string(jb, "status", status_str(probes[i].status));
184 if (probes[i].message) {
185 cwist_json_add_string(jb, "message", probes[i].message);
186 }
188 }
191
192 const char *json = cwist_json_get_raw(jb);
193 cwist_sstring_assign(res->body, (char *)json);
194 cwist_http_header_add(&res->headers, "Content-Type", "application/json");
195
196 switch (overall) {
197 case CWIST_HEALTH_OK: res->status_code = CWIST_HTTP_OK; break;
200 default: res->status_code = CWIST_HTTP_SERVICE_UNAVAILABLE; break;
201 }
203}
Memory allocation wrappers backed by libttak.
Safe string type with helper methods.
cwist_error_t cwist_sstring_assign(cwist_sstring *str, const char *data)
Assign a C string.
Definition sstring.c:504
Simple JSON string builder utility.
const char * cwist_json_get_raw(cwist_json_builder *b)
Returns the raw string buffer. Invalidated on destroy.
void cwist_json_add_string(cwist_json_builder *b, const char *key, const char *value)
Add a string value.
void cwist_json_begin_object(cwist_json_builder *b)
Begin a JSON object.
void cwist_json_end_object(cwist_json_builder *b)
End a JSON object.
void cwist_json_builder_destroy(cwist_json_builder *b)
Destroy a JSON builder.
cwist_json_builder * cwist_json_builder_create(void)
Create a new JSON builder.
void cwist_json_begin_array(cwist_json_builder *b, const char *key)
Begin a JSON array.
void cwist_json_end_array(cwist_json_builder *b)
End a JSON array.
void cwist_healthz_unregister(const char *name)
Deactivate a registered health probe.
Definition healthz.c:88
#define CWIST_HEALTHZ_MAX_PROBES
Definition healthz.c:17
struct cwist_healthz_entry cwist_healthz_entry_t
bool cwist_healthz_register(const char *name, cwist_health_probe_fn fn, void *ctx)
Register or update a health probe.
Definition healthz.c:45
void cwist_healthz_run(cwist_health_probe_t *out_probes, size_t max_probes, size_t *out_count, cwist_health_status_t *out_overall)
Run all active probes and aggregate their results.
Definition healthz.c:130
void cwist_app_healthz(cwist_http_response *res)
Serve the /healthz HTTP endpoint as a JSON response.
Definition healthz.c:168
Standardised readiness and liveness probing for CWIST.
cwist_health_probe_t(* cwist_health_probe_fn)(void *ctx)
User-provided probe callback.
Definition healthz.h:38
@ CWIST_HEALTH_FAIL
Definition healthz.h:27
@ CWIST_HEALTH_OK
Definition healthz.h:25
@ CWIST_HEALTH_DEGRADED
Definition healthz.h:26
enum cwist_health_status cwist_health_status_t
Classification of a subsystem health check.
@ CWIST_HTTP_OK
Definition http.h:28
cwist_error_t cwist_http_header_add(cwist_http_header_node **head, const char *key, const char *value)
Add a header to the list.
Definition http.c:1861
@ CWIST_HTTP_SERVICE_UNAVAILABLE
Definition http.h:111
size_t count
Definition otel.c:58
size_t cap
Definition otel.c:56
Result of a single probe.
Definition healthz.h:31
cwist_health_status_t status
Definition healthz.h:33
HTTP Response Object. Supports standard string body or Zero-Copy pointer body.
Definition http.h:82
cwist_sstring * body
Definition http.h:87
cwist_http_status_t status_code
Definition http.h:84
cwist_http_header_node * headers
Definition http.h:86
Simple JSON string builder utility.