-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
168 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,23 @@ | ||
import type { LoaderFunctionArgs } from '@remix-run/node' | ||
import { logger } from '#/utils/common' | ||
|
||
export async function loader({ request }: LoaderFunctionArgs) { | ||
const host = request.headers.get('X-Forwarded-Host') ?? request.headers.get('host') | ||
const url = new URL('/', `http://${host}`) | ||
|
||
// TODO: put some real logic here | ||
// if we can connect to the database and make a simple query | ||
// and make a HEAD request to ourselves, then we're good. | ||
|
||
try { | ||
// if we can connect to the database and make a simple query | ||
// and make a HEAD request to ourselves, then we're good. | ||
await Promise.all([ | ||
// TODO: put some real logic here | ||
fetch(url.toString(), { method: 'HEAD' }).then((r) => { | ||
if (!r.ok) return Promise.reject(r) | ||
}), | ||
]) | ||
return new Response('🫡 All is well!') | ||
} catch (error: unknown) { | ||
console.error('healthcheck ❌', { error }) | ||
logger('ERROR', 'healthcheck ❌', { error }) | ||
return new Response('🔥 Unhealthy', { status: 500 }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import pico from 'picocolors' | ||
|
||
export type EnumValues<Type> = Type[keyof Type] | ||
|
||
export type LogLevel = 'INFO' | 'WARN' | 'ERROR' | 'DEBUG' | 'QUERY' | ||
|
||
export function logTimestamp(date?: Date, localtime = true): string { | ||
const now = date ?? new Date() | ||
const useUTC = !localtime | ||
|
||
const year = useUTC ? now.getUTCFullYear() : now.getFullYear() | ||
const month = String(useUTC ? now.getUTCMonth() + 1 : now.getMonth() + 1).padStart(2, '0') | ||
const day = String(useUTC ? now.getUTCDate() : now.getDate()).padStart(2, '0') | ||
const hours = String(useUTC ? now.getUTCHours() : now.getHours()).padStart(2, '0') | ||
const minutes = String(useUTC ? now.getUTCMinutes() : now.getMinutes()).padStart(2, '0') | ||
const seconds = String(useUTC ? now.getUTCSeconds() : now.getSeconds()).padStart(2, '0') | ||
|
||
return pico.dim(`[${year}-${month}-${day} ${hours}:${minutes}:${seconds}]`) | ||
} | ||
|
||
// TODO replace with `node:utils.styleText` (requires node >= 21) | ||
const parseLogLevel = (level: LogLevel): string => { | ||
const colors = { | ||
INFO: pico.green, | ||
WARN: pico.yellow, | ||
ERROR: pico.red, | ||
DEBUG: pico.magenta, | ||
QUERY: pico.blue, | ||
} | ||
return colors[level] ? colors[level](level) : pico.gray(level) | ||
} | ||
|
||
export function logger(level: LogLevel, message: string, ...args: unknown[]): void { | ||
const logPrefix = `${logTimestamp()} ${parseLogLevel(level)}` | ||
const logMethod = { | ||
INFO: console.info, | ||
WARN: console.warn, | ||
ERROR: console.error, | ||
DEBUG: console.debug, | ||
QUERY: console.log, | ||
} | ||
const logFunc = logMethod[level] || console.log | ||
const logMessage = level === 'INFO' || level === 'WARN' ? ` ${message}` : message | ||
|
||
// If log level === DEBUG and env is not development, don't print the log | ||
if (level === 'DEBUG' && process.env.APP_LOG_LEVEL?.toLowerCase() !== 'debug') { | ||
return | ||
} | ||
|
||
logFunc(logPrefix, logMessage, ...args) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { default as pico } from 'picocolors' | ||
|
||
/** | ||
* Formats the current timestamp for logs. | ||
* @param {Date} [date] Optional date to use for the timestamp. Defaults to the current date. | ||
* @param {boolean} [localtime=true] Whether to use local time or UTC. Defaults to local time. | ||
* @returns {string} Formatted timestamp string. | ||
*/ | ||
export function logTimestamp(date, localtime = true) { | ||
const now = date ?? new Date() | ||
const useUTC = !localtime | ||
|
||
const year = useUTC ? now.getUTCFullYear() : now.getFullYear() | ||
const month = String(useUTC ? now.getUTCMonth() + 1 : now.getMonth() + 1).padStart(2, '0') | ||
const day = String(useUTC ? now.getUTCDate() : now.getDate()).padStart(2, '0') | ||
const hours = String(useUTC ? now.getUTCHours() : now.getHours()).padStart(2, '0') | ||
const minutes = String(useUTC ? now.getUTCMinutes() : now.getMinutes()).padStart(2, '0') | ||
const seconds = String(useUTC ? now.getUTCSeconds() : now.getSeconds()).padStart(2, '0') | ||
|
||
return pico.dim(`[${year}-${month}-${day} ${hours}:${minutes}:${seconds}]`) | ||
} | ||
|
||
/** | ||
* Parse the log level to return a color-coded string. | ||
* TODO: Replace with `node:utils.styleText` for Node >= 21. | ||
* @param {string} level The log level to parse. | ||
* @returns {string} A color-coded log level string. | ||
*/ | ||
const parseLogLevel = (level) => { | ||
const colors = { | ||
INFO: pico.green, | ||
WARN: pico.yellow, | ||
ERROR: pico.red, | ||
DEBUG: pico.magenta, | ||
QUERY: pico.blue, | ||
} | ||
return colors[level] ? colors[level](level) : pico.gray(level) | ||
} | ||
|
||
/** | ||
* Logs a message with a given log level and optional arguments. | ||
* @param {string} level The log level (INFO, WARN, ERROR, DEBUG, QUERY). | ||
* @param {string} message The message to log. | ||
* @param {...any} args Additional arguments to log. | ||
*/ | ||
export default function logger(level, message, ...args) { | ||
const logPrefix = `${logTimestamp()} ${parseLogLevel(level)}` | ||
const logMethod = { | ||
INFO: console.info, | ||
WARN: console.warn, | ||
ERROR: console.error, | ||
DEBUG: console.debug, | ||
QUERY: console.log, | ||
} | ||
const logFunc = logMethod[level] || console.log | ||
const logMessage = level === 'INFO' || level === 'WARN' ? ` ${message}` : message | ||
|
||
// If log level is DEBUG and environment is not set to 'debug', do not print the log. | ||
if (level === 'DEBUG' && process.env.APP_LOG_LEVEL?.toLowerCase() !== 'debug') { | ||
return | ||
} | ||
|
||
logFunc(logPrefix, logMessage, ...args) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters