Skip to content

Commit

Permalink
Improve logging messages
Browse files Browse the repository at this point in the history
  • Loading branch information
0237h committed May 6, 2024
1 parent eb8a5c3 commit 916a7d4
Show file tree
Hide file tree
Showing 13 changed files with 79 additions and 86 deletions.
8 changes: 3 additions & 5 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { config } from "./src/config.js";
import { logger } from "./src/logger.js";
import GET from "./src/fetch/GET.js";
import * as prometheus from "./src/prometheus.js";

if (config.verbose) logger.enable();
import { APIError } from "./src/fetch/utils.js";

const app = Bun.serve({
hostname: config.hostname,
port: config.port,
fetch(req: Request) {
let pathname = new URL(req.url).pathname;
if (req.method === "GET") return GET(req);
prometheus.request_error.inc({ pathname: new URL(req.url).pathname, status: 400 });
return new Response("Invalid request", { status: 400 });
return APIError(pathname, 405, "invalid_request_method", "Invalid request method, only GET allowed");
}
});

Expand Down
4 changes: 1 addition & 3 deletions src/clickhouse/makeQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ export async function makeQuery<T = unknown>(query: string) {
prometheus.bytes_read.inc(data.statistics.bytes_read);
prometheus.rows_read.inc(data.statistics.rows_read);
prometheus.elapsed.inc(data.statistics.elapsed);
logger.info({ query, statistics: data.statistics, rows: data.rows });
logger.trace("<makeQuery>\n", { query, statistics: data.statistics, rows: data.rows });

return data;
} catch (e: any) {
logger.error(e.message);

throw new Error(e.message);
}
}
2 changes: 2 additions & 0 deletions src/clickhouse/ping.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { PingResult } from "@clickhouse/client-web";
import client from "./createClient.js";
import { logger } from "../logger.js";

// Does not work with Bun's implementation of Node streams.
export async function ping(): Promise<PingResult> {
try {
await client.exec({ query: "SELECT 1" });
logger.info("Successfully pinged database");
return { success: true };
} catch (err) {
const message = typeof err === "string" ? err : JSON.stringify(err);
Expand Down
2 changes: 2 additions & 0 deletions src/fetch/GET.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import swaggerFavicon from "../../swagger/favicon.png"
import transfers from "./transfers.js";
import { APIError, toJSON } from "./utils.js";
import { APP_VERSION } from "../config.js";
import { logger } from "../logger.js";

export default async function (req: Request) {
const { pathname } = new URL(req.url);
logger.trace(`Incoming request: [${pathname}]`)
prometheus.request.inc({ pathname });

// Landing page
Expand Down
36 changes: 16 additions & 20 deletions src/fetch/balance.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { makeQuery } from "../clickhouse/makeQuery.js";
import { logger } from "../logger.js";
import { getBalanceChanges } from "../queries.js";
import * as prometheus from "../prometheus.js";
import { APIError, addMetadata, toJSON } from "./utils.js";
import { parseLimit, parsePage } from "../utils.js";

Expand All @@ -13,25 +12,25 @@ function verifyParams(searchParams: URLSearchParams) {
}

export default async function (req: Request) {
try {
const { pathname, searchParams } = new URL(req.url);
logger.info({ searchParams: Object.fromEntries(Array.from(searchParams)) });
const { pathname, searchParams } = new URL(req.url);
logger.trace("<balance>\n", { searchParams: Object.fromEntries(Array.from(searchParams)) });

try {
verifyParams(searchParams);
} catch (e: any) {
return APIError(pathname, 400, "bad_query_input", e.message);
}
try {
verifyParams(searchParams);
} catch (e: any) {
return APIError(pathname, 400, "bad_query_input", e.message);
}

const query = getBalanceChanges(searchParams);
let response;
const query = getBalanceChanges(searchParams);
let response;

try {
response = await makeQuery(query);
} catch (e: any) {
return APIError(pathname, 500, "failed_database_query", e.message);
}
try {
response = await makeQuery(query);
} catch (e: any) {
return APIError(pathname, 500, "failed_database_query", e.message);
}

try {
return toJSON(
addMetadata(
response,
Expand All @@ -40,9 +39,6 @@ export default async function (req: Request) {
)
);
} catch (e: any) {
logger.error(e);
prometheus.request_error.inc({ pathname: "/balance", status: 400 });

return new Response(e.message, { status: 400 });
return APIError(pathname, 500, "failed_response", e.message);
}
}
9 changes: 7 additions & 2 deletions src/fetch/head.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ import { makeQuery } from "../clickhouse/makeQuery.js";

export default async function (req: Request) {
let query = "SELECT block_num FROM cursors ORDER BY block_num DESC LIMIT 1";
let pathname = new URL(req.url).pathname;
let response;

try {
response = await makeQuery(query);
} catch (e: any) {
return APIError(new URL(req.url).pathname, 500, "failed_database_query", e.message);
return APIError(pathname, 500, "failed_database_query", e.message);
}

return toJSON(addMetadata(response));
try {
return toJSON(addMetadata(response));
} catch (e: any) {
return APIError(pathname, 500, "failed_response", e.message);
}
}
23 changes: 8 additions & 15 deletions src/fetch/health.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
import client from "../clickhouse/createClient.js";
import { logger } from "../logger.js";
import * as prometheus from "../prometheus.js";
import { APIError } from "./utils.js";

// TODO: Add log entry
export default async function (_req: Request) {
try {
const response = await client.ping();

if (response.success === false) throw new Error(response.error.message);
if (response.success === true) return new Response("OK");

return new Response("Unknown response from ClickHouse");
} catch (e: any) {
logger.error(e);
prometheus.request_error.inc({ pathname: "/health", status: 503 });

return new Response(e.message, { status: 503 });
export default async function (req: Request) {
const response = await client.ping();

if (!response.success) {
return APIError(new URL(req.url).pathname, 503, "failed_ping_database", response.error.message);
}

return new Response("OK");
}
2 changes: 2 additions & 0 deletions src/fetch/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { registry } from "../prometheus.js";
import { makeQuery } from "../clickhouse/makeQuery.js";
import { getBalanceChanges, getTotalSupply, getTransfers } from "../queries.js";
import { APIError, addMetadata } from "./utils.js";
import { logger } from "../logger.js";
const TAGS = {
MONITORING: "Monitoring",
HEALTH: "Health",
Expand All @@ -29,6 +30,7 @@ const head_example = addMetadata({
}
});

logger.debug("Querying examples for OpenAPI...");
const supply_example = await makeQuery(
getTotalSupply(new URLSearchParams({ limit: "1" }), true)
).then(
Expand Down
36 changes: 16 additions & 20 deletions src/fetch/supply.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { makeQuery } from "../clickhouse/makeQuery.js";
import { logger } from "../logger.js";
import { getTotalSupply } from "../queries.js";
import * as prometheus from "../prometheus.js";
import { APIError, addMetadata, toJSON } from "./utils.js";
import { parseLimit, parsePage } from "../utils.js";

Expand All @@ -13,25 +12,25 @@ function verifyParams(searchParams: URLSearchParams) {
}

export default async function (req: Request) {
try {
const { pathname, searchParams } = new URL(req.url);
logger.info({ searchParams: Object.fromEntries(Array.from(searchParams)) });
const { pathname, searchParams } = new URL(req.url);
logger.trace("<supply>\n", { searchParams: Object.fromEntries(Array.from(searchParams)) });

try {
verifyParams(searchParams);
} catch (e: any) {
return APIError(pathname, 400, "bad_query_input", e.message);
}
try {
verifyParams(searchParams);
} catch (e: any) {
return APIError(pathname, 400, "bad_query_input", e.message);
}

const query = getTotalSupply(searchParams);
let response;
const query = getTotalSupply(searchParams);
let response;

try {
response = await makeQuery(query);
} catch (e: any) {
return APIError(pathname, 500, "failed_database_query", e.message);
}
try {
response = await makeQuery(query);
} catch (e: any) {
return APIError(pathname, 500, "failed_database_query", e.message);
}

try {
return toJSON(
addMetadata(
response,
Expand All @@ -40,9 +39,6 @@ export default async function (req: Request) {
)
);
} catch (e: any) {
logger.error(e);
prometheus.request_error.inc({ pathname: "/supply", status: 400 });

return new Response(e.message, { status: 400 });
return APIError(pathname, 500, "failed_response", e.message);
}
}
28 changes: 12 additions & 16 deletions src/fetch/transfers.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import { makeQuery } from "../clickhouse/makeQuery.js";
import { logger } from "../logger.js";
import { getTransfers } from "../queries.js";
import * as prometheus from "../prometheus.js";
import { APIError, addMetadata, toJSON } from "./utils.js";
import { parseLimit, parsePage } from "../utils.js";

export default async function (req: Request) {
const { pathname, searchParams } = new URL(req.url);
logger.trace("<transfers>\n", { searchParams: Object.fromEntries(Array.from(searchParams)) });

const query = getTransfers(searchParams);
let response;

try {
const { pathname, searchParams } = new URL(req.url);
logger.info({ searchParams: Object.fromEntries(Array.from(searchParams)) });

const query = getTransfers(searchParams);
let response;
response = await makeQuery(query);
} catch (e: any) {
return APIError(pathname, 500, "failed_database_query", e.message);
}

try {
response = await makeQuery(query);
} catch (e: any) {
return APIError(pathname, 500, "failed_database_query", e.message);
}

try {
return toJSON(
addMetadata(
response,
Expand All @@ -27,9 +26,6 @@ export default async function (req: Request) {
)
);
} catch (e: any) {
logger.error(e);
prometheus.request_error.inc({ pathname: "/transfers", status: 400 });

return new Response(e.message, { status: 400 });
return APIError(pathname, 500, "failed_response", e.message);
}
}
2 changes: 1 addition & 1 deletion src/fetch/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function APIError(pathname: string, status: number, code?: string, detail
detail: detail ? detail : ""
}

logger.error(api_error);
logger.error("<APIError>\n", api_error);
prometheus.request_error.inc({ pathname, status });
return toJSON(api_error, status);
}
Expand Down
7 changes: 5 additions & 2 deletions src/logger.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Logger, type ILogObj } from "tslog";
import { APP_NAME, APP_VERSION } from "./config.js";
import { APP_NAME, APP_VERSION, config } from "./config.js";

class TsLogger extends Logger<ILogObj> {
constructor() {
Expand All @@ -11,11 +11,14 @@ class TsLogger extends Logger<ILogObj> {
public enable(type: "pretty" | "json" = "pretty") {
this.settings.type = type;
this.settings.minLevel = 0;
this.info("Enabled logger");
}

public disable() {
this.settings.type = "hidden";
this.info("Disabled logger");
}
}

export const logger = new TsLogger();
export const logger = new TsLogger();
if (config.verbose) logger.enable();
6 changes: 4 additions & 2 deletions src/prometheus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@ export const registry = new client.Registry();
export function registerCounter(name: string, help = "help", labelNames: string[] = [], config?: CounterConfiguration<string>) {
try {
registry.registerMetric(new Counter({ name, help, labelNames, ...config }));
logger.debug(`Registered new counter metric: ${name}`);
return registry.getSingleMetric(name) as Counter;
} catch (e) {
logger.error({ name, e });
logger.error("Error registering counter:", { name, e });
throw new Error(`${e}`);
}
}

export function registerGauge(name: string, help = "help", labelNames: string[] = [], config?: GaugeConfiguration<string>) {
try {
registry.registerMetric(new Gauge({ name, help, labelNames, ...config }));
logger.debug(`Registered new gauge metric: ${name}`);
return registry.getSingleMetric(name) as Gauge;
} catch (e) {
logger.error({ name, e });
logger.error("Error registering gauge:", { name, e });
throw new Error(`${e}`);
}
}
Expand Down

0 comments on commit 916a7d4

Please sign in to comment.