Skip to content

Commit f56c419

Browse files
authored
Merge pull request #368 from objectstack-ai/copilot/add-debug-logs-to-kernel
2 parents 2768088 + bab3d28 commit f56c419

File tree

12 files changed

+475
-107
lines changed

12 files changed

+475
-107
lines changed

examples/basic/logger-example.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ async function examplePluginLogging() {
182182
dependencies: ['database'],
183183

184184
init: async (ctx: PluginContext) => {
185-
const db = ctx.getService('db');
185+
const db = ctx.getService('db') as any;
186186
ctx.logger.info('API plugin initialized', { dbConnected: db.connected });
187187

188188
ctx.registerService('api', { server: 'http://localhost:3000' });

examples/basic/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"typecheck": "tsc --noEmit"
1010
},
1111
"dependencies": {
12-
"@objectstack/spec": "workspace:*"
12+
"@objectstack/spec": "workspace:*",
13+
"@objectstack/core": "workspace:*"
1314
},
1415
"devDependencies": {
1516
"typescript": "^5.0.0",

packages/client/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"build": "tsc"
99
},
1010
"dependencies": {
11-
"@objectstack/spec": "workspace:*"
11+
"@objectstack/spec": "workspace:*",
12+
"@objectstack/core": "workspace:*"
1213
},
1314
"devDependencies": {
1415
"typescript": "^5.0.0"

packages/client/src/index.ts

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { QueryAST, SortNode, AggregationNode, WindowFunctionNode } from '@objectstack/spec/data';
2+
import { Logger, createLogger } from '@objectstack/core';
23

34
export interface ClientConfig {
45
baseUrl: string;
@@ -7,6 +8,14 @@ export interface ClientConfig {
78
* Custom fetch implementation (e.g. node-fetch or for Next.js caching)
89
*/
910
fetch?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
11+
/**
12+
* Logger instance for debugging
13+
*/
14+
logger?: Logger;
15+
/**
16+
* Enable debug logging
17+
*/
18+
debug?: boolean;
1019
}
1120

1221
export interface DiscoveryResult {
@@ -41,27 +50,44 @@ export class ObjectStackClient {
4150
private token?: string;
4251
private fetchImpl: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
4352
private routes?: DiscoveryResult['routes'];
53+
private logger: Logger;
4454

4555
constructor(config: ClientConfig) {
4656
this.baseUrl = config.baseUrl.replace(/\/$/, ''); // Remove trailing slash
4757
this.token = config.token;
4858
this.fetchImpl = config.fetch || globalThis.fetch.bind(globalThis);
59+
60+
// Initialize logger
61+
this.logger = config.logger || createLogger({
62+
level: config.debug ? 'debug' : 'info',
63+
format: 'pretty'
64+
});
65+
66+
this.logger.debug('ObjectStack client created', { baseUrl: this.baseUrl });
4967
}
5068

5169
/**
5270
* Initialize the client by discovering server capabilities and routes.
5371
*/
5472
async connect() {
73+
this.logger.debug('Connecting to ObjectStack server', { baseUrl: this.baseUrl });
74+
5575
try {
5676
// Connect to the discovery endpoint
5777
// During boot, we might not know routes, so we check convention /api/v1 first
5878
const res = await this.fetch(`${this.baseUrl}/api/v1`);
5979

6080
const data = await res.json();
6181
this.routes = data.routes;
82+
83+
this.logger.info('Connected to ObjectStack server', {
84+
routes: Object.keys(data.routes || {}),
85+
capabilities: data.capabilities
86+
});
87+
6288
return data as DiscoveryResult;
6389
} catch (e) {
64-
console.error('Failed to connect to ObjectStack Server', e);
90+
this.logger.error('Failed to connect to ObjectStack server', e as Error, { baseUrl: this.baseUrl });
6591
throw e;
6692
}
6793
}
@@ -225,6 +251,12 @@ export class ObjectStackClient {
225251
}
226252

227253
private async fetch(url: string, options: RequestInit = {}): Promise<Response> {
254+
this.logger.debug('HTTP request', {
255+
method: options.method || 'GET',
256+
url,
257+
hasBody: !!options.body
258+
});
259+
228260
const headers: Record<string, string> = {
229261
'Content-Type': 'application/json',
230262
...(options.headers as Record<string, string> || {}),
@@ -236,13 +268,28 @@ export class ObjectStackClient {
236268

237269
const res = await this.fetchImpl(url, { ...options, headers });
238270

271+
this.logger.debug('HTTP response', {
272+
method: options.method || 'GET',
273+
url,
274+
status: res.status,
275+
ok: res.ok
276+
});
277+
239278
if (!res.ok) {
240279
let errorBody;
241280
try {
242281
errorBody = await res.json();
243282
} catch {
244283
errorBody = { message: res.statusText };
245284
}
285+
286+
this.logger.error('HTTP request failed', undefined, {
287+
method: options.method || 'GET',
288+
url,
289+
status: res.status,
290+
error: errorBody
291+
});
292+
246293
throw new Error(`[ObjectStack] Request failed: ${res.status} ${JSON.stringify(errorBody)}`);
247294
}
248295

@@ -252,7 +299,10 @@ export class ObjectStackClient {
252299
private getRoute(key: keyof DiscoveryResult['routes']): string {
253300
if (!this.routes) {
254301
// Fallback for strictness, but we allow bootstrapping
255-
console.warn(`[ObjectStackClient] Accessing ${key} route before connect(). Using default /api/v1/${key}`);
302+
this.logger.warn('Accessing route before connect()', {
303+
route: key,
304+
fallback: `/api/v1/${key}`
305+
});
256306
return `/api/v1/${key}`;
257307
}
258308
return this.routes[key] || `/api/v1/${key}`;

0 commit comments

Comments
 (0)