Openstatus www.openstatus.dev

otel api (#1291)

* otel api

* ci: apply automated fixes

* update

* fix test

* ci: apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

authored by

Thibault Le Ouay
autofix-ci[bot]
and committed by
GitHub
b405ae9c 1514d1d4

+135 -38
+1
apps/server/src/routes/v1/monitors/get.test.ts
··· 9 9 "x-openstatus-key": "1", 10 10 }, 11 11 }); 12 + 12 13 const result = MonitorSchema.safeParse(await res.json()); 13 14 14 15 expect(res.status).toBe(200);
+9 -1
apps/server/src/routes/v1/monitors/get.ts
··· 52 52 }); 53 53 } 54 54 55 - const data = MonitorSchema.parse(_monitor); 55 + const data = MonitorSchema.parse({ 56 + ..._monitor, 57 + openTelemetry: _monitor.otelEndpoint 58 + ? { 59 + headers: _monitor.otelHeaders ?? undefined, 60 + endpoint: _monitor.otelEndpoint ?? undefined, 61 + } 62 + : undefined, 63 + }); 56 64 57 65 return c.json(data, 200); 58 66 });
+11 -1
apps/server/src/routes/v1/monitors/get_all.ts
··· 38 38 ) 39 39 .all(); 40 40 41 - const data = z.array(MonitorSchema).parse(_monitors); 41 + const data = z.array(MonitorSchema).parse( 42 + _monitors.map((monitor) => ({ 43 + ...monitor, 44 + openTelemetry: monitor.otelEndpoint 45 + ? { 46 + endpoint: monitor.otelEndpoint ?? undefined, 47 + headers: monitor.otelHeaders ?? undefined, 48 + } 49 + : undefined, 50 + })), 51 + ); 42 52 43 53 return c.json(data, 200); 44 54 });
+9 -1
apps/server/src/routes/v1/monitors/post.ts
··· 104 104 .returning() 105 105 .get(); 106 106 107 - const data = MonitorSchema.parse(_newMonitor); 107 + const data = MonitorSchema.parse({ 108 + ..._newMonitor, 109 + openTelemetry: _newMonitor.otelEndpoint 110 + ? { 111 + headers: _newMonitor.otelHeaders ?? undefined, 112 + endpoint: _newMonitor.otelEndpoint ?? undefined, 113 + } 114 + : undefined, 115 + }); 108 116 109 117 return c.json(data, 200); 110 118 });
+13 -4
apps/server/src/routes/v1/monitors/post_http.ts
··· 79 79 } 80 80 } 81 81 82 - const { request, regions, assertions, otelHeaders, ...rest } = input; 82 + const { request, regions, assertions, openTelemetry, ...rest } = input; 83 83 84 84 const headers = input.request.headers 85 85 ? Object.entries(input.request.headers) 86 86 : undefined; 87 87 88 - const otelHeadersEntries = otelHeaders 89 - ? Object.entries(otelHeaders).map(([key, value]) => ({ 88 + const otelHeadersEntries = openTelemetry?.headers 89 + ? Object.entries(openTelemetry.headers).map(([key, value]) => ({ 90 90 key: key, 91 91 value: value, 92 92 })) ··· 110 110 headers: headersEntries ? JSON.stringify(headersEntries) : undefined, 111 111 assertions: assert.length > 0 ? serialize(assert) : undefined, 112 112 timeout: input.timeout || 45000, 113 + otelEndpoint: openTelemetry?.endpoint, 113 114 otelHeaders: otelHeadersEntries 114 115 ? JSON.stringify(otelHeadersEntries) 115 116 : undefined, ··· 117 118 .returning() 118 119 .get(); 119 120 120 - const data = MonitorSchema.parse(_newMonitor); 121 + const data = MonitorSchema.parse({ 122 + ..._newMonitor, 123 + openTelemetry: _newMonitor.otelEndpoint 124 + ? { 125 + headers: _newMonitor.otelHeaders ?? undefined, 126 + endpoint: _newMonitor.otelEndpoint ?? undefined, 127 + } 128 + : undefined, 129 + }); 121 130 122 131 return c.json(data, 200); 123 132 });
+7 -3
apps/server/src/routes/v1/monitors/post_tcp.test.ts
··· 23 23 public: true, 24 24 }), 25 25 }); 26 - 27 - const result = MonitorSchema.safeParse(await res.json()); 28 - 26 + const r = await res.json(); 27 + console.log(r); 28 + const result = MonitorSchema.safeParse(r); 29 + if (result.error) { 30 + console.error(result.error); 31 + throw new Error("Invalid monitor payload"); 32 + } 29 33 expect(res.status).toBe(200); 30 34 expect(result.success).toBe(true); 31 35 });
+13 -4
apps/server/src/routes/v1/monitors/post_tcp.ts
··· 76 76 } 77 77 } 78 78 79 - const { request, regions, otelHeaders, ...rest } = input; 80 - const otelHeadersEntries = otelHeaders 81 - ? Object.entries(otelHeaders).map(([key, value]) => ({ 79 + const { request, regions, openTelemetry, ...rest } = input; 80 + const otelHeadersEntries = openTelemetry?.headers 81 + ? Object.entries(openTelemetry.headers).map(([key, value]) => ({ 82 82 key: key, 83 83 value: value, 84 84 })) ··· 99 99 otelHeaders: otelHeadersEntries 100 100 ? JSON.stringify(otelHeadersEntries) 101 101 : undefined, 102 + otelEndpoint: openTelemetry?.endpoint, 102 103 }) 103 104 .returning() 104 105 .get(); 105 106 106 - const data = MonitorSchema.parse(_newMonitor); 107 + const data = MonitorSchema.parse({ 108 + ..._newMonitor, 109 + openTelemetry: _newMonitor.otelEndpoint 110 + ? { 111 + headers: _newMonitor.otelHeaders ?? undefined, 112 + endpoint: _newMonitor.otelEndpoint ?? undefined, 113 + } 114 + : undefined, 115 + }); 107 116 108 117 return c.json(data, 200); 109 118 });
+9 -1
apps/server/src/routes/v1/monitors/put.ts
··· 111 111 .returning() 112 112 .get(); 113 113 114 - const data = MonitorSchema.parse(_newMonitor); 114 + const data = MonitorSchema.parse({ 115 + ..._newMonitor, 116 + openTelemetry: _newMonitor.otelEndpoint 117 + ? { 118 + headers: _newMonitor.otelHeaders ?? undefined, 119 + endpoint: _newMonitor.otelEndpoint ?? undefined, 120 + } 121 + : undefined, 122 + }); 115 123 return c.json(data, 200); 116 124 }); 117 125 }
+13 -4
apps/server/src/routes/v1/monitors/put_http.ts
··· 92 92 }); 93 93 } 94 94 95 - const { request, regions, assertions, otelHeaders, ...rest } = input; 95 + const { request, regions, assertions, openTelemetry, ...rest } = input; 96 96 97 97 const headers = input.request.headers 98 98 ? Object.entries(input.request.headers) 99 99 : undefined; 100 100 101 - const otelHeadersEntries = otelHeaders 102 - ? Object.entries(otelHeaders).map(([key, value]) => ({ 101 + const otelHeadersEntries = openTelemetry?.headers 102 + ? Object.entries(openTelemetry.headers).map(([key, value]) => ({ 103 103 key: key, 104 104 value: value, 105 105 })) ··· 122 122 otelHeaders: otelHeadersEntries 123 123 ? JSON.stringify(otelHeadersEntries) 124 124 : undefined, 125 + otelEndpoint: openTelemetry?.endpoint, 125 126 assertions: assert ? serialize(assert) : "", 126 127 timeout: input.timeout || 45000, 127 128 updatedAt: new Date(), ··· 130 131 .returning() 131 132 .get(); 132 133 133 - const data = MonitorSchema.parse(_newMonitor); 134 + const data = MonitorSchema.parse({ 135 + ..._newMonitor, 136 + openTelemetry: _newMonitor.otelEndpoint 137 + ? { 138 + headers: _newMonitor.otelHeaders ?? undefined, 139 + endpoint: _newMonitor.otelEndpoint ?? undefined, 140 + } 141 + : undefined, 142 + }); 134 143 return c.json(data, 200); 135 144 }); 136 145 }
+13 -4
apps/server/src/routes/v1/monitors/put_tcp.ts
··· 90 90 }); 91 91 } 92 92 93 - const { request, regions, otelHeaders, ...rest } = input; 93 + const { request, regions, openTelemetry, ...rest } = input; 94 94 95 - const otelHeadersEntries = otelHeaders 96 - ? Object.entries(otelHeaders).map(([key, value]) => ({ 95 + const otelHeadersEntries = openTelemetry?.headers 96 + ? Object.entries(openTelemetry.headers).map(([key, value]) => ({ 97 97 key: key, 98 98 value: value, 99 99 })) ··· 109 109 otelHeaders: otelHeadersEntries 110 110 ? JSON.stringify(otelHeadersEntries) 111 111 : undefined, 112 + otelEndpoint: openTelemetry?.endpoint, 112 113 timeout: input.timeout || 45000, 113 114 updatedAt: new Date(), 114 115 }) ··· 116 117 .returning() 117 118 .get(); 118 119 119 - const data = MonitorSchema.parse(_newMonitor); 120 + const data = MonitorSchema.parse({ 121 + ..._newMonitor, 122 + openTelemetry: _newMonitor.otelEndpoint 123 + ? { 124 + headers: _newMonitor.otelHeaders ?? undefined, 125 + endpoint: _newMonitor.otelEndpoint ?? undefined, 126 + } 127 + : undefined, 128 + }); 120 129 return c.json(data, 200); 121 130 }); 122 131 }
+37 -15
apps/server/src/routes/v1/monitors/schema.ts
··· 206 206 jobType: z.enum(monitorJobTypes).optional().default("http").openapi({ 207 207 description: "The type of the monitor", 208 208 }), 209 + openTelemetry: z 210 + .object({ 211 + endpoint: z 212 + .string() 213 + .url() 214 + .optional() 215 + .default("http://localhost:4317") 216 + .openapi({ 217 + description: "The endpoint of the OpenTelemetry collector", 218 + }), 219 + headers: z.record(z.string()).optional().default({}).openapi({ 220 + description: "The headers to send to the OpenTelemetry collector", 221 + }), 222 + }) 223 + .optional() 224 + .openapi({ 225 + description: "The OpenTelemetry configuration", 226 + }), 209 227 }) 210 228 .openapi("Monitor"); 211 229 ··· 325 343 regions: z.array(z.enum(flyRegions)).openapi({ 326 344 description: "Regions to run the request in", 327 345 }), 328 - otelEndpoint: z 329 - .string() 330 - .url() 331 - .optional() 332 - .openapi({ 333 - description: "OTEL endpoint to send metrics to", 334 - examples: ["https://otel.example.com"], 335 - }), 336 - otelHeaders: z 337 - .record(z.string(), z.string()) 338 - .optional() 339 - .openapi({ 340 - description: "Headers to send with the OTEL request", 341 - examples: [{ "Content-Type": "application/json" }], 342 - }), 346 + openTelemetry: z 347 + .object({ 348 + endpoint: z 349 + .string() 350 + .url() 351 + .optional() 352 + .openapi({ 353 + description: "OTEL endpoint to send metrics to", 354 + examples: ["https://otel.example.com"], 355 + }), 356 + headers: z 357 + .record(z.string(), z.string()) 358 + .optional() 359 + .openapi({ 360 + description: "Headers to send with the OTEL request", 361 + examples: [{ "Content-Type": "application/json" }], 362 + }), 363 + }) 364 + .nullish(), 343 365 }); 344 366 345 367 const httpRequestSchema = z.object({