Openstatus www.openstatus.dev
at 57f471a7cf950bc467fcd98d6cd09e7c53593dae 112 lines 2.5 kB view raw
1import { AsyncLocalStorage } from "node:async_hooks"; 2// import * as Sentry from "@sentry/node"; 3import { sentry } from "@hono/sentry"; 4import { 5 configureSync, 6 getConsoleSink, 7 getLogger, 8 jsonLinesFormatter, 9 withContext, 10} from "@logtape/logtape"; 11// import { getSentrySink } from "@logtape/sentry"; 12import { Hono } from "hono"; 13import { showRoutes } from "hono/dev"; 14import { requestId } from "hono/request-id"; 15// import { logger } from "hono/logger"; 16import { checkerRoute } from "./checker"; 17import { cronRouter } from "./cron"; 18import { env } from "./env"; 19 20const { NODE_ENV, PORT } = env(); 21 22configureSync({ 23 sinks: { 24 console: getConsoleSink({ formatter: jsonLinesFormatter }), 25 // sentry: getSentrySink(), 26 }, 27 loggers: [ 28 { 29 category: "workflow", 30 lowestLevel: "debug", 31 sinks: ["console"], 32 }, 33 ], 34 contextLocalStorage: new AsyncLocalStorage(), 35}); 36 37const logger = getLogger(["workflow"]); 38const app = new Hono({ strict: false }); 39 40app.use("*", requestId()); 41 42app.use("*", sentry({ dsn: env().SENTRY_DSN })); 43 44app.use("*", async (c, next) => { 45 const requestId = c.get("requestId"); 46 const startTime = Date.now(); 47 48 await withContext( 49 { 50 requestId, 51 method: c.req.method, 52 url: c.req.url, 53 userAgent: c.req.header("User-Agent"), 54 // ipAddress: c.req.header("CF-Connecting-IP") || c.req.header("X-Forwarded-For") 55 }, 56 async () => { 57 logger.info("Request started", { 58 method: c.req.method, 59 url: c.req.url, 60 requestId, 61 }); 62 63 await next(); 64 65 const duration = Date.now() - startTime; 66 logger.info("Request completed", { 67 status: c.res.status, 68 duration, 69 requestId, 70 }); 71 }, 72 ); 73}); 74 75app.onError((err, c) => { 76 logger.error("Request error", { 77 error: { 78 name: err.name, 79 message: err.message, 80 stack: err.stack, 81 }, 82 method: c.req.method, 83 url: c.req.url, 84 }); 85 c.get("sentry").captureException(err); 86 87 return c.json({ error: "Internal server error" }, 500); 88}); 89 90app.get("/", (c) => c.text("workflows", 200)); 91 92/** 93 * Ping Pong 94 */ 95app.get("/ping", (c) => c.json({ ping: "pong" }, 200)); 96 97/** 98 * Cron Routes 99 */ 100app.route("/cron", cronRouter); 101 102app.route("/", checkerRoute); 103 104if (NODE_ENV === "development") { 105 showRoutes(app, { verbose: true, colorize: true }); 106} 107 108console.log(`Starting server on port ${PORT}`); 109 110const server = { port: PORT, fetch: app.fetch }; 111 112export default server;