Skip to content

Commit 5df65d3

Browse files
feat(api): dynamically change logging level via API (#825)
* feat(api): add authenticated endpoint to dynamically manage logging level - Add ADMIN_API_KEY environment variable for secure access - Add functionality to modify logging level at runtime - Implement tRPC endpoints for getting and setting log level - Enhance logger module to track all logger instances - Add proper OpenAPI documentation with system tag * fix: remove unused import * env var ADMIN_API_KEY * refactor(api): move logging router procedures into separate files * fix(api): remove unnecessary success field from logging procedure responses * refactor(api): organize api keys by type * test(api): add UT to check invalid log level updates * chore: add changeset --------- Co-authored-by: PJColombo <[email protected]>
1 parent 54cdc87 commit 5df65d3

File tree

18 files changed

+273
-33
lines changed

18 files changed

+273
-33
lines changed

.changeset/calm-experts-draw.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@blobscan/api": minor
3+
---
4+
5+
Added procedures to retrieve and update the logger's level

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ DIRECT_URL=postgresql://blobscan:s3cr3t@localhost:5432/blobscan_dev?schema=publi
1212
BLOBSCAN_WEB_TAG=next
1313
BLOBSCAN_API_TAG=next
1414
INDEXER_TAG=master
15+
ADMIN_API_KEY=secretkey
1516

1617
### blobscan website
1718

.env.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ S3_STORAGE_ENABLED=true
3232
S3_STORAGE_ENDPOINT=http://localhost:9090
3333
S3_STORAGE_FORCE_PATH_STYLE=true
3434

35+
ADMIN_API_KEY=secretkey
36+
3537
BEE_ENDPOINT=http://localhost:1633
3638
SWARM_BATCH_ID=f89e63edf757f06e89933761d6d46592d03026efb9871f9d244f34da86b6c242
3739

apps/docs/src/app/docs/environment/page.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ nextjs:
3232

3333
| Variable | Description | Required | Default value |
3434
| ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------- | ------------------------------- | -------------------------------------------- |
35+
| `ADMIN_API_KEY` | API key used to authenticate requests to admin endpoints (e.g., logging level management) | No | (empty) |
3536
| `BLOB_DATA_API_ENABLED` | Controls whether the blob data API endpoint is enabled | No | `true` |
3637
| `BLOB_DATA_API_KEY` | API key used to authenticate requests to retrieve blob data from the blobscan API | No | (empty) |
3738
| `CHAIN_ID` | EVM chain id | Yes | `1` |

apps/rest-api-server/src/index.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,14 @@ async function main() {
6666
enableTracing: env.TRACES_ENABLED,
6767
prisma,
6868
scope: "rest-api",
69-
serviceApiKeys: {
70-
blobDataReadKey: env.BLOB_DATA_API_KEY,
71-
indexerServiceSecret: env.SECRET_KEY,
72-
loadNetworkServiceKey: env.WEAVEVM_API_KEY,
69+
apiKeys: {
70+
accesses: {
71+
blobDataRead: env.BLOB_DATA_API_KEY,
72+
},
73+
services: {
74+
indexer: env.SECRET_KEY,
75+
loadNetwork: env.WEAVEVM_API_KEY,
76+
},
7377
},
7478
}),
7579
onError({ error }) {

apps/web/src/pages/api/trpc/[...trpc].ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ export default createNextApiHandler({
2323
chainId: env.CHAIN_ID,
2424
prisma,
2525
enableTracing: env.TRACES_ENABLED,
26-
serviceApiKeys: {
27-
blobDataReadKey: env.BLOB_DATA_API_KEY,
26+
apiKeys: {
27+
accesses: {
28+
blobDataRead: env.BLOB_DATA_API_KEY,
29+
},
2830
},
2931
}),
3032
onError({ error }) {

packages/api/src/app-router.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { blockchainSyncStateRouter } from "./routers/blockchain-sync-state";
88
import { ethPriceRouter } from "./routers/eth-price";
99
import { healthcheck } from "./routers/healthcheck";
1010
import { indexerRouter } from "./routers/indexer";
11+
import { loggingRouter } from "./routers/logging";
1112
import { search } from "./routers/search";
1213
import { stateRouter } from "./routers/state";
1314
import { statsRouter } from "./routers/stats";
@@ -25,6 +26,7 @@ export function createAppRouter(config?: AppRouterConfig) {
2526
blob: createBlobRouter(config?.blobRouter),
2627
blobStoragesState: blobStoragesStateRouter,
2728
block: blockRouter,
29+
loggingRouter,
2830
syncState: blockchainSyncStateRouter,
2931
ethPrice: ethPriceRouter,
3032
indexer: indexerRouter,

packages/api/src/context.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,31 @@ import type {
1010
import type { BlobPropagator } from "@blobscan/blob-propagator";
1111
import type { BlobscanPrismaClient } from "@blobscan/db";
1212

13-
import type { ServiceClient } from "./utils";
14-
import { createServiceClient } from "./utils";
13+
import type { ApiClient } from "./utils";
14+
import { createApiClient } from "./utils";
1515

1616
export type CreateContextOptions =
1717
| NodeHTTPCreateContextFnOptions<NodeHTTPRequest, NodeHTTPResponse>
1818
| CreateNextContextOptions;
1919

2020
type CreateInnerContextOptions = Partial<CreateContextOptions> & {
21-
serviceClient?: ServiceClient;
21+
apiClient?: ApiClient;
2222
blobPropagator?: BlobPropagator;
2323
prisma: BlobscanPrismaClient;
2424
};
2525

2626
export type ServiceApiKeys = Partial<{
27-
indexerServiceSecret: string;
28-
loadNetworkServiceKey: string;
29-
blobDataReadKey: string;
27+
indexer: string;
28+
loadNetwork: string;
29+
}>;
30+
31+
export type AccessKeys = Partial<{
32+
blobDataRead: string;
33+
}>;
34+
35+
export type ApiKeys = Partial<{
36+
services: ServiceApiKeys;
37+
accesses: AccessKeys;
3038
}>;
3139

3240
export type CreateContextParams = {
@@ -35,20 +43,20 @@ export type CreateContextParams = {
3543
prisma: BlobscanPrismaClient;
3644
enableTracing?: boolean;
3745
scope: ContextScope;
38-
serviceApiKeys?: ServiceApiKeys;
46+
apiKeys?: ApiKeys;
3947
};
4048

4149
export type TRPCInnerContext = {
4250
prisma: BlobscanPrismaClient;
4351
blobPropagator?: BlobPropagator;
44-
apiClient?: ServiceClient;
52+
apiClient?: ApiClient;
4553
};
4654

4755
export function createTRPCInnerContext(opts: CreateInnerContextOptions) {
4856
return {
4957
prisma: opts.prisma,
5058
blobPropagator: opts.blobPropagator,
51-
apiClient: opts.serviceClient,
59+
apiClient: opts.apiClient,
5260
};
5361
}
5462

@@ -60,17 +68,17 @@ export function createTRPCContext({
6068
chainId,
6169
enableTracing,
6270
scope,
63-
serviceApiKeys,
71+
apiKeys,
6472
}: CreateContextParams) {
6573
return async (opts: CreateContextOptions) => {
6674
try {
67-
const serviceClient = serviceApiKeys
68-
? createServiceClient(serviceApiKeys, opts.req)
75+
const apiClient = apiKeys
76+
? createApiClient(apiKeys, opts.req)
6977
: undefined;
7078

7179
const innerContext = createTRPCInnerContext({
7280
prisma,
73-
serviceClient,
81+
apiClient,
7482
blobPropagator,
7583
});
7684

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import type { LoggerLevel } from "@blobscan/logger";
2+
import { logger, logLevelEnum } from "@blobscan/logger";
3+
import { z } from "@blobscan/zod";
4+
5+
import { createAuthedProcedure } from "../../procedures";
6+
7+
export const getLevel = createAuthedProcedure("admin")
8+
.meta({
9+
openapi: {
10+
method: "GET",
11+
path: "/logging/level",
12+
summary: "Get the current logging level",
13+
tags: ["system"],
14+
},
15+
})
16+
.input(z.void())
17+
.output(
18+
z.object({
19+
level: logLevelEnum,
20+
})
21+
)
22+
.query(() => {
23+
return {
24+
level: logger.level as LoggerLevel,
25+
};
26+
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { t } from "../../trpc-client";
2+
import { getLevel } from "./getLevel";
3+
import { updateLevel } from "./updateLevel";
4+
5+
export const loggingRouter = t.router({
6+
getLevel,
7+
updateLevel,
8+
});

0 commit comments

Comments
 (0)